diff --git a/.gitattributes b/.gitattributes
index 1e4aed154..b16894c76 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,4 +1,4 @@
-# Set default behaviour for some text-like files, in case users don't have core.autocrlf set.
+# Set default behaviour for some text-like files, in case users don't have webodfcore.autocrlf set.
*.cmake text eol=native
diff --git a/.github/workflows/desktop.yml b/.github/workflows/desktop.yml
new file mode 100644
index 000000000..791aceae7
--- /dev/null
+++ b/.github/workflows/desktop.yml
@@ -0,0 +1,125 @@
+# Builds the viewer of OpenDocument for the desktop on the three systems it
+# runs on, and runs the tests of the library in the webengine of qt on each of
+# them. Two of those systems are ones no one of this project owns, which is
+# what this is for: the branches "if (WIN32)" and "if (APPLE)" of the build are
+# never run anywhere else.
+name: Viewer of the desktop
+
+on:
+ push:
+ branches: [master]
+ pull_request:
+ workflow_dispatch:
+
+jobs:
+ desktop:
+ name: ${{ matrix.name }}
+ runs-on: ${{ matrix.runner }}
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - name: Linux
+ runner: ubuntu-latest
+ qt: linux_gcc_64
+ - name: Windows
+ runner: windows-latest
+ qt: win64_msvc2022_64
+ # The runner is held at macos 15: the sdk of macos 26 dropped the
+ # framework AGL, that the configuration of Qt 6.8 still asks for,
+ # and the link of the runtime fails without it.
+ - name: macOS
+ runner: macos-15
+ qt: clang_64
+
+ steps:
+ # The whole history: the version of the build comes from "git describe",
+ # which a shallow checkout gives nothing to describe.
+ - uses: actions/checkout@v5
+ with:
+ fetch-depth: 0
+
+ - uses: actions/setup-node@v5
+ with:
+ node-version: 22
+ cache: npm
+
+ # A java runtime runs the closure compiler and rhino.
+ - uses: actions/setup-java@v5
+ with:
+ distribution: temurin
+ java-version: 21
+
+ # Qt WebEngine is an extension since 6.8, in a repository of its own; the
+ # action asks for it as a module, and webchannel and positioning come
+ # with it.
+ - uses: jurplel/install-qt-action@v4
+ with:
+ version: 6.8.2
+ arch: ${{ matrix.qt }}
+ modules: qtwebengine qtwebchannel qtpositioning
+ cache: true
+
+ # The webengine reads these on linux, where a runner carries no desktop.
+ - name: Libraries the engine reads
+ if: runner.os == 'Linux'
+ run: |
+ sudo apt-get update
+ sudo apt-get install --no-install-recommends -y \
+ libnss3 libxkbcommon-x11-0 libxcomposite1 libxdamage1 \
+ libxrandr2 libxtst6 libasound2t64 fonts-dejavu-core
+
+ - name: Dependencies of the build
+ run: npm ci
+
+ # No generator is named, so cmake takes the one of visual studio on
+ # windows, which finds the compiler of microsoft itself: nothing has to
+ # put it in the environment beforehand. MinGW, that Qt WebEngine does
+ # not compile with, is never the one taken.
+ - name: Configure
+ run: >
+ cmake -S . -B build
+ -DWEBODF_DESKTOP=ON
+ -DWEBODF_QTJSRUNTIME=ON
+ -DCMAKE_BUILD_TYPE=Release
+
+ # "--config" holds for the generators of more than one configuration,
+ # the one of visual studio among them, that pay no heed to
+ # "CMAKE_BUILD_TYPE"; the others take no harm from it.
+
+ # The library first: a viewer built on a library that fails its tests is
+ # worth nothing. The target runs every suite, in node, in rhino, on the
+ # sources and on the file the compiler wrote, and in the webengine of qt.
+ - name: Tests of the library
+ env:
+ QT_QPA_PLATFORM: offscreen
+ QTWEBENGINE_CHROMIUM_FLAGS: --disable-gpu --no-sandbox
+ run: cmake --build build --config Release --target webodf.js-tests
+
+ - name: Viewer
+ run: cmake --build build --config Release --target product-opendocumentviewer-desktop
+
+ # What the tools of the platform gather beside the program: the whole of
+ # it runs on a machine where qt is not installed.
+ # The prefix is absolute: the script that qt writes to deploy the
+ # libraries builds the path of "qt.conf" from it and refuses a relative
+ # one.
+ - name: Install what is deployed
+ run: >
+ cmake --install build --config Release
+ --prefix ${{ github.workspace }}/build/dist
+
+ # An archive rather than the files: a bundle of macos holds symbolic
+ # links, that an artifact of loose files loses.
+ - name: Gather what was installed
+ run: cmake -E tar czf ../opendocumentviewer-${{ matrix.name }}.tar.gz .
+ working-directory: build/dist
+
+ # "archive: false" hands the file over as it is: an artifact is wrapped
+ # in a zip otherwise, and whoever downloads it unpacks twice. The name
+ # of the artifact is then the name of the file.
+ - uses: actions/upload-artifact@v7
+ with:
+ path: build/opendocumentviewer-${{ matrix.name }}.tar.gz
+ archive: false
+ if-no-files-found: error
diff --git a/.github/workflows/library.yml b/.github/workflows/library.yml
new file mode 100644
index 000000000..c3fa2ebb2
--- /dev/null
+++ b/.github/workflows/library.yml
@@ -0,0 +1,59 @@
+# Builds the library the short way, with node alone, and runs what that build
+# runs: the tests in node, the same ones in rhino, and the check of the types.
+# It is the short one, that answers on every push, where the build of the
+# viewers is the long one.
+name: Library
+
+on:
+ push:
+ branches: [master]
+ pull_request:
+ workflow_dispatch:
+
+jobs:
+ library:
+ name: Library, with node
+ runs-on: ubuntu-latest
+
+ steps:
+ # The whole history: the version of the build comes from "git describe",
+ # which a shallow checkout gives nothing to describe.
+ - uses: actions/checkout@v5
+ with:
+ fetch-depth: 0
+
+ - uses: actions/setup-node@v5
+ with:
+ node-version: 22
+ cache: npm
+
+ # A java runtime runs the closure compiler and rhino.
+ - uses: actions/setup-java@v5
+ with:
+ distribution: temurin
+ java-version: 21
+
+ - name: Dependencies of the build
+ run: npm ci
+
+ - name: Types of the library and of the tests
+ run: |
+ npm run check
+ npm run check:tests
+
+ - name: Tests, in node
+ run: npm test
+
+ - name: Tests, in rhino
+ run: npm run test:rhino
+
+ - name: Library
+ run: npm run build
+
+ # "archive: false" hands the library over as it is, where an artifact
+ # is wrapped in a zip otherwise.
+ - uses: actions/upload-artifact@v7
+ with:
+ path: dist/webodf.js
+ archive: false
+ if-no-files-found: error
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 000000000..dd4f3cedf
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,154 @@
+# Builds every product a machine without a key can make, and publishes them
+# with the release of github. Gitlab builds and publishes its own, see
+# ".gitlab-ci.yml": neither forge pushes a file to the other. What needs a
+# signature is left out: the apk of android, the bundle of macos and the
+# application of ios, whose keys belong to whoever publishes them, see
+# "README-Products.md".
+name: Release
+
+on:
+ push:
+ tags: ['v*']
+ workflow_dispatch:
+
+jobs:
+ release:
+ name: Release of github
+ runs-on: ubuntu-latest
+ permissions:
+ contents: write
+
+ steps:
+ - uses: actions/checkout@v5
+ with:
+ fetch-depth: 0
+
+ - uses: actions/setup-node@v5
+ with:
+ node-version: 22
+ cache: npm
+
+ # The library, that no machine of the matrix writes: it is the package
+ # the other projects depend on.
+ - name: Package of the library
+ run: |
+ npm ci
+ mkdir -p products
+ npm pack --pack-destination products
+
+ # The release is opened before the products are built, so that each
+ # machine has one to hand its own to. A release that stands already is
+ # written to rather than opened again, so that the workflow can be run
+ # a second time on the same tag.
+ - name: Release of github
+ env:
+ GH_TOKEN: ${{ github.token }}
+ TAG: ${{ github.ref_name }}
+ run: |
+ if gh release view "$TAG" >/dev/null 2>&1; then
+ gh release upload "$TAG" products/* --clobber
+ else
+ gh release create "$TAG" --title "$TAG" \
+ --notes "The products of $TAG." products/*
+ fi
+
+ products:
+ name: Products of ${{ matrix.name }}
+ needs: release
+ runs-on: ${{ matrix.runner }}
+ permissions:
+ contents: write
+
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - name: Linux
+ runner: ubuntu-latest
+ qt: linux_gcc_64
+ - name: Windows
+ runner: windows-latest
+ qt: win64_msvc2022_64
+ # The runner is held at macos 15: the sdk of macos 26 dropped the
+ # framework AGL, that the configuration of Qt 6.8 still asks for,
+ # and the link of the runtime fails without it.
+ - name: macOS
+ runner: macos-15
+ qt: clang_64
+
+ steps:
+ # The whole history: the version of the build comes from "git describe",
+ # which a shallow checkout gives nothing to describe.
+ - uses: actions/checkout@v5
+ with:
+ fetch-depth: 0
+
+ - uses: actions/setup-node@v5
+ with:
+ node-version: 22
+ cache: npm
+
+ # A java runtime runs the closure compiler and rhino.
+ - uses: actions/setup-java@v5
+ with:
+ distribution: temurin
+ java-version: 21
+
+ # Qt WebEngine is an extension since 6.8, in a repository of its own; the
+ # modules are the ones the viewer links against.
+ - uses: jurplel/install-qt-action@v4
+ with:
+ version: 6.8.2
+ arch: ${{ matrix.qt }}
+ modules: qtwebengine qtwebchannel qtpositioning
+ cache: true
+
+ # The tools that write the packages of linux: what is not found is
+ # skipped by the build, which says so at the end.
+ - name: Tools of the packages
+ if: runner.os == 'Linux'
+ run: |
+ sudo apt-get update
+ sudo apt-get install --no-install-recommends -y \
+ rpm libnss3 libxkbcommon-x11-0 libxcomposite1 libxdamage1 \
+ libxrandr2 libxtst6 libasound2t64 fonts-dejavu-core
+
+ - name: Dependencies of the build
+ run: npm ci
+
+ # No generator is named, so cmake takes the one of visual studio on
+ # windows, which finds the compiler of microsoft itself: nothing has to
+ # put it in the environment beforehand. MinGW, that Qt WebEngine does
+ # not compile with, is never the one taken.
+ - name: Configure
+ run: >
+ cmake -S . -B build
+ -DWEBODF_DESKTOP=ON
+ -DWEBODF_PROGRAMS=ON
+ -DWEBODF_QTJSRUNTIME=ON
+ -DCMAKE_BUILD_TYPE=Release
+
+ # The library first: a product built on a library that fails its tests is
+ # worth nothing.
+ - name: Tests of the library
+ env:
+ QT_QPA_PLATFORM: offscreen
+ QTWEBENGINE_CHROMIUM_FLAGS: --disable-gpu --no-sandbox
+ run: cmake --build build --config Release --target webodf.js-tests
+
+ # One target gathers them all in "build/products", and names what this
+ # machine had no tool to write.
+ - name: Products
+ run: cmake --build build --config Release --target products
+
+ # Each machine hands its own products to the release, one file at a
+ # time: an artifact would wrap them in a zip of its own, and whoever
+ # downloads a package of debian wants that file and not a zip holding
+ # it.
+ # The shell is named: powershell, the one of windows, hands the star
+ # over as it stands rather than naming the files it stands for.
+ - name: Products of this machine, in the release
+ shell: bash
+ env:
+ GH_TOKEN: ${{ github.token }}
+ run: gh release upload ${{ github.ref_name }} build/products/* --clobber
diff --git a/.gitignore b/.gitignore
index fdf3b92d3..1be0a3f5a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,39 +1,47 @@
-/webodf/tests/simple_slide.odp
-#android/bin
-#android/gen
-nativeQtClient/nativeQtClient.pro.user
-programs/firefoxextension/content/web/viewer.html
-programs/firefoxextension/install.rdf
-programs/ios/WebODF.xcodeproj/project.xcworkspace
-programs/ios/WebODF.xcodeproj/xcuserdata
-programs/ios/www/ZoomIn.png
-programs/ios/www/ZoomOut.png
-programs/ios/www/app/
-programs/ios/www/sencha-touch.css
-programs/ios/www/sencha-touch.js
-programs/ios/www/webodf.js
+# What an editor or a system leaves beside the sources.
.DS_Store
-webodf/webodf.css.js
-build
-*.sw?
.idea
-node_modules/.bin/
-node_modules/requirejs/
-webodf/coverage/
-node_modules/karma-chrome-launcher/
-node_modules/karma-coffee-preprocessor/
-node_modules/karma-coverage/
-node_modules/karma-firefox-launcher/
-node_modules/karma-html2js-preprocessor/
-node_modules/karma-jasmine/
-node_modules/karma-junit-reporter/
-node_modules/karma-phantomjs-launcher/
-node_modules/karma-requirejs/
-node_modules/karma-script-launcher/
-node_modules/karma/
-fontFaceDeclsTest.odt
-test.odt
-simple.odt
-simpleFrame.odt
-webodf/tests/*.odt
-webodf/tests/odf/newloadsave.odt
+*.sw?
+
+# What cmake leaves where it is run: a configuration made in the sources rather
+# than in a directory of its own writes these two, and a stale cache in the
+# sources makes every later build refuse to configure.
+/CMakeCache.txt
+/CMakeFiles/
+/cmake.log
+
+# The build with cmake, that is made in a directory of its own.
+build
+
+# The build with node: its outputs, the tools it downloads and the report of
+# the coverage.
+dist
+.tools
+coverage
+
+# Only the runtime dependency is versioned, see README-Building.md. The tools
+# of the build are installed with npm.
+node_modules/*
+!node_modules/.package-lock.json
+!node_modules/@xmldom
+
+# The css of the viewer, written as a string of javascript by the build.
+webodf/webodf.css.js
+
+# The documents the tests write beside the ones they read.
+# What an office leaves beside a document it has open.
+.~lock.*#
+
+# What a test writes, that goes to a directory of its own, see
+# "webodf/tests/CMakeLists.txt".
+webodf/tests/out/
+
+# The library is copied into the assets of the viewer of android.
+programs/opendocumentviewer-android/src/main/assets/webodf.js
+# The pages of the format are written by cmake from the text of "programs/text",
+# among the assets, as the library is: gradle reads them from there.
+programs/opendocumentviewer-android/src/main/assets/about.en.html
+programs/opendocumentviewer-android/src/main/assets/about.fr.html
+programs/opendocumentviewer-android/.gradle
+programs/opendocumentviewer-android/build
+programs/opendocumentviewer-android/local.properties
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 000000000..7ec25eb71
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,123 @@
+# Builds the products and publishes them with the release of gitlab. Github
+# builds and publishes its own, see ".github/workflows/release.yml": neither
+# forge pushes a file to the other.
+#
+# The runners of gitlab.com are of linux, so the products are the ones of
+# linux and the ones no platform is needed for: the archive of the desktop,
+# the packages of debian and of fedora, the add-ons and the library. The
+# viewers of windows and of macos are built by the workflow of github, on the
+# machines of those systems.
+#
+# What needs a key of its own is left out, as there too: the apk of android,
+# the bundle of macos and the application of ios.
+
+stages:
+ - products
+ - release
+
+variables:
+ # The whole history: the version of the build comes from "git describe",
+ # which a shallow clone gives nothing to describe.
+ GIT_DEPTH: "0"
+ PACKAGE: ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/webodf
+
+products:
+ stage: products
+ # The image carries node 22, which the build asks for, on debian trixie,
+ # whose packages carry the qt 6.8 the viewer is built against: the node of
+ # trixie itself is a 20 and is too old.
+ image: node:22-trixie
+ rules:
+ - if: $CI_COMMIT_TAG =~ /^v[0-9]/
+ before_script:
+ - apt-get update
+ - >
+ apt-get install --no-install-recommends -y
+ build-essential cmake ninja-build git curl ca-certificates
+ default-jre-headless rpm
+ qt6-base-dev qt6-webengine-dev qt6-webengine-dev-tools
+ libgl-dev fonts-dejavu-core
+ - npm ci
+ script:
+ - >
+ cmake -S . -B build
+ -DWEBODF_DESKTOP=ON
+ -DWEBODF_PROGRAMS=ON
+ -DWEBODF_QTJSRUNTIME=ON
+ -DCMAKE_BUILD_TYPE=Release
+ # The library first: a product built on a library that fails its tests is
+ # worth nothing.
+ - QT_QPA_PLATFORM=offscreen QTWEBENGINE_CHROMIUM_FLAGS="--disable-gpu --no-sandbox"
+ cmake --build build --target webodf.js-tests
+ # One target gathers them all in "build/products", and names what this
+ # machine had no tool to write.
+ - cmake --build build --target products
+ - mkdir -p build/products
+ - npm pack --pack-destination build/products
+ # Each product goes to the generic package registry of the project, whose
+ # token is the one of the job: no token of a person is needed. One file of
+ # json is written beside each product, which is the link the release is
+ # given, so that the release has only to send them.
+ - |
+ version=${CI_COMMIT_TAG#v}
+ mkdir -p links
+ for file in build/products/*; do
+ name=$(basename "$file")
+ url=$PACKAGE/$version/$name
+ curl --fail --silent --show-error --upload-file "$file" \
+ --header "JOB-TOKEN: $CI_JOB_TOKEN" "$url"
+ printf '{"name":"%s","url":"%s","link_type":"package","direct_asset_path":"/%s"}' \
+ "$name" "$url" "$name" > "links/$name.json"
+ done
+ artifacts:
+ paths:
+ - build/products
+ - links
+ expire_in: 1 week
+
+release:
+ stage: release
+ # The image is the one of the products, for the client of http it holds: the
+ # image of "release-cli" holds none, and its "update" takes no link, so the
+ # api of the releases is called instead.
+ image: node:22-trixie
+ rules:
+ - if: $CI_COMMIT_TAG =~ /^v[0-9]/
+ needs:
+ - job: products
+ artifacts: true
+ before_script:
+ - apt-get update
+ - apt-get install --no-install-recommends -y curl ca-certificates
+ script:
+ # A release that stands already is given the links it has not got yet,
+ # rather than opened again, so that the pipeline can be run a second time
+ # on the same tag. A link that is there answers 400, which is not a
+ # failure here.
+ - |
+ set -eu
+ api=${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/releases
+ auth="JOB-TOKEN: $CI_JOB_TOKEN"
+ json='Content-Type: application/json'
+ code=$(curl --silent --output /dev/null --write-out '%{http_code}' \
+ --header "$auth" "$api/$CI_COMMIT_TAG")
+ if [ "$code" = "404" ]; then
+ links=$(cat links/*.json | sed 's/}{/},{/g')
+ curl --fail --silent --show-error --request POST \
+ --header "$auth" --header "$json" \
+ --data "{\"tag_name\":\"$CI_COMMIT_TAG\",
+ \"name\":\"$CI_COMMIT_TAG\",
+ \"description\":\"The products of $CI_COMMIT_TAG.\",
+ \"assets\":{\"links\":[$links]}}" \
+ "$api"
+ else
+ for link in links/*.json; do
+ code=$(curl --silent --output /dev/null --write-out '%{http_code}' \
+ --request POST --header "$auth" --header "$json" \
+ --data @"$link" "$api/$CI_COMMIT_TAG/assets/links")
+ case $code in
+ 2*|400) ;;
+ *) echo "the link of $link was refused ($code)"; exit 1 ;;
+ esac
+ done
+ fi
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 54a56fe5b..7b8f58226 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,10 +1,16 @@
# This makefile 'compiles' WebODF using various tools, instruments the code and
# builds and packages programs that use WebODF.
-# WebODF is mostly a JavaScript project. CMake needs to know about the C++ parts
-project (WebODF C CXX)
+# The project needs cmake 3.10 and works with the policies of cmake 3.24. The
+# most useful of them is CMP0135: the archives of the tools are downloaded
+# from an url, so the timestamps of the files they hold have to be the ones of
+# the extraction, otherwise a change of the url does not rebuild what depends
+# on them. Older versions of cmake read the range as its first version only.
+cmake_minimum_required(VERSION 3.10...3.24)
+message("CMake version: ${CMAKE_VERSION}")
-cmake_minimum_required(VERSION 2.8.11)
+# WebODF is mostly a JavaScript project. CMake needs to know about the C++ parts
+project(WebODF C CXX)
# Require separate build dir
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
@@ -38,9 +44,21 @@ else (OVERRULED_WEBODF_VERSION)
set(WEBODF_VERSION ${CMAKE_MATCH_1})
else (CMAKE_MATCH_1)
# get version number from git
- exec_program(git ${CMAKE_CURRENT_SOURCE_DIR}
- ARGS describe --tags --dirty --match "v[0-9]*"
- OUTPUT_VARIABLE GIT_WEBODF_VERSION)
+ # A build of a tag is named after that tag alone: a release is what the
+ # tag says, and a file written in the tree while it is built, which a
+ # machine of integration does, would else add "-dirty" to the name of
+ # every product.
+ execute_process(COMMAND git describe --tags --exact-match --match "v[0-9]*"
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ OUTPUT_VARIABLE GIT_WEBODF_VERSION
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET)
+ if (NOT GIT_WEBODF_VERSION)
+ execute_process(COMMAND git describe --tags --dirty --match "v[0-9]*"
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ OUTPUT_VARIABLE GIT_WEBODF_VERSION
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ endif ()
# check version number from git
string(REGEX MATCH "^v([0-9]+.[0-9]+.[0-9]+((-[0-9]+-[0-9a-z]+)?(-dirty)?)?)$" CHECKED_WEBODF_VERSION "${GIT_WEBODF_VERSION}")
if (CMAKE_MATCH_1)
@@ -52,29 +70,95 @@ else (OVERRULED_WEBODF_VERSION)
endif (OVERRULED_WEBODF_VERSION)
message(STATUS "WebODF version " ${WEBODF_VERSION})
+# The version is read once, when the build is configured, and it names the
+# packages, so a build made after a commit would keep the version of the one
+# before. Reading these two files here ties the configuration to them: cmake
+# runs itself again, before make, as soon as a commit or a checkout writes
+# them, and the version follows the sources without anything to remember.
+foreach (GIT_FILE .git/HEAD .git/index)
+ if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${GIT_FILE})
+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${GIT_FILE}
+ ${CMAKE_CURRENT_BINARY_DIR}/git-watch/${GIT_FILE} COPYONLY)
+ endif()
+endforeach()
+
+# The manifest of an add-on only takes up to four numbers separated by dots,
+# where git describe adds the number of commits and the hash of the last one:
+# "0.5.10-161-gc2572a4a" is written "0.5.10.161", so that the builds between
+# two tags still follow each other. A tagged build is left as it is.
+string(REGEX REPLACE "^([0-9]+(\\.[0-9]+)*)-([0-9]+)-g[0-9a-f]+.*$" "\\1.\\3"
+ WEBODF_MANIFEST_VERSION "${WEBODF_VERSION}")
+string(REGEX REPLACE "-dirty$" "" WEBODF_MANIFEST_VERSION "${WEBODF_MANIFEST_VERSION}")
+
#########################################################
## Find installed dependencies
#########################################################
-set(QT_MIN_VERSION "5.1.1")
-find_package(Qt5Network)
-find_package(Qt5Xml)
-find_package(Qt5PrintSupport)
-find_package(Qt5WebKitWidgets)
+# qtjsruntime runs the tests in the webengine of qt, see "webodf/tests". It is
+# opt-in, as it needs the modules of qt, that weigh more than the rest of the
+# build together, while "npm run test:browser" runs the same tests in a browser
+# that is installed anyway. Without the option, the modules are not looked for
+# at all, so no warning is reported for something that is not asked for.
+#
+# It ran in Qt WebKit until 2026, that Qt dropped in 5.6, in 2016, and that
+# Debian stopped packaging in 13: the program was rewritten for webengine, that
+# is the blink of chromium, see "programs/qtjsruntime".
+option(WEBODF_QTJSRUNTIME "Build qtjsruntime, that runs the tests in the webengine of qt" OFF)
+
+# The viewer of OpenDocument for the desktop is a window of qt around the page
+# the library draws in, see "programs/opendocumentviewer-desktop". It is opt-in
+# for the same reason, and it is built by the option alone, without
+# WEBODF_PROGRAMS, as it needs neither Dojo nor the editors.
+option(WEBODF_DESKTOP "Build the viewer of OpenDocument for the desktop, in qt" OFF)
+
+# 6.4 is the oldest version the two programs are written for, the one of Debian
+# 12. Everything they use was already in the first release of Qt 6: a channel to
+# the page, a collection of scripts on the profile, a handler of a url scheme,
+# and printing to a pdf.
+set(BUILD_QTJSRUNTIME FALSE)
+set(BUILD_DESKTOP FALSE)
+if (WEBODF_QTJSRUNTIME OR WEBODF_DESKTOP)
+ find_package(Qt6 6.4 COMPONENTS Core Gui Widgets PrintSupport WebChannel WebEngineCore WebEngineWidgets)
+
+ if (Qt6_FOUND)
+ set(BUILD_QTJSRUNTIME ${WEBODF_QTJSRUNTIME})
+ set(BUILD_DESKTOP ${WEBODF_DESKTOP})
+ else ()
+ message(FATAL_ERROR "Qt6 with the modules Core Gui Widgets PrintSupport WebChannel WebEngineCore WebEngineWidgets was not found, so neither qtjsruntime nor the viewer for the desktop can be built. On Debian 12 and later: apt-get install qt6-base-dev qt6-base-dev-tools qt6-webchannel-dev qt6-webengine-dev qt6-webengine-dev-tools")
+ endif ()
+endif ()
-if (Qt5Network_FOUND AND Qt5Xml_FOUND AND Qt5PrintSupport_FOUND AND Qt5WebKitWidgets_FOUND)
- set(BUILD_QTJSRUNTIME TRUE)
+# Java runs the closure compiler and rhino, that check the types of the
+# sources and run the tests in a second engine. Neither writes the library:
+# terser does, with node. So java is looked for and not required, and a
+# machine without it builds everything but the checks, which is what a build
+# in a sandbox does, see the flatpak of the viewer.
+find_package(Java COMPONENTS Runtime)
+if (Java_JAVA_EXECUTABLE)
+ set(WEBODF_HAS_JAVA TRUE)
else ()
- message(WARNING "Qt5 with modules Qt5Network Qt5Xmle Qt5PrintSupport Qt5WebKitWidgets was not found. qtjsruntime will no be built.")
- set(BUILD_QTJSRUNTIME FALSE)
+ set(WEBODF_HAS_JAVA FALSE)
+ message(STATUS "No java was found: the types of the sources are not checked, and the tests are not run in rhino.")
endif ()
-# java runtime is needed for Closure Compiler
-find_package(Java COMPONENTS Runtime REQUIRED)
+# A build that is given a library that was built already builds nothing of it:
+# it neither runs node nor asks for it. That is what a build in a sandbox
+# does, where there is neither node nor a network to install its tools from,
+# see the flatpak of the viewer of the desktop.
+set(WEBODF_PREBUILT_LIBRARY "" CACHE FILEPATH
+ "A webodf.js that was built already, to be used instead of building one")
+if (WEBODF_PREBUILT_LIBRARY AND NOT EXISTS "${WEBODF_PREBUILT_LIBRARY}")
+ message(FATAL_ERROR
+ "WEBODF_PREBUILT_LIBRARY names ${WEBODF_PREBUILT_LIBRARY}, which is not there.")
+endif ()
# Node.js will be downloaded on Windows systems, so check for installed version is below
-SET(REQUIRED_NODEJS_VERSION 0.10.5)
+# 22.22.2 is the oldest release of node jsdom runs on, that the tests need.
+# The tools of the build are tested with 24, the release under long term
+# support. The exact range is in the field "engines" of "package.json", that
+# cmake cannot express.
+SET(REQUIRED_NODEJS_VERSION 22.22.2)
#########################################################
@@ -92,92 +176,104 @@ else ( IS_DIRECTORY $ENV{WEBODF_DOWNLOAD_DIR} )
endif ( IS_DIRECTORY $ENV{WEBODF_DOWNLOAD_DIR} )
MESSAGE ( STATUS "external downloads will be stored/expected in: ${EXTERNALS_DOWNLOAD_DIR}" )
+# The two jars are downloaded for java to run them: a build without java, or
+# one that was given a library and checks nothing, asks nothing of the
+# network. A sandbox has no network at all, see the flatpak of the viewer.
+if (WEBODF_HAS_JAVA AND NOT WEBODF_PREBUILT_LIBRARY)
+
# Closure Compiler
ExternalProject_Add(
ClosureCompiler
DOWNLOAD_DIR ${EXTERNALS_DOWNLOAD_DIR}
- URL "http://dl.google.com/closure-compiler/compiler-20160911.tar.gz"
- URL_MD5 7e85253436e492aa580ce3c3b8f585e7
+ URL "https://repo1.maven.org/maven2/com/google/javascript/closure-compiler/v20260804/closure-compiler-v20260804.jar"
+ # Without the hash, cmake has no way to tell whether the file it already has
+ # is the right one, so it downloads it again at every build, see the target
+ # Gradle below.
+ URL_HASH SHA256=0cb86a4b96769c679b4fc2d2dc0e5acd0abd0dff932945b90fbe327247466a29
+ DOWNLOAD_NO_EXTRACT TRUE
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
)
-set(CLOSURE_JAR ${CMAKE_BINARY_DIR}/ClosureCompiler-prefix/src/ClosureCompiler/closure-compiler-v20160911.jar)
+# Same version as the build with node, see scripts/lib/closure.js.
+set(CLOSURE_JAR ${EXTERNALS_DOWNLOAD_DIR}/closure-compiler-v20260804.jar)
# Rhino
ExternalProject_Add(
Rhino
DOWNLOAD_DIR ${EXTERNALS_DOWNLOAD_DIR}
- URL "http://ftp.mozilla.org/pub/js/rhino1_7R3.zip"
- URL_MD5 99d94103662a8d0b571e247a77432ac5
+ URL "https://repo1.maven.org/maven2/org/mozilla/rhino-all/1.9.1/rhino-all-1.9.1.jar"
+ URL_HASH SHA256=1cc2b468a51857747dcb29ae533e352a2abc04e81c5aa61e397dc774dd395329
+ DOWNLOAD_NO_EXTRACT TRUE
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
)
-set(RHINO ${CMAKE_BINARY_DIR}/Rhino-prefix/src/Rhino/js.jar)
+# Same version as the build with node, see scripts/lib/rhino.js.
+set(RHINO ${EXTERNALS_DOWNLOAD_DIR}/rhino-all-1.9.1.jar)
-# JSDoc
-ExternalProject_Add(
- JsDoc
- DOWNLOAD_DIR ${EXTERNALS_DOWNLOAD_DIR}
- URL "https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/jsdoc-toolkit/jsdoc_toolkit-2.4.0.zip"
- URL_MD5 a8f78f5ecd24b54501147b2af341a231
- CONFIGURE_COMMAND ""
- BUILD_COMMAND ""
- INSTALL_COMMAND ""
+endif ()
+
+
+# Node.js is expected to be installed, on every platform. Windows used to
+# download a single node.exe, but the build needs npm as well, that comes with
+# the installer only, and the url that binary was at holds the releases of
+# 2013 alone.
+SET(NODEJS_VERSION 0.0.0)
+# Debian uses nodejs as binary name, due to conflict with node package (Amateur Packet Radio Node Program)
+# https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager
+FIND_PROGRAM(NODEJS_EXECUTABLE
+ NAMES nodejs node
+ PATHS ""
+ DOC "Path to Node.js executable"
)
-set(JSDOCDIR ${CMAKE_BINARY_DIR}/JsDoc-prefix/src/JsDoc/jsdoc-toolkit)
-
-# Node.js
-set(NODEVERSION 0.10.20)
-if(WIN32)
- # On windows, it is significantly faster and more reliable to download
- # a pre-built 32-bit binary
- set(NODE_BIN_URL "http://nodejs.org/dist/v${NODEVERSION}/node.exe")
- set(NODE_BIN_MD5 "3bc43fbbfcddc376d5769e9757bd0bca")
- file(DOWNLOAD "${NODE_BIN_URL}" "${EXTERNALS_DOWNLOAD_DIR}/node-download.exe"
- SHOW_PROGRESS
- EXPECTED_MD5 ${NODE_BIN_MD5}
- )
- set(NODE ${CMAKE_BINARY_DIR}/NodeJS-prefix/bin/node.exe)
- set(NPM ${CMAKE_BINARY_DIR}/NodeJS-prefix/bin/npm.exe)
- execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/NodeJS-prefix
- COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/NodeJS-prefix/bin
- COMMAND ${CMAKE_COMMAND} -E copy ${EXTERNALS_DOWNLOAD_DIR}/node-download.exe "${NODE}"
- )
- add_custom_target(NodeJS DEPENDS "${NODE}")
-else(WIN32)
- SET(NODEJS_VERSION 0.0.0)
- # Debian uses nodejs as binary name, due to conflict with node package (Amateur Packet Radio Node Program)
- # https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager
- FIND_PROGRAM(NODEJS_EXECUTABLE
- NAMES nodejs node
- PATHS ""
- DOC "Path to Node.js executable"
- )
- IF(NODEJS_EXECUTABLE)
- EXEC_PROGRAM(${NODEJS_EXECUTABLE} ARGS --version OUTPUT_VARIABLE NODEJS_VERSION)
- string(SUBSTRING ${NODEJS_VERSION} 1 -1 NODEJS_VERSION)
- MESSAGE (STATUS "Installed Node.js found: ${NODEJS_EXECUTABLE} - ${NODEJS_VERSION}")
- ELSE(NODEJS_EXECUTABLE)
- MESSAGE (STATUS "No installed Node.js found. On platforms other than Windows, Node.js is not downloaded, but expected to be installed.")
- ENDIF(NODEJS_EXECUTABLE)
-
- # fail if NodeJS version requirement is not satisfied
- if (${NODEJS_VERSION} VERSION_LESS ${REQUIRED_NODEJS_VERSION})
- message(FATAL_ERROR "Node.js is required in version " ${REQUIRED_NODEJS_VERSION} " or later")
- else()
- message(STATUS "good Node.js found: " ${NODEJS_VERSION} " (" ${REQUIRED_NODEJS_VERSION} " required.)")
- endif()
- set(NODE ${NODEJS_EXECUTABLE})
- FIND_PROGRAM(NPM
- NAMES npm
- PATHS ""
- DOC "Path to NPM executable"
- )
- MESSAGE (STATUS "npm found: " ${NPM})
- add_custom_target(NodeJS DEPENDS "${NODEJS_EXECUTABLE}")
-endif(WIN32)
+IF(NODEJS_EXECUTABLE)
+ execute_process(COMMAND ${NODEJS_EXECUTABLE} --version
+ OUTPUT_VARIABLE NODEJS_VERSION
+ ERROR_VARIABLE NODEJS_SAID
+ RESULT_VARIABLE NODEJS_ANSWERED
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ # A node that is there and answers nothing is a node that cannot be used,
+ # and it is said as much: the version was read as it stood, so an answer
+ # of nothing ended the build on "string sub-command SUBSTRING requires
+ # four arguments", which tells a reader nothing of node.
+ if (NOT NODEJS_ANSWERED EQUAL 0 OR NODEJS_VERSION STREQUAL "")
+ message(FATAL_ERROR "Node.js was found at " ${NODEJS_EXECUTABLE}
+ " but it answered nothing when asked for its version"
+ " (\"${NODEJS_EXECUTABLE} --version\" said \"${NODEJS_SAID}\")."
+ "\nThe path may be one that cmake kept from a build that went"
+ " before, of a node that is no longer installed: run it again"
+ " with -U NODEJS_EXECUTABLE -U NPM.")
+ endif ()
+ string(SUBSTRING "${NODEJS_VERSION}" 1 -1 NODEJS_VERSION)
+ MESSAGE (STATUS "Installed Node.js found: ${NODEJS_EXECUTABLE} - ${NODEJS_VERSION}")
+ELSE(NODEJS_EXECUTABLE)
+ MESSAGE (STATUS "No installed Node.js found. Node.js is not downloaded, but expected to be installed.")
+ENDIF(NODEJS_EXECUTABLE)
+
+# fail if NodeJS version requirement is not satisfied. find_program() caches
+# what it finds, so a node that was installed later, by nvm for instance, is
+# only seen once the entry is dropped: the path is named here, as it is often
+# an older one that is still in the cache.
+if (WEBODF_PREBUILT_LIBRARY)
+ message(STATUS "The library is taken from ${WEBODF_PREBUILT_LIBRARY}: node is not needed.")
+elseif (NODEJS_VERSION VERSION_LESS REQUIRED_NODEJS_VERSION)
+ message(FATAL_ERROR "Node.js is required in version "
+ ${REQUIRED_NODEJS_VERSION} " or later, but "
+ ${NODEJS_EXECUTABLE} " is " ${NODEJS_VERSION}
+ ".\nIf a newer node is installed, cmake kept the path it found before:"
+ " run it again with -U NODEJS_EXECUTABLE -U NPM.")
+else()
+ message(STATUS "good Node.js found: " ${NODEJS_VERSION} " (" ${REQUIRED_NODEJS_VERSION} " required.)")
+endif()
+set(NODE ${NODEJS_EXECUTABLE})
+FIND_PROGRAM(NPM
+ NAMES npm
+ PATHS ""
+ DOC "Path to NPM executable"
+)
+MESSAGE (STATUS "npm found: " ${NPM})
+add_custom_target(NodeJS DEPENDS "${NODEJS_EXECUTABLE}")
# copy node_modules directory from source to build
# (this is needed if a module is required in there)
@@ -190,90 +286,108 @@ add_custom_target(copy_node_modules ALL
COMMENT copying node_modules from source to build
)
-# Android
-# If android sdk is properly installed, cmake only needs to know where to find
-# the executable 'android'.
-# The variable ANDROID_SDK_DIR can be provided if a specific android sdk version
-# is desired or if the android executable is not in the path.
-if (ANDROID_SDK_DIR)
- set(ANDROID ${ANDROID_SDK_DIR}/tools/android)
-else (ANDROID_SDK_DIR)
- find_program(ANDROID NAMES android DOC "Path to the Android executable.")
-endif(ANDROID_SDK_DIR)
-FIND_PROGRAM(ANT NAMES ant DOC "Path to the Ant executable.")
-if(ANDROID AND ANT)
- set(BUILD_APK TRUE)
- message(STATUS "Found Android and Ant: building an APK for Android.")
- message(STATUS "android: ${ANDROID}")
- message(STATUS "ant: ${ANT}")
-else()
- message(STATUS "Android was not found: APK will not be built.")
-endif()
+# The coverage is measured by c8, that reads the one V8 records while it runs
+# the tests: it neither parses nor rewrites the sources, so it does not
+# constrain the version of ECMAScript the library is written in. It replaces
+# JSCoverage, whose last release, 0.5.1 of 2010, bundles SpiderMonkey 1.7 and
+# does not build any more with gcc 14 or clang 16.
+#
+# It is a target of its own, never built by "all", as it is only useful to
+# measure the coverage and it runs the whole suite of the tests again.
+add_custom_target(coverage
+ COMMAND ${NPM} run coverage
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ COMMENT "Measuring the coverage of the tests with c8"
+ USES_TERMINAL
+)
+
+# The programs, the editors and the extensions, need Dojo, that is downloaded
+# from the registry of npm, see below. They are built only when they are asked
+# for, so that the library builds without them.
+option(WEBODF_PROGRAMS "Build the editors and the extensions of programs/" OFF)
+
-# JSCoverage
-if(WIN32)
- # JSCoverage only builds with Cygwin/MiniGW
- # Rather than force a dependency on a specific compiler, download binaries
- ExternalProject_Add(
- JSCoverage
- DOWNLOAD_DIR ${EXTERNALS_DOWNLOAD_DIR}
- URL "http://siliconforks.com/jscoverage/download/jscoverage-0.5.1-windows.zip"
- CONFIGURE_COMMAND ""
- BUILD_COMMAND ""
- INSTALL_COMMAND ""
- TEST_COMMAND ""
- )
- set(JSCOVERAGE ${CMAKE_BINARY_DIR}/JSCoverage-prefix/src/JSCoverage/jscoverage)
-elseif(APPLE)
-else()
- ExternalProject_Add(
- JSCoverage
- DOWNLOAD_DIR ${EXTERNALS_DOWNLOAD_DIR}
- URL "http://siliconforks.com/jscoverage/download/jscoverage-0.5.1.tar.bz2"
- URL_MD5 a70d79a6759367fbcc0bcc18d6866ff3
- PATCH_COMMAND cat ${CMAKE_CURRENT_SOURCE_DIR}/JSCoverage.patch | patch -p1
- CONFIGURE_COMMAND "./configure"
- BUILD_COMMAND make -j${NProcessors}
- BUILD_IN_SOURCE 1
- INSTALL_COMMAND ""
- )
- set(JSCOVERAGE ${CMAKE_BINARY_DIR}/JSCoverage-prefix/src/JSCoverage/jscoverage)
-endif()
# Dojo
+# The source release of dojotoolkit.org is not published any more, so the four
+# packages are taken from the registry of npm, where they are still released.
+set(DOJO_VERSION 1.17.3)
+if (WEBODF_PROGRAMS)
ExternalProject_Add(
- Dojo
+ DojoCore
DOWNLOAD_DIR ${EXTERNALS_DOWNLOAD_DIR}
- URL "http://download.dojotoolkit.org/release-1.8.1/dojo-release-1.8.1-src.tar.gz"
- URL_MD5 9b80b9a736b81c336accd832f3c3aea2
+ URL "https://registry.npmjs.org/dojo/-/dojo-${DOJO_VERSION}.tgz"
+ # Without the hash, cmake downloads the archive again at every build, as it
+ # cannot tell whether the one it holds is the right one.
+ URL_HASH SHA256=84d7e0e59a024885631276f2ae44064b778fbb83d12ecfa0d3fc93f44c9d38b1
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
)
-set(DOJO ${CMAKE_BINARY_DIR}/Dojo-prefix/src/Dojo)
-
-# Dojo requires a patch on windows
-if(WIN32)
- set(DOJOPATCH_URL "http://bugs.dojotoolkit.org/raw-attachment/ticket/15413/node-win-1.8.patch")
- set(DOJOPATCH_MD5 "51eae664ddbe919c28c4e3082748cd19")
- set(DOJOPATCH ${EXTERNALS_DOWNLOAD_DIR}/dojo-node.patch)
-
- file(DOWNLOAD "${DOJOPATCH_URL}" "${DOJOPATCH}"
- SHOW_PROGRESS
- EXPECTED_MD5 ${DOJOPATCH_MD5}
- )
-
-
- ExternalProject_Add_Step(Dojo applyPatch
- COMMAND cat ${DOJOPATCH} | patch -p0 -d ${CMAKE_BINARY_DIR}/Dojo-prefix/src/Dojo/util/
- DEPENDEES build
- )
-endif(WIN32)
+ExternalProject_Add(
+ DojoDijit
+ DOWNLOAD_DIR ${EXTERNALS_DOWNLOAD_DIR}
+ URL "https://registry.npmjs.org/dijit/-/dijit-${DOJO_VERSION}.tgz"
+ URL_HASH SHA256=d1e0e41d21ebfd0214ec4c1956816d04efcdf68a84c4aa85600a7c34846b5a26
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+)
+ExternalProject_Add(
+ DojoDojox
+ DOWNLOAD_DIR ${EXTERNALS_DOWNLOAD_DIR}
+ URL "https://registry.npmjs.org/dojox/-/dojox-${DOJO_VERSION}.tgz"
+ URL_HASH SHA256=ba6fa9e334a9519247afc7cf52a72f57458078d8e4ef1074ee4ca4e826b7203e
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+)
+ExternalProject_Add(
+ DojoUtil
+ DOWNLOAD_DIR ${EXTERNALS_DOWNLOAD_DIR}
+ URL "https://registry.npmjs.org/dojo-util/-/dojo-util-${DOJO_VERSION}.tgz"
+ URL_HASH SHA256=1811801438bd81f306834b2c864d6345d649797a32088b3333a7f6732a97e484
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+)
+add_custom_target(Dojo DEPENDS DojoCore DojoDijit DojoDojox DojoUtil)
+set(DOJO_CORE ${CMAKE_BINARY_DIR}/DojoCore-prefix/src/DojoCore)
+set(DOJO_DIJIT ${CMAKE_BINARY_DIR}/DojoDijit-prefix/src/DojoDijit)
+set(DOJO_DOJOX ${CMAKE_BINARY_DIR}/DojoDojox-prefix/src/DojoDojox)
+set(DOJO_UTIL ${CMAKE_BINARY_DIR}/DojoUtil-prefix/src/DojoUtil)
+endif (WEBODF_PROGRAMS)
##############################
## Define custom macros
##############################
+# The pages of the products tell what the OpenDocument format is worth, and they
+# tell it in the same words: the text is written once, in "programs/text", and
+# inserted where a page names it, "@FORMAT_TEXT@". A page is a template,
+# "*.html.in", and the page itself is written into the build directory.
+#
+# The text is read here, and it is named as a dependency of the configuration,
+# so that cmake runs itself again when it is revised: the pages then follow
+# without anything to remember.
+set(TEXT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/programs/text)
+foreach (LANGUAGE en fr)
+ file(READ ${TEXT_DIR}/format.${LANGUAGE}.html FORMAT_TEXT_${LANGUAGE})
+ # The newline an editor writes at the end of a file would become a blank line
+ # in every page, so the text is taken without what closes it.
+ string(REGEX REPLACE "[ \t\r\n]+$" "" FORMAT_TEXT_${LANGUAGE}
+ "${FORMAT_TEXT_${LANGUAGE}}")
+ set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS
+ ${TEXT_DIR}/format.${LANGUAGE}.html)
+endforeach ()
+
+# INSERT_TEXT (template output language)
+# Writes the page of a product, with the text of the format in it.
+macro(INSERT_TEXT _template _output _language)
+ set(FORMAT_TEXT "${FORMAT_TEXT_${_language}}")
+ configure_file(${_template} ${_output} @ONLY)
+endmacro(INSERT_TEXT)
+
# COPY_FILES (varname srcdir tgtdir files)
# Creates a target that copies the listed files from the srcdir to the tgtdir,
# preserving their relative path.
@@ -323,13 +437,31 @@ set(LIBJSLICENSEFILE ${CMAKE_CURRENT_SOURCE_DIR}/AGPL-3.0.txt)
set(WEBODFJS_DIR ${CMAKE_CURRENT_BINARY_DIR}/webodf.js-${WEBODF_VERSION})
set(WEBODFJS_ZIP webodf.js-${WEBODF_VERSION}.zip)
-set(WODOTEXTEDITORBUILDDIR ${CMAKE_CURRENT_BINARY_DIR}/wodotexteditor)
-
-set(WODOCOLLABTEXTEDITORBUILDDIR ${CMAKE_BINARY_DIR}/wodocollabtexteditor)
-set(WODOCOLLABTEXTEDITOR_ZIP ${CMAKE_CURRENT_BINARY_DIR}/wodocollabtexteditor-${WEBODF_VERSION}.zip)
-
-set(FIREFOX_EXTENSION_ODFVIEWER_DIR ${CMAKE_CURRENT_BINARY_DIR}/firefox-extension-odfviewer-${WEBODF_VERSION})
-set(FIREFOX_EXTENSION_ODFVIEWER ${FIREFOX_EXTENSION_ODFVIEWER_DIR}.xpi)
+set(OPENDOCUMENTTEXTEDITORBUILDDIR ${CMAKE_CURRENT_BINARY_DIR}/opendocumenttexteditor)
+
+set(OPENDOCUMENTTEXTCOLLABBUILDDIR ${CMAKE_BINARY_DIR}/opendocumenttextcollab)
+set(OPENDOCUMENTTEXTCOLLAB_ZIP ${CMAKE_CURRENT_BINARY_DIR}/opendocumenttextcollab-${WEBODF_VERSION}.zip)
+
+# The add-on is packed twice, from the same scripts: the manifest version 3
+# needs Firefox 109, of 2023, and the version 2 reaches back to Firefox 48, of
+# 2016. See "README-Products.md".
+set(OPENDOCUMENTVIEWER_FIREFOX_DIR ${CMAKE_CURRENT_BINARY_DIR}/opendocumentviewer-firefox-${WEBODF_VERSION})
+set(OPENDOCUMENTVIEWER_FIREFOX ${OPENDOCUMENTVIEWER_FIREFOX_DIR}.xpi)
+set(OPENDOCUMENTVIEWER_FIREFOX_MV2_DIR ${CMAKE_CURRENT_BINARY_DIR}/opendocumentviewer-firefox-mv2-${WEBODF_VERSION})
+set(OPENDOCUMENTVIEWER_FIREFOX_MV2 ${OPENDOCUMENTVIEWER_FIREFOX_MV2_DIR}.xpi)
+# Chrome takes a zip, and a file of rules rather than a script: it dropped the
+# blocking webRequest the two others redirect with.
+set(OPENDOCUMENTVIEWER_CHROME_DIR ${CMAKE_CURRENT_BINARY_DIR}/opendocumentviewer-chrome-${WEBODF_VERSION})
+set(OPENDOCUMENTVIEWER_CHROME ${OPENDOCUMENTVIEWER_CHROME_DIR}.zip)
+
+# Thunderbird reads the attachments of the messages, which no request carries,
+# so it gets a script of its own. The version 3 needs Thunderbird 128, of 2024,
+# and the version 2 reaches back to the 98, of 2022, the first that opens a
+# menu on an attachment.
+set(OPENDOCUMENTVIEWER_THUNDERBIRD_DIR ${CMAKE_CURRENT_BINARY_DIR}/opendocumentviewer-thunderbird-${WEBODF_VERSION})
+set(OPENDOCUMENTVIEWER_THUNDERBIRD ${OPENDOCUMENTVIEWER_THUNDERBIRD_DIR}.xpi)
+set(OPENDOCUMENTVIEWER_THUNDERBIRD_MV2_DIR ${CMAKE_CURRENT_BINARY_DIR}/opendocumentviewer-thunderbird-mv2-${WEBODF_VERSION})
+set(OPENDOCUMENTVIEWER_THUNDERBIRD_MV2 ${OPENDOCUMENTVIEWER_THUNDERBIRD_MV2_DIR}.xpi)
####################
@@ -345,14 +477,150 @@ else()
endif()
+
+#############################
+## The products of the build
+#############################
+
+# A product is a file someone is given: an add-on, a zip of the library, an
+# apk. Each one is written where the target that packs it stands, so the list
+# is kept here: the target "products" packs them all and tells where each one
+# was written, as the paths are of no help to remember. The target is named
+# beside the path, so that the list follows the targets and not the files,
+# whose names hold the version of the build.
+set_property(GLOBAL PROPERTY WEBODF_PRODUCTS "")
+set_property(GLOBAL PROPERTY WEBODF_PRODUCT_NAMES "")
+set_property(GLOBAL PROPERTY WEBODF_PRODUCT_TARGETS "")
+set_property(GLOBAL PROPERTY WEBODF_PRODUCTS_MISSING "")
+macro(WEBODF_PRODUCT target path)
+ set_property(GLOBAL APPEND PROPERTY WEBODF_PRODUCTS ${path})
+ set_property(GLOBAL APPEND PROPERTY WEBODF_PRODUCT_TARGETS ${target})
+ get_filename_component(WEBODF_PRODUCT_NAME_OF ${path} NAME)
+ set_property(GLOBAL APPEND PROPERTY WEBODF_PRODUCT_NAMES
+ ${WEBODF_PRODUCT_NAME_OF})
+endmacro(WEBODF_PRODUCT)
+
+# A product a tool of the machine writes among the products itself, whose name
+# that tool settles: it is named in the list and not copied again, and it is
+# looked for by the target rather than by its path.
+macro(WEBODF_PRODUCT_MADE target name)
+ set_property(GLOBAL APPEND PROPERTY WEBODF_PRODUCT_TARGETS ${target})
+ set_property(GLOBAL APPEND PROPERTY WEBODF_PRODUCT_NAMES ${name})
+endmacro(WEBODF_PRODUCT_MADE)
+
+# What this machine has no tool to make: it is named at the end beside what
+# was made, so that a reader of the list is not left wondering whether a
+# product is missing because it failed or because nothing here could write it.
+macro(WEBODF_PRODUCT_MISSING what tool)
+ set_property(GLOBAL APPEND PROPERTY WEBODF_PRODUCTS_MISSING
+ "${what}, for want of ${tool}")
+endmacro(WEBODF_PRODUCT_MISSING)
+
#############################
## Build Library and programs
#############################
# the lib
-add_subdirectory(webodf)
+if (WEBODF_PREBUILT_LIBRARY)
+ # The library was built already and is taken as it is: nothing of it is
+ # read, checked or written here, and neither node nor java is asked for.
+ # A program of this build reads it where it would have been written.
+ add_custom_command(
+ OUTPUT ${CMAKE_BINARY_DIR}/webodf/webodf.js
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/webodf
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ ${WEBODF_PREBUILT_LIBRARY} ${CMAKE_BINARY_DIR}/webodf/webodf.js
+ DEPENDS ${WEBODF_PREBUILT_LIBRARY}
+ COMMENT "The library, taken from ${WEBODF_PREBUILT_LIBRARY}")
+ add_custom_target(webodf.js-target
+ DEPENDS ${CMAKE_BINARY_DIR}/webodf/webodf.js)
+else ()
+ add_subdirectory(webodf)
+endif ()
# the programs/components
-add_subdirectory(programs)
+if (WEBODF_PROGRAMS)
+ add_subdirectory(programs)
+else ()
+ # Two programs are built by their own option, without the others: the tests
+ # of the library are run with the first one, and the second needs neither
+ # Dojo nor the editors.
+ if (BUILD_QTJSRUNTIME)
+ add_subdirectory(programs/qtjsruntime)
+ endif ()
+ if (BUILD_DESKTOP)
+ add_subdirectory(programs/opendocumentviewer-desktop)
+ endif ()
+endif ()
+
+# The target that runs every test of this build, beside "products" that packs
+# every product: the tests of the library, in each engine the build has, and
+# the ones of the programs that carry some.
+add_custom_target(tests
+ COMMAND ${CMAKE_COMMAND} -E echo ""
+ COMMAND ${CMAKE_COMMAND} -E echo "Every test of this build has run.")
+# A build that was given a library reads none of its sources, so there is
+# nothing of the library to test here: only the programs are.
+if (TARGET webodf.js-tests)
+ add_dependencies(tests webodf.js-tests)
+endif ()
+foreach (WEBODF_TEST_TARGET
+ test-opendocumenttexteditor
+ test-opendocumenttextcollab
+ test-opendocumentviewer-webext
+ test-opendocumentviewer-thunderbird)
+ if (TARGET ${WEBODF_TEST_TARGET})
+ add_dependencies(tests ${WEBODF_TEST_TARGET})
+ endif ()
+endforeach ()
+
+# The target that packs every product of this build and gathers them in one
+# place. Each product is written where the target that packs it stands, deep
+# in the tree of the build, so "make products" or "ninja products" copies them
+# all into "products/" and tells what is there: no one has to remember where
+# an add-on or an apk was written.
+get_property(WEBODF_PRODUCT_FILES GLOBAL PROPERTY WEBODF_PRODUCTS)
+get_property(WEBODF_PRODUCT_TARGET_LIST GLOBAL PROPERTY WEBODF_PRODUCT_TARGETS)
+if (WEBODF_PRODUCT_FILES)
+ set(WEBODF_PRODUCTS_DIR ${CMAKE_BINARY_DIR}/products)
+ get_property(WEBODF_PRODUCT_NAME_LIST GLOBAL PROPERTY WEBODF_PRODUCT_NAMES)
+ string(REPLACE ";" "," WEBODF_PRODUCT_NAMES_ARG "${WEBODF_PRODUCT_NAME_LIST}")
+ # What a build that went before left in the directory is taken away: the
+ # products carry the version they were built from, so they would pile up
+ # under names of their own, and a reader would not know which build a
+ # product is of.
+ set(WEBODF_PRODUCT_STEPS
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${WEBODF_PRODUCTS_DIR}
+ COMMAND ${CMAKE_COMMAND}
+ -DDIR=${WEBODF_PRODUCTS_DIR}
+ "-DKEEP=${WEBODF_PRODUCT_NAMES_ARG}"
+ -P ${CMAKE_CURRENT_SOURCE_DIR}/scripts/cmake/keep-products.cmake)
+ foreach (WEBODF_PRODUCT_FILE ${WEBODF_PRODUCT_FILES})
+ list(APPEND WEBODF_PRODUCT_STEPS
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ ${WEBODF_PRODUCT_FILE} ${WEBODF_PRODUCTS_DIR})
+ endforeach ()
+ list(APPEND WEBODF_PRODUCT_STEPS
+ COMMAND ${CMAKE_COMMAND} -E echo ""
+ COMMAND ${CMAKE_COMMAND} -E echo
+ "The products of this build are in ${WEBODF_PRODUCTS_DIR}:")
+ foreach (WEBODF_PRODUCT_NAME ${WEBODF_PRODUCT_NAME_LIST})
+ list(APPEND WEBODF_PRODUCT_STEPS
+ COMMAND ${CMAKE_COMMAND} -E echo " ${WEBODF_PRODUCT_NAME}")
+ endforeach ()
+ get_property(WEBODF_MISSING GLOBAL PROPERTY WEBODF_PRODUCTS_MISSING)
+ if (WEBODF_MISSING)
+ list(APPEND WEBODF_PRODUCT_STEPS
+ COMMAND ${CMAKE_COMMAND} -E echo ""
+ COMMAND ${CMAKE_COMMAND} -E echo
+ "This machine has no tool to make:")
+ foreach (WEBODF_MISSING_ONE ${WEBODF_MISSING})
+ list(APPEND WEBODF_PRODUCT_STEPS
+ COMMAND ${CMAKE_COMMAND} -E echo " ${WEBODF_MISSING_ONE}")
+ endforeach ()
+ endif ()
+ add_custom_target(products ${WEBODF_PRODUCT_STEPS})
+ add_dependencies(products ${WEBODF_PRODUCT_TARGET_LIST})
+endif ()
# vim:expandtab
diff --git a/ChangeLog.md b/ChangeLog.md
index d2be39134..e60a5a050 100644
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,10 +1,86 @@
+# Changes between 0.5.10 and 0.6.0
+
+## WebODF
+
+### Features
+
+* A text is drawn over pages, as it is printed, and no longer as one run of
+ text: each page is a box of its own, of the size the document writes, with
+ the header and the foot of its master page. A paragraph and a table that
+ cross the end of a page are cut there.
+* The pages are read one at a time or two to a row, as a book is read, and the
+ first page may stand alone on the right.
+* The lists, the headings and the chapters are numbered as an office numbers
+ them, from the outline style of the document and from the list styles, and
+ the numbers run on from page to page.
+* The tabs of a text are laid at the stops its style writes, left, centre,
+ right and character.
+* The notes of the foot are drawn at the foot of the page their number stands
+ on, and the text of that page is shorter by as much.
+* A page and a section are written in the columns they ask for.
+* The formulas a text holds are drawn, read from the MathML the package
+ carries, where an office writes an image beside them that a package need not
+ hold.
+* The links of a document are followed when a reader clicks one.
+* The spacings of two entries of an index are added, as an office adds them:
+ the table of contents of the schema of OpenDocument is drawn on the pages an
+ office draws it on, and every chapter begins within a page of where an office
+ begins it.
+
+### Fixes
+
+* A document that holds no styles, no automatic styles and no master styles is
+ drawn, where a reader looked for a page layout in nothing at all and threw.
+* A table wider than the text of the page is drawn to the width of the text,
+ and a word longer than its column is broken, as an office breaks it.
+* A table whose style says it may not be cut between two of its rows is written
+ whole on the page that follows.
+* A tab stop written for a page of another size is drawn against the edge of
+ the text rather than in the margin.
+* The fonts of a document are asked for by name before the text is broken into
+ pages, as an engine may hold its fonts ready before it draws with them.
+
+### Performance
+
+* A page is measured in one reading rather than one node at a time, and read
+ from what was written last rather than from its head.
+* The first pages are drawn as soon as they are broken, and the rest follow a
+ few at a time.
+* The style a paragraph names is read once, and an element of thousands of
+ nodes is parted before it is written on a page.
+
+## Products
+
+* A viewer of OpenDocument for the desktop, in qt, with its AppImage, its
+ flatpak, its deb, its rpm and its installer of windows.
+* The add-ons of firefox, of chrome and of thunderbird, in manifest v2 and v3.
+* A viewer for android and one for ios.
+* Docnosis reads a document against the schema of the standard.
+* Every product of the build is made by one command, and the build says what is
+ wanting where a tool is not installed.
+
+## Documentation
+
+* What a program may lean on in the library is written in "PUBLIC-API.md".
+* The readmes say how each product is built, tried and handed over, and what
+ each of them runs on.
+
+# Changes between 0.5.9 and 0.5.10
+
+## WebODF
+
+### Fixes
+
+* Save an empty `` element where a document holds no
+ `` ([#918](https://github.com/webodf/WebODF/pull/918))
+
# Changes between 0.5.8 and 0.5.9
## WebODF
## Fixes
-* Fix an issue where ODF zip files were incorrectly generated ([#917](https://github.com/kogmbh/WebODF/pull/917))
+* Fix an issue where ODF zip files were incorrectly generated ([#917](https://github.com/webodf/WebODF/pull/917))
# Changes between 0.5.7 and 0.5.8
@@ -12,15 +88,15 @@
### Fixes
-* Fix chrome selections that cannot be collapsd by clicking inside them ([#905](https://github.com/kogmbh/WebODF/issues/905))
-* Fix Inserted images being 1cm by 1cm in LibreOffice/OO ([#904](https://github.com/kogmbh/WebODF/issues/904))
-* Fix exported zip file being uncompressed ([#21]https://github.com/kogmbh/WebODF/issues/21)
+* Fix chrome selections that cannot be collapsd by clicking inside them ([#905](https://github.com/webodf/WebODF/issues/905))
+* Fix Inserted images being 1cm by 1cm in LibreOffice/OO ([#904](https://github.com/webodf/WebODF/issues/904))
+* Fix exported zip file being uncompressed ([#21]https://github.com/webodf/WebODF/issues/21)
## Wodo.TextEditor
### Fixes
-* Disable custom buttons save/saveAs/close/download when there is no session ([#893](https://github.com/kogmbh/WebODF/pull/893))
+* Disable custom buttons save/saveAs/close/download when there is no session ([#893](https://github.com/webodf/WebODF/pull/893))
# Changes between 0.5.6 and 0.5.7
@@ -28,13 +104,13 @@
### Fixes
-* Fix breaking all empty annotations on merging the paragraph they are contained in with the one before ([#877](https://github.com/kogmbh/WebODF/pull/877)))
-* Fix error message popup on deleting an annotation starting at the end of a paragraph or styled range ([#880](https://github.com/kogmbh/WebODF/pull/880)))
-* Fix wrong style information for text in annotations ([#881](https://github.com/kogmbh/WebODF/pull/881)))
+* Fix breaking all empty annotations on merging the paragraph they are contained in with the one before ([#877](https://github.com/webodf/WebODF/pull/877)))
+* Fix error message popup on deleting an annotation starting at the end of a paragraph or styled range ([#880](https://github.com/webodf/WebODF/pull/880)))
+* Fix wrong style information for text in annotations ([#881](https://github.com/webodf/WebODF/pull/881)))
### Improvements
-* In OpAddAnnotation support annotated ranges with 0 length ([#879](https://github.com/kogmbh/WebODF/pull/879)))
+* In OpAddAnnotation support annotated ranges with 0 length ([#879](https://github.com/webodf/WebODF/pull/879)))
### Breaking changes
@@ -46,7 +122,7 @@ See also section about WebODF
### Improvements
-* Add a "review" modus where users can add, edit and remove own annotations, but not modify the actual document content ([#883](https://github.com/kogmbh/WebODF/pull/883)))
+* Add a "review" modus where users can add, edit and remove own annotations, but not modify the actual document content ([#883](https://github.com/webodf/WebODF/pull/883)))
# Changes between 0.5.5 and 0.5.6
@@ -55,7 +131,7 @@ See also section about WebODF
### Fixes
-* No longer fail due to possible Byte Order Marks in ODF-internal XML files with Chromium ([#872](https://github.com/kogmbh/WebODF/issues/872)))
+* No longer fail due to possible Byte Order Marks in ODF-internal XML files with Chromium ([#872](https://github.com/webodf/WebODF/issues/872)))
## Wodo.TextEditor
@@ -63,7 +139,7 @@ See also section about WebODF
### Improvements
-* Add options for "Save as" and "Download" buttons in Wodo.TextEditor ([#865](https://github.com/kogmbh/WebODF/pull/865)))
+* Add options for "Save as" and "Download" buttons in Wodo.TextEditor ([#865](https://github.com/webodf/WebODF/pull/865)))
# Changes between 0.5.4 and 0.5.5
@@ -72,11 +148,11 @@ See also section about WebODF
### Improvements
-* Add a "documentModified" state with change signal to UndoManager classes ([#857](https://github.com/kogmbh/WebODF/pull/857)))
+* Add a "documentModified" state with change signal to UndoManager classes ([#857](https://github.com/webodf/WebODF/pull/857)))
### Fixes
-* No longer fail on "draw:master-page-name" attributes values with non-alphabetic chars ([#742](https://github.com/kogmbh/WebODF/pull/742)))
+* No longer fail on "draw:master-page-name" attributes values with non-alphabetic chars ([#742](https://github.com/webodf/WebODF/pull/742)))
## Wodo.TextEditor
@@ -84,15 +160,15 @@ See also section about WebODF
### Improvements
-* Add a "documentModified" state with change signal ([#857](https://github.com/kogmbh/WebODF/pull/857)))
+* Add a "documentModified" state with change signal ([#857](https://github.com/webodf/WebODF/pull/857)))
### Fixes
-* Fix wrongly enabled hyperlink tools with no document loaded ([#833](https://github.com/kogmbh/WebODF/pull/833))
-* Prevent Cross-Site Scripting from style names and font names ([#849](https://github.com/kogmbh/WebODF/pull/849)) (CVE-2015-3012)
-* Avoid badly rendered toolbar element with subsets of tools ([#855](https://github.com/kogmbh/WebODF/pull/855)))
-* Prevent Cross-Site Scripting from links ([#850](https://github.com/kogmbh/WebODF/pull/850)) (CVE-2015-3012)
-* Prevent browser translation service breaking the editor logic ([#862](https://github.com/kogmbh/WebODF/pull/862)))
+* Fix wrongly enabled hyperlink tools with no document loaded ([#833](https://github.com/webodf/WebODF/pull/833))
+* Prevent Cross-Site Scripting from style names and font names ([#849](https://github.com/webodf/WebODF/pull/849)) (CVE-2015-3012)
+* Avoid badly rendered toolbar element with subsets of tools ([#855](https://github.com/webodf/WebODF/pull/855)))
+* Prevent Cross-Site Scripting from links ([#850](https://github.com/webodf/WebODF/pull/850)) (CVE-2015-3012)
+* Prevent browser translation service breaking the editor logic ([#862](https://github.com/webodf/WebODF/pull/862)))
# Changes between 0.5.3 and 0.5.4
@@ -100,8 +176,8 @@ See also section about WebODF
### Fixes
-* Only highlight ODF fields in edit mode ([#816](https://github.com/kogmbh/WebODF/issues/816))
-* Prevent Cross-Site Scripting from file names ([#851](https://github.com/kogmbh/WebODF/pull/851)) (CVE-2014-9716)
+* Only highlight ODF fields in edit mode ([#816](https://github.com/webodf/WebODF/issues/816))
+* Prevent Cross-Site Scripting from file names ([#851](https://github.com/webodf/WebODF/pull/851)) (CVE-2014-9716)
## Wodo.TextEditor
See also section about WebODF
@@ -117,17 +193,17 @@ See also section about WebODF
### Improvements
-* Add support for double line-through in Firefox (Chrome/Safari + IE don't support this feature) ([#758](https://github.com/kogmbh/WebODF/pull/758))
-* Add support for subscript & superscript ([#755](https://github.com/kogmbh/WebODF/pull/755))
+* Add support for double line-through in Firefox (Chrome/Safari + IE don't support this feature) ([#758](https://github.com/webodf/WebODF/pull/758))
+* Add support for subscript & superscript ([#755](https://github.com/webodf/WebODF/pull/755))
* In odf.OdfContainer allow creation of document template types as well as querying and setting the template state of the document
### Fixes
-* Fixed occasional crash when splitting a paragraph ([#723](https://github.com/kogmbh/WebODF/issues/723))
+* Fixed occasional crash when splitting a paragraph ([#723](https://github.com/webodf/WebODF/issues/723))
* Keep IME composition menu & avatar in the correct position when entering characters
* Allow screen-readers to read the document content correctly in OSX 10.8+ versions of Safari
-* Scroll newly created annotations completely into view ([#486](https://github.com/kogmbh/WebODF/issues/486))
-* Improve line ending detection when word-wrapping occurs ([#774](https://github.com/kogmbh/WebODF/pull/774))
+* Scroll newly created annotations completely into view ([#486](https://github.com/webodf/WebODF/issues/486))
+* Improve line ending detection when word-wrapping occurs ([#774](https://github.com/webodf/WebODF/pull/774))
## Wodo.TextEditor
@@ -148,7 +224,7 @@ See also section about WebODF
### Fixes
* For ODP files sometimes template elements from the master pages were rendered inside the actual slides.
-* Navigation via home/end keys, or up/down cursor keys is more reliable on all browsers. ([#555](https://github.com/kogmbh/WebODF/issues/555), [#405](https://github.com/kogmbh/WebODF/issues/405), [#224](https://github.com/kogmbh/WebODF/issues/224), [#185](https://github.com/kogmbh/WebODF/issues/185), [#124](https://github.com/kogmbh/WebODF/issues/124), [#98](https://github.com/kogmbh/WebODF/issues/98))
+* Navigation via home/end keys, or up/down cursor keys is more reliable on all browsers. ([#555](https://github.com/webodf/WebODF/issues/555), [#405](https://github.com/webodf/WebODF/issues/405), [#224](https://github.com/webodf/WebODF/issues/224), [#185](https://github.com/webodf/WebODF/issues/185), [#124](https://github.com/webodf/WebODF/issues/124), [#98](https://github.com/webodf/WebODF/issues/98))
* More elements from master pages are now correctly positioned when displayed inside slides.
* In slides hide elements of class "header", "footer", "page-number" and "date-time" from master pages when configured so.
@@ -160,7 +236,7 @@ See also section about WebODF
### Improvements
* numbering of multi-level lists is now well supported in rendering, including display of only a subset of the list numbers and continued numbering from previous lists (both `text:continue-numbering` and `text:continue-list`)
-([#565](https://github.com/kogmbh/WebODF/pull/565))
+([#565](https://github.com/webodf/WebODF/pull/565))
### Fixes
@@ -175,6 +251,6 @@ See also section about WebODF
* Start-up of editor no longer hangs in some browsers
Two different bugs were fixed which so far broke the start-up with Safari and other browsers using older WebKit versions as well as the default browser on Android 4.0.3
-([#693](https://github.com/kogmbh/WebODF/issues/693))
+([#693](https://github.com/webodf/WebODF/issues/693))
* All toolbar elements are now disabled when no document is loaded.
-([#709](https://github.com/kogmbh/WebODF/issues/709))
+([#709](https://github.com/webodf/WebODF/issues/709))
diff --git a/JSCoverage.patch b/JSCoverage.patch
deleted file mode 100644
index 332db9c49..000000000
--- a/JSCoverage.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-diff -Naurw jscoverage-0.5.1-orig/js/Makefile.in jscoverage-0.5.1/js/Makefile.in
---- jscoverage-0.5.1-orig/js/Makefile.in 2010-09-23 14:00:00.000000000 +0200
-+++ jscoverage-0.5.1/js/Makefile.in 2019-02-07 23:57:30.292080849 +0100
-@@ -431,6 +431,7 @@
- NSPR_STATIC_PATH = $(DIST)/lib
- endif
-
-+CXXFLAGS += -fpermissive
- ifdef MOZ_SHARK
- CFLAGS += -F/System/Library/PrivateFrameworks
- CXXFLAGS += -F/System/Library/PrivateFrameworks
-diff -Naurw jscoverage-0.5.1-orig/util.c jscoverage-0.5.1/util.c
---- jscoverage-0.5.1-orig/util.c 2010-09-23 14:00:00.000000000 +0200
-+++ jscoverage-0.5.1/util.c 2019-02-07 23:58:18.369297990 +0100
-@@ -478,6 +478,10 @@
- p->next = head;
- head = p;
- }
-+ else if (S_ISDIR(buf.st_mode)) {
-+ head = recursive_dir_list(root, entry_wrt_root, head);
-+ free(entry_wrt_root);
-+ }
- else {
- fatal("refusing to follow symbolic link: %s", entry);
- }
diff --git a/LicenseHeaderTemplate.js b/LicenseHeaderTemplate.js
index 426000d1c..aac1e0f6c 100644
--- a/LicenseHeaderTemplate.js
+++ b/LicenseHeaderTemplate.js
@@ -18,6 +18,6 @@
* along with WebODF. If not, see .
* @licend
*
- * @source: http://www.webodf.org/
- * @source: https://github.com/kogmbh/WebODF/
+ * @source: https://webodf.org/
+ * @source: https://github.com/webodf/WebODF/
*/
diff --git a/PUBLIC-API.md b/PUBLIC-API.md
new file mode 100644
index 000000000..9dd5d074d
--- /dev/null
+++ b/PUBLIC-API.md
@@ -0,0 +1,161 @@
+# The public API of WebODF
+
+This says what a program may lean on: the objects the library offers, what
+they answer and what they promise. Everything else in `webodf/lib` is the
+inside of the library and may change without warning.
+
+The library is one file, `webodf.js`, built as
+[README-Building.md](README-Building.md) says. It writes two namespaces of its
+own, `odf` and `gui`, and nothing else in the page.
+
+```html
+
+
+
+```
+
+## What the library runs in
+
+The library reads the elements of a document by their namespace, writes the
+rules of the pages in a sheet of the document, lays the pages in boxes that
+keep the spacings of an office apart, and asks the engine for the fonts a
+document names before it breaks it into pages. An engine that has all of that
+draws a document; one that has not draws nothing.
+
+| engine | floor |
+|--------------|-------|
+| Chrome | 88 |
+| Firefox | 78 |
+| Safari | 15.4 |
+| Qt WebEngine | 6.4 |
+
+Internet Explorer draws nothing of a document, whatever its version: it has no
+DOM that reads a namespace. The sources are written in the third edition of
+the language, and the compiler is told so, but that says how the file is
+parsed and not what it needs to run.
+
+The same document is not broken into the same number of pages by two engines:
+the lines are not of the same height, and eight hundred pages of one are eight
+hundred and sixty of another. A program that counts on a number of pages
+counts on the engine as well.
+
+## odf.OdfCanvas
+
+A canvas draws one document in one element of a page. It is made with the
+element to draw in, and the element is emptied of whatever it held.
+
+### Reading a document
+
+| call | what it does |
+|---------------------------------------------|------------------------------------------------------------------------------------------------|
+| `load(url)` | Read the document at that address and draw it. A canvas that held another document forgets it. |
+| `odfContainer()` | The `odf.OdfContainer` of the document that is drawn, or nothing before one is read. |
+| `setOdfContainer(container, suppressEvent)` | Draw a document that was read another way. |
+| `save(callback)` | Write the document back, as it stands, and answer the bytes to the callback. |
+| `destroy(callback)` | Take the document out of the page and let go of what it held. |
+
+### Being told what happens
+
+`addListener(name, handler)` asks to be told of one of these:
+
+| name | when | what the handler is given |
+|--------------------|------------------------------------------------|---------------------------|
+| `statereadychange` | the document is read, or could not be | the `odf.OdfContainer` |
+| `pagesdrawn` | every page of a text has been broken and drawn | nothing |
+| `click` | the reader clicks in the document | the event |
+
+A document that cannot be read is answered all the same: the container says
+`odf.OdfContainer.INVALID` rather than `DONE`.
+
+```js
+canvas.addListener("statereadychange", function (container) {
+ if (container.state === odf.OdfContainer.INVALID) {
+ return;
+ }
+ canvas.fitSmart(window.innerWidth);
+});
+```
+
+### Drawing a text over pages
+
+A text is drawn as one run of text until it is asked otherwise. What follows
+is of a text; a presentation and a drawing are drawn slide by slide whatever
+is asked here.
+
+| call | what it does |
+|-------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| `setPaginated(on)` | Break the text into pages, or draw it as one run again. |
+| `isPaginated()` | Whether it is broken into pages. |
+| `setPageMode(mode)` | `"pages"` lays the pages one under another, each page a box of its own; `"columns"` lays them beside one another, each page a column; `"flow"` writes the text as one run, as a page of the web is written. |
+| `setPagesPerRow(n)` | How many pages stand side by side on a row: one to scroll a document, two to read a book. |
+| `setFirstPageOnItsOwn(alone)` | Whether the first page stands alone on the right of its row, as the first page of a book does. |
+| `refreshNumbering()` | Write the labels of the lists and of the headings again, after an editor has changed one. |
+| `pageBoxAt(x)` | Where the page that holds that place begins and ends across, or nothing when the text is drawn as one run. |
+
+Breaking a document of many pages takes time: it is done a few pages at a
+time, so a reader sees the first of them at once, and `pagesdrawn` says when
+the last of them is drawn.
+
+### The size the document is drawn at
+
+| call | what it does |
+|-------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| `setZoomLevel(zoom)`, `getZoomLevel()` | The size the document is drawn at, one being the size it was written at. |
+| `fitToWidth(width)` | Scale the document to that width, up or down. |
+| `fitSmart(width, height)` | Scale it down to that width, and to that height where one is given, but never up: a document is read at the size it was written at where the window holds it. |
+| `fitToHeight(height)`, `fitToContainingElement(w, h)` | The same, of a height, or of the element the canvas draws in. |
+| `getSizer()` | The element the document is drawn in, which is what the zoom is set on. |
+| `getElement()` | The element the canvas was made with. |
+| `refreshSize()` | Read the size of the window again, after it has changed. |
+
+### Slides
+
+`showFirstPage()`, `showNextPage()`, `showPreviousPage()` and `showPage(n)`
+move through the slides of a presentation.
+
+### Annotations
+
+`enableAnnotations(on, showRemoveButton)` draws the annotations of a document
+in a lane beside the text. `addAnnotation`, `forgetAnnotation`,
+`refreshAnnotations` and `getAnnotationViewManager` are for an editor that
+writes them.
+
+## odf.OdfContainer
+
+The document itself: the parts of the package and the tree of the document.
+
+| call | what it does |
+|--------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| `new odf.OdfContainer(url, onchange)` | Read a document from an address; the callback is told at every turn of its state. |
+| `state` | `odf.OdfContainer.LOADING`, `DONE` or `INVALID`. |
+| `rootElement` | The document, whose `body`, `styles`, `automaticStyles`, `masterStyles`, `meta` and `settings` are the parts of it. A document that holds none of one of these is given an empty one, so a reader never has nothing to read. |
+| `getDocumentType()` | `"text"`, `"presentation"`, `"spreadsheet"` or `"drawing"`. |
+| `getContentElement()` | The element of the body that holds what is written. |
+| `getPart(path)`, `getPartData(path, callback)` | A part of the package: an image, a formula, a chart. |
+| `setBlob(path, mimetype, content)`, `removeBlob(path)` | Put a part in the package or take it out. |
+| `save(callback)`, `getUrl()` | Write the package back, and the address it was read from. |
+| `isTemplate()`, `setIsTemplate(on)` | Whether the document is a template, `.ott` rather than `.odt`. |
+
+## The viewer of the desktop
+
+The window of the viewer speaks to the page it draws in through
+`window.viewer`, see `programs/opendocumentviewer-desktop/assets/viewer.js`:
+
+| call | what it does |
+|------------------------------------|------------------------------------------------------------------------|
+| `load()` | Draw the document the window serves. |
+| `unload()` | Put the document away and show what the window shows with none. |
+| `zoomBy(factor)`, `setZoom(level)` | Zoom in and out. |
+| `fit()` | Draw the page as wide as the window allows. |
+| `setPages(perRow, firstAlone)` | One page to a row, two, or two with the first on the right of its own. |
+
+## What is not the public API
+
+The objects under `ops`, `gui` and `webodfcore` are those of the editor and of
+the inside of the library. They are written for the editors that live in this
+repository and they change with them. A program that leans on them leans on
+something that may be written otherwise tomorrow.
diff --git a/README-Building.md b/README-Building.md
index 80a3e30ed..a16e3fcdd 100644
--- a/README-Building.md
+++ b/README-Building.md
@@ -1,91 +1,702 @@
-## Building WebODF on Linux
+## Two ways to build
+
+The library "webodf.js" is built in two ways.
+
+- **With cmake**, described first, as it was done originally: it builds the
+ library and it is the only way to build everything else, the viewers, the
+ add-ons, the editors and the tools, listed in "README-Products.md". The
+ products of "programs/" are behind the option WEBODF_PROGRAMS, off by
+ default, since they are the longest to build and need Dojo. The closure
+ compiler, Rhino and Dojo are downloaded from maven central and from the
+ registry of npm, at the same versions as the build with node uses.
+- **With node**, described in "Building with node" below: the shortest way to
+ the library alone, and to nothing else. It needs node only, and java for the
+ optional check of the types.
+
+Both produce the same file, byte for byte: the build with cmake writes the
+library by running "scripts/build.js" as well. It still compiles the sources
+with the closure compiler, but only to check their types, as it compiles with
+SIMPLE_OPTIMIZATIONS, which neither folds the definition IS_COMPILED_CODE nor
+drops what it makes unreachable: the loader of the classes and the runner of the
+scripts stayed in a library that never calls them, with the eval() they read a
+file with.
+
+So "npm install" is needed for the build with cmake too, as terser minifies the
+library.
+
+Some parts of the build with cmake are opt-in, so that a plain build stays short
+and needs nothing but node and cmake:
+
+| Option | What it adds |
+|--------------------|---------------------------------------------------------|
+| WEBODF_PROGRAMS | The editors and the extensions of "programs/" |
+| WEBODF_QTJSRUNTIME | qtjsruntime, that runs the tests in the webengine of qt |
+| WEBODF_DESKTOP | The viewer of OpenDocument for the desktop, in qt |
+| WEBODF_ANDROID | The viewer of OpenDocument for android, with its sdk |
+| WEBODF_IOS | The viewer of OpenDocument for iOS, on macOS alone |
+
+Four more settings say how the build is run rather than what it holds:
+
+| Setting | What it says |
+|-------------------------|-------------------------------------------------------------------------------|
+| WEBODF_PACKAGE_FLATPAK | OFF leaves the flatpak out of "products", the rest being packed still |
+| WEBODF_PREBUILT_LIBRARY | A "webodf.js" built elsewhere is taken as it stands, so node is not run |
+| WEBODF_TESTS_ON_SCREEN | The window of qtjsruntime is shown while the tests run, hidden otherwise |
+| WEBODF_DOWNLOAD_DIR | An environment variable: the directory the downloads are kept in |
-For creating the file "webodf.js" out of the sources CMake and Java needs to be installed.
+WEBODF_PREBUILT_LIBRARY is what a sandbox is built with, where neither node nor
+the network is at hand: the flatpak of the viewer builds the C++ alone against
+the library the build outside made, see "Products".
-Another optional, but recommended requirement are the Qt5 libs, which are used to create and run tests.
+WEBODF_QTJSRUNTIME and WEBODF_DESKTOP need Qt 6.4 or later, with the modules
+Core, Gui, Widgets, PrintSupport, WebChannel, WebEngineCore and
+WebEngineWidgets, that Debian 12 and later install with:
-Further requirements, like the [Closure Compiler][], will be conveniently downloaded automatically during the build, as usually the latest version will be used,
-which might not yet be available as a package. So during (first) build also a connection to the internet will be needed.
-Downloaded requirements will be cached in the build directory.
-[Closure Compiler]: https://developers.google.com/closure/compiler/
+```sh
+apt-get install qt6-base-dev qt6-base-dev-tools qt6-webchannel-dev qt6-webengine-dev qt6-webengine-dev-tools
+```
-With the requirements installed, either download the zip file from https://github.com/kogmbh/WebODF/archive/master.zip and unzip it
+Two libraries the modules of qt look for are packaged apart, and cmake reports
+them as "Could NOT find XKB" and "Could NOT find Cups" when they are absent.
+Neither stops the build: xkbcommon is the keyboard of the platform, and cups is
+the printing of the system, that the export to pdf does not go through, as it
+is drawn by the webengine itself.
- wget https://github.com/kogmbh/WebODF/archive/master.zip
- unzip master.zip
- mv WebODF-master webodf
+```sh
+apt-get install libxkbcommon-dev libxkbcommon-x11-dev libcups2-dev
+```
-or get the complete repo with git:
+qtjsruntime ran in Qt WebKit until 2026, that Qt dropped in 5.6, in 2016, and
+that Debian stopped packaging in Debian 13: the program was rewritten for
+webengine, which is the blink of chromium. Its option stays off because the
+modules of qt weigh more than the rest of the build together, and because "npm run test:browser"
+runs the same suite in a browser that is installed anyway.
- git clone https://github.com/kogmbh/WebODF.git webodf
+On a machine without a screen, a build server for instance, the platform without
+one is used:
-For building now in the same directory where either of above commands were done the following commands should be entered:
+```sh
+QT_QPA_PLATFORM=offscreen make -C build test-qtjsruntime
+```
- mkdir build
- cd build
- cmake ../webodf
- make webodf.js-target
+It runs the whole suite of the browser, 35 files of tests where the run with
+node runs 3: the others need a dom, a layout and computed styles, which is what
+this program is kept for.
-A successful run will yield the file "webodf.js" in the subfolder "build/webodf/" (among other things), from where you can then copy it and use for your website.
+WEBODF_DESKTOP builds the viewer for the desktop, which is a window of qt around
+the page the library draws in, see "README-Products.md". It is built by that
+option alone, without WEBODF_PROGRAMS, as it needs neither Dojo nor the
+editors.
-### Dependencies on Ubuntu
-For a Ubuntu 18.04 distribution you can satisfy the build dependencies with:
+## The builds that answer by themselves
- apt-get install libqt5webkit5-dev default-jdk
+Two workflows of GitHub Actions are in ".github/workflows":
+* "library.yml" builds the library with node and runs what that build runs: the
+ types of the library and of the tests, the tests in node and the same ones in
+ rhino. It is the short one, and it answers on every push.
+* "desktop.yml" builds the viewer of the desktop on linux, on windows and on
+ macos, and runs every suite of tests on each of them, in the webengine of qt
+ among the others. What it installs is gathered as an artifact, so a viewer
+ that no one here can build is downloaded and tried.
+
+The second is what tells whether the branches "if (WIN32)" and "if (APPLE)" of
+the build hold: they run nowhere else. Qt is installed by [install-qt-action](https://github.com/jurplel/install-qt-action),
+that takes it from the repository of Qt with the module of WebEngine, and
+windows is given the compiler of microsoft, that WebEngine needs.
-## Building WebODF on Windows
+The history is fetched whole, as the version of the build comes from "git describe",
+and a shallow checkout gives it nothing to describe.
-The following steps have been tested with the Microsoft C\C++ compilers that are installed with Visual Studio 2010. It may be possible to use MinGW but it has not been verified.
-* Visual Studio 2010 (or [Visual Studio 2010 Express][] works as well)
-* [Visual Studio 2010 Service Pack 1][]
-* [Qt 5.2.1 x86 installer](http://download.qt-project.org/official_releases/qt/5.2/5.2.1/qt-opensource-windows-x86-msvc2010-5.2.1.exe) for Visual Studio 2010
-* [CMake 2.8.12.2 x86](http://www.cmake.org/files/v2.8/cmake-2.8.12.2-win32-x86.exe)
-* [Java Runtime 1.7](http://java.com/en/download/index.jsp) (or more recent)
-* [Git for Windows][]
+## Coverage
-[Visual Studio 2010 Express]: http://www.visualstudio.com/en-us/downloads#d-2010-express
-[Visual Studio 2010 Service Pack 1]: http://www.microsoft.com/en-us/download/details.aspx?id=23691
-[Git for Windows]: http://msysgit.github.io/
+The coverage of the tests is measured by [c8][], with node and with cmake:
-### Visual Studio 2010
+```sh
+npm run coverage
+make coverage
+```
-We only need the C\C++ compilers but it is easier to get this by installing Visual Studio 2010. It can also be obtained from the Windows 7 SDK but I would
-recommend the above. To avoid issues with CMake, [Visual Studio 2010 Service Pack 1][] also needs to be downloaded and installed.
+By default it writes a table on the terminal and a report to browse in "coverage/index.html".
+Another reporter is chosen by passing it through:
-### Git for Windows
+```sh
+node scripts/coverage.js --reporter=lcov
+```
-[Git][Git for Windows] itself isn't strictly necessary, but some Unix programs like cat are used during the build.
-As you will generally need git to download the source, this is easiest way to get the msys utilities.
+c8 reads the coverage V8 records while it runs, so it neither parses nor
+rewrites the sources: the version of ECMAScript the library is written in does
+not matter to it. The tests run on the bundle, that is written with a source map
+so that the coverage is reported on the files of "webodf/lib".
-### Setup PATH variable
+It replaces JSCoverage, that instrumented the sources for the target
+"instrumented" of the original build. Its last release, 0.5.1 of 2010, bundles
+SpiderMonkey 1.7, whose autoconf 2.13 probe declares "main()" without a return
+type: gcc 14 and clang 16 reject it, as -Wimplicit-int is an error in C23, so it
+does not build any more on a recent distribution.
-Add the following directories to the PATH variable
+[c8]: https://github.com/bcoe/c8
-* CMake path e.g `C:\Program Files (x86)\CMake 2.8\bin`
-* QMake path e.g `C:\QtSDK\bin`
-* Unix tools path e.g `C:\Program Files (x86)\Git\bin` (Git installer will add this automatically if you select the add Unix tools to PATH option during install)
-### Building webodf.js
-These commands should be entered from the Visual Studio 2010 command prompt so that msbuild will be added to the PATH
+## Building WebODF on Linux
+
+For creating the file "webodf.js" out of the sources cmake and node need to be
+installed. Java is looked for and not required: it runs the checks of the types
+and the tests in rhino, and a machine without it builds everything else.
- git clone https://github.com/kogmbh/WebODF.git webodf
- md build
- cd build
- cmake -G "Visual Studio 10" ..\webodf
- msbuild WebODF.sln
+Another optional, but recommended requirement are the Qt 6 libs, which are used
+to run the tests in the webengine of qt.
+Further requirements, like the [Closure Compiler][], will be conveniently
+downloaded automatically during the build, as usually the latest version will be
+used, which might not yet be available as a package. So during (first) build
+also a connection to the internet will be needed. Downloaded requirements will
+be cached in the build directory.
+
+[Closure Compiler]: https://developers.google.com/closure/compiler/
-## Building WebODF on OSX 10.7.5 (Lion) or OSX 10.9.5 (Mavericks)
+With the requirements installed, either download the zip file from https://github.com/webodf/WebODF/archive/master.zip
+and unzip it:
-Qt5 can be installed via homebrew, but will not be linked by default. CMake must be instructed where to find this package by
-specifying the Qt5 location in CMAKE_PATH_PREFIX environment variable:
+```sh
+wget https://github.com/webodf/WebODF/archive/master.zip
+unzip master.zip
+mv WebODF-master webodf
+```
- cmake -DCMAKE_PREFIX_PATH=/usr/local/Cellar/qt5/5.4.1 ../webodf
-
-If the build process returns an error `(libuv) Failed to create kqueue (24)`,
-this can be resolved by increasing the limit on the number of open file descriptors:
+or get the complete repo with git:
+
+```sh
+git clone https://github.com/webodf/WebODF.git webodf
+```
+
+For building now in the same directory where either of above commands were done
+the following commands should be entered:
+
+```sh
+mkdir build
+cd build
+cmake -S ../webodf
+make webodf.js-target
+```
+
+A successful run will yield the file "webodf.js" in the subfolder "build/webodf/",
+among other things, from where you can then copy it and use for your website.
+
+CMake writes the files of another builder when it is asked to, and ninja builds
+the same thing in less time, as it starts every step it can at once where make
+walks the directories:
+
+```sh
+cmake -S ../webodf -G Ninja
+ninja webodf.js-target
+```
+
+The package is "ninja-build" on Debian and Ubuntu, and the command it installs
+is "ninja".
+
+Only the wait changes: the file that comes out is the same, byte for byte. A
+directory is bound to the builder it was configured with, so a build that was
+made with make is configured again in a directory of its own, or with
+"--fresh".
+
+CMake keeps the paths of the programs it finds in "build/CMakeCache.txt", so a
+node that is installed afterwards, with nvm for instance, is not seen: it keeps
+using the one it found the first time, and reports it as too old. The entries
+are dropped with:
+
+```sh
+cmake -S ../webodf -U NODEJS_EXECUTABLE -U NPM
+```
+
+### Dependencies on Debian and Ubuntu
+
+The build needs cmake and node, that is installed apart, see "Building with
+node" below for the version, and it takes a java runtime for the checks where
+one is installed:
+
+```sh
+apt-get install cmake default-jre
+```
+
+The generator Ninja is another package, and it is optional: it is asked for by
+"-G Ninja" and it builds in less time than make, see above.
+
+```sh
+apt-get install ninja-build
+```
+
+The modules of Qt are only needed by the option WEBODF_QTJSRUNTIME, see "Two ways to build"
+above.
+
+The ways the viewer of the desktop is handed over each ask for a tool of their
+own, see "README-Products.md". None of them is needed to build the viewer: the
+target "products" makes what the tools of the machine allow, and says at the
+end which tool is missing for the rest.
+
+```sh
+apt-get install dpkg-dev rpm flatpak flatpak-builder libfuse2t64
+flatpak remote-add --user --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
+flatpak install --user flathub org.kde.Platform//6.9 org.kde.Sdk//6.9 \
+ io.qt.qtwebengine.BaseApp//6.9
+```
+
+| Target | The tool it asks for | Where it comes from |
+|-------------------|---------------------------|--------------------------------|
+| package-archive | none, cmake writes it | |
+| package-deb | dpkg-deb, dpkg-shlibdeps | "dpkg" and "dpkg-dev" |
+| package-rpm | rpmbuild | "rpm" |
+| package-appimage | linuxdeploy, its plugin of qt, appimagetool | not packaged by Debian, see below |
+| package-flatpak | flatpak-builder, and the runtime of KDE | "flatpak-builder", and Flathub |
+
+The runtime and the base app are installed for the user and not for the
+system: a build dir is written by the user who builds, and taking a package
+that root installed apart into it asks to change the owner of files, which the
+kernel refuses ("error: fchownat: Operation not permitted"). An installation
+of the user keeps the owner in the attributes of the files and changes
+nothing. Each installation carries its own remotes, hence the first line.
+
+The flatpak asks for three things and not one: the tool that builds it, the
+runtime of KDE it is built against, which weighs some two gigabytes, and the
+base app of qt, which carries the webengine the viewer is drawn in and that
+the runtime of KDE does not carry. The two last are installed from Flathub,
+the third line above. Both are looked for when cmake
+is run, and what is missing is named among the products that could not be made:
+
+```
+This machine has no tool to make:
+ the flatpak, for want of io.qt.qtwebengine.BaseApp//6.9
+```
+
+A branch of that runtime is declared end of life as soon as a newer one is
+out, so no version is written in the manifest: the newest branch of
+"org.kde.Sdk" the machine has is taken, and the manifest is written with it.
+Install a newer one and run cmake again, and the flatpak follows. A build that
+wants one branch and not another names it:
+
+```sh
+cmake -S . -B build -DWEBODF_FLATPAK_RUNTIME=6.9
+```
+
+A machine that will not build a flatpak at all leaves it out, and "products"
+makes everything else without naming it as missing:
+
+```sh
+cmake -S . -B build -DWEBODF_PACKAGE_FLATPAK=OFF
+```
+
+The branch of the runtime is the version of qt it carries, and the viewer is
+built with qt 6.4 or newer, so branches older than that are left aside: a
+machine that kept only one of them is told that it has no runtime to build
+against, and a branch named by hand that is older stops the configuration at
+once rather than the build later.
+
+A tool that is installed afterwards is only seen when cmake is run again, as
+what was found is kept in the cache of the build, see "Building everything
+again without downloading it again" below.
+
+The tools of the AppImage are AppImages themselves, packaged by no
+distribution: they are taken from the releases of their projects, made
+runnable and put in the path under the names "linuxdeploy",
+"linuxdeploy-plugin-qt" and "appimagetool", which are the names cmake looks
+for.
+
+```sh
+mkdir -p ~/.local/bin
+cd ~/.local/bin
+wget -O linuxdeploy https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
+wget -O linuxdeploy-plugin-qt https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-x86_64.AppImage
+wget -O appimagetool https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage
+chmod +x linuxdeploy linuxdeploy-plugin-qt appimagetool
+```
+
+An AppImage is run by fuse, which "libfuse2t64" carries, or with
+"--appimage-extract-and-run" where fuse is not allowed. Once they are in the
+path, cmake is run again for them to be found, as it keeps what it found
+before:
+
+```sh
+cmake -S . -B build -U LINUXDEPLOY -U LINUXDEPLOY_QT -U APPIMAGETOOL
+ninja -C build products
+```
+
+Nothing of this builds the viewer for windows or for macos from a machine of
+linux: those systems build it themselves, which is what the runner of the
+build is for, see ".github/workflows/desktop.yml".
+
+
+## Building WebODF on Windows
+
+The library alone needs node and cmake, java for the checks, and nothing of the
+compiler: it is javascript. The compiler is needed by the two products of qt, qtjsruntime and
+the viewer of the desktop, and it has to be the one of Microsoft, as Qt
+WebEngine does not compile with MinGW.
+
+* [Visual Studio 2022](https://visualstudio.microsoft.com/downloads/), the
+ Build Tools alone are enough, with the workload "Desktop development with C++"
+* [The installer of Qt 6](https://www.qt.io/download-qt-installer), version 6.8
+ or later, architecture "MSVC 2022 64-bit", with the modules WebEngine and
+ WebChannel, for the options WEBODF_QTJSRUNTIME and WEBODF_DESKTOP only. Since
+ 6.8 WebEngine is an extension, in a repository of its own
+* [CMake](https://cmake.org/download/)
+* [A java runtime](https://www.java.com/en/download/), 17 or later, that runs
+ the closure compiler and rhino
+* [Node](https://nodejs.org/), 20 or later
+* [Git for Windows](https://gitforwindows.org/), which also brings the unix
+ tools the build calls, "cat" among them
+
+Everything of that list is installed at once by the script
+"programs/opendocumentviewer-desktop/data/setup-windows.ps1", that a machine of
+its own is set up with, see "README-Products.md". It is what the build of
+windows is tested with, as no one of this project owns such a machine.
+
+Only x86_64 and ARM64 are built: Qt 6 dropped the 32 bits.
+
+### Building webodf.js
- ulimit -n 8192
+The commands are entered in the "x64 Native Tools Command Prompt for VS 2022",
+that puts the compiler in the path:
+
+```sh
+git clone https://github.com/webodf/WebODF.git webodf
+md build
+cd build
+cmake -G Ninja -DCMAKE_BUILD_TYPE=Release ..\webodf
+cmake --build .
+```
+
+The generator "Visual Studio 17 2022" builds as well, and it is slower.
+
+
+## Building WebODF on macOS
+
+Qt 6 is installed by homebrew, "brew install qt", or by the installer of qt,
+and homebrew does not link it by default. CMake is told where it is by the
+variable CMAKE_PREFIX_PATH:
+
+```sh
+cmake -DCMAKE_PREFIX_PATH=$(brew --prefix qt) ../webodf
+```
+
+If the build process returns an error `(libuv) Failed to create kqueue (24)`,
+this can be resolved by increasing the limit on the number of open file
+descriptors:
+
+```sh
+ulimit -n 8192
+```
+
+The viewer of the desktop is packed as a bundle, signed and notarised, which is
+another matter, see "README-Products.md".
+
+## Javascript dependencies
+
+Unlike most node projects, the runtime dependency "@xmldom/xmldom" (about 400 kB)
+is versioned inside the directory "node_modules", and it has been so since 2012
+(commit "include node_modules directory with xmldom"), so that WebODF can be run
+from a simple checkout, without npm and without network access. The tools of the
+build (terser, jsdoc) are not versioned: they are installed with "npm install"
+and the file ".gitignore" keeps only "@xmldom".
+
+This dependency is used by the file "webodf/lib/runtime.js", that needs a
+DOMParser when WebODF runs inside node, for example for the command line tools.
+A browser uses its own native parser, so this dependency is never included in
+the compiled file "webodf.js".
+
+As a consequence, an update of a dependency must commit the versioned copy along
+with the file "package.json":
+
+```sh
+npm install
+git add package.json package-lock.json node_modules
+```
+
+Without it, a fresh checkout keeps running the previous version, whatever the
+file "package.json" says.
+
+JSZip is versioned too, but differently: the file "webodf/lib/externs/JSZip.js"
+holds its distribution, that is concatenated into "webodf.js", as a browser
+needs it to read and write the zip an ODF document is. It is updated by hand,
+from the file "dist/jszip.js" of the package, whose wrapper is replaced by the
+one the previous copy carries: the class is attached to the shared object
+"externs" rather than to the global scope, and the modules of its bundle are
+hidden from the commonjs of node, that would otherwise capture the export. The
+call to new Buffer() of its module "nodeBuffer" is patched as well, as node
+deprecated it.
+
+The version in use is JSZip 2.6.1, the last of its line. JSZip 3 is not used
+yet, for two reasons only: its api is asynchronous, so the three calls of Zip.js
+would go through the promises it ships with, and it weighs 17 kB more once
+minified, since it added a layer of streams. Both versions run on the same
+browsers, IE 6 included.
+
+## Building with node
+
+The library is also built without cmake and without java, with node only. It is
+the shortest way to "webodf.js", and it does not download anything but the
+packages of npm. It builds the library and nothing else: every other product
+is built by cmake, see "README-Products.md".
+
+Node 22.22.2 or later is needed, both here and for the build with cmake: 22 is
+the oldest release that is still maintained, and jsdom, that the tests use, runs
+on none of its earlier ones. The exact range is in the field "engines" of
+"package.json"; the tools are tested with node 24, the release under long term
+support. Node is expected to be installed, on every platform, npm along with it:
+it used to be downloaded on Windows, but only the binary of node, without the
+npm the build needs.
+
+```sh
+npm install
+npm run build
+```
+
+The result is written in "dist/webodf.js". The sources are concatenated in the
+order of their dependencies, taken from the file "webodf/lib/manifest.json",
+then minified with terser. The output has the same size as the one of the
+closure compiler used with SIMPLE_OPTIMIZATIONS, that the original build used.
+
+Each command builds one output, so only what is needed is built:
+
+```sh
+npm run build # the library, in "dist/webodf.js"
+npm run doc # the documentation of the api, in "dist/docs"
+npm run check # check the types with the closure compiler (java is needed)
+npm run check:tests # check the types of the library and of the tests
+npm test # run the tests with node
+npm run test:rhino # run the tests with Rhino, on a java virtual machine
+npm run test:browser # run the tests in a browser, with all the suites
+npm run test:extension # run the add-on of Chrome and check it shows a document
+npm run all # check, test, build and doc
+```
+
+The command "npm run check" uses the closure compiler as a type checker only:
+it writes no output. The jar is downloaded once from maven central into the
+directory ".tools" and the version is pinned in "scripts/lib/closure.js".
+
+"npm run check:tests" checks the tests as well, as the target "compiled.js" of
+the build with cmake does, so that both builds report the same errors. The
+library alone is fully typed, the tests are not: they declare mocks that are
+partial on purpose, so reportUnknownTypes is off for them.
+
+It ends with a second pass over the libraries packaged with "webodf.js", JSZip
+for now, that only reads their jsdoc, as the target "simplecompiled.js" of the
+build with cmake does. Their types are not checked, since they are not written
+for the compiler, but an annotation it cannot parse stops the build, so the
+check with node has to see it too.
+
+```sh
+CLOSURE_VERSION=v20240101 npm run check # another version
+CLOSURE_JAR=/path/to/compiler.jar npm run check # another copy
+```
+
+The groups of checks removed from the compilers newer than 2016 are dropped
+automatically when an older one is used. The compiler of 2016, that the project
+used until now, does not check the sources any more: they use globalThis, that
+it does not know.
+
+The configuration for karma, in "webodf/tools/karma.conf.js", is kept and is
+still generated by "webodf/tools/updateJS.js" during a build with cmake, but the
+command "npm run test:browser" replaces it and needs no extra package.
+
+### Running with Rhino
+
+Rhino runs javascript on a java virtual machine and gives a second engine for
+the tests, besides node. The jar of Rhino is downloaded from maven central into
+".tools", like the one of the closure compiler, and the version is set in
+"scripts/lib/rhino.js" or with the environment variable RHINO_VERSION.
+
+The file "tests.js" selects the suites from what the runtime provides, so each
+engine runs what it can:
+
+| Engine | Suites | What it provides |
+|------------------|--------|-----------------------------------------|
+| a browser | 35 | everything, with a layout and its css |
+| node, with jsdom | 26 | a dom with a range and a tree walker |
+| node, alone | 3 | the package xmldom, without a range |
+| Rhino | 3 | the dom of java, lists without an index |
+
+The tests with node use jsdom when it is installed, which is the case after
+"npm install": it is a development dependency, the library itself does not use
+it. Three suites are added only in a browser: two measure where the text is
+drawn, that needs a layout engine, and one compares the rules of a stylesheet
+one by one, that needs a css parser rejecting the same rules.
+
+The runtime for Rhino could not even start between 2013 and now, so its own
+tests had never been run.
+
+### Running the tests in a browser
+
+The command "npm run test:browser" serves the tests over http, since a page
+loaded from a file cannot read them, then opens them in a chromium found on the
+system. The browser is not downloaded: set WEBODF_BROWSER to its path, or
+install one with "npx playwright install chromium".
+
+Two tests fail today, and they are not a defect of the browser:
+
+- RuntimeTests.testRead reads the raw bytes of a file that starts with a byte
+ order mark. The runtime asks for them with the trick of the mime type
+ "charset=x-user-defined", but a recent chromium decodes the answer as utf-8
+ and removes the mark first. Reading the answer as an array buffer, as it is
+ done since a long time, would fix it.
+- MaliciousDocumentTests.loadInjectionDocument reads a document the same way.
+
+### Outputs
+
+| Path | Built by | Content |
+|-----------------------------------|----------|----------------------------------------|
+| `dist/webodf.js` | node | the library, minified |
+| `dist/docs/` | node | documentation of the api |
+| `build/webodf/webodf.js` | cmake | the library, minified |
+| `build/webodf/webodf-debug.js` | cmake | the library, readable |
+| `build/webodf/webodf-compiled.js` | cmake | the library without its license header |
+| `build/webodf/simplecompiled.js` | cmake | the library and its tests, run by node |
+| `build/webodf/webodf.css.js` | cmake | the css of the viewer, as a string |
+| `build/webodf/webodfversion.js` | cmake | the version, from `git describe` |
+
+The build with node writes in "dist" and needs no other directory: the version
+and the css are generated in memory, not in files. The build with cmake writes
+in the directory given to cmake, usually "build", next to the sources, and
+keeps its downloads there.
+
+Both libraries are the same file, byte for byte: the sources concatenated in the
+order of their dependencies, with IS_COMPILED_CODE set to true so that the
+runtime does not load the classes one by one, minified by terser. The build
+with cmake runs "scripts/build.js" as well, see "Two ways to build" above.
+
+### Building everything again without downloading it again
+
+The build directory holds two kinds of files: what was made here, and what was
+fetched from elsewhere. Only the first has to go.
+
+```sh
+ninja -C build -t clean # every file a rule wrote, nothing else
+ninja -C build products
+```
+
+"ninja -t clean" leaves the archives of "build/downloads", some 210 MB, and it
+leaves the directories the external projects were unpacked into,
+"build/*-prefix". Nothing is asked of the network again.
+
+When even the cmake cache is to go, keep the downloads elsewhere so that they
+outlive the directory:
+
+```sh
+export WEBODF_DOWNLOAD_DIR=$HOME/.cache/webodf-downloads
+mkdir -p "$WEBODF_DOWNLOAD_DIR"
+mv build/downloads/* "$WEBODF_DOWNLOAD_DIR"/
+rm -rf build
+cmake -S . -B build -G Ninja
+ninja -C build products
+```
+
+The variable is read at configure time and printed back: "external downloads
+will be stored/expected in: ...". The external projects are unpacked again,
+which costs no network, only some minutes.
+
+A build directory cannot be shared between two machines, nor between a container
+and its host. Cmake writes into its cache the path of every tool it found —
+cmake itself, node, npm, java, the Android SDK — and those paths are read again
+without being checked. A cache made in a container names tools the host does not
+have, and the build fails with "cmake: not found", an empty version of node or
+an SDK that is not there. Give each machine a build directory of its own, and
+share only "$WEBODF_DOWNLOAD_DIR".
+
+To make cmake look for the tools again without losing the rest of the cache,
+unset the variables that hold them and configure again, from outside the source
+directory:
+
+```sh
+cmake -S . -B build -U NODEJS_EXECUTABLE -U NPM -U DPKG_DEB -U RPMBUILD
+```
+
+### Running the add-ons without installing them
+
+The three packages of "programs/opendocumentviewer-webext", see "README-Products.md", are
+loaded from their directory, with a profile of their own, so that nothing has to
+be clicked and nothing is kept:
+
+```sh
+npx web-ext run --source-dir build/opendocumentviewer-firefox-mv2-x.y.z/
+chromium --user-data-dir=$(mktemp -d) --no-first-run \
+ --load-extension=build/opendocumentviewer-chrome-x.y.z/
+```
+
+web-ext writes a temporary profile, installs the add-on in it and follows the
+changes of the files; "--firefox" chooses the binary and "--url" opens a page at
+once. Open the page after the add-on is installed, not with it:
+a page that is asked for while Firefox is still starting is not redirected, and
+the add-on looks broken when it is not. Firefox refuses an unsigned xpi, but not
+a directory loaded this way, which is what "about:debugging" does by hand.
+
+Chrome keeps the profile of "--user-data-dir", hence the temporary directory,
+and "--load-extension" only takes a directory, never a zip.
+
+"npm run test:extension" does all of it for Chrome: it builds the package,
+serves a document under a type that says nothing, asks the browser for it and
+checks that the viewer of the add-on drew it. It needs a chromium, like
+"npm run test:browser", and the library of "dist".
+
+It is worth running: a rule Chrome refuses is dropped without a word, and the
+documents are downloaded as if the add-on were not installed. Neither the linter
+of addons.mozilla.org nor the closure compiler sees it. Firefox is not driven,
+as web-ext is not a dependency of this project.
+
+### What the closure compiler is used for
+
+The library is not compiled with it any more, only checked. It is worth keeping,
+because the sources are annotated with types in their jsdoc and the check is
+strict: every expression must have a known type. It helps to find real issues,
+and nine were found when merging repositories, among them a null document, a
+variable used for two different types and a type of record missing a member that
+the code used.
+
+## Measuring
+
+The benchmark measures the library on a document of a hundred pages, and
+writes the times of some twenty actions:
+
+```sh
+make -C build benchmark-html
+xdg-open build/programs/benchmark/index.html
+```
+
+The whole of it is another target, that measures the four documents, of one,
+ten, a hundred and a thousand pages, and writes every action of every document
+in one table, of an action to a line and a document to a column, which is read
+across:
+
+```sh
+make -C build benchmark-html-all
+xdg-open build/programs/benchmark/all.html
+```
+
+Both are a matter of minutes: the last action, that selects the whole document
+and removes it, takes half a minute on a hundred pages and far more on a
+thousand, as one operation is made for each paragraph of the selection and the
+document holds eleven thousand of them. It is left out by a parameter when the
+wait is too long:
+
+```
+index.html?includeSlow=false
+```
+
+The two are the same page with other parameters, that are given by hand as
+well:
+
+```
+index.html?fileUrl=1page.odt,10pages.odt&layout=matrix
+```
+
+and a single document, or a document of your own, by:
+
+```
+index.html?fileUrl=1000pages.odt
+index.html?fileUrl=/path/to/document.odt&includeSlow=false
+```
+
+The two last columns of the table of one document, "km/h" and "pages/h", are
+the distance the cursor travelled over the time it took: they are read as a
+rate, and they are a joke of the authors of the benchmark rather than a
+measure of the library. The table of every document holds the times alone.
diff --git a/README-Products.md b/README-Products.md
index 3862d968f..b3c18bc5c 100644
--- a/README-Products.md
+++ b/README-Products.md
@@ -1,62 +1,1031 @@
## Products
-The WebODF repository not only contains sources for the library webodf.js, but also a few products based on it. This is the complete list of products that can be created ("x.y.z" is a placeholder for the actual version number):
+The library "webodf.js" alone is built with node too, and this is the simplest
+way to get it, see "README-Building.md". The products below, that bundle the
+library with the editors, the extensions and their documentation, are built
+with cmake only.
+
+The WebODF repository not only contains sources for the library webodf.js, but
+also a few products based on it. This is the complete list of products that can
+be created ("x.y.z" is a placeholder for the actual version number):
+
+### What each product runs on
+
+A product runs where the engine it is drawn in has what the library asks of
+it: the elements of a document are read by their namespace, the rules of the
+pages are written in a sheet of the document, and the pages are laid in
+columns that keep the spacings of an office apart. The floors below follow
+from that, and from what each store and each system asks of a package.
+
+| product | floor | what sets it |
+|--------------------------------|------------------------------------|-------------------------------------------------------------------|
+| library "webodf.js" | Chrome 88, Firefox 78, Safari 15.4 | flex, `contain`, `insertRule` with `@namespace`, `document.fonts` |
+| add-on for Firefox (mv3) | Firefox 109 | `strict_min_version` of the manifest |
+| add-on for Firefox (mv2) | Firefox 52 | `strict_min_version` of the manifest |
+| add-on for Chrome | Chrome 88 | `minimum_chrome_version` of the manifest |
+| add-on for Thunderbird | Thunderbird 128 (mv3), 98 (mv2) | `strict_min_version` of the manifest |
+| viewer of the desktop | Qt 6.4 | `find_package(Qt6 6.4)`, the one of Debian 12 |
+| viewer of the desktop, windows | Windows 10 | `MinVersion` of the installer |
+| viewer of the desktop, macos | macOS 12 | `CMAKE_OSX_DEPLOYMENT_TARGET`, 12.0 by default |
+| viewer of android | Android 5 (API 21) | `minSdk` of the build, built against API 36 |
+| viewer of ios | iOS 15 | `deploymentTarget` of the project |
+
+Internet Explorer draws nothing of a document, whatever its version: it has no
+DOM that reads a namespace, which everything here leans on. The sources are
+still written in the third edition of the language, and the compiler is told
+so, but that says how the file is parsed and not what it needs to run.
+
+None of them is built by a plain "make": they are asked for by their own
+target, from the build directory, and they need the option WEBODF_PROGRAMS,
+see "README-Building.md". The targets are listed by:
+
+```sh
+make -C build help
+```
+
+Each product answers to "product-", that builds it and runs the tests that go
+with it, and to "build-" and "test-", that do one or the other. The commands
+below are run from the build directory, or prefixed with "make -C build" from
+the sources, since the makefiles are written there and not next to the sources.
+Every product is written at the root of that directory, next to "webodf/".
### webodf.js library with API documentation
-This product bundles the file webodf.js, the debug version webodf-debug.js and API documentation into one zip file.
+This product bundles the file webodf.js, the debug version webodf-debug.js and
+API documentation into one zip file.
With a prepared setup for building, you execute this command:
- make product-library
+```sh
+make product-library
+```
-This creates a file "webodf.js-x.y.z.zip" in the same folder, which can be copied and unzipped on a system where you want to develop using the webodf.js library.
+This creates a file "webodf.js-x.y.z.zip" in the same folder, which can be
+copied and unzipped on a system where you want to develop using the webodf.js library.
Download the latest officially released version from the [WebODF homepage](http://webodf.org/download).
### Wodo.TextEditor component
-For those who want to get an OpenDocument Text editor with just a few lines of JavaScript in their HTML5 app, the component Wodo.TextEditor is the right choice.
+For those who want to get an OpenDocument Text editor with just a few lines of
+JavaScript in their HTML5 app, the component Wodo.TextEditor is the right choice.
-This product bundles a [HOWTO](https://github.com/kogmbh/WebODF/blob/master/programs/editor/HOWTO-wodotexteditor.md), example files, API documentation and a subdirectory with all files belonging to the component in one zip file.
+This product bundles a [HOWTO](programs/editor/HOWTO-wodotexteditor.md),
+example files, API documentation and a subdirectory with all files belonging to
+the component in one zip file.
With a prepared setup for building, you execute this command:
- make product-wodotexteditor
+```sh
+make product-opendocumenttexteditor
+```
+
+It creates a file "opendocumenttexteditor-x.y.z.zip", which can be copied and
+used on a system where you want to develop using the component. Unzip it there
+and read the included HOWTO.md file.
+
+See the online demo on [webodf.org/demo](http://webodf.org/demo) and download
+the latest officially released version from the [WebODF homepage](http://webodf.org/download).
+
+#### Trying the editor
-It creates a file "wodotexteditor-x.y.z.zip", which can be copied and used on a system where you want to develop using the component.
-Unzip it there and read the included HOWTO.md file.
+The editor reads its own files by request, so it is served rather than opened:
+a page that is opened from a disk reaches none of them.
-See the online demo on [webodf.org/demo](http://webodf.org/demo) and download the latest officially released version from the [WebODF homepage](http://webodf.org/download).
+```sh
+ninja -C build products
+cd build/opendocumenttexteditor
+python3 -m http.server 8098
+```
+
+| Page | What it shows |
+|-------------------|------------------------------------------------------|
+| texteditor.html | the editor on "welcome.odt", the document it carries |
+| localeditor.html | a document of the disk, opened and written again |
+| revieweditor.html | the same, with the annotations of a review |
+
+What is worth looking at, in that order: the document is drawn with its styles
+and its picture; the toolbar answers, bold, italic, the styles of a paragraph,
+undo; a word typed in the text stays there and the cursor follows it;
+"localeditor.html" opens an "*.odt" of the disk and writes it again; and the
+console of the browser reports nothing.
+
+The tests of the library cover none of that: they draw documents, they do not
+write in them.
### Wodo.CollabTextEditor component
-For those who want to get an OpenDocument Text editor for collaborative editing in their HTML5 app, the component Wodo.CollabTextEditor is a good choice.
+For those who want to get an OpenDocument Text editor for collaborative editing
+in their HTML5 app, the component Wodo.CollabTextEditor is a good choice.
-There is currently no documentation for it, besides what is in the code. Wodo.CollabTextEditor is not a complete solution itself, but has some abstraction layers which have to be implemented by adapters to the respective server systems. See the demo file ["splitscreeneditor.js"](programs/editor/splitscreeneditor.js) for an example application by a client-side server with an example adapter.
-This product bundles a subdirectory with all files belonging to the component in one zip file.
+There is currently no documentation for it, besides what is in the code.
+Wodo.CollabTextEditor is not a complete solution itself, but has some
+abstraction layers which have to be implemented by adapters to the respective
+server systems.
+
+Nothing of it is opened as the editor of one writer is: the product carries no
+page at all, only the component and what it draws with. A page of its own has
+to load it, and a server of sessions has to answer it, which is what an
+adapter is written for. The server the demonstrations of the time answered to
+is gone, so what can be told of this component here is that it is built and
+that its files are whole. See the demo file ["splitscreeneditor.js"](programs/editor/splitscreeneditor.js)
+for an example application by a client-side server with an example adapter.
+This product bundles a subdirectory with all files belonging to the component in
+one zip file.
With a prepared setup for building, you execute this command:
- make product-wodocollabtexteditor
+```sh
+make product-opendocumenttextcollab
+```
-It creates a file "wodocollabtexteditor-x.y.z.zip", which can be copied and used on a system where you want to develop using the component.
-Unzip it there and move the subdirectory "wodo" to your deployment.
+It creates a file "opendocumenttextcollab-x.y.z.zip", which can be copied and
+used on a system where you want to develop using the component. Unzip it there
+and move the subdirectory "wodo" to your deployment.
Download the latest officially released version from the [WebODF homepage](http://webodf.org/download).
-### Firefox Add-on ODF Viewer
+### OpenDocument Viewer, the add-ons of the browsers
-This Firefox add-on enables to view files in the OpenDocument format directly in your Firefox browser, without installing a big office suite.
+This Firefox add-on enables to view files in the OpenDocument format directly in
+your Firefox browser, without installing a big office suite.
With a prepared setup for building, you execute this command:
- make product-firefoxextension
+```sh
+make product-opendocumentviewer-webext
+```
+
+This creates three files:
+
+- "opendocumentviewer-firefox-x.y.z.xpi", of the manifest version 3, that
+ Firefox reads from its version 109, of 2023;
+- "opendocumentviewer-firefox-mv2-x.y.z.xpi", of the manifest version 2, that
+ it reads from its version 52, of 2017, and still reads today;
+- "opendocumentviewer-chrome-x.y.z.zip", for Chrome from its version 88, of
+ 2021, and the browsers built on it, Edge and Opera among them.
+
+Chrome for Android runs no extension at all, whatever its version, so only its
+desktop releases are reached. Firefox for Android runs the two xpi.
+
+The two xpi pass "addons-linter", the tool addons.mozilla.org validates a
+submission with, without an error. Two warnings are left, both on
+"data_collection_permissions": it is newer than the versions of Firefox the
+manifests reach back to, that ignore the keys they do not know, and it is
+declared nonetheless, as a submission without it is refused.
+
+Chrome dropped the blocking webRequest the two others redirect with, so its
+package sends the documents to the viewer with a rule of
+declarativeNetRequest, from a service worker. The rule is written by the
+worker rather than read from a file of the package, as the url it redirects to
+has to be an absolute one, and the identifier of the extension is only known
+once it is installed.
+
+The rule matches the nine extensions of the format in the url, where the
+background script of Firefox also reads the content type: a document a server
+sends under a generic type, or under a url without an extension, is missed. A
+rule only reads the response headers from Chrome 128, and asking for that
+would leave out forty of its releases.
+
+The page of the welcome comes in two, and each package carries the one of its
+own under the same name: in a browser a link is enough to read a document, where
+Thunderbird needs the menu of an attachment, and telling one the ways of the
+other would be telling it wrong. They are written from
+"welcome-browser.*.html.in" and "welcome-thunderbird.*.html.in", and both hold
+the text of the format, see "One text for every product" below.
+
+### Running the packages without installing them
+
+Both browsers load a package from a directory, with a profile of their own, so
+that nothing has to be clicked and nothing is kept:
+
+```sh
+npx web-ext run --source-dir build/opendocumentviewer-firefox-mv2-x.y.z/
+chromium --user-data-dir=$(mktemp -d) --no-first-run \
+ --load-extension=build/opendocumentviewer-chrome-x.y.z/
+```
+
+web-ext writes a temporary profile, installs the add-on in it and follows the
+changes of the files. Firefox refuses an unsigned xpi, but not a directory
+loaded this way, which is also what "about:debugging" does by hand.
+
+Chrome keeps the profile of --user-data-dir, hence the temporary directory,
+and --load-extension only takes a directory, never a zip.
+
+The version of an add-on only takes up to four numbers separated by dots,
+where git describe adds the number of commits and a hash: the build writes
+"0.5.10-161-gc2572a4a" as "0.5.10.161", so that the builds between two tags
+still follow each other.
+
+That version is read when the build is configured, not when it is made, and it
+names the packages. A build made after a commit would therefore carry the
+version of the commit before. Cmake watches ".git/HEAD" and ".git/index" for
+that reason: a commit or a checkout writes one of them, cmake configures itself
+again before make runs, and the packages are named after the sources they hold.
+Nothing has to be remembered, and "cmake ." by hand is only needed when the
+options change.
+
+An xpi is a zip whose "manifest.json" sits at its root. The two hold the same
+scripts, only their manifest differs: the version 3 declares the hosts apart,
+in "host_permissions", and its web accessible resources as objects. Firefox
+keeps reading the version 2, unlike Chrome, so the version 2 alone would reach
+every Firefox in use; the version 3 is built as well because it is the one
+addons.mozilla.org asks for.
+
+The add-on was published on addons.mozilla.org, and it is not listed there any
+more: the page of "webodf" answers 404 and a search of the store returns
+nothing. The xpi of the build is installed by hand, see above.
+
+The description the stores are given, that the field "description" of the
+manifests holds a shortened form of, as Chrome only takes 132 characters
+there:
+
+> OpenDocument Viewer reads the documents of the OpenDocument format, the
+> ones of LibreOffice, OpenOffice and Collabora: text (.odt, .fodt, .ott),
+> spreadsheets (.ods, .fods, .ots) and presentations (.odp, .fodp, .otp).
+>
+> A document opens in the browser, at once, with no download and no office
+> suite to install.
+>
+> The add-on is light, half a megabyte, where the readers of the format that
+> are installed apart weigh a hundred times that.
+>
+> OpenDocument is the first format of office documents that was approved as
+> an international standard, ISO/IEC 26300, in 2006, and the only one that
+> works as one: it is written in the open by OASIS, it belongs to no company,
+> and several programs of several makers write and read the whole of it.
+>
+> A document written today is still read in twenty years, by whoever, with
+> whatever.
+
+An add-on has to be signed by Mozilla to install in a release Firefox, whoever
+distributes it.
+
+The add-on replaces the bootstrapped one of 2012, that declared an XPCOM
+stream converter and targeted the versions 6 to 15 of Firefox: that kind of
+add-on stopped loading in Firefox 57, of 2017.
+
+Its background script watches the responses whose content type, or whose
+extension when the server sends a generic one, is one of the nine of the
+OpenDocument format, and sends them to the page "viewer.html" of the add-on,
+that reads the document with WebODF. "webodf.js" is a file of its own inside
+the package, as the content security policy of an add-on forbids the script
+that used to be written inside the page.
+
+A document that is read from the disk is opened from the page itself, with
+"open a local document": webRequest only watches http, https and the web
+sockets, so a file:// url never reaches the background script, and Firefox
+offers to save it or to open it with an office suite as it would without the
+add-on. The stream converter that was replaced sat under all of them, so it
+caught those as well; no api of a WebExtension does.
+
+A text is drawn over pages, which the library breaks it into: the pages of a
+text are in no odt at all — the file holds a flow of paragraphs, and where a
+page ends is decided by whoever draws it. Each page is a box of the size the
+master page of the document gives it, and what does not fit in one is cut
+there, a paragraph between two of its words and a table between two of its
+rows, with the rows of its head written again. A presentation is another
+matter, its slides being written apart in the file, and it is drawn one slide
+at a time.
+
+A reader asks for it, and for the way the pages are laid out, of the canvas:
+
+```js
+canvas.setPaginated(true); // pages, one under another
+canvas.setPagesPerRow(2); // two to a row, as a book is read
+canvas.setFirstPageOnItsOwn(true); // the first page on the right, as a book
+canvas.setPageMode("columns"); // every page on one row, scrolled sideways
+canvas.setPageMode("flow"); // one run of text, cut nowhere
+```
+
+The pages are broken a few at a time: the first of them are drawn in half a
+second where a document of eight hundred pages takes minutes, and a reader
+reads them while the rest is broken.
+
+The add-on holds nothing of its own outside the browser. It asks for
+"webRequest" and "webRequestBlocking" to send the responses to its page, for
+the hosts to read them, and for "downloads" to save the document the page
+shows, since a page of an add-on may not save a file of another origin by
+itself.
+
+Only the APIs Firefox has carried since its version 47 are used, so the
+version 2 runs down to the version 52 its manifest asks for, that is the one
+the key "author" needs. Chrome is out of reach for both: its manifest version
+3 wants a service worker as background, that Firefox does not support, and it
+dropped the blocking webRequest this add-on redirects with.
+
+### OpenDocument Viewer for Thunderbird
+
+The same viewer reads the attachments of the messages, so that a document that
+arrives by mail is read in Thunderbird, without saving it and without an office
+suite.
+
+An attachment never travels over http: it is a part of the message itself,
+addressed in "mailbox://" or "imap://", that webRequest never sees. The way of
+the browsers does not reach it, and the add-on takes another one: it reads the
+attachment as a file with "messages.getAttachmentFile" and opens it in a tab of
+the viewer. That is the path the button "open a local document" already takes,
+so "viewer.html" is used as it is.
+
+The document is opened from an entry of the menu of the attachment, and from
+the menu of a message that carries one, where it is shown once the attachments
+have been read. There is no button of its own in the header of a message:
+Thunderbird disables such a button but never hides it, and one that is grey on
+nearly every message is noise.
+
+The manager of the add-ons of Thunderbird shows two texts. The short one, that
+sits under the name, is the field "description" of the manifest, and it is one
+sentence. The long one, under the tab of the details, is not in the package at
+all: it is the text of the listing of addons.thunderbird.net, written there at
+the submission, and the manager reads it from the store. The one below is
+that text.
+
+> Reads the OpenDocument attachments of a message inside Thunderbird, without
+> saving them and without an office suite.
+>
+> How it is used:
+> - right-click an attachment and choose "Open in OpenDocument Viewer";
+> - or right-click the message that carries it, which offers the same entry,
+> and a submenu when it carries several documents;
+> - the document opens in a tab, at the size of the page, and nothing is
+> written to the disk.
+>
+> It reads the text (.odt, .ott, .fodt), the spreadsheets (.ods, .ots, .fods)
+> and the presentations (.odp, .otp, .fodp) that LibreOffice and every other
+> office suite write.
+>
+> Why this format rather than the other one: OpenDocument is the first format
+> of office documents approved as an international standard, ISO/IEC 26300, in
+> 2006, and the only one that works as one. It is written in the open by OASIS,
+> it belongs to no company, and several programs of several makers write and
+> read all of it. OOXML was approved in 2008 with a transitional form, meant
+> for the older documents and to be dropped from the standard, and that form is
+> still what the office suites write today, Microsoft 365 among them, on the
+> desktop as on the web.
+>
+> It holds no permission on the network, reads no message but the one that is
+> shown, and is free software, under the AGPL 3.
+
+Neither text takes a link, so the way to the page that tells the whole of it is
+the button of the options, the wrench of that same page, which "options_ui"
+points at "welcome.html": a page that holds nothing but the choice of the
+language, since the manager opens a single address and knows none.
+
+The page of the welcome is written once for each language it is translated in,
+"welcome.fr.html" beside "welcome.en.html", and the one of the language of
+Thunderbird is opened, English being the one the others fall on. Its opening
+is written three times, in the attributes of the title and of the first
+sentence: the add-on greets a reader when it is installed, says it is up to
+date when it is updated, and tells what it is when it is read from the
+manager. A page of
+prose is read and corrected far more easily as a page than as a file of
+sentences apart, which is why the messages of i18n are not used for it.
+
+A page of welcome is opened when the add-on is installed, and once more when
+it is updated from a version that never showed it, a flag of the storage
+telling one from the other. It says where the entries of the menu are, how the
+settings are changed so that a double click opens the document in Thunderbird,
+and what the format is worth against the other one. The pictures of the menus
+are read from "skin/default/menu-attachment.png" and
+"skin/default/menu-message.png". They carry the words of Thunderbird, so one
+is kept for each language they are taken in, named after it:
+"menu-message.fr.png" beside "menu-message.png". The page tries the language
+of the reader, then that language alone, "pt" for "pt-BR", then the English
+one. Each figure that finds no picture at all leaves the page rather than
+showing a hole, so the page holds with none of them, with one, or with the
+whole set.
+
+A double click on an attachment is not answered for: Thunderbird carries no api
+for that, and what it runs is the program the settings of the system name,
+LibreOffice for a document of this format. Neither does an add-on write those
+settings: no api reads or writes the handlers of the types, and only an
+experiment, that runs privileged code and breaks at every release, reaches
+them. An add-on adds a way of opening an attachment, it does not take the one
+of the system over.
+
+The entry is shown on the documents alone. An attachment is one when its type
+is one of the nine of the format, or, for the servers that send everything as
+an octet stream, when its name ends in one of the nine extensions.
+
+The add-on asks for "menus", to add the entry, for "messagesRead", to read the
+attachment of the message that is shown, and for "downloads", as the viewer
+saves the document it draws. It reads no other message, and no network.
+
+```sh
+make -C build product-opendocumentviewer-thunderbird
+```
+
+It is packed twice as well: the version 3 needs Thunderbird 128, of 2024, and
+the version 2 reaches back to the 98, of 2022. That floor is the one of the
+menu on an attachment; every other call the add-on makes is older: the button
+of the header comes from the 71, the list of the messages that are shown and
+its event from the 81, and the attachments of a message from the 88.
+Thunderbird carries no service worker, so both hold their background as
+scripts. The add-on is published on
+[addons.thunderbird.net](https://addons.thunderbird.net/), which is not AMO,
+and is signed there.
+
+The linter of Mozilla reads those packages as well, and reports two warnings
+on each that belong to Firefox and not to Thunderbird: the permission
+"messagesRead", that it does not know, and the key
+"data_collection_permissions", that AMO asks for since Firefox 140 and that no
+Thunderbird of those versions reads.
+
+### OpenDocument Viewer for Android
+
+This application shows a document in the OpenDocument format on Android, so
+that the documents a phone receives are read without an office suite. It
+registers for the nine types of the format, so the system offers it when one
+is opened.
+
+Started on its own, from the list of the applications, it shows an empty page
+that asks for a document, and opens the picker of the system when it is touched:
+the system reads the file and hands it over, so the viewer holds no permission
+to reach the storage. It carries no bar and no button, as there would be one of
+each.
+
+It runs from Android 5.0, the release the web view began to be updated apart
+from the system in, so it holds a recent engine even on an old phone.
+
+With a prepared setup for building, from the build directory:
+
+```sh
+cmake -S ../webodf -DWEBODF_PROGRAMS=ON -DWEBODF_ANDROID=ON
+make product-opendocumentviewer-android
+```
+
+It is behind the option WEBODF_ANDROID, as it needs the sdk of android and a
+jdk, that the build does not download. Gradle is downloaded, as the closure
+compiler and Rhino are: its version is the one the plugin of android asks for,
+9 for the plugin 9, where Debian 13 packages the 4.4.1 of 2017. The sdk is read from
+-DANDROID_SDK, from $ANDROID_HOME or $ANDROID_SDK_ROOT, from a
+"local.properties" that is already there, or from "~/Android/Sdk" and
+"/usr/lib/android-sdk". What is looked for in each of them is a "platforms"
+directory: a machine may hold a "/usr/lib/android-sdk" of the tools of the
+platform alone, which is not an sdk to build with, beside a whole one
+elsewhere. Cmake stops with a message when it finds none, and
+keeps what it found in its cache, so that the option or the variable is given
+once and not at every build. It writes "local.properties" itself, which is how
+gradle reads the sdk when make runs from another shell.
+
+A variable that is exported apart, "ANDROID_HOME=/path/to/sdk; cmake ...", is
+never seen by cmake: the semicolon ends the command, and the assignment stays
+in the shell. It is written in the same command as cmake, with no semicolon,
+or exported, or given as -DANDROID_SDK.
+The command line tools that install the sdk are at https://developer.android.com/studio#command-tools,
+and the packages the build needs are:
+
+```sh
+sdkmanager "platforms;android-36" "build-tools;36.0.0" "platform-tools"
+```
+
+The apk that is written is not signed, as only its author may sign it, so it
+installs nowhere as it is. A second one is built for a test, that gradle signs
+with the key it writes for that:
+
+```sh
+make opendocumentviewer-android-debug
+```
+
+It is written next to the other, in "build/programs/opendocumentviewer-android/build/
+outputs/apk/debug/opendocumentviewer-android-debug.apk", and installs on a device with
+"adb install", or in Waydroid, that runs Android on a Linux desktop:
+
+```sh
+waydroid session start
+waydroid app install .../opendocumentviewer-android-debug.apk
+```
+
+A document is read from the shared storage of Waydroid, "~/.local/share/waydroid/data/media/0",
+that Android sees as "/sdcard": copy one there and open it with a file manager,
+that offers the viewer among the applications that read the format.
+
+Waydroid needs a web view of its own, that its images hold; the viewer draws
+nothing without one.
+
+The texts of the stores are in the sources, under
+"programs/opendocumentviewer-android/src/main/fastlane/metadata/android/", in
+the layout fastlane defines: a directory for each locale, with "title.txt", a
+"short_description.txt" of 80 characters at most, a "full_description.txt" of
+4000, and a changelog for each version code. F-Droid reads them from the
+repository at each build, so the description of the store is written and
+reviewed with the code; Google Play does not, and its console asks for the
+same texts by hand, or its publishing api does.
+
+The icon is drawn once, in 512 pixels, and the sizes are cut from it. F-Droid
+reads it in "images/icon.png" of the locale, transparent, as it draws it on
+the ground of its own card. Google Play refuses a transparency and masks the
+corners itself, so it is given an opaque copy, "store/icon-play.png", that is
+uploaded by hand and is in no package. The launcher of android gets an
+adaptive icon, "mipmap-anydpi-v26/icon.xml": a white ground and a drawing that
+holds in the 72dp of the 108dp that every shape of every maker shows, with the
+sizes of the five densities beside it, and a square icon with a margin for the
+launchers before android 8.
+
+The sdk is the only part of the build that is not free software, and the reason
+this product is off by default. The build tools are free: Debian builds them
+from the sources of AOSP and ships them in main. The platform is not free: it
+comes from the servers of Google, under the Android Software Development Kit License Agreement,
+that gradle asks to accept and writes in "$ANDROID_HOME/licenses/". Debian may
+not redistribute it, and only packages an installer that downloads it, in
+non-free. Those terms cover the sdk, not what is built with it: the apk stays
+under the license of WebODF.
+
+It is a web view that reads a page and the library from the assets of the
+application, with no framework, no plugin and no dependency at all: the sources
+are in "programs/opendocumentviewer-android" and hold one class. Everything is served
+over "https://webodf.invalid/", from the requests the web view is intercepted
+on, as a page loaded from "file://" may not read another file with XMLHttpRequest,
+which is how the library reads a document. Only the four files of the viewer and
+the one document are served, each compared by its name and never used to build a
+path. The document the system hands over comes as a "content://" uri, that a web
+view may not read, so it is copied into the cache first.
+
+Nothing the viewer does reaches the network. The application asks for no
+permission, INTERNET included, so the system refuses a connection whatever
+happens. The web view answers every request itself, and answers with nothing at
+all when the address is not one of its files: a document that holds an image or
+a style sheet of the web tells no server that it was opened. Safe Browsing is
+turned off in the manifest, as there is no address to check, which spares the
+web view from asking Google for its lists, and the metrics it may report are
+turned off as well.
+
+The web view is still the one of the system, kept up to date by Google, and what
+it does on its own, such as reading the configuration of its field trials,
+belongs to it rather than to this application.
+
+It replaces the product of "programs/cordova", that drove cordova 3.5, of 2014,
+and built android with ant, which google dropped in 2015 for gradle, through the
+executable "android", that the sdk replaced by "sdkmanager" in 2018.
+
+### OpenDocument Viewer for the desktop
+
+This program shows a document of the OpenDocument format on a desktop, on linux,
+on windows and on macos: a window of qt around the same page the add-ons of the
+browsers and the viewer for android draw a document in. There is one place where
+the reading of the format lives, and one behaviour to keep in step.
+
+It reads the text (.odt), the spreadsheets (.ods), the presentations (.odp) and
+the drawings (.odg), with their templates. A document is opened from the menu,
+by dropping it in the window, or by naming it on the command line, which is how
+a file manager opens one. It is drawn at the size it was written at, and only
+scaled down when it is wider than the window; the menu of the display zooms it,
+sets it back to its own size, or fits it to the width.
+
+A document is printed, and written as a pdf, by the printing of the engine.
+
+The menu of the help, and the foot of the empty screen, lead to a page that
+tells what the viewer does and what the format is worth, in French or in
+English, after the language of the system. The part about the format is the same
+text as the one the add-ons and the viewer for android show, and it is the same
+file: see "One text for every product" below.
+
+With a prepared setup for building, from the build directory:
+
+```sh
+cmake -S ../webodf -DWEBODF_DESKTOP=ON
+make product-opendocumentviewer-desktop
+```
+
+It is behind the option WEBODF_DESKTOP, as it needs the modules of qt, and it
+is built by that option alone: it needs neither Dojo nor the editors, so
+WEBODF_PROGRAMS is not asked for. The modules are the ones qtjsruntime needs,
+see "README-Building.md".
+
+The program is one file: the page, its style, its script, the library and the
+icon are all put in it, so it runs wherever it is copied. It is installed with
+what a desktop needs to offer it for a document:
+
+```sh
+make install
+```
+
+It writes the program in "bin", an entry in "share/applications" that names the
+nine types of the format, and the icon under the name of the entry, as the
+specification of the freedesktop asks. A double click on a document then offers
+the viewer among the applications that read the format.
+
+#### Trying the viewer that was built
+
+The program that was built is run where it stands, without installing it and
+without packing it:
+
+```sh
+build/programs/opendocumentviewer-desktop/opendocumentviewer-desktop
+build/programs/opendocumentviewer-desktop/opendocumentviewer-desktop a-document.odt
+```
+
+Named with a document, it opens it; named with nothing, it opens the empty
+screen. The library it draws with is put in it when it is linked, so a fix of
+the library is seen only once the program is linked again: "make -C build
+product-opendocumentviewer-desktop" answers for both.
+
+The archive holds the same program with the entry of the menu and the icon, for
+a machine where it is to be tried as it is handed over:
+
+```sh
+mkdir -p /tmp/viewer
+tar xzf build/products/opendocumentviewer-x.y.z-linux-x86_64.tar.gz -C /tmp/viewer
+/tmp/viewer/bin/opendocumentviewer-desktop a-document.odt
+```
+
+The page and the document it shows are served by the program itself, under a
+scheme of its own, "odf:", see "programs/opendocumentviewer-desktop/viewerscheme.cpp":
+they are one origin that way, which is what the page needs to read the document,
+and the disk is not opened to it for that, as the one document that was chosen
+is served, at one address, whichever file it is.
+
+#### The viewer on windows
+
+Nothing in the program is of linux, and the build writes what windows asks for:
+the icon in the format of its own, made from the icon of the project at the
+sizes windows draws it at, the version that the properties of the file show, and
+a program that opens no terminal behind its window.
+
+Qt WebEngine does not compile with MinGW, which the documentation of Qt states,
+so the compiler is the one of Microsoft. The program is of 64 bits, and only of
+64 bits: Qt 6 is built for x86_64 and for arm64, and no longer for a windows of
+32 bits. The property WIN32_EXECUTABLE of cmake, that the build sets, is named
+after the interface of windows and not after an architecture: it says that the
+program opens a window rather than a terminal. What is needed, beside the sources:
+
+* Visual Studio Build Tools, for the compiler and the linker;
+* Qt 6 with the modules of the viewer, WebEngine among them, from the installer
+ of Qt;
+* CMake, Ninja, node and a java runtime, as on linux.
+
+```sh
+cmake -S ..\webodf -DWEBODF_DESKTOP=ON -DWEBODF_QTJSRUNTIME=ON
+cmake --build . --config Release --target test-qtjsruntime
+cmake --build . --config Release --target product-opendocumentviewer-desktop
+cmake --install . --config Release --prefix dist
+```
+
+The generator of visual studio holds more than one configuration and pays no
+heed to "CMAKE_BUILD_TYPE": the configuration is named at each build and at the
+installation, otherwise the build writes "Debug" and the installation looks for
+"Release".
+
+The first target runs the tests of the library in the webengine of qt, the whole
+suite of the browser: it is what tells that the library behaves on windows as it
+does elsewhere, which nobody has known since Qt WebKit died. It costs nothing to
+ask for once the modules of qt are there, see "README-Building.md".
+
+The installation runs "windeployqt", which gathers the libraries of qt,
+"QtWebEngineProcess.exe" and the resources it reads beside the program: the
+directory then runs on a machine where qt is not installed. That is what the
+script of the installer takes:
+
+```sh
+iscc programs\opendocumentviewer-desktop\opendocumentviewer.iss
+```
+
+It is written for [Inno Setup](https://jrsoftware.org/isinfo.php), and it
+declares the nine types of the format under one identifier, in
+"OpenWithProgids": the viewer is then offered beside the office suite of the
+machine, in "Open with", and it never takes the place of what a double click
+opens. Windows warns about a program that is not signed, so a certificate is
+needed for an installer that is handed to others.
+
+##### A machine to build on
+
+The build needs a windows, and there is none to cross build from: the compiler
+of Microsoft does not run elsewhere, and MinGW, that does, is the one WebEngine
+refuses. A virtual machine answers, in VirtualBox as in QEMU. Microsoft offers
+an evaluation of windows, and a machine that is already prepared for
+development, at https://developer.microsoft.com/windows/downloads/. Give it 8 GB
+of memory and 60 GB of disk: Qt with WebEngine and the build tools of Visual
+Studio weigh some 30 GB together, and the build writes as much again.
+
+Everything is then installed by one script, in a terminal opened as an
+administrator:
+
+```powershell
+powershell -ExecutionPolicy Bypass -File programs\opendocumentviewer-desktop\data\setup-windows.ps1
+```
+
+It takes the tools from winget and Qt from its own repository, with
+[aqtinstall](https://github.com/miurahr/aqtinstall), the installer of Qt asking
+for an account that a script cannot answer for. Since Qt 6.8, WebEngine is an
+extension rather than a module, in a repository of its own, so the script checks
+that it was written and says what to do when it was not. It ends by printing the
+commands above.
+
+A machine without a graphics card, which a virtual one often is, draws the
+documents all the same: chromium falls back on the processor. Should a window
+stay empty, the fallback is asked for by hand:
+
+```powershell
+set QTWEBENGINE_CHROMIUM_FLAGS=--disable-gpu
+```
+
+#### The viewer on macos
+
+The same program, and the same build: what macos asks for beyond it is a bundle
+rather than a plain executable, an icon in the format of its own, made from the
+same drawing as the one of windows, and a "Info.plist" that names the eleven
+types the viewer reads.
+
+```sh
+cmake -S ../webodf -DWEBODF_DESKTOP=ON -DWEBODF_QTJSRUNTIME=ON \
+ -DCMAKE_PREFIX_PATH=$HOME/Qt/6.8.2/macos
+cmake --build . --target test-qtjsruntime
+cmake --build . --target product-opendocumentviewer-desktop
+cmake --install . --prefix dist
+```
+
+The installation runs "macdeployqt", which gathers the frameworks of qt,
+"QtWebEngineProcess.app" and the resources it reads inside the bundle:
+"OpenDocumentViewer.app" then runs on a machine where qt is not installed. The
+name of the bundle holds no space, as the script that qt writes to deploy the
+libraries does not quote the path it is given; the name a desktop shows is
+"OpenDocument Viewer", from the plist.
+
+One thing of macos is in the code rather than in the build: a document opened by
+a double click, or by "Open with", is not named on the command line there. The
+system sends it to the application once it is running, as an event, which
+"main.cpp" listens for. Without it the viewer would open its empty window and
+forget what it was asked for.
+
+The bundle is neither signed nor notarised by the build. Without that, macos
+refuses to open it save through the menu of the context, and says it comes from
+an unidentified developer. Both need an account of the developer program of
+Apple, at a hundred dollars a year:
+
+```sh
+codesign --deep --force --options runtime --sign "Developer ID Application: ..." \
+ dist/OpenDocumentViewer.app
+xcrun notarytool submit --wait ...
+xcrun stapler staple dist/OpenDocumentViewer.app
+```
+
+### One place for every product
+
+Every product is written where the target that packs it stands, deep in the
+tree of the build. They are gathered in one place by:
+
+```sh
+make -C build products # or: ninja -C build products
+```
+
+which makes each one, gathers it in "products/" of the build and names it. The
+add-ons of the browsers and of Thunderbird, the two editors, the apk of android,
+docnosis, the archive of the viewer of the desktop and the packages of it a
+system installs are all there, each one named after the version of the sources
+it was built from, so a product tells which sources it holds.
+
+A way of handing the viewer over that the machine has no tool to write is named
+at the end, with the tool that is wanting, so that a product that is missing is
+not taken for one that failed:
+
+```
+The products of this build are in build/products:
+ docnosis-0.5.10-314-g3b87b4ee.zip
+ opendocumentviewer-firefox-0.5.10-314-g3b87b4ee.xpi
+ opendocumentviewer-0.5.10-314-g3b87b4ee-linux-x86_64.tar.gz
+ opendocumentviewer-0.5.10-314-g3b87b4ee-x86_64.deb
+ opendocumenttexteditor-0.5.10-314-g3b87b4ee.zip
+
+This machine has no tool to make:
+ the package of fedora, for want of rpmbuild
+ the AppImage, for want of linuxdeploy
+ the flatpak, for want of flatpak-builder
+```
+
+The tests are run the same way, by one target:
+
+```sh
+make -C build tests
+```
+
+### The release of the products
+
+A tag that names a version publishes the products with the release, on both
+forges and apart: github builds and publishes its own, see
+".github/workflows/release.yml", gitlab builds and publishes its own, see
+".gitlab-ci.yml". Neither pushes a file to the other, and neither holds a
+token of the other: github signs its release with the token of the run, and
+gitlab with the token of the job.
+
+The runners of gitlab are of linux, so what asks for a machine of windows or
+of macos is built by github alone. What asks for a key of its own is built by
+neither, as a key belongs to whoever publishes and not to a forge.
+
+| Product | github | gitlab | Why |
+|---------------------------------|--------|--------|-------------------------------|
+| library, tgz | yes | yes | node alone builds it |
+| add-ons of the browsers, xpi | yes | yes | node alone builds them |
+| the two editors, zip | yes | yes | node alone builds them |
+| archive of the desktop, linux | yes | yes | a runner of linux |
+| package of debian, deb | yes | yes | dpkg-deb, of linux |
+| package of fedora, rpm | yes | yes | rpmbuild, of linux |
+| AppImage | no | no | linuxdeploy, not there |
+| flatpak | no | no | flatpak-builder, not there |
+| archive of the desktop, windows | yes | no | a runner of windows |
+| archive of the desktop, macos | yes | no | a runner of macos |
+| apk of android | no | no | it is signed by its publisher |
+| bundle of macos, signed | no | no | it is notarised by Apple |
+| application of ios | no | no | it is signed by its publisher |
+
+The AppImage and the flatpak would be built by adding their tools to the
+runner of linux: the targets are there and skip themselves when the tool is
+wanting, as they do on any machine.
+
+### Handing the viewer of the desktop over
+
+A program of the desktop is not a file that is downloaded and read, as an
+add-on is: it is installed. Five ways are written here, from the shortest to
+the most finished. Each one is a target of its own, for a build that wants one
+of them alone:
+
+```sh
+make -C build package-deb
+```
+
+and "products" makes the ones the tools of the machine allow, with everything
+else the build is for, see "One place for every product" above.
+
+| Target | What it writes | What it asks of the machine |
+|------------------|------------------------------------------------|-----------------------------------------------------------|
+| package-archive | "opendocumentviewer-x.y.z-linux-x86_64.tar.gz" | qt 6 of the system, unpacked by hand |
+| package-deb | "opendocumentviewer-x.y.z-x86_64.deb" | dpkg-deb, and qt 6 named as a dependency |
+| package-rpm | "opendocumentviewer-x.y.z-x86_64.rpm" | rpmbuild, and qt 6 named as a dependency |
+| package-appimage | "OpenDocumentViewer-x.y.z-x86_64.AppImage" | linuxdeploy and its plugin of qt, and it carries qt |
+| package-flatpak | "org.webodf.OpenDocumentViewer-x.y.z.flatpak" | flatpak-builder and the runtime of KDE, and it carries qt |
+
+Every one of them is written among the products of the build.
+
+The archive and the packages of a system name the qt of the machine rather
+than carrying it, which is what a distribution asks for: a program that
+carries its own qt is a program that no one updates when qt is fixed. The two
+universal packages carry it, which is what someone who runs another
+distribution than the one the package was made on needs.
+
+The manifest of the flatpak names the runtime of KDE, that carries qt, and the
+base app of qt, that carries its webengine, and gives the sandbox what a reader needs and no more: a window,
+and the documents the reader opens. It reaches no network, as a document is
+drawn on the machine and nothing of it is sent.
+
+That runtime is installed apart from the tool, and the build asks for both when
+cmake is run rather than in the middle of the build, where a runtime that is
+not there reads as a broken build:
+
+```sh
+flatpak remote-add --user --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
+flatpak install --user flathub org.kde.Platform//6.9 org.kde.Sdk//6.9 \
+ io.qt.qtwebengine.BaseApp//6.9
+cmake -S . -B build
+```
+
+The branch is the newest one the machine has, read when cmake is run, as a
+branch of the runtime is declared end of life as soon as a newer one is out;
+"-DWEBODF_FLATPAK_RUNTIME=6.9" names another. Without any of them, "products"
+is made without the flatpak and says so at the end, and
+"make -C build package-flatpak" tells what to install.
+
+### OpenDocument Viewer for iOS
+
+Apple allows no engine of the web but its own on iOS, so a viewer there is a
+shell around WKWebView, the view of the system, which is the WebKit of Safari.
+It is what Cordova did in 2012, in the project that was in the attic,
+with the UIWebView of the time: the same architecture, without the framework
+between, and with the engine of today, that compiles the javascript rather than
+reading it.
+
+The shell is written in Swift, in "Sources", and it is the one of android in the
+words of another system: the page, the library, the way a document is served and
+the way a link is followed are the same, see "ViewerActivity.java" beside it.
+Everything is served under "odf://viewer/", by a handler of that scheme, so that
+the page and the document are of one origin: it is what lets the library read a
+document with a request, and no name a document holds reaches anything else. No
+request of this viewer ever leaves the device.
+
+The page it shows is the page of android, file for file: cmake copies it, with
+the library and the pages about the format, into "Resources".
+
+```sh
+cmake -S ../webodf -DWEBODF_IOS=ON
+make product-opendocumentviewer-ios
+```
+
+The application itself is built by Xcode, on a mac: nothing else builds one for
+iOS. The project is written by [XcodeGen](https://github.com/yonaskolb/XcodeGen)
+from "project.yml", a project of Xcode being a file no one writes by hand:
+
+```sh
+brew install xcodegen
+cd programs/opendocumentviewer-ios
+xcodegen generate
+open OpenDocumentViewer.xcodeproj
+```
+
+What is needed beyond the code is not code: a mac with Xcode, an account of the
+developer program of Apple, that costs a hundred dollars a year, the signature
+of the application, and the review of the App Store. There is no F-Droid there,
+and no way to hand an application over outside the store, save to the devices of
+the developer.
+
+### One text for every product
+
+Three products tell what the OpenDocument format is worth, in French and in
+English: the add-ons of the browsers, in their page of the welcome, the viewer
+for android and the one for the desktop, in their page about. It is one text,
+written once, in "programs/text/format.en.html" and "programs/text/format.fr.html".
+
+A page that shows it is a template, "*.html.in", that names it where it goes:
+
+```html
+@FORMAT_TEXT@
+```
+
+Cmake reads the text and writes the page, see the macro INSERT_TEXT in the
+CMakeLists of the root. The page of a product is written where that product
+reads it: in the build directory for the add-ons and for the viewer of the
+desktop, which reads it from its resources, and among the assets for android,
+where gradle reads it, as the library is copied there as well. Those pages are
+not in the repository, only their templates and the text.
+
+The text is named as a dependency of the configuration, so cmake runs itself
+again as soon as it is revised, and the three products follow. A revision is
+therefore made in one file, and it cannot be forgotten in another.
+
+### Products that are not built any more
+
+One product of "programs/cordova" is still declared, and no version of its
+toolchain is available: it is kept until it is either brought up to date or
+dropped.
+
+"make product-opendocumentviewer-firefoxos" packs it for Firefox OS. The system was abandoned
+by Mozilla in 2016, but it lives on through its forks, B2G OS, KaiOS and
+Capyloon, so the product is worth reviving rather than dropping. KaiOS in
+particular runs on feature phones that no office suite serves, which is the kind
+of place a viewer of the OpenDocument format is the most useful.
+
+### docnosis, that tells whether a document keeps to the standard
+
+A page, and nothing else: a document is dropped on it, and it says what it is
+made of and whether it holds to OpenDocument. The document is read in the page
+and goes nowhere — nothing is uploaded, and no server sees it, which is what
+sets it apart from [the validator of the ODF Toolkit](https://odfvalidator.org/),
+of [odftoolkit.org](https://odftoolkit.org/), that reads the same schemas in
+java, on a server.
+
+```sh
+cmake -S ../webodf -DWEBODF_PROGRAMS=ON
+make product-docnosis
+```
+
+It writes "docnosis-x.y.z.zip", that holds the page, the schemas and the sources
+of the library: the validator of Relax NG is left out of "webodf.js", as no
+viewer uses it, so the page reads the library from its sources. A document is
+dropped on the page, or named in the address, which is how it is run without
+hands:
+
+```
+index.html?file=document.odt
+```
+
+What it tells of a document:
+
+* the type it declares, and whether the package says the same;
+* the version of the standard it was written to, from 1.0 to 1.4, the schemas
+ of every one of them being there, as published by OASIS;
+* whether it holds to the schema of that version;
+* what it holds that the standard does not define, named by the namespace it is
+ written under, "loext" for LibreOffice.
+
+That last one is the point of the whole thing. A document of LibreOffice does
+not fit the schema, and it is not broken for that: the standard says that a
+program writes its additions under a name of its own and that a reader that does
+not know them ignores them, see the text of the format. Reporting them apart
+from the errors is what keeps a validator from calling a sound document broken.
+
+### The products that were
+
+A viewer of documents has been written for whatever ran a web view, since 2012,
+and the list is kept here: what a thing was, and what became of it. The code is
+in the history of the repository, and it is taken out of the commit that dropped
+it:
+
+```sh
+git log --diff-filter=D -- programs/touchui
+git show ^:programs/touchui/index.html
+```
-This creates a file "firefox-extension-odfviewer-x.y.z.xpi", which can be directly installed as add-on in Firefox browsers.
+| Product | What it was | What became of it |
+|---------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| nativeQtClient | A window of qt 4, with a tree of files, that showed a document in a QWebView. It carried "programs/touchui" | Dropped in 2026, commit 3b64c38a. The viewer of the desktop, in qt 6, does what it did |
+| The client for iOS | Cordova 1.8 around a UIWebView, of 2012, that Apple stopped accepting | Dropped in 2026, commit 3b64c38a. Written again in Swift, around WKWebView |
+| The client of the BlackBerry PlayBook | A widget of WebWorks, of 2012, with an extension of its own to read a file. The tablet was abandoned in 2014, BlackBerry 10 in 2022, and the servers that signed an application are gone | Dropped in 2026, commit 3b64c38a. Nothing replaces it, as nothing runs it |
+| The viewer for android of cordova | Cordova 3.5, of 2014, built with ant, that google dropped in 2015 | Replaced in 2026 by "programs/opendocumentviewer-android", that is a web view and no framework |
+| The viewer for Firefox OS | Cordova as well, packed as a widget of the system | Still declared, and still unbuildable, see above |
+| qtjsruntime in Qt WebKit | The tests of the library, run in the webkit of qt | Written again in 2026 for the webengine of qt 6, WebKit having left qt in 5.6 |
+| "programs/touchui" | The touch interface of 2012, written with Sencha Touch: a browser of files and a view of a document. It was never packed on its own, the client of qt and the one of the PlayBook carried it | Dropped in 2026, commit de1bf464, with the externs of Ext JS that went with it. [Sencha Touch was merged into Ext JS](https://www.sencha.com/products/touch/), which is sold rather than free, and the viewers of today need no framework at all: a page and the library |
-Download and install the latest officially released version from [Mozilla's Add-on website](https://addons.mozilla.org/firefox/addon/webodf/).
+Two products were envisaged and never written: one for KaiOS, which the package
+of Firefox OS is the beginning of, and one for macos, which is the viewer of the
+desktop once it is packed as a bundle, signed and notarised.
diff --git a/README.md b/README.md
index 4ba715b6f..d265067b5 100644
--- a/README.md
+++ b/README.md
@@ -2,14 +2,20 @@
WebODF is a ODF JavaScript library originally created by KO GmbH.
-It makes it easy to add Open Document Format (ODF) support to your website and to your mobile or desktop application. It uses HTML and CSS to display ODF documents.
+It makes it easy to add Open Document Format (ODF) support to your website and
+to your mobile or desktop application. It uses HTML and CSS to display ODF
+documents.
* Visit the project homepage at: [WebODF](https://webodf.org)
* Want some live demos? Visit: [WebODF Demos](https://webodf.org/demos/)
* Get in contact:
+ * the issues of the repository, that are read
* Slack: webodf.slack.com, use the [self-invite](https://join.slack.com/t/webodf/shared_invite/enQtNTQ1NDAyNDU1NjY2LWFlZDg1NzBjY2IzY2RmMzhhMTcwZjM1YjJjOTRmMjM4Yzg1MzhjODY5N2MwOWQwMWNiNzhlZTVlYjI3MDY5YTc)
- * [mailing list](https://lists.opendocsociety.org/mailman/listinfo/webodf) or
- * IRC (#webodf auf freenode, [Web access](http://webchat.freenode.net/?nick=webodfcurious_gh&channels=webodf))
+ * the [mailing list](https://lists.nlnet.nl/archives/list/webodf@nlnet.nl/),
+ that NLnet hosts
+
+The channel of freenode was the other way, and it answers no more: freenode was
+abandoned in 2021.
### License
@@ -17,35 +23,61 @@ WebODF is a Free Software project. All code is available under the AGPL.
If you are interested in using WebODF in your commercial product
(and do not want to disclose your sources / obey AGPL),
-get in touch at [the license page](https://webodf.org/about/license.html) for a license suited to your needs.
+get in touch at [the license page](https://webodf.org/about/license.html) for a
+license suited to your needs.
### Creating webodf.js...
-webodf.js is compiled by using the Closure Compiler. This compiler concatenates and compacts all JavaScript files, so that they are smaller and execute faster. CMake is used to setup the buildsystem, so webodf.js can be created:
+webodf.js is compiled by using the Closure Compiler. This compiler concatenates
+and compacts all JavaScript files, so that they are smaller and execute faster.
+CMake is used to setup the buildsystem, so webodf.js can be created:
+
+```sh
+git clone https://github.com/webodf/WebODF.git webodf
+mkdir build
+cd build
+cmake -S ../webodf
+make webodf.js-target
+```
- git clone https://github.com/kogmbh/WebODF.git webodf
- mkdir build
- cd build
- cmake ../webodf
- make webodf.js-target
+A successful run will yield the file "webodf.js" in the subfolder "build/webodf/",
+among other things, from where you can then copy it and use for your website.
-A successful run will yield the file "webodf.js" in the subfolder "build/webodf/" (among other things), from where you can then copy it and use for your website.
+For more details about preparing the build of webodf.js , e.g. on Windows or OSX,
+please study ["README-Building.md"](README-Building.md).
-For more details about preparing the build of webodf.js , e.g. on Windows or OSX, please study ["README-Building.md"](README-Building.md).
+What a program may lean on in the library — the canvas that draws a document,
+the container that holds it, and what each of them answers — is written in
+["PUBLIC-API.md"](PUBLIC-API.md).
### ... and more
-This repository not only contains code for the library webodf.js, but also a few products based on it. Here is the complete list:
+This repository not only contains code for the library webodf.js, but also a few
+products based on it. Here is the complete list:
-build target | output location (in build/) | description | download/packages
------------------------------|---------------------------------------|------------------------------------|-----
-webodf.js-target | webodf/webodf.js | the library | (see product-library)
-product-library | webodf.js-x.y.z.zip | zip file with library and API docs | [WebODF homepage](http://webodf.org/download)
-product-wodotexteditor | wodotexteditor-x.y.z.zip | simple to use editor component | [WebODF homepage](http://webodf.org/download)
-product-wodocollabtexteditor | wodocollabtexteditor-x.y.z.zip | collaborative editor component | [WebODF homepage](http://webodf.org/download)
-product-firefoxextension | firefox-extension-odfviewer-x.y.z.xpi | ODF viewer Firefox add-on | [Mozilla's Add-on website](https://addons.mozilla.org/firefox/addon/webodf/)
+build target | output location (in build/) | description |
+---------------------------------------|-----------------------------------------------------|----------------------------------------------|
+webodf.js-target | webodf/webodf.js | the library as standalone for any js project |
+product-library | node-webodf-x.y.z.tgz | the library and the classes it is made of |
+product-opendocumenttexteditor | opendocumenttexteditor-x.y.z.zip | simple to use editor component |
+product-opendocumenttextcollab | opendocumenttextcollab-x.y.z.zip | collaborative editor component |
+product-opendocumentviewer-webext | opendocumentviewer-firefox-x.y.z.xpi | ODF viewer add-on for Firefox and Chrome |
+product-opendocumentviewer-thunderbird | opendocumentviewer-thunderbird-x.y.z.xpi | ODF viewer add-on for Thunderbird |
+product-opendocumentviewer-desktop | opendocumentviewer-x.y.z-*.tar.gz, .deb, .rpm, .zip | ODF viewer for linux, windows and macos |
+product-opendocumentviewer-android | opendocumentviewer-x.y.z.apk | ODF viewer application for Android |
("x.y.z" is a placeholder for the actual version number)
-For more details about the different products, please study ["README-Products.md"](README-Products.md).
+A tag that names a version publishes these products with the release, on both
+forges and apart:
+
+* [the releases of github](https://github.com/webodf/WebODF/releases)
+* [the releases of gitlab](https://gitlab.com/Sempia/WebODF/-/releases)
+
+Github builds the viewers of windows and of macos, which its runners of those
+systems alone can build; gitlab, whose runners are of linux, builds what a linux
+builds. What asks for a key of its own is published by neither: the apk of
+android, the bundle of macos and the application of ios. Which product lands
+where is named in ["README-Products.md"](README-Products.md), which tells more
+of the products as well.
diff --git a/attic/CMakeLists.txt b/attic/CMakeLists.txt
deleted file mode 100644
index 4be50f553..000000000
--- a/attic/CMakeLists.txt
+++ /dev/null
@@ -1 +0,0 @@
-add_subdirectory(programs)
diff --git a/attic/README b/attic/README
deleted file mode 100644
index c01a8a30e..000000000
--- a/attic/README
+++ /dev/null
@@ -1,2 +0,0 @@
-This directory is the place where we keep code that is not currently supported but might be revived in the future if someone would like to revive it.
-Reviving welcome.
diff --git a/attic/programs/CMakeLists.txt b/attic/programs/CMakeLists.txt
deleted file mode 100644
index 2fbfeb114..000000000
--- a/attic/programs/CMakeLists.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-add_subdirectory(nativeQtClient)
-
-add_subdirectory(playbook)
-
diff --git a/attic/programs/ios/Default-Landscape~ipad.png b/attic/programs/ios/Default-Landscape~ipad.png
deleted file mode 100644
index 06bb96b39..000000000
Binary files a/attic/programs/ios/Default-Landscape~ipad.png and /dev/null differ
diff --git a/attic/programs/ios/Default-Portrait~ipad.png b/attic/programs/ios/Default-Portrait~ipad.png
deleted file mode 100644
index dbfed967a..000000000
Binary files a/attic/programs/ios/Default-Portrait~ipad.png and /dev/null differ
diff --git a/attic/programs/ios/WebODF.xcodeproj/project.pbxproj b/attic/programs/ios/WebODF.xcodeproj/project.pbxproj
deleted file mode 100644
index ac8217180..000000000
--- a/attic/programs/ios/WebODF.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,518 +0,0 @@
-// !$*UTF8*$!
-{
- archiveVersion = 1;
- classes = {
- };
- objectVersion = 46;
- objects = {
-
-/* Begin PBXBuildFile section */
- CB099EC714DAC535000D7B99 /* Default-Portrait~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = CB099EC614DAC535000D7B99 /* Default-Portrait~ipad.png */; };
- CB099EC914DAC53D000D7B99 /* Default-Landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = CB099EC814DAC53D000D7B99 /* Default-Landscape~ipad.png */; };
- CB29ECBD14FFBBBB00CEAEE3 /* unzip.c in Sources */ = {isa = PBXBuildFile; fileRef = CB29ECBC14FFBBBB00CEAEE3 /* unzip.c */; };
- CB29ECBF14FFBC0500CEAEE3 /* ioapi.c in Sources */ = {isa = PBXBuildFile; fileRef = CB29ECBE14FFBC0500CEAEE3 /* ioapi.c */; };
- CB29ECC114FFBC1B00CEAEE3 /* mztools.c in Sources */ = {isa = PBXBuildFile; fileRef = CB29ECC014FFBC1B00CEAEE3 /* mztools.c */; };
- CB29ECC314FFBC5500CEAEE3 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = CB29ECC214FFBC5500CEAEE3 /* libz.dylib */; };
- CB36D11814F68F7F0084BECB /* www in Resources */ = {isa = PBXBuildFile; fileRef = CB36D11714F68F7F0084BECB /* www */; };
- CB533D9114DABDA600C733F6 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CB533D9014DABDA600C733F6 /* Foundation.framework */; };
- CB533D9314DABDA600C733F6 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CB533D9214DABDA600C733F6 /* UIKit.framework */; };
- CB533D9514DABDA600C733F6 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CB533D9414DABDA600C733F6 /* CoreGraphics.framework */; };
- CB533D9714DABDA600C733F6 /* AddressBook.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CB533D9614DABDA600C733F6 /* AddressBook.framework */; };
- CB533D9914DABDA600C733F6 /* AddressBookUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CB533D9814DABDA600C733F6 /* AddressBookUI.framework */; };
- CB533D9B14DABDA600C733F6 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CB533D9A14DABDA600C733F6 /* AudioToolbox.framework */; };
- CB533D9D14DABDA600C733F6 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CB533D9C14DABDA600C733F6 /* AVFoundation.framework */; };
- CB533D9F14DABDA600C733F6 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CB533D9E14DABDA600C733F6 /* CoreLocation.framework */; };
- CB533DA114DABDA600C733F6 /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CB533DA014DABDA600C733F6 /* MediaPlayer.framework */; };
- CB533DA314DABDA600C733F6 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CB533DA214DABDA600C733F6 /* QuartzCore.framework */; };
- CB533DA514DABDA600C733F6 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CB533DA414DABDA600C733F6 /* SystemConfiguration.framework */; };
- CB533DA714DABDA600C733F6 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CB533DA614DABDA600C733F6 /* MobileCoreServices.framework */; };
- CB533DA914DABDA600C733F6 /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CB533DA814DABDA600C733F6 /* CoreMedia.framework */; };
- CB533DAF14DABDA600C733F6 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = CB533DAD14DABDA600C733F6 /* InfoPlist.strings */; };
- CB533DB114DABDA600C733F6 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = CB533DB014DABDA600C733F6 /* main.m */; };
- CB533DB914DABDA600C733F6 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = CB533DB714DABDA600C733F6 /* Localizable.strings */; };
- CB533DC014DABDA600C733F6 /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = CB533DBF14DABDA600C733F6 /* icon.png */; };
- CB533DC214DABDA600C733F6 /* icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = CB533DC114DABDA600C733F6 /* icon@2x.png */; };
- CB533DC414DABDA600C733F6 /* icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = CB533DC314DABDA600C733F6 /* icon-72.png */; };
- CB533DC714DABDA600C733F6 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = CB533DC614DABDA600C733F6 /* Default.png */; };
- CB533DC914DABDA600C733F6 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = CB533DC814DABDA600C733F6 /* Default@2x.png */; };
- CB533DCD14DABDA600C733F6 /* Cordova.plist in Resources */ = {isa = PBXBuildFile; fileRef = CB533DCC14DABDA600C733F6 /* Cordova.plist */; };
- CB533DD114DABDA600C733F6 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CB533DD014DABDA600C733F6 /* AppDelegate.m */; };
- CB533DD414DABDA600C733F6 /* MainViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CB533DD314DABDA600C733F6 /* MainViewController.m */; };
- CB533DD614DABDA600C733F6 /* MainViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = CB533DD514DABDA600C733F6 /* MainViewController.xib */; };
- CB588C8B1588F70900D9CC12 /* welcome.odt in Resources */ = {isa = PBXBuildFile; fileRef = CB588C8A1588F70900D9CC12 /* welcome.odt */; };
- CBD2B77314FF8E9700FC3A44 /* NativeZip.m in Sources */ = {isa = PBXBuildFile; fileRef = CBD2B77214FF8E9700FC3A44 /* NativeZip.m */; };
- CBDCA69D1504EAEB00C706C7 /* WebViewCache.m in Sources */ = {isa = PBXBuildFile; fileRef = CBDCA69C1504EAEB00C706C7 /* WebViewCache.m */; };
- CBE61BDB1588AC0900970DD8 /* Cordova.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CBE61BDA1588AC0900970DD8 /* Cordova.framework */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXFileReference section */
- CB099EC614DAC535000D7B99 /* Default-Portrait~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default-Portrait~ipad.png"; path = "../Default-Portrait~ipad.png"; sourceTree = ""; };
- CB099EC814DAC53D000D7B99 /* Default-Landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default-Landscape~ipad.png"; path = "../Default-Landscape~ipad.png"; sourceTree = ""; };
- CB29ECBC14FFBBBB00CEAEE3 /* unzip.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = unzip.c; path = WebODF/Classes/minizip/unzip.c; sourceTree = ""; };
- CB29ECBE14FFBC0500CEAEE3 /* ioapi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ioapi.c; path = WebODF/Classes/minizip/ioapi.c; sourceTree = ""; };
- CB29ECC014FFBC1B00CEAEE3 /* mztools.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mztools.c; path = WebODF/Classes/minizip/mztools.c; sourceTree = ""; };
- CB29ECC214FFBC5500CEAEE3 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
- CB36D11714F68F7F0084BECB /* www */ = {isa = PBXFileReference; lastKnownFileType = folder; path = www; sourceTree = ""; };
- CB533D8C14DABDA500C733F6 /* KO Viewer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "KO Viewer.app"; sourceTree = BUILT_PRODUCTS_DIR; };
- CB533D9014DABDA600C733F6 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
- CB533D9214DABDA600C733F6 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
- CB533D9414DABDA600C733F6 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
- CB533D9614DABDA600C733F6 /* AddressBook.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AddressBook.framework; path = System/Library/Frameworks/AddressBook.framework; sourceTree = SDKROOT; };
- CB533D9814DABDA600C733F6 /* AddressBookUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AddressBookUI.framework; path = System/Library/Frameworks/AddressBookUI.framework; sourceTree = SDKROOT; };
- CB533D9A14DABDA600C733F6 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
- CB533D9C14DABDA600C733F6 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
- CB533D9E14DABDA600C733F6 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; };
- CB533DA014DABDA600C733F6 /* MediaPlayer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MediaPlayer.framework; path = System/Library/Frameworks/MediaPlayer.framework; sourceTree = SDKROOT; };
- CB533DA214DABDA600C733F6 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
- CB533DA414DABDA600C733F6 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
- CB533DA614DABDA600C733F6 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; };
- CB533DA814DABDA600C733F6 /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; };
- CB533DAC14DABDA600C733F6 /* WebODF-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "WebODF-Info.plist"; sourceTree = ""; };
- CB533DAE14DABDA600C733F6 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
- CB533DB014DABDA600C733F6 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
- CB533DB214DABDA600C733F6 /* WebODF-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "WebODF-Prefix.pch"; sourceTree = ""; };
- CB533DB814DABDA600C733F6 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = Resources/en.lproj/Localizable.strings; sourceTree = ""; };
- CB533DBF14DABDA600C733F6 /* icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = icon.png; path = Resources/icons/icon.png; sourceTree = ""; };
- CB533DC114DABDA600C733F6 /* icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "icon@2x.png"; path = "Resources/icons/icon@2x.png"; sourceTree = ""; };
- CB533DC314DABDA600C733F6 /* icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "icon-72.png"; path = "Resources/icons/icon-72.png"; sourceTree = ""; };
- CB533DC614DABDA600C733F6 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Default.png; path = Resources/splash/Default.png; sourceTree = ""; };
- CB533DC814DABDA600C733F6 /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default@2x.png"; path = "Resources/splash/Default@2x.png"; sourceTree = ""; };
- CB533DCC14DABDA600C733F6 /* Cordova.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Cordova.plist; sourceTree = ""; };
- CB533DCF14DABDA600C733F6 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = Classes/AppDelegate.h; sourceTree = ""; };
- CB533DD014DABDA600C733F6 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = Classes/AppDelegate.m; sourceTree = ""; };
- CB533DD214DABDA600C733F6 /* MainViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = MainViewController.h; path = Classes/MainViewController.h; sourceTree = ""; };
- CB533DD314DABDA600C733F6 /* MainViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = MainViewController.m; path = Classes/MainViewController.m; sourceTree = ""; };
- CB533DD514DABDA600C733F6 /* MainViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = MainViewController.xib; path = Classes/MainViewController.xib; sourceTree = ""; };
- CB588C8A1588F70900D9CC12 /* welcome.odt */ = {isa = PBXFileReference; lastKnownFileType = file; path = welcome.odt; sourceTree = ""; };
- CBD2B77114FF8E9700FC3A44 /* NativeZip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NativeZip.h; path = Classes/NativeZip.h; sourceTree = ""; };
- CBD2B77214FF8E9700FC3A44 /* NativeZip.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NativeZip.m; path = Classes/NativeZip.m; sourceTree = ""; };
- CBDCA69B1504EAEB00C706C7 /* WebViewCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebViewCache.h; path = Classes/WebViewCache.h; sourceTree = ""; };
- CBDCA69C1504EAEB00C706C7 /* WebViewCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = WebViewCache.m; path = Classes/WebViewCache.m; sourceTree = ""; };
- CBE61BDA1588AC0900970DD8 /* Cordova.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cordova.framework; path = ../../../../../Shared/Cordova/Frameworks/Cordova.framework; sourceTree = ""; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
- CB533D8614DABDA500C733F6 /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- CBE61BDB1588AC0900970DD8 /* Cordova.framework in Frameworks */,
- CB29ECC314FFBC5500CEAEE3 /* libz.dylib in Frameworks */,
- CB533D9114DABDA600C733F6 /* Foundation.framework in Frameworks */,
- CB533D9314DABDA600C733F6 /* UIKit.framework in Frameworks */,
- CB533D9514DABDA600C733F6 /* CoreGraphics.framework in Frameworks */,
- CB533D9714DABDA600C733F6 /* AddressBook.framework in Frameworks */,
- CB533D9914DABDA600C733F6 /* AddressBookUI.framework in Frameworks */,
- CB533D9B14DABDA600C733F6 /* AudioToolbox.framework in Frameworks */,
- CB533D9D14DABDA600C733F6 /* AVFoundation.framework in Frameworks */,
- CB533D9F14DABDA600C733F6 /* CoreLocation.framework in Frameworks */,
- CB533DA114DABDA600C733F6 /* MediaPlayer.framework in Frameworks */,
- CB533DA314DABDA600C733F6 /* QuartzCore.framework in Frameworks */,
- CB533DA514DABDA600C733F6 /* SystemConfiguration.framework in Frameworks */,
- CB533DA714DABDA600C733F6 /* MobileCoreServices.framework in Frameworks */,
- CB533DA914DABDA600C733F6 /* CoreMedia.framework in Frameworks */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- CB533D8914DABDA500C733F6 /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
- CB533D7E14DABDA500C733F6 = {
- isa = PBXGroup;
- children = (
- CB588C8A1588F70900D9CC12 /* welcome.odt */,
- CBE61BDA1588AC0900970DD8 /* Cordova.framework */,
- CB29ECC214FFBC5500CEAEE3 /* libz.dylib */,
- CB29ECC014FFBC1B00CEAEE3 /* mztools.c */,
- CB29ECBE14FFBC0500CEAEE3 /* ioapi.c */,
- CB29ECBC14FFBBBB00CEAEE3 /* unzip.c */,
- CB36D11714F68F7F0084BECB /* www */,
- CB533DAA14DABDA600C733F6 /* WebODF */,
- CB533D8F14DABDA500C733F6 /* Frameworks */,
- CB533D8D14DABDA500C733F6 /* Products */,
- );
- sourceTree = "";
- };
- CB533D8D14DABDA500C733F6 /* Products */ = {
- isa = PBXGroup;
- children = (
- CB533D8C14DABDA500C733F6 /* KO Viewer.app */,
- );
- name = Products;
- sourceTree = "";
- };
- CB533D8F14DABDA500C733F6 /* Frameworks */ = {
- isa = PBXGroup;
- children = (
- CB533D9014DABDA600C733F6 /* Foundation.framework */,
- CB533D9214DABDA600C733F6 /* UIKit.framework */,
- CB533D9414DABDA600C733F6 /* CoreGraphics.framework */,
- CB533D9614DABDA600C733F6 /* AddressBook.framework */,
- CB533D9814DABDA600C733F6 /* AddressBookUI.framework */,
- CB533D9A14DABDA600C733F6 /* AudioToolbox.framework */,
- CB533D9C14DABDA600C733F6 /* AVFoundation.framework */,
- CB533D9E14DABDA600C733F6 /* CoreLocation.framework */,
- CB533DA014DABDA600C733F6 /* MediaPlayer.framework */,
- CB533DA214DABDA600C733F6 /* QuartzCore.framework */,
- CB533DA414DABDA600C733F6 /* SystemConfiguration.framework */,
- CB533DA614DABDA600C733F6 /* MobileCoreServices.framework */,
- CB533DA814DABDA600C733F6 /* CoreMedia.framework */,
- );
- name = Frameworks;
- sourceTree = "";
- };
- CB533DAA14DABDA600C733F6 /* WebODF */ = {
- isa = PBXGroup;
- children = (
- CB533DB514DABDA600C733F6 /* Resources */,
- CB533DCE14DABDA600C733F6 /* Classes */,
- CB533DAB14DABDA600C733F6 /* Supporting Files */,
- );
- path = WebODF;
- sourceTree = "";
- };
- CB533DAB14DABDA600C733F6 /* Supporting Files */ = {
- isa = PBXGroup;
- children = (
- CB533DAC14DABDA600C733F6 /* WebODF-Info.plist */,
- CB533DAD14DABDA600C733F6 /* InfoPlist.strings */,
- CB533DB014DABDA600C733F6 /* main.m */,
- CB533DB214DABDA600C733F6 /* WebODF-Prefix.pch */,
- CB533DCC14DABDA600C733F6 /* Cordova.plist */,
- CB533DD514DABDA600C733F6 /* MainViewController.xib */,
- );
- name = "Supporting Files";
- sourceTree = "";
- };
- CB533DB514DABDA600C733F6 /* Resources */ = {
- isa = PBXGroup;
- children = (
- CB533DB614DABDA600C733F6 /* en.lproj */,
- CB533DBE14DABDA600C733F6 /* icons */,
- CB533DC514DABDA600C733F6 /* splash */,
- );
- name = Resources;
- sourceTree = "";
- };
- CB533DB614DABDA600C733F6 /* en.lproj */ = {
- isa = PBXGroup;
- children = (
- CB533DB714DABDA600C733F6 /* Localizable.strings */,
- );
- name = en.lproj;
- sourceTree = "";
- };
- CB533DBE14DABDA600C733F6 /* icons */ = {
- isa = PBXGroup;
- children = (
- CB533DBF14DABDA600C733F6 /* icon.png */,
- CB533DC114DABDA600C733F6 /* icon@2x.png */,
- CB533DC314DABDA600C733F6 /* icon-72.png */,
- );
- name = icons;
- sourceTree = "";
- };
- CB533DC514DABDA600C733F6 /* splash */ = {
- isa = PBXGroup;
- children = (
- CB099EC814DAC53D000D7B99 /* Default-Landscape~ipad.png */,
- CB099EC614DAC535000D7B99 /* Default-Portrait~ipad.png */,
- CB533DC614DABDA600C733F6 /* Default.png */,
- CB533DC814DABDA600C733F6 /* Default@2x.png */,
- );
- name = splash;
- sourceTree = "";
- };
- CB533DCE14DABDA600C733F6 /* Classes */ = {
- isa = PBXGroup;
- children = (
- CBDCA69B1504EAEB00C706C7 /* WebViewCache.h */,
- CBDCA69C1504EAEB00C706C7 /* WebViewCache.m */,
- CB533DCF14DABDA600C733F6 /* AppDelegate.h */,
- CB533DD014DABDA600C733F6 /* AppDelegate.m */,
- CB533DD214DABDA600C733F6 /* MainViewController.h */,
- CB533DD314DABDA600C733F6 /* MainViewController.m */,
- CBD2B77114FF8E9700FC3A44 /* NativeZip.h */,
- CBD2B77214FF8E9700FC3A44 /* NativeZip.m */,
- );
- name = Classes;
- sourceTree = "";
- };
-/* End PBXGroup section */
-
-/* Begin PBXNativeTarget section */
- CB533D8B14DABDA500C733F6 /* KO Viewer */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = CB533DDB14DABDA600C733F6 /* Build configuration list for PBXNativeTarget "KO Viewer" */;
- buildPhases = (
- CB533D8514DABDA500C733F6 /* Sources */,
- CB533D8614DABDA500C733F6 /* Frameworks */,
- CB533D8714DABDA500C733F6 /* Resources */,
- CB533D8814DABDA500C733F6 /* Sources */,
- CB533D8914DABDA500C733F6 /* Frameworks */,
- CB533D8A14DABDA500C733F6 /* ShellScript */,
- );
- buildRules = (
- );
- dependencies = (
- );
- name = "KO Viewer";
- productName = WebODF;
- productReference = CB533D8C14DABDA500C733F6 /* KO Viewer.app */;
- productType = "com.apple.product-type.application";
- };
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
- CB533D8014DABDA500C733F6 /* Project object */ = {
- isa = PBXProject;
- attributes = {
- LastUpgradeCheck = 0430;
- };
- buildConfigurationList = CB533D8314DABDA500C733F6 /* Build configuration list for PBXProject "WebODF" */;
- compatibilityVersion = "Xcode 3.2";
- developmentRegion = English;
- hasScannedForEncodings = 0;
- knownRegions = (
- en,
- es,
- );
- mainGroup = CB533D7E14DABDA500C733F6;
- productRefGroup = CB533D8D14DABDA500C733F6 /* Products */;
- projectDirPath = "";
- projectRoot = "";
- targets = (
- CB533D8B14DABDA500C733F6 /* KO Viewer */,
- );
- };
-/* End PBXProject section */
-
-/* Begin PBXResourcesBuildPhase section */
- CB533D8714DABDA500C733F6 /* Resources */ = {
- isa = PBXResourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- CB588C8B1588F70900D9CC12 /* welcome.odt in Resources */,
- CB533DAF14DABDA600C733F6 /* InfoPlist.strings in Resources */,
- CB533DB914DABDA600C733F6 /* Localizable.strings in Resources */,
- CB533DC014DABDA600C733F6 /* icon.png in Resources */,
- CB533DC214DABDA600C733F6 /* icon@2x.png in Resources */,
- CB533DC414DABDA600C733F6 /* icon-72.png in Resources */,
- CB533DC714DABDA600C733F6 /* Default.png in Resources */,
- CB533DC914DABDA600C733F6 /* Default@2x.png in Resources */,
- CB533DCD14DABDA600C733F6 /* Cordova.plist in Resources */,
- CB533DD614DABDA600C733F6 /* MainViewController.xib in Resources */,
- CB099EC714DAC535000D7B99 /* Default-Portrait~ipad.png in Resources */,
- CB099EC914DAC53D000D7B99 /* Default-Landscape~ipad.png in Resources */,
- CB36D11814F68F7F0084BECB /* www in Resources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXResourcesBuildPhase section */
-
-/* Begin PBXShellScriptBuildPhase section */
- CB533D8A14DABDA500C733F6 /* ShellScript */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- );
- outputPaths = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/bash;
- shellScript = "rsync -a ../touchui/app/ www/app/\ncp ../touchui/sencha-touch.* www/\ncp ../touchui/*.png www/\nif [ ! -e www/webodf.js ]; then\n # webodf.js should be built\n if [ ! -e build ]; then mkdir build; fi\n cd build\n cmake -G Xcode ../../.. && make && cp webodf/webodf.js ..\n if [ ! -e webodf.js ]; then\n echo \"put webodf.js in the ios/www directory\"\n exit 1;\n fi\nfi\n";
- };
-/* End PBXShellScriptBuildPhase section */
-
-/* Begin PBXSourcesBuildPhase section */
- CB533D8514DABDA500C733F6 /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- CB533DB114DABDA600C733F6 /* main.m in Sources */,
- CB533DD114DABDA600C733F6 /* AppDelegate.m in Sources */,
- CB533DD414DABDA600C733F6 /* MainViewController.m in Sources */,
- CBD2B77314FF8E9700FC3A44 /* NativeZip.m in Sources */,
- CB29ECBD14FFBBBB00CEAEE3 /* unzip.c in Sources */,
- CB29ECBF14FFBC0500CEAEE3 /* ioapi.c in Sources */,
- CB29ECC114FFBC1B00CEAEE3 /* mztools.c in Sources */,
- CBDCA69D1504EAEB00C706C7 /* WebViewCache.m in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- CB533D8814DABDA500C733F6 /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXSourcesBuildPhase section */
-
-/* Begin PBXVariantGroup section */
- CB533DAD14DABDA600C733F6 /* InfoPlist.strings */ = {
- isa = PBXVariantGroup;
- children = (
- CB533DAE14DABDA600C733F6 /* en */,
- );
- name = InfoPlist.strings;
- sourceTree = "";
- };
- CB533DB714DABDA600C733F6 /* Localizable.strings */ = {
- isa = PBXVariantGroup;
- children = (
- CB533DB814DABDA600C733F6 /* en */,
- );
- name = Localizable.strings;
- sourceTree = "";
- };
-/* End PBXVariantGroup section */
-
-/* Begin XCBuildConfiguration section */
- CB533DD914DABDA600C733F6 /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- ARCHS = "$(ARCHS_STANDARD_32_BIT)";
- CLANG_ENABLE_OBJC_ARC = NO;
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
- COPY_PHASE_STRIP = NO;
- GCC_C_LANGUAGE_STANDARD = gnu99;
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_OPTIMIZATION_LEVEL = 0;
- GCC_PREPROCESSOR_DEFINITIONS = (
- "DEBUG=1",
- "$(inherited)",
- );
- GCC_SYMBOLS_PRIVATE_EXTERN = NO;
- GCC_VERSION = com.apple.compilers.llvmgcc42;
- GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 3.0;
- SDKROOT = iphoneos;
- };
- name = Debug;
- };
- CB533DDA14DABDA600C733F6 /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- ARCHS = "$(ARCHS_STANDARD_32_BIT)";
- CLANG_ENABLE_OBJC_ARC = NO;
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
- COPY_PHASE_STRIP = YES;
- GCC_C_LANGUAGE_STANDARD = gnu99;
- GCC_VERSION = com.apple.compilers.llvmgcc42;
- GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 3.0;
- SDKROOT = iphoneos;
- VALIDATE_PRODUCT = YES;
- };
- name = Release;
- };
- CB533DDC14DABDA600C733F6 /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = YES;
- CODE_SIGN_IDENTITY = "iPhone Developer: Jos van den Oever (GJ9RDPR233)";
- COPY_PHASE_STRIP = NO;
- FRAMEWORK_SEARCH_PATHS = /Users/Shared/Cordova/Frameworks;
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_PRECOMPILE_PREFIX_HEADER = YES;
- GCC_PREFIX_HEADER = "WebODF/WebODF-Prefix.pch";
- GCC_PREPROCESSOR_DEFINITIONS = "PHONEGAP_FRAMEWORK=YES";
- GCC_THUMB_SUPPORT = NO;
- GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
- INFOPLIST_FILE = "WebODF/WebODF-Info.plist";
- IPHONEOS_DEPLOYMENT_TARGET = 5.0;
- OTHER_LDFLAGS = (
- "-weak_framework",
- UIKit,
- "-weak_framework",
- AVFoundation,
- "-weak_framework",
- CoreMedia,
- "-weak_library",
- /usr/lib/libSystem.B.dylib,
- );
- PRODUCT_NAME = "$(TARGET_NAME)";
- PROVISIONING_PROFILE = "8A253628-DC77-4EEA-8543-53315AA93987";
- TARGETED_DEVICE_FAMILY = "1,2";
- WRAPPER_EXTENSION = app;
- };
- name = Debug;
- };
- CB533DDD14DABDA600C733F6 /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = YES;
- ARCHS = (
- armv6,
- "$(ARCHS_STANDARD_32_BIT)",
- );
- CODE_SIGN_IDENTITY = "iPhone Developer: Jos van den Oever (GJ9RDPR233)";
- COPY_PHASE_STRIP = YES;
- DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
- FRAMEWORK_SEARCH_PATHS = /Users/Shared/Cordova/Frameworks;
- GCC_PRECOMPILE_PREFIX_HEADER = YES;
- GCC_PREFIX_HEADER = "WebODF/WebODF-Prefix.pch";
- GCC_PREPROCESSOR_DEFINITIONS = "PHONEGAP_FRAMEWORK=YES";
- GCC_THUMB_SUPPORT = NO;
- GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
- INFOPLIST_FILE = "WebODF/WebODF-Info.plist";
- IPHONEOS_DEPLOYMENT_TARGET = 5.0;
- OTHER_LDFLAGS = (
- "-weak_framework",
- UIKit,
- "-weak_framework",
- AVFoundation,
- "-weak_framework",
- CoreMedia,
- "-weak_library",
- /usr/lib/libSystem.B.dylib,
- );
- PRODUCT_NAME = "$(TARGET_NAME)";
- PROVISIONING_PROFILE = "8A253628-DC77-4EEA-8543-53315AA93987";
- TARGETED_DEVICE_FAMILY = "1,2";
- VALIDATE_PRODUCT = YES;
- WRAPPER_EXTENSION = app;
- };
- name = Release;
- };
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
- CB533D8314DABDA500C733F6 /* Build configuration list for PBXProject "WebODF" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- CB533DD914DABDA600C733F6 /* Debug */,
- CB533DDA14DABDA600C733F6 /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
- CB533DDB14DABDA600C733F6 /* Build configuration list for PBXNativeTarget "KO Viewer" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- CB533DDC14DABDA600C733F6 /* Debug */,
- CB533DDD14DABDA600C733F6 /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
-/* End XCConfigurationList section */
- };
- rootObject = CB533D8014DABDA500C733F6 /* Project object */;
-}
diff --git a/attic/programs/ios/WebODF/Classes/AppDelegate.h b/attic/programs/ios/WebODF/Classes/AppDelegate.h
deleted file mode 100644
index 1057ae84f..000000000
--- a/attic/programs/ios/WebODF/Classes/AppDelegate.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
- */
-
-//
-// AppDelegate.h
-// WebODF
-//
-// Created by KO GmbH on 6/13/12.
-// Copyright __MyCompanyName__ 2012. All rights reserved.
-//
-
-#import
-#define CORDOVA_FRAMEWORK
-#ifdef CORDOVA_FRAMEWORK
- #import
-#else
- #import "CDVViewController.h"
-#endif
-#import "WebViewCache.h"
-
-
-@interface AppDelegate : NSObject < UIApplicationDelegate > {
-
-}
-
-// invoke string is passed to your app on launch, this is only valid if you
-// edit WebODF-Info.plist to add a protocol
-// a simple tutorial can be found here :
-// http://iphonedevelopertips.com/cocoa/launching-your-own-application-via-a-custom-url-scheme.html
-
-@property (nonatomic, retain) IBOutlet UIWindow* window;
-@property (nonatomic, retain) IBOutlet CDVViewController* viewController;
-@property (nonatomic, retain) IBOutlet WebViewCache* cache;
-
-@end
-
diff --git a/attic/programs/ios/WebODF/Classes/AppDelegate.m b/attic/programs/ios/WebODF/Classes/AppDelegate.m
deleted file mode 100644
index 7d6358d86..000000000
--- a/attic/programs/ios/WebODF/Classes/AppDelegate.m
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
- */
-
-//
-// AppDelegate.m
-// WebODF
-//
-// Created by KO GmbH on 6/13/12.
-// Copyright __MyCompanyName__ 2012. All rights reserved.
-//
-
-#import "AppDelegate.h"
-#import "MainViewController.h"
-
-#ifdef CORDOVA_FRAMEWORK
- #import
- #import
-#else
- #import "CDVPlugin.h"
- #import "CDVURLProtocol.h"
-#endif
-#import "WebViewCache.h"
-
-@implementation AppDelegate
-
-@synthesize window, viewController, cache;
-
-- (id) init
-{
- /** If you need to do any extra app-specific initialization, you can do it here
- * -jm
- **/
- NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
- [cookieStorage setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways];
-
- [CDVURLProtocol registerURLProtocol];
-
- return [super init];
-}
-
-#pragma UIApplicationDelegate implementation
-
-/**
- * This is main kick off after the app inits, the views and Settings are setup here. (preferred - iOS4 and up)
- */
-- (BOOL) application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
-{
- NSURL* url = [launchOptions objectForKey:UIApplicationLaunchOptionsURLKey];
- NSString* invokeString = nil;
-
- if (url && [url isKindOfClass:[NSURL class]]) {
- invokeString = [url absoluteString];
- NSLog(@"WebODF launchOptions = %@", url);
- }
-
- CGRect screenBounds = [[UIScreen mainScreen] bounds];
- self.window = [[[UIWindow alloc] initWithFrame:screenBounds] autorelease];
- self.window.autoresizesSubviews = YES;
-
- CGRect viewBounds = [[UIScreen mainScreen] applicationFrame];
-
- self.viewController = [[[MainViewController alloc] init] autorelease];
- self.viewController.useSplashScreen = YES;
- self.viewController.wwwFolderName = @"www";
- self.viewController.startPage = @"index.html";
- self.viewController.invokeString = invokeString;
- self.viewController.view.frame = viewBounds;
-
- // check whether the current orientation is supported: if it is, keep it, rather than forcing a rotation
- BOOL forceStartupRotation = YES;
- UIDeviceOrientation curDevOrientation = [[UIDevice currentDevice] orientation];
-
- if (UIDeviceOrientationUnknown == curDevOrientation) {
- // UIDevice isn't firing orientation notifications yet… go look at the status bar
- curDevOrientation = (UIDeviceOrientation)[[UIApplication sharedApplication] statusBarOrientation];
- }
-
- if (UIDeviceOrientationIsValidInterfaceOrientation(curDevOrientation)) {
- for (NSNumber *orient in self.viewController.supportedOrientations) {
- if ([orient intValue] == curDevOrientation) {
- forceStartupRotation = NO;
- break;
- }
- }
- }
-
- if (forceStartupRotation) {
- NSLog(@"supportedOrientations: %@", self.viewController.supportedOrientations);
- // The first item in the supportedOrientations array is the start orientation (guaranteed to be at least Portrait)
- UIInterfaceOrientation newOrient = [[self.viewController.supportedOrientations objectAtIndex:0] intValue];
- NSLog(@"AppDelegate forcing status bar to: %d from: %d", newOrient, curDevOrientation);
- [[UIApplication sharedApplication] setStatusBarOrientation:newOrient];
- }
-
- [self.window addSubview:self.viewController.view];
- [self.window makeKeyAndVisible];
-
- NSString *path = @"./cache";
- NSUInteger diskCapacity = 1*1024*1024;
- NSUInteger memoryCapacity = 0*1024*1024;
-
- cache = [[WebViewCache alloc] initWithMemoryCapacity: memoryCapacity
- diskCapacity: diskCapacity diskPath: path];
- [NSURLCache setSharedURLCache:cache];
-
- // copy welcome.odt to the Documents folder
-
-
- NSFileManager *fileManager = [NSFileManager defaultManager];
- NSError *error;
- NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
- NSString *documentsDirectory = [paths objectAtIndex:0];
-
- NSString *txtPath = [documentsDirectory stringByAppendingPathComponent:@"welcome.odt"];
-
- if ([fileManager fileExistsAtPath:txtPath] == NO) {
- NSString *resourcePath = [[NSBundle mainBundle] pathForResource:@"welcome" ofType:@"odt"];
- [fileManager copyItemAtPath:resourcePath toPath:txtPath error:&error];
- }
-
- return YES;
-}
-
-// this happens while we are running ( in the background, or from within our own app )
-// only valid if WebODF-Info.plist specifies a protocol to handle
-- (BOOL) application:(UIApplication*)application handleOpenURL:(NSURL*)url
-{
- if (!url) {
- return NO;
- }
-
- // calls into javascript global function 'handleOpenURL'
- NSString* jsString = [NSString stringWithFormat:@"handleOpenURL(\"%@\");", url];
- [self.viewController.webView stringByEvaluatingJavaScriptFromString:jsString];
-
- // all plugins will get the notification, and their handlers will be called
- [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:CDVPluginHandleOpenURLNotification object:url]];
-
- return YES;
-}
-
-- (void) dealloc
-{
- [super dealloc];
-}
-
-@end
diff --git a/attic/programs/ios/WebODF/Classes/MainViewController.h b/attic/programs/ios/WebODF/Classes/MainViewController.h
deleted file mode 100644
index 213b69572..000000000
--- a/attic/programs/ios/WebODF/Classes/MainViewController.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
- */
-
-//
-// MainViewController.h
-// WebODF
-//
-// Created by KO GmbH on 6/13/12.
-// Copyright __MyCompanyName__ 2012. All rights reserved.
-//
-#define CORDOVA_FRAMEWORK
-#ifdef CORDOVA_FRAMEWORK
- #import
-#else
- #import "CDVViewController.h"
-#endif
-
-@interface MainViewController : CDVViewController
-
-@end
diff --git a/attic/programs/ios/WebODF/Classes/MainViewController.m b/attic/programs/ios/WebODF/Classes/MainViewController.m
deleted file mode 100644
index 0cefa4eed..000000000
--- a/attic/programs/ios/WebODF/Classes/MainViewController.m
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
- */
-
-//
-// MainViewController.h
-// WebODF
-//
-// Created by KO GmbH on 6/13/12.
-// Copyright __MyCompanyName__ 2012. All rights reserved.
-//
-
-#import "MainViewController.h"
-
-@implementation MainViewController
-
-- (id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
-{
- self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
- if (self) {
- // Custom initialization
- }
- return self;
-}
-
-- (void) didReceiveMemoryWarning
-{
- // Releases the view if it doesn't have a superview.
- [super didReceiveMemoryWarning];
-
- // Release any cached data, images, etc that aren't in use.
-}
-
-#pragma mark - View lifecycle
-
-- (void) viewDidLoad
-{
- [super viewDidLoad];
- // Do any additional setup after loading the view from its nib.
-}
-
-- (void) viewDidUnload
-{
- [super viewDidUnload];
- // Release any retained subviews of the main view.
- // e.g. self.myOutlet = nil;
-}
-
-- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
-{
- // Return YES for supported orientations
- return [super shouldAutorotateToInterfaceOrientation:interfaceOrientation];
-}
-
-/* Comment out the block below to over-ride */
-/*
-- (CDVCordovaView*) newCordovaViewWithFrame:(CGRect)bounds
-{
- return[super newCordovaViewWithFrame:bounds];
-}
-*/
-
-/* Comment out the block below to over-ride */
-/*
-#pragma CDVCommandDelegate implementation
-
-- (id) getCommandInstance:(NSString*)className
-{
- return [super getCommandInstance:className];
-}
-
-- (BOOL) execute:(CDVInvokedUrlCommand*)command
-{
- return [super execute:command];
-}
-
-- (NSString*) pathForResource:(NSString*)resourcepath;
-{
- return [super pathForResource:resourcepath];
-}
-
-- (void) registerPlugin:(CDVPlugin*)plugin withClassName:(NSString*)className
-{
- return [super registerPlugin:plugin withClassName:className];
-}
-*/
-
-#pragma UIWebDelegate implementation
-
-- (void) webViewDidFinishLoad:(UIWebView*) theWebView
-{
- // only valid if ___PROJECTNAME__-Info.plist specifies a protocol to handle
- if (self.invokeString)
- {
- // this is passed before the deviceready event is fired, so you can access it in js when you receive deviceready
- NSString* jsString = [NSString stringWithFormat:@"var invokeString = \"%@\";", self.invokeString];
- [theWebView stringByEvaluatingJavaScriptFromString:jsString];
- }
-
- // Black base color for background matches the native apps
- theWebView.backgroundColor = [UIColor blackColor];
-
- return [super webViewDidFinishLoad:theWebView];
-}
-
-/* Comment out the block below to over-ride */
-/*
-
-- (void) webViewDidStartLoad:(UIWebView*)theWebView
-{
- return [super webViewDidStartLoad:theWebView];
-}
-
-- (void) webView:(UIWebView*)theWebView didFailLoadWithError:(NSError*)error
-{
- return [super webView:theWebView didFailLoadWithError:error];
-}
-
-- (BOOL) webView:(UIWebView*)theWebView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
-{
- return [super webView:theWebView shouldStartLoadWithRequest:request navigationType:navigationType];
-}
-*/
-
-@end
diff --git a/attic/programs/ios/WebODF/Classes/MainViewController.xib b/attic/programs/ios/WebODF/Classes/MainViewController.xib
deleted file mode 100644
index 9837f578c..000000000
--- a/attic/programs/ios/WebODF/Classes/MainViewController.xib
+++ /dev/null
@@ -1,118 +0,0 @@
-
-
-
- 1280
- 11C25
- 1919
- 1138.11
- 566.00
-
-
- IBProxyObject
- IBUIView
-
-
- com.apple.InterfaceBuilder.IBCocoaTouchPlugin
-
-
-
-
-
-
-
-
-
-
-
- view
-
-
-
- 3
-
-
-
-
-
- 0
-
-
-
-
-
- 1
-
-
-
-
- -1
-
-
- File's Owner
-
-
- -2
-
-
-
-
-
-
- MainViewController
- com.apple.InterfaceBuilder.IBCocoaTouchPlugin
- UIResponder
- com.apple.InterfaceBuilder.IBCocoaTouchPlugin
- com.apple.InterfaceBuilder.IBCocoaTouchPlugin
-
-
-
-
-
- 3
-
-
-
-
- MainViewController
- UIViewController
-
- IBProjectSource
- ./Classes/MainViewController.h
-
-
-
-
- 0
- IBCocoaTouchFramework
- YES
- 3
- 916
-
-
diff --git a/attic/programs/ios/WebODF/Classes/NSData+Base64.h b/attic/programs/ios/WebODF/Classes/NSData+Base64.h
deleted file mode 100644
index eb1ff485a..000000000
--- a/attic/programs/ios/WebODF/Classes/NSData+Base64.h
+++ /dev/null
@@ -1,33 +0,0 @@
-//
-// NSData+Base64.h
-// base64
-//
-// Created by Matt Gallagher on 2009/06/03.
-// Copyright 2009 Matt Gallagher. All rights reserved.
-//
-// Permission is given to use this source code file, free of charge, in any
-// project, commercial or otherwise, entirely at your risk, with the condition
-// that any redistribution (in part or whole) of source code must retain
-// this copyright and permission notice. Attribution in compiled projects is
-// appreciated but not required.
-//
-
-#import
-
-void *NewBase64Decode(
- const char *inputBuffer,
- size_t length,
- size_t *outputLength);
-
-char *NewBase64Encode(
- const void *inputBuffer,
- size_t length,
- bool separateLines,
- size_t *outputLength);
-
-@interface NSData (Base64)
-
-+ (NSData *)dataFromBase64String:(NSString *)aString;
-- (NSString *)base64EncodedString;
-
-@end
diff --git a/attic/programs/ios/WebODF/Classes/NSData+Base64.m b/attic/programs/ios/WebODF/Classes/NSData+Base64.m
deleted file mode 100644
index 13f828d09..000000000
--- a/attic/programs/ios/WebODF/Classes/NSData+Base64.m
+++ /dev/null
@@ -1,299 +0,0 @@
-//
-// NSData+Base64.m
-// base64
-//
-// Created by Matt Gallagher on 2009/06/03.
-// Copyright 2009 Matt Gallagher. All rights reserved.
-//
-// Permission is given to use this source code file, free of charge, in any
-// project, commercial or otherwise, entirely at your risk, with the condition
-// that any redistribution (in part or whole) of source code must retain
-// this copyright and permission notice. Attribution in compiled projects is
-// appreciated but not required.
-//
-
-#import "NSData+Base64.h"
-
-//
-// Mapping from 6 bit pattern to ASCII character.
-//
-static unsigned char base64EncodeLookup[65] =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
-//
-// Definition for "masked-out" areas of the base64DecodeLookup mapping
-//
-#define xx 65
-
-//
-// Mapping from ASCII character to 6 bit pattern.
-//
-static unsigned char base64DecodeLookup[256] =
-{
- xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx,
- xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx,
- xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, 62, xx, xx, xx, 63,
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, xx, xx, xx, xx, xx, xx,
- xx, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, xx, xx, xx, xx, xx,
- xx, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, xx, xx, xx, xx, xx,
- xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx,
- xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx,
- xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx,
- xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx,
- xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx,
- xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx,
- xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx,
- xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx,
-};
-
-//
-// Fundamental sizes of the binary and base64 encode/decode units in bytes
-//
-#define BINARY_UNIT_SIZE 3
-#define BASE64_UNIT_SIZE 4
-
-//
-// NewBase64Decode
-//
-// Decodes the base64 ASCII string in the inputBuffer to a newly malloced
-// output buffer.
-//
-// inputBuffer - the source ASCII string for the decode
-// length - the length of the string or -1 (to specify strlen should be used)
-// outputLength - if not-NULL, on output will contain the decoded length
-//
-// returns the decoded buffer. Must be free'd by caller. Length is given by
-// outputLength.
-//
-void *NewBase64Decode(
- const char *inputBuffer,
- size_t length,
- size_t *outputLength)
-{
- if (length == -1)
- {
- length = strlen(inputBuffer);
- }
-
- size_t outputBufferSize = (length / BASE64_UNIT_SIZE) * BINARY_UNIT_SIZE;
- unsigned char *outputBuffer = (unsigned char *)malloc(outputBufferSize);
-
- size_t i = 0;
- size_t j = 0;
- while (i < length)
- {
- //
- // Accumulate 4 valid characters (ignore everything else)
- //
- unsigned char accumulated[BASE64_UNIT_SIZE];
- bzero(accumulated, sizeof(unsigned char) * BASE64_UNIT_SIZE);
- size_t accumulateIndex = 0;
- while (i < length)
- {
- unsigned char decode = base64DecodeLookup[inputBuffer[i++]];
- if (decode != xx)
- {
- accumulated[accumulateIndex] = decode;
- accumulateIndex++;
-
- if (accumulateIndex == BASE64_UNIT_SIZE)
- {
- break;
- }
- }
- }
-
- //
- // Store the 6 bits from each of the 4 characters as 3 bytes
- //
- outputBuffer[j] = (accumulated[0] << 2) | (accumulated[1] >> 4);
- outputBuffer[j + 1] = (accumulated[1] << 4) | (accumulated[2] >> 2);
- outputBuffer[j + 2] = (accumulated[2] << 6) | accumulated[3];
- j += accumulateIndex - 1;
- }
-
- if (outputLength)
- {
- *outputLength = j;
- }
- return outputBuffer;
-}
-
-//
-// NewBase64Decode
-//
-// Encodes the arbitrary data in the inputBuffer as base64 into a newly malloced
-// output buffer.
-//
-// inputBuffer - the source data for the encode
-// length - the length of the input in bytes
-// separateLines - if zero, no CR/LF characters will be added. Otherwise
-// a CR/LF pair will be added every 64 encoded chars.
-// outputLength - if not-NULL, on output will contain the encoded length
-// (not including terminating 0 char)
-//
-// returns the encoded buffer. Must be free'd by caller. Length is given by
-// outputLength.
-//
-char *NewBase64Encode(
- const void *buffer,
- size_t length,
- bool separateLines,
- size_t *outputLength)
-{
- const unsigned char *inputBuffer = (const unsigned char *)buffer;
-
- #define MAX_NUM_PADDING_CHARS 2
- #define OUTPUT_LINE_LENGTH 64
- #define INPUT_LINE_LENGTH ((OUTPUT_LINE_LENGTH / BASE64_UNIT_SIZE) * BINARY_UNIT_SIZE)
- #define CR_LF_SIZE 0
-
- //
- // Byte accurate calculation of final buffer size
- //
- size_t outputBufferSize =
- ((length / BINARY_UNIT_SIZE)
- + ((length % BINARY_UNIT_SIZE) ? 1 : 0))
- * BASE64_UNIT_SIZE;
- if (separateLines)
- {
- outputBufferSize +=
- (outputBufferSize / OUTPUT_LINE_LENGTH) * CR_LF_SIZE;
- }
-
- //
- // Include space for a terminating zero
- //
- outputBufferSize += 1;
-
- //
- // Allocate the output buffer
- //
- char *outputBuffer = (char *)malloc(outputBufferSize);
- if (!outputBuffer)
- {
- return NULL;
- }
-
- size_t i = 0;
- size_t j = 0;
- const size_t lineLength = separateLines ? INPUT_LINE_LENGTH : length;
- size_t lineEnd = lineLength;
-
- while (true)
- {
- if (lineEnd > length)
- {
- lineEnd = length;
- }
-
- for (; i + BINARY_UNIT_SIZE - 1 < lineEnd; i += BINARY_UNIT_SIZE)
- {
- //
- // Inner loop: turn 48 bytes into 64 base64 characters
- //
- outputBuffer[j++] = base64EncodeLookup[(inputBuffer[i] & 0xFC) >> 2];
- outputBuffer[j++] = base64EncodeLookup[((inputBuffer[i] & 0x03) << 4)
- | ((inputBuffer[i + 1] & 0xF0) >> 4)];
- outputBuffer[j++] = base64EncodeLookup[((inputBuffer[i + 1] & 0x0F) << 2)
- | ((inputBuffer[i + 2] & 0xC0) >> 6)];
- outputBuffer[j++] = base64EncodeLookup[inputBuffer[i + 2] & 0x3F];
- }
-
- if (lineEnd == length)
- {
- break;
- }
-
- //
- // Add the newline
- //
- //outputBuffer[j++] = '\r';
- //outputBuffer[j++] = '\n';
- lineEnd += lineLength;
- }
-
- if (i + 1 < length)
- {
- //
- // Handle the single '=' case
- //
- outputBuffer[j++] = base64EncodeLookup[(inputBuffer[i] & 0xFC) >> 2];
- outputBuffer[j++] = base64EncodeLookup[((inputBuffer[i] & 0x03) << 4)
- | ((inputBuffer[i + 1] & 0xF0) >> 4)];
- outputBuffer[j++] = base64EncodeLookup[(inputBuffer[i + 1] & 0x0F) << 2];
- outputBuffer[j++] = '=';
- }
- else if (i < length)
- {
- //
- // Handle the double '=' case
- //
- outputBuffer[j++] = base64EncodeLookup[(inputBuffer[i] & 0xFC) >> 2];
- outputBuffer[j++] = base64EncodeLookup[(inputBuffer[i] & 0x03) << 4];
- outputBuffer[j++] = '=';
- outputBuffer[j++] = '=';
- }
- outputBuffer[j] = 0;
-
- //
- // Set the output length and return the buffer
- //
- if (outputLength)
- {
- *outputLength = j;
- }
- return outputBuffer;
-}
-
-@implementation NSData (Base64)
-
-//
-// dataFromBase64String:
-//
-// Creates an NSData object containing the base64 decoded representation of
-// the base64 string 'aString'
-//
-// Parameters:
-// aString - the base64 string to decode
-//
-// returns the autoreleased NSData representation of the base64 string
-//
-+ (NSData *)dataFromBase64String:(NSString *)aString
-{
- NSData *data = [aString dataUsingEncoding:NSASCIIStringEncoding];
- size_t outputLength;
- void *outputBuffer = NewBase64Decode([data bytes], [data length], &outputLength);
- NSData *result = [NSData dataWithBytes:outputBuffer length:outputLength];
- free(outputBuffer);
- return result;
-}
-
-//
-// base64EncodedString
-//
-// Creates an NSString object that contains the base 64 encoding of the
-// receiver's data. Lines are broken at 64 characters long.
-//
-// returns an autoreleased NSString being the base 64 representation of the
-// receiver.
-//
-- (NSString *)base64EncodedString
-{
- size_t outputLength;
- char *outputBuffer =
- NewBase64Encode([self bytes], [self length], true, &outputLength);
-
- NSString *result =
- [[[NSString alloc]
- initWithBytes:outputBuffer
- length:outputLength
- encoding:NSASCIIStringEncoding]
- autorelease];
- free(outputBuffer);
- return result;
-}
-
-@end
diff --git a/attic/programs/ios/WebODF/Classes/NativeZip.h b/attic/programs/ios/WebODF/Classes/NativeZip.h
deleted file mode 100644
index 8f7177916..000000000
--- a/attic/programs/ios/WebODF/Classes/NativeZip.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#import
-
-@interface NativeZip : CDVPlugin {
- NSString* callbackID;
-}
-
-@property (nonatomic, copy) NSString* callbackID;
-
-- (void) load:(BOOL)base64 arguments:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
-- (void) loadAsString:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
-- (void) loadAsDataURL:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
-
-@end
\ No newline at end of file
diff --git a/attic/programs/ios/WebODF/Classes/NativeZip.m b/attic/programs/ios/WebODF/Classes/NativeZip.m
deleted file mode 100644
index 7ed75475b..000000000
--- a/attic/programs/ios/WebODF/Classes/NativeZip.m
+++ /dev/null
@@ -1,87 +0,0 @@
-#import "NativeZip.h"
-#import "minizip/unzip.h"
-#import "NSData+Base64.h"
-
-@implementation NativeZip
-@synthesize callbackID;
-
--(void) load:(BOOL)base64 arguments:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
-{
- self.callbackID = [arguments objectAtIndex:0];
- NSString *zipPath = [arguments objectAtIndex:1];
- NSString *entryPath = [arguments objectAtIndex:2];
- NSString *mimetype = nil;
- if (base64 == TRUE) {
- mimetype = [arguments objectAtIndex:3];
- }
-
- const char* path = [ zipPath cStringUsingEncoding:NSUTF8StringEncoding ];
- unzFile unzipFile = unzOpen(path);
- NSString* jsString = nil;
- BOOL error = TRUE;
- if (!unzipFile) {
- jsString = [[NSString alloc] initWithString: @"cannot open file"];
- [jsString autorelease];
- } else {
- path = [ entryPath cStringUsingEncoding:NSUTF8StringEncoding ];
- int r = unzLocateFile(unzipFile, path, 2);
- if (r != UNZ_OK) {
- jsString = [[NSString alloc] initWithString: @"cannot find entry"];
- [jsString autorelease];
- } else {
- unz_file_info info;
- r = unzGetCurrentFileInfo(unzipFile, &info, 0, 0, 0, 0, 0, 0);
- if (r != UNZ_OK) {
- jsString = [[NSString alloc] initWithString: @"cannot determine size"];
- [jsString autorelease];
- } else {
- r = unzOpenCurrentFile(unzipFile);
- if (r != UNZ_OK) {
- jsString = [[NSString alloc] initWithString: @"cannot open entry"];
- [jsString autorelease];
- } else {
- char* contents = malloc(info.uncompressed_size);
- r = unzReadCurrentFile(unzipFile, contents, info.uncompressed_size);
- if (r != info.uncompressed_size) {
- jsString = [[NSString alloc] initWithString: @"cannot uncompress file"];
- [jsString autorelease];
- } else {
- if (base64) {
- NSData* readData = [NSData dataWithBytes:(const void *)contents length:sizeof(unsigned char)*info.uncompressed_size];
- jsString = [NSString stringWithFormat:@"data:%@;base64,%@", mimetype, [readData base64EncodedString]];
- } else {
- jsString = [[NSString alloc] initWithUTF8String: contents];
- [jsString autorelease];
- }
- }
- unzCloseCurrentFile(unzipFile);
- free(contents);
- error = FALSE;
- }
- }
- }
- unzClose(unzipFile);
- }
-
- CDVPluginResult* pluginResult = [CDVPluginResult
- resultWithStatus:CDVCommandStatus_OK
- messageAsString: jsString
- ];
- if (!error) {
- [self writeJavascript: [pluginResult toSuccessCallbackString:self.callbackID]];
- } else {
- [self writeJavascript: [pluginResult toErrorCallbackString:self.callbackID]];
- }
- //free(jsString); [jsString release];
-}
-
--(void)loadAsString:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
-{
- [self load:FALSE arguments:arguments withDict:options];
-}
--(void)loadAsDataURL:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
-{
- [self load:TRUE arguments:arguments withDict:options];
-}
-
-@end
diff --git a/attic/programs/ios/WebODF/Classes/WebViewCache.h b/attic/programs/ios/WebODF/Classes/WebViewCache.h
deleted file mode 100644
index 216a0bf2b..000000000
--- a/attic/programs/ios/WebODF/Classes/WebViewCache.h
+++ /dev/null
@@ -1,15 +0,0 @@
-//
-// WebCache.h
-// KO Viewer
-//
-// Created by Tobias Hintze on 3/5/12.
-// Copyright (c) 2012 KO GmbH. All rights reserved.
-//
-
-#import
-
-@interface WebViewCache : NSURLCache
-
-- (NSData*)getSomeData:(NSString*)zip entry:(NSString*)entry;
-
-@end
diff --git a/attic/programs/ios/WebODF/Classes/WebViewCache.m b/attic/programs/ios/WebODF/Classes/WebViewCache.m
deleted file mode 100644
index 777bfa47a..000000000
--- a/attic/programs/ios/WebODF/Classes/WebViewCache.m
+++ /dev/null
@@ -1,74 +0,0 @@
-//
-// WebCache.m
-// KO Viewer
-//
-// Created by Tobias Hintze on 3/5/12.
-// Copyright (c) 2012 KO GmbH. All rights reserved.
-//
-
-#import "WebViewCache.h"
-#import "minizip/unzip.h"
-
-@implementation WebViewCache
-
-- (NSCachedURLResponse*)cachedResponseForRequest:(NSURLRequest*)request
-{
- [super removeAllCachedResponses];
- NSURL *url = [request URL];
- if ([url query]) {
- NSData *somedata = [self getSomeData:[url path] entry:[url query]];
- NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:url
- MIMEType:@"text/xml"
- expectedContentLength:[somedata length]
- textEncodingName:nil];
- NSCachedURLResponse *cachedResponse = [[NSCachedURLResponse alloc]
- initWithResponse:response data:somedata];
- [response autorelease];
- [cachedResponse autorelease];
- return cachedResponse;
- }
- return [super cachedResponseForRequest:request];
-}
-
-- (NSData*)getSomeData:(NSString*)zip entry:(NSString*)entry
-{
- NSLog(@"get some data: %@ %@", zip, entry);
- const char* path = [ zip cStringUsingEncoding:NSUTF8StringEncoding ];
- unzFile unzipFile = unzOpen(path);
- NSData *data = nil;
- if (!unzipFile) {
- NSLog(@"cannot open file %@", zip);
- } else {
- path = [ entry cStringUsingEncoding:NSUTF8StringEncoding ];
- int r = unzLocateFile(unzipFile, path, 2);
- if (r != UNZ_OK) {
- NSLog(@"cannot find entry %@", entry);
- } else {
- unz_file_info info;
- r = unzGetCurrentFileInfo(unzipFile, &info, 0, 0, 0, 0, 0, 0);
- if (r != UNZ_OK) {
- NSLog(@"cannot determine size of %@", entry);
- } else {
- r = unzOpenCurrentFile(unzipFile);
- if (r != UNZ_OK) {
- NSLog(@"cannot open entry %@", entry);
- } else {
- char* contents = malloc(info.uncompressed_size);
- r = unzReadCurrentFile(unzipFile, contents, info.uncompressed_size);
- if (r != info.uncompressed_size) {
- NSLog(@"cannot uncompress file %@", entry);
- } else {
- data = [NSData dataWithBytes:(const void *)contents length:sizeof(unsigned char)*info.uncompressed_size];
- NSLog(@"read file entry %li %@", info.uncompressed_size, entry);
- }
- unzCloseCurrentFile(unzipFile);
- free(contents);
- }
- }
- }
- unzClose(unzipFile);
- }
- return data;
-}
-
-@end
diff --git a/attic/programs/ios/WebODF/Classes/minizip/.gitattributes b/attic/programs/ios/WebODF/Classes/minizip/.gitattributes
deleted file mode 100644
index b15706354..000000000
--- a/attic/programs/ios/WebODF/Classes/minizip/.gitattributes
+++ /dev/null
@@ -1,4 +0,0 @@
-# Unset behaviour for some text-like files, as this is just a copy of original files,
-# with obviously DOS line endings
-
-* binary
diff --git a/attic/programs/ios/WebODF/Classes/minizip/crypt.h b/attic/programs/ios/WebODF/Classes/minizip/crypt.h
deleted file mode 100644
index 622f4bc2e..000000000
--- a/attic/programs/ios/WebODF/Classes/minizip/crypt.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/* crypt.h -- base code for crypt/uncrypt ZIPfile
-
-
- Version 1.01e, February 12th, 2005
-
- Copyright (C) 1998-2005 Gilles Vollant
-
- This code is a modified version of crypting code in Infozip distribution
-
- The encryption/decryption parts of this source code (as opposed to the
- non-echoing password parts) were originally written in Europe. The
- whole source package can be freely distributed, including from the USA.
- (Prior to January 2000, re-export from the US was a violation of US law.)
-
- This encryption code is a direct transcription of the algorithm from
- Roger Schlafly, described by Phil Katz in the file appnote.txt. This
- file (appnote.txt) is distributed with the PKZIP program (even in the
- version without encryption capabilities).
-
- If you don't need crypting in your application, just define symbols
- NOCRYPT and NOUNCRYPT.
-
- This code support the "Traditional PKWARE Encryption".
-
- The new AES encryption added on Zip format by Winzip (see the page
- http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong
- Encryption is not supported.
-*/
-
-#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))
-
-/***********************************************************************
- * Return the next byte in the pseudo-random sequence
- */
-static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab)
-{
- unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an
- * unpredictable manner on 16-bit systems; not a problem
- * with any known compiler so far, though */
-
- temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;
- return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
-}
-
-/***********************************************************************
- * Update the encryption keys with the next byte of plain text
- */
-static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c)
-{
- (*(pkeys+0)) = CRC32((*(pkeys+0)), c);
- (*(pkeys+1)) += (*(pkeys+0)) & 0xff;
- (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
- {
- register int keyshift = (int)((*(pkeys+1)) >> 24);
- (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);
- }
- return c;
-}
-
-
-/***********************************************************************
- * Initialize the encryption keys and the random header according to
- * the given password.
- */
-static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab)
-{
- *(pkeys+0) = 305419896L;
- *(pkeys+1) = 591751049L;
- *(pkeys+2) = 878082192L;
- while (*passwd != '\0') {
- update_keys(pkeys,pcrc_32_tab,(int)*passwd);
- passwd++;
- }
-}
-
-#define zdecode(pkeys,pcrc_32_tab,c) \
- (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))
-
-#define zencode(pkeys,pcrc_32_tab,c,t) \
- (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c))
-
-#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED
-
-#define RAND_HEAD_LEN 12
- /* "last resort" source for second part of crypt seed pattern */
-# ifndef ZCR_SEED2
-# define ZCR_SEED2 3141592654UL /* use PI as default pattern */
-# endif
-
-static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting)
- const char *passwd; /* password string */
- unsigned char *buf; /* where to write header */
- int bufSize;
- unsigned long* pkeys;
- const unsigned long* pcrc_32_tab;
- unsigned long crcForCrypting;
-{
- int n; /* index in random header */
- int t; /* temporary */
- int c; /* random byte */
- unsigned char header[RAND_HEAD_LEN-2]; /* random header */
- static unsigned calls = 0; /* ensure different random header each time */
-
- if (bufSize> 7) & 0xff;
- header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);
- }
- /* Encrypt random header (last two bytes is high word of crc) */
- init_keys(passwd, pkeys, pcrc_32_tab);
- for (n = 0; n < RAND_HEAD_LEN-2; n++)
- {
- buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);
- }
- buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);
- buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);
- return n;
-}
-
-#endif
diff --git a/attic/programs/ios/WebODF/Classes/minizip/ioapi.c b/attic/programs/ios/WebODF/Classes/minizip/ioapi.c
deleted file mode 100644
index 7f20c182f..000000000
--- a/attic/programs/ios/WebODF/Classes/minizip/ioapi.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/* ioapi.c -- IO base function header for compress/uncompress .zip
- files using zlib + zip or unzip API
-
- Version 1.01e, February 12th, 2005
-
- Copyright (C) 1998-2005 Gilles Vollant
-*/
-
-#include
-#include
-#include
-
-#include "zlib.h"
-#include "ioapi.h"
-
-
-
-/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
-
-#ifndef SEEK_CUR
-#define SEEK_CUR 1
-#endif
-
-#ifndef SEEK_END
-#define SEEK_END 2
-#endif
-
-#ifndef SEEK_SET
-#define SEEK_SET 0
-#endif
-
-voidpf ZCALLBACK fopen_file_func OF((
- voidpf opaque,
- const char* filename,
- int mode));
-
-uLong ZCALLBACK fread_file_func OF((
- voidpf opaque,
- voidpf stream,
- void* buf,
- uLong size));
-
-uLong ZCALLBACK fwrite_file_func OF((
- voidpf opaque,
- voidpf stream,
- const void* buf,
- uLong size));
-
-long ZCALLBACK ftell_file_func OF((
- voidpf opaque,
- voidpf stream));
-
-long ZCALLBACK fseek_file_func OF((
- voidpf opaque,
- voidpf stream,
- uLong offset,
- int origin));
-
-int ZCALLBACK fclose_file_func OF((
- voidpf opaque,
- voidpf stream));
-
-int ZCALLBACK ferror_file_func OF((
- voidpf opaque,
- voidpf stream));
-
-
-voidpf ZCALLBACK fopen_file_func (opaque, filename, mode)
- voidpf opaque;
- const char* filename;
- int mode;
-{
- FILE* file = NULL;
- const char* mode_fopen = NULL;
- if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
- mode_fopen = "rb";
- else
- if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
- mode_fopen = "r+b";
- else
- if (mode & ZLIB_FILEFUNC_MODE_CREATE)
- mode_fopen = "wb";
-
- if ((filename!=NULL) && (mode_fopen != NULL))
- file = fopen(filename, mode_fopen);
- return file;
-}
-
-
-uLong ZCALLBACK fread_file_func (opaque, stream, buf, size)
- voidpf opaque;
- voidpf stream;
- void* buf;
- uLong size;
-{
- uLong ret;
- ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream);
- return ret;
-}
-
-
-uLong ZCALLBACK fwrite_file_func (opaque, stream, buf, size)
- voidpf opaque;
- voidpf stream;
- const void* buf;
- uLong size;
-{
- uLong ret;
- ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream);
- return ret;
-}
-
-long ZCALLBACK ftell_file_func (opaque, stream)
- voidpf opaque;
- voidpf stream;
-{
- long ret;
- ret = ftell((FILE *)stream);
- return ret;
-}
-
-long ZCALLBACK fseek_file_func (opaque, stream, offset, origin)
- voidpf opaque;
- voidpf stream;
- uLong offset;
- int origin;
-{
- int fseek_origin=0;
- long ret;
- switch (origin)
- {
- case ZLIB_FILEFUNC_SEEK_CUR :
- fseek_origin = SEEK_CUR;
- break;
- case ZLIB_FILEFUNC_SEEK_END :
- fseek_origin = SEEK_END;
- break;
- case ZLIB_FILEFUNC_SEEK_SET :
- fseek_origin = SEEK_SET;
- break;
- default: return -1;
- }
- ret = 0;
- fseek((FILE *)stream, offset, fseek_origin);
- return ret;
-}
-
-int ZCALLBACK fclose_file_func (opaque, stream)
- voidpf opaque;
- voidpf stream;
-{
- int ret;
- ret = fclose((FILE *)stream);
- return ret;
-}
-
-int ZCALLBACK ferror_file_func (opaque, stream)
- voidpf opaque;
- voidpf stream;
-{
- int ret;
- ret = ferror((FILE *)stream);
- return ret;
-}
-
-void fill_fopen_filefunc (pzlib_filefunc_def)
- zlib_filefunc_def* pzlib_filefunc_def;
-{
- pzlib_filefunc_def->zopen_file = fopen_file_func;
- pzlib_filefunc_def->zread_file = fread_file_func;
- pzlib_filefunc_def->zwrite_file = fwrite_file_func;
- pzlib_filefunc_def->ztell_file = ftell_file_func;
- pzlib_filefunc_def->zseek_file = fseek_file_func;
- pzlib_filefunc_def->zclose_file = fclose_file_func;
- pzlib_filefunc_def->zerror_file = ferror_file_func;
- pzlib_filefunc_def->opaque = NULL;
-}
diff --git a/attic/programs/ios/WebODF/Classes/minizip/ioapi.h b/attic/programs/ios/WebODF/Classes/minizip/ioapi.h
deleted file mode 100644
index e73a3b2bd..000000000
--- a/attic/programs/ios/WebODF/Classes/minizip/ioapi.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/* ioapi.h -- IO base function header for compress/uncompress .zip
- files using zlib + zip or unzip API
-
- Version 1.01e, February 12th, 2005
-
- Copyright (C) 1998-2005 Gilles Vollant
-*/
-
-#ifndef _ZLIBIOAPI_H
-#define _ZLIBIOAPI_H
-
-
-#define ZLIB_FILEFUNC_SEEK_CUR (1)
-#define ZLIB_FILEFUNC_SEEK_END (2)
-#define ZLIB_FILEFUNC_SEEK_SET (0)
-
-#define ZLIB_FILEFUNC_MODE_READ (1)
-#define ZLIB_FILEFUNC_MODE_WRITE (2)
-#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
-
-#define ZLIB_FILEFUNC_MODE_EXISTING (4)
-#define ZLIB_FILEFUNC_MODE_CREATE (8)
-
-
-#ifndef ZCALLBACK
-
-#if (defined(WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK)
-#define ZCALLBACK CALLBACK
-#else
-#define ZCALLBACK
-#endif
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode));
-typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size));
-typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
-typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream));
-typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin));
-typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream));
-typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));
-
-typedef struct zlib_filefunc_def_s
-{
- open_file_func zopen_file;
- read_file_func zread_file;
- write_file_func zwrite_file;
- tell_file_func ztell_file;
- seek_file_func zseek_file;
- close_file_func zclose_file;
- testerror_file_func zerror_file;
- voidpf opaque;
-} zlib_filefunc_def;
-
-
-
-void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
-
-#define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size))
-#define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size))
-#define ZTELL(filefunc,filestream) ((*((filefunc).ztell_file))((filefunc).opaque,filestream))
-#define ZSEEK(filefunc,filestream,pos,mode) ((*((filefunc).zseek_file))((filefunc).opaque,filestream,pos,mode))
-#define ZCLOSE(filefunc,filestream) ((*((filefunc).zclose_file))((filefunc).opaque,filestream))
-#define ZERROR(filefunc,filestream) ((*((filefunc).zerror_file))((filefunc).opaque,filestream))
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/attic/programs/ios/WebODF/Classes/minizip/mztools.c b/attic/programs/ios/WebODF/Classes/minizip/mztools.c
deleted file mode 100644
index 74e6c7577..000000000
--- a/attic/programs/ios/WebODF/Classes/minizip/mztools.c
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- Additional tools for Minizip
- Code: Xavier Roche '2004
- License: Same as ZLIB (www.gzip.org)
-*/
-
-/* Code */
-#include
-#include
-#include
-#include "zlib.h"
-#include "unzip.h"
-
-#define READ_8(adr) ((unsigned char)*(adr))
-#define READ_16(adr) ( READ_8(adr) | (READ_8(adr+1) << 8) )
-#define READ_32(adr) ( READ_16(adr) | (READ_16((adr)+2) << 16) )
-
-#define WRITE_8(buff, n) do { \
- *((unsigned char*)(buff)) = (unsigned char) ((n) & 0xff); \
-} while(0)
-#define WRITE_16(buff, n) do { \
- WRITE_8((unsigned char*)(buff), n); \
- WRITE_8(((unsigned char*)(buff)) + 1, (n) >> 8); \
-} while(0)
-#define WRITE_32(buff, n) do { \
- WRITE_16((unsigned char*)(buff), (n) & 0xffff); \
- WRITE_16((unsigned char*)(buff) + 2, (n) >> 16); \
-} while(0)
diff --git a/attic/programs/ios/WebODF/Classes/minizip/mztools.h b/attic/programs/ios/WebODF/Classes/minizip/mztools.h
deleted file mode 100644
index 82d1597ad..000000000
--- a/attic/programs/ios/WebODF/Classes/minizip/mztools.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- Additional tools for Minizip
- Code: Xavier Roche '2004
- License: Same as ZLIB (www.gzip.org)
-*/
-
-#ifndef _zip_tools_H
-#define _zip_tools_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef _ZLIB_H
-#include "zlib.h"
-#endif
-
-#include "unzip.h"
-
-/* Repair a ZIP file (missing central directory)
- file: file to recover
- fileOut: output file after recovery
- fileOutTmp: temporary file name used for recovery
-*/
-extern int ZEXPORT unzRepair(const char* file,
- const char* fileOut,
- const char* fileOutTmp,
- uLong* nRecovered,
- uLong* bytesRecovered);
-
-#endif
diff --git a/attic/programs/ios/WebODF/Classes/minizip/unzip.c b/attic/programs/ios/WebODF/Classes/minizip/unzip.c
deleted file mode 100644
index 81aee6a14..000000000
--- a/attic/programs/ios/WebODF/Classes/minizip/unzip.c
+++ /dev/null
@@ -1,1597 +0,0 @@
-/* unzip.c -- IO for uncompress .zip files using zlib
- Version 1.01e, February 12th, 2005
-
- Copyright (C) 1998-2005 Gilles Vollant
-
- Read unzip.h for more info
-*/
-
-/* Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of
-compatibility with older software. The following is from the original crypt.c. Code
-woven in by Terry Thorsen 1/2003.
-*/
-/*
- Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
-
- See the accompanying file LICENSE, version 2000-Apr-09 or later
- (the contents of which are also included in zip.h) for terms of use.
- If, for some reason, all these files are missing, the Info-ZIP license
- also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
-*/
-/*
- crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h]
-
- The encryption/decryption parts of this source code (as opposed to the
- non-echoing password parts) were originally written in Europe. The
- whole source package can be freely distributed, including from the USA.
- (Prior to January 2000, re-export from the US was a violation of US law.)
- */
-
-/*
- This encryption code is a direct transcription of the algorithm from
- Roger Schlafly, described by Phil Katz in the file appnote.txt. This
- file (appnote.txt) is distributed with the PKZIP program (even in the
- version without encryption capabilities).
- */
-
-
-#include
-#include
-#include
-#include "zlib.h"
-#include "unzip.h"
-
-#ifdef STDC
-# include
-# include
-# include
-#endif
-#ifdef NO_ERRNO_H
- extern int errno;
-#else
-# include
-#endif
-
-
-#ifndef local
-# define local static
-#endif
-/* compile with -Dlocal if your debugger can't find static symbols */
-
-
-#ifndef CASESENSITIVITYDEFAULT_NO
-# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
-# define CASESENSITIVITYDEFAULT_NO
-# endif
-#endif
-
-
-#ifndef UNZ_BUFSIZE
-#define UNZ_BUFSIZE (16384)
-#endif
-
-#ifndef UNZ_MAXFILENAMEINZIP
-#define UNZ_MAXFILENAMEINZIP (256)
-#endif
-
-#ifndef ALLOC
-# define ALLOC(size) (malloc(size))
-#endif
-#ifndef TRYFREE
-# define TRYFREE(p) {if (p) free(p);}
-#endif
-
-#define SIZECENTRALDIRITEM (0x2e)
-#define SIZEZIPLOCALHEADER (0x1e)
-
-
-
-
-const char unz_copyright[] =
- " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
-
-/* unz_file_info_interntal contain internal info about a file in zipfile*/
-typedef struct unz_file_info_internal_s
-{
- uLong offset_curfile;/* relative offset of local header 4 bytes */
-} unz_file_info_internal;
-
-
-/* file_in_zip_read_info_s contain internal information about a file in zipfile,
- when reading and decompress it */
-typedef struct
-{
- char *read_buffer; /* internal buffer for compressed data */
- z_stream stream; /* zLib stream structure for inflate */
-
- uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
- uLong stream_initialised; /* flag set if stream structure is initialised*/
-
- uLong offset_local_extrafield;/* offset of the local extra field */
- uInt size_local_extrafield;/* size of the local extra field */
- uLong pos_local_extrafield; /* position in the local extra field in read*/
-
- uLong crc32; /* crc32 of all data uncompressed */
- uLong crc32_wait; /* crc32 we must obtain after decompress all */
- uLong rest_read_compressed; /* number of byte to be decompressed */
- uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/
- zlib_filefunc_def z_filefunc;
- voidpf filestream; /* io structore of the zipfile */
- uLong compression_method; /* compression method (0==store) */
- uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
- int raw;
-} file_in_zip_read_info_s;
-
-
-/* unz_s contain internal information about the zipfile
-*/
-typedef struct
-{
- zlib_filefunc_def z_filefunc;
- voidpf filestream; /* io structore of the zipfile */
- unz_global_info gi; /* public global information */
- uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
- uLong num_file; /* number of the current file in the zipfile*/
- uLong pos_in_central_dir; /* pos of the current file in the central dir*/
- uLong current_file_ok; /* flag about the usability of the current file*/
- uLong central_pos; /* position of the beginning of the central dir*/
-
- uLong size_central_dir; /* size of the central directory */
- uLong offset_central_dir; /* offset of start of central directory with
- respect to the starting disk number */
-
- unz_file_info cur_file_info; /* public info about the current file in zip*/
- unz_file_info_internal cur_file_info_internal; /* private info about it*/
- file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current
- file if we are decompressing it */
- int encrypted;
-# ifndef NOUNCRYPT
- unsigned long keys[3]; /* keys defining the pseudo-random sequence */
- const unsigned long* pcrc_32_tab;
-# endif
-} unz_s;
-
-
-#ifndef NOUNCRYPT
-#include "crypt.h"
-#endif
-
-/* ===========================================================================
- Read a byte from a gz_stream; update next_in and avail_in. Return EOF
- for end of file.
- IN assertion: the stream s has been sucessfully opened for reading.
-*/
-
-
-local int unzlocal_getByte OF((
- const zlib_filefunc_def* pzlib_filefunc_def,
- voidpf filestream,
- int *pi));
-
-local int unzlocal_getByte(pzlib_filefunc_def,filestream,pi)
- const zlib_filefunc_def* pzlib_filefunc_def;
- voidpf filestream;
- int *pi;
-{
- unsigned char c;
- int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
- if (err==1)
- {
- *pi = (int)c;
- return UNZ_OK;
- }
- else
- {
- if (ZERROR(*pzlib_filefunc_def,filestream))
- return UNZ_ERRNO;
- else
- return UNZ_EOF;
- }
-}
-
-
-/* ===========================================================================
- Reads a long in LSB order from the given gz_stream. Sets
-*/
-local int unzlocal_getShort OF((
- const zlib_filefunc_def* pzlib_filefunc_def,
- voidpf filestream,
- uLong *pX));
-
-local int unzlocal_getShort (pzlib_filefunc_def,filestream,pX)
- const zlib_filefunc_def* pzlib_filefunc_def;
- voidpf filestream;
- uLong *pX;
-{
- uLong x ;
- int i;
- int err;
-
- err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
- x = (uLong)i;
-
- if (err==UNZ_OK)
- err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
- x += ((uLong)i)<<8;
-
- if (err==UNZ_OK)
- *pX = x;
- else
- *pX = 0;
- return err;
-}
-
-local int unzlocal_getLong OF((
- const zlib_filefunc_def* pzlib_filefunc_def,
- voidpf filestream,
- uLong *pX));
-
-local int unzlocal_getLong (pzlib_filefunc_def,filestream,pX)
- const zlib_filefunc_def* pzlib_filefunc_def;
- voidpf filestream;
- uLong *pX;
-{
- uLong x ;
- int i;
- int err;
-
- err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
- x = (uLong)i;
-
- if (err==UNZ_OK)
- err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
- x += ((uLong)i)<<8;
-
- if (err==UNZ_OK)
- err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
- x += ((uLong)i)<<16;
-
- if (err==UNZ_OK)
- err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
- x += ((uLong)i)<<24;
-
- if (err==UNZ_OK)
- *pX = x;
- else
- *pX = 0;
- return err;
-}
-
-
-/* My own strcmpi / strcasecmp */
-local int strcmpcasenosensitive_internal (fileName1,fileName2)
- const char* fileName1;
- const char* fileName2;
-{
- for (;;)
- {
- char c1=*(fileName1++);
- char c2=*(fileName2++);
- if ((c1>='a') && (c1<='z'))
- c1 -= 0x20;
- if ((c2>='a') && (c2<='z'))
- c2 -= 0x20;
- if (c1=='\0')
- return ((c2=='\0') ? 0 : -1);
- if (c2=='\0')
- return 1;
- if (c1c2)
- return 1;
- }
-}
-
-
-#ifdef CASESENSITIVITYDEFAULT_NO
-#define CASESENSITIVITYDEFAULTVALUE 2
-#else
-#define CASESENSITIVITYDEFAULTVALUE 1
-#endif
-
-#ifndef STRCMPCASENOSENTIVEFUNCTION
-#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
-#endif
-
-/*
- Compare two filename (fileName1,fileName2).
- If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
- If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
- or strcasecmp)
- If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
- (like 1 on Unix, 2 on Windows)
-
-*/
-extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity)
- const char* fileName1;
- const char* fileName2;
- int iCaseSensitivity;
-{
- if (iCaseSensitivity==0)
- iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
-
- if (iCaseSensitivity==1)
- return strcmp(fileName1,fileName2);
-
- return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
-}
-
-#ifndef BUFREADCOMMENT
-#define BUFREADCOMMENT (0x400)
-#endif
-
-/*
- Locate the Central directory of a zipfile (at the end, just before
- the global comment)
-*/
-local uLong unzlocal_SearchCentralDir OF((
- const zlib_filefunc_def* pzlib_filefunc_def,
- voidpf filestream));
-
-local uLong unzlocal_SearchCentralDir(pzlib_filefunc_def,filestream)
- const zlib_filefunc_def* pzlib_filefunc_def;
- voidpf filestream;
-{
- unsigned char* buf;
- uLong uSizeFile;
- uLong uBackRead;
- uLong uMaxBack=0xffff; /* maximum size of global comment */
- uLong uPosFound=0;
-
- if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
- return 0;
-
-
- uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
-
- if (uMaxBack>uSizeFile)
- uMaxBack = uSizeFile;
-
- buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
- if (buf==NULL)
- return 0;
-
- uBackRead = 4;
- while (uBackReaduMaxBack)
- uBackRead = uMaxBack;
- else
- uBackRead+=BUFREADCOMMENT;
- uReadPos = uSizeFile-uBackRead ;
-
- uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
- (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
- if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
- break;
-
- if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
- break;
-
- for (i=(int)uReadSize-3; (i--)>0;)
- if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
- ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
- {
- uPosFound = uReadPos+i;
- break;
- }
-
- if (uPosFound!=0)
- break;
- }
- TRYFREE(buf);
- return uPosFound;
-}
-
-/*
- Open a Zip file. path contain the full pathname (by example,
- on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
- "zlib/zlib114.zip".
- If the zipfile cannot be opened (file doesn't exist or in not valid), the
- return value is NULL.
- Else, the return value is a unzFile Handle, usable with other function
- of this unzip package.
-*/
-extern unzFile ZEXPORT unzOpen2 (path, pzlib_filefunc_def)
- const char *path;
- zlib_filefunc_def* pzlib_filefunc_def;
-{
- unz_s us;
- unz_s *s;
- uLong central_pos,uL;
-
- uLong number_disk; /* number of the current dist, used for
- spaning ZIP, unsupported, always 0*/
- uLong number_disk_with_CD; /* number the the disk with central dir, used
- for spaning ZIP, unsupported, always 0*/
- uLong number_entry_CD; /* total number of entries in
- the central dir
- (same than number_entry on nospan) */
-
- int err=UNZ_OK;
-
- if (unz_copyright[0]!=' ')
- return NULL;
-
- if (pzlib_filefunc_def==NULL)
- fill_fopen_filefunc(&us.z_filefunc);
- else
- us.z_filefunc = *pzlib_filefunc_def;
-
- us.filestream= (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque,
- path,
- ZLIB_FILEFUNC_MODE_READ |
- ZLIB_FILEFUNC_MODE_EXISTING);
- if (us.filestream==NULL)
- return NULL;
-
- central_pos = unzlocal_SearchCentralDir(&us.z_filefunc,us.filestream);
- if (central_pos==0)
- err=UNZ_ERRNO;
-
- if (ZSEEK(us.z_filefunc, us.filestream,
- central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
- err=UNZ_ERRNO;
-
- /* the signature, already checked */
- if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- /* number of this disk */
- if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- /* number of the disk with the start of the central directory */
- if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- /* total number of entries in the central dir on this disk */
- if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- /* total number of entries in the central dir */
- if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- if ((number_entry_CD!=us.gi.number_entry) ||
- (number_disk_with_CD!=0) ||
- (number_disk!=0))
- err=UNZ_BADZIPFILE;
-
- /* size of the central directory */
- if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- /* offset of start of central directory with respect to the
- starting disk number */
- if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- /* zipfile comment length */
- if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- if ((central_pospfile_in_zip_read!=NULL)
- unzCloseCurrentFile(file);
-
- ZCLOSE(s->z_filefunc, s->filestream);
- TRYFREE(s);
- return UNZ_OK;
-}
-
-
-/*
- Write info about the ZipFile in the *pglobal_info structure.
- No preparation of the structure is needed
- return UNZ_OK if there is no problem. */
-extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info)
- unzFile file;
- unz_global_info *pglobal_info;
-{
- unz_s* s;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- *pglobal_info=s->gi;
- return UNZ_OK;
-}
-
-
-/*
- Translate date/time from Dos format to tm_unz (readable more easilty)
-*/
-local void unzlocal_DosDateToTmuDate (ulDosDate, ptm)
- uLong ulDosDate;
- tm_unz* ptm;
-{
- uLong uDate;
- uDate = (uLong)(ulDosDate>>16);
- ptm->tm_mday = (uInt)(uDate&0x1f) ;
- ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
- ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
-
- ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
- ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
- ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
-}
-
-/*
- Get Info about the current file in the zipfile, with internal only info
-*/
-local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,
- unz_file_info *pfile_info,
- unz_file_info_internal
- *pfile_info_internal,
- char *szFileName,
- uLong fileNameBufferSize,
- void *extraField,
- uLong extraFieldBufferSize,
- char *szComment,
- uLong commentBufferSize));
-
-local int unzlocal_GetCurrentFileInfoInternal (file,
- pfile_info,
- pfile_info_internal,
- szFileName, fileNameBufferSize,
- extraField, extraFieldBufferSize,
- szComment, commentBufferSize)
- unzFile file;
- unz_file_info *pfile_info;
- unz_file_info_internal *pfile_info_internal;
- char *szFileName;
- uLong fileNameBufferSize;
- void *extraField;
- uLong extraFieldBufferSize;
- char *szComment;
- uLong commentBufferSize;
-{
- unz_s* s;
- unz_file_info file_info;
- unz_file_info_internal file_info_internal;
- int err=UNZ_OK;
- uLong uMagic;
- long lSeek=0;
-
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- if (ZSEEK(s->z_filefunc, s->filestream,
- s->pos_in_central_dir+s->byte_before_the_zipfile,
- ZLIB_FILEFUNC_SEEK_SET)!=0)
- err=UNZ_ERRNO;
-
-
- /* we check the magic */
- if (err==UNZ_OK)
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
- err=UNZ_ERRNO;
- else if (uMagic!=0x02014b50)
- err=UNZ_BADZIPFILE;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
- err=UNZ_ERRNO;
-
- unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
- err=UNZ_ERRNO;
-
- lSeek+=file_info.size_filename;
- if ((err==UNZ_OK) && (szFileName!=NULL))
- {
- uLong uSizeRead ;
- if (file_info.size_filename0) && (fileNameBufferSize>0))
- if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
- err=UNZ_ERRNO;
- lSeek -= uSizeRead;
- }
-
-
- if ((err==UNZ_OK) && (extraField!=NULL))
- {
- uLong uSizeRead ;
- if (file_info.size_file_extraz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
- lSeek=0;
- else
- err=UNZ_ERRNO;
- if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
- if (ZREAD(s->z_filefunc, s->filestream,extraField,uSizeRead)!=uSizeRead)
- err=UNZ_ERRNO;
- lSeek += file_info.size_file_extra - uSizeRead;
- }
- else
- lSeek+=file_info.size_file_extra;
-
-
- if ((err==UNZ_OK) && (szComment!=NULL))
- {
- uLong uSizeRead ;
- if (file_info.size_file_commentz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
- lSeek=0;
- else
- err=UNZ_ERRNO;
- if ((file_info.size_file_comment>0) && (commentBufferSize>0))
- if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
- err=UNZ_ERRNO;
- lSeek+=file_info.size_file_comment - uSizeRead;
- }
- else
- lSeek+=file_info.size_file_comment;
-
- if ((err==UNZ_OK) && (pfile_info!=NULL))
- *pfile_info=file_info;
-
- if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
- *pfile_info_internal=file_info_internal;
-
- return err;
-}
-
-
-
-/*
- Write info about the ZipFile in the *pglobal_info structure.
- No preparation of the structure is needed
- return UNZ_OK if there is no problem.
-*/
-extern int ZEXPORT unzGetCurrentFileInfo (file,
- pfile_info,
- szFileName, fileNameBufferSize,
- extraField, extraFieldBufferSize,
- szComment, commentBufferSize)
- unzFile file;
- unz_file_info *pfile_info;
- char *szFileName;
- uLong fileNameBufferSize;
- void *extraField;
- uLong extraFieldBufferSize;
- char *szComment;
- uLong commentBufferSize;
-{
- return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,
- szFileName,fileNameBufferSize,
- extraField,extraFieldBufferSize,
- szComment,commentBufferSize);
-}
-
-/*
- Set the current file of the zipfile to the first file.
- return UNZ_OK if there is no problem
-*/
-extern int ZEXPORT unzGoToFirstFile (file)
- unzFile file;
-{
- int err=UNZ_OK;
- unz_s* s;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- s->pos_in_central_dir=s->offset_central_dir;
- s->num_file=0;
- err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
- &s->cur_file_info_internal,
- NULL,0,NULL,0,NULL,0);
- s->current_file_ok = (err == UNZ_OK);
- return err;
-}
-
-/*
- Set the current file of the zipfile to the next file.
- return UNZ_OK if there is no problem
- return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
-*/
-extern int ZEXPORT unzGoToNextFile (file)
- unzFile file;
-{
- unz_s* s;
- int err;
-
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- if (!s->current_file_ok)
- return UNZ_END_OF_LIST_OF_FILE;
- if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */
- if (s->num_file+1==s->gi.number_entry)
- return UNZ_END_OF_LIST_OF_FILE;
-
- s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
- s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
- s->num_file++;
- err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
- &s->cur_file_info_internal,
- NULL,0,NULL,0,NULL,0);
- s->current_file_ok = (err == UNZ_OK);
- return err;
-}
-
-
-/*
- Try locate the file szFileName in the zipfile.
- For the iCaseSensitivity signification, see unzipStringFileNameCompare
-
- return value :
- UNZ_OK if the file is found. It becomes the current file.
- UNZ_END_OF_LIST_OF_FILE if the file is not found
-*/
-extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity)
- unzFile file;
- const char *szFileName;
- int iCaseSensitivity;
-{
- unz_s* s;
- int err;
-
- /* We remember the 'current' position in the file so that we can jump
- * back there if we fail.
- */
- unz_file_info cur_file_infoSaved;
- unz_file_info_internal cur_file_info_internalSaved;
- uLong num_fileSaved;
- uLong pos_in_central_dirSaved;
-
-
- if (file==NULL)
- return UNZ_PARAMERROR;
-
- if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
- return UNZ_PARAMERROR;
-
- s=(unz_s*)file;
- if (!s->current_file_ok)
- return UNZ_END_OF_LIST_OF_FILE;
-
- /* Save the current state */
- num_fileSaved = s->num_file;
- pos_in_central_dirSaved = s->pos_in_central_dir;
- cur_file_infoSaved = s->cur_file_info;
- cur_file_info_internalSaved = s->cur_file_info_internal;
-
- err = unzGoToFirstFile(file);
-
- while (err == UNZ_OK)
- {
- char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
- err = unzGetCurrentFileInfo(file,NULL,
- szCurrentFileName,sizeof(szCurrentFileName)-1,
- NULL,0,NULL,0);
- if (err == UNZ_OK)
- {
- if (unzStringFileNameCompare(szCurrentFileName,
- szFileName,iCaseSensitivity)==0)
- return UNZ_OK;
- err = unzGoToNextFile(file);
- }
- }
-
- /* We failed, so restore the state of the 'current file' to where we
- * were.
- */
- s->num_file = num_fileSaved ;
- s->pos_in_central_dir = pos_in_central_dirSaved ;
- s->cur_file_info = cur_file_infoSaved;
- s->cur_file_info_internal = cur_file_info_internalSaved;
- return err;
-}
-
-
-/*
-///////////////////////////////////////////
-// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
-// I need random access
-//
-// Further optimization could be realized by adding an ability
-// to cache the directory in memory. The goal being a single
-// comprehensive file read to put the file I need in a memory.
-*/
-
-/*
-typedef struct unz_file_pos_s
-{
- uLong pos_in_zip_directory; // offset in file
- uLong num_of_file; // # of file
-} unz_file_pos;
-*/
-
-extern int ZEXPORT unzGetFilePos(file, file_pos)
- unzFile file;
- unz_file_pos* file_pos;
-{
- unz_s* s;
-
- if (file==NULL || file_pos==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- if (!s->current_file_ok)
- return UNZ_END_OF_LIST_OF_FILE;
-
- file_pos->pos_in_zip_directory = s->pos_in_central_dir;
- file_pos->num_of_file = s->num_file;
-
- return UNZ_OK;
-}
-
-extern int ZEXPORT unzGoToFilePos(file, file_pos)
- unzFile file;
- unz_file_pos* file_pos;
-{
- unz_s* s;
- int err;
-
- if (file==NULL || file_pos==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
-
- /* jump to the right spot */
- s->pos_in_central_dir = file_pos->pos_in_zip_directory;
- s->num_file = file_pos->num_of_file;
-
- /* set the current file */
- err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
- &s->cur_file_info_internal,
- NULL,0,NULL,0,NULL,0);
- /* return results */
- s->current_file_ok = (err == UNZ_OK);
- return err;
-}
-
-/*
-// Unzip Helper Functions - should be here?
-///////////////////////////////////////////
-*/
-
-/*
- Read the local header of the current zipfile
- Check the coherency of the local header and info in the end of central
- directory about this file
- store in *piSizeVar the size of extra info in local header
- (filename and size of extra field data)
-*/
-local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar,
- poffset_local_extrafield,
- psize_local_extrafield)
- unz_s* s;
- uInt* piSizeVar;
- uLong *poffset_local_extrafield;
- uInt *psize_local_extrafield;
-{
- uLong uMagic,uData,uFlags;
- uLong size_filename;
- uLong size_extra_field;
- int err=UNZ_OK;
-
- *piSizeVar = 0;
- *poffset_local_extrafield = 0;
- *psize_local_extrafield = 0;
-
- if (ZSEEK(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
- s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
- return UNZ_ERRNO;
-
-
- if (err==UNZ_OK)
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
- err=UNZ_ERRNO;
- else if (uMagic!=0x04034b50)
- err=UNZ_BADZIPFILE;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
- err=UNZ_ERRNO;
-/*
- else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
- err=UNZ_BADZIPFILE;
-*/
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
- err=UNZ_ERRNO;
- else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
- err=UNZ_BADZIPFILE;
-
- if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
- (s->cur_file_info.compression_method!=Z_DEFLATED))
- err=UNZ_BADZIPFILE;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
- err=UNZ_ERRNO;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
- err=UNZ_ERRNO;
- else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
- ((uFlags & 8)==0))
- err=UNZ_BADZIPFILE;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
- err=UNZ_ERRNO;
- else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
- ((uFlags & 8)==0))
- err=UNZ_BADZIPFILE;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
- err=UNZ_ERRNO;
- else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) &&
- ((uFlags & 8)==0))
- err=UNZ_BADZIPFILE;
-
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
- err=UNZ_ERRNO;
- else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
- err=UNZ_BADZIPFILE;
-
- *piSizeVar += (uInt)size_filename;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
- err=UNZ_ERRNO;
- *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
- SIZEZIPLOCALHEADER + size_filename;
- *psize_local_extrafield = (uInt)size_extra_field;
-
- *piSizeVar += (uInt)size_extra_field;
-
- return err;
-}
-
-/*
- Open for reading data the current file in the zipfile.
- If there is no error and the file is opened, the return value is UNZ_OK.
-*/
-extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password)
- unzFile file;
- int* method;
- int* level;
- int raw;
- const char* password;
-{
- int err=UNZ_OK;
- uInt iSizeVar;
- unz_s* s;
- file_in_zip_read_info_s* pfile_in_zip_read_info;
- uLong offset_local_extrafield; /* offset of the local extra field */
- uInt size_local_extrafield; /* size of the local extra field */
-# ifndef NOUNCRYPT
- char source[12];
-# else
- if (password != NULL)
- return UNZ_PARAMERROR;
-# endif
-
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- if (!s->current_file_ok)
- return UNZ_PARAMERROR;
-
- if (s->pfile_in_zip_read != NULL)
- unzCloseCurrentFile(file);
-
- if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
- &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
- return UNZ_BADZIPFILE;
-
- pfile_in_zip_read_info = (file_in_zip_read_info_s*)
- ALLOC(sizeof(file_in_zip_read_info_s));
- if (pfile_in_zip_read_info==NULL)
- return UNZ_INTERNALERROR;
-
- pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
- pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
- pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
- pfile_in_zip_read_info->pos_local_extrafield=0;
- pfile_in_zip_read_info->raw=raw;
-
- if (pfile_in_zip_read_info->read_buffer==NULL)
- {
- TRYFREE(pfile_in_zip_read_info);
- return UNZ_INTERNALERROR;
- }
-
- pfile_in_zip_read_info->stream_initialised=0;
-
- if (method!=NULL)
- *method = (int)s->cur_file_info.compression_method;
-
- if (level!=NULL)
- {
- *level = 6;
- switch (s->cur_file_info.flag & 0x06)
- {
- case 6 : *level = 1; break;
- case 4 : *level = 2; break;
- case 2 : *level = 9; break;
- }
- }
-
- if ((s->cur_file_info.compression_method!=0) &&
- (s->cur_file_info.compression_method!=Z_DEFLATED))
- err=UNZ_BADZIPFILE;
-
- pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
- pfile_in_zip_read_info->crc32=0;
- pfile_in_zip_read_info->compression_method =
- s->cur_file_info.compression_method;
- pfile_in_zip_read_info->filestream=s->filestream;
- pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
- pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
-
- pfile_in_zip_read_info->stream.total_out = 0;
-
- if ((s->cur_file_info.compression_method==Z_DEFLATED) &&
- (!raw))
- {
- pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
- pfile_in_zip_read_info->stream.zfree = (free_func)0;
- pfile_in_zip_read_info->stream.opaque = (voidpf)0;
- pfile_in_zip_read_info->stream.next_in = (voidpf)0;
- pfile_in_zip_read_info->stream.avail_in = 0;
-
- err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
- if (err == Z_OK)
- pfile_in_zip_read_info->stream_initialised=1;
- else
- {
- TRYFREE(pfile_in_zip_read_info);
- return err;
- }
- /* windowBits is passed < 0 to tell that there is no zlib header.
- * Note that in this case inflate *requires* an extra "dummy" byte
- * after the compressed stream in order to complete decompression and
- * return Z_STREAM_END.
- * In unzip, i don't wait absolutely Z_STREAM_END because I known the
- * size of both compressed and uncompressed data
- */
- }
- pfile_in_zip_read_info->rest_read_compressed =
- s->cur_file_info.compressed_size ;
- pfile_in_zip_read_info->rest_read_uncompressed =
- s->cur_file_info.uncompressed_size ;
-
-
- pfile_in_zip_read_info->pos_in_zipfile =
- s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
- iSizeVar;
-
- pfile_in_zip_read_info->stream.avail_in = (uInt)0;
-
- s->pfile_in_zip_read = pfile_in_zip_read_info;
-
-# ifndef NOUNCRYPT
- if (password != NULL)
- {
- int i;
- s->pcrc_32_tab = get_crc_table();
- init_keys(password,s->keys,s->pcrc_32_tab);
- if (ZSEEK(s->z_filefunc, s->filestream,
- s->pfile_in_zip_read->pos_in_zipfile +
- s->pfile_in_zip_read->byte_before_the_zipfile,
- SEEK_SET)!=0)
- return UNZ_INTERNALERROR;
- if(ZREAD(s->z_filefunc, s->filestream,source, 12)<12)
- return UNZ_INTERNALERROR;
-
- for (i = 0; i<12; i++)
- zdecode(s->keys,s->pcrc_32_tab,source[i]);
-
- s->pfile_in_zip_read->pos_in_zipfile+=12;
- s->encrypted=1;
- }
-# endif
-
-
- return UNZ_OK;
-}
-
-extern int ZEXPORT unzOpenCurrentFile (file)
- unzFile file;
-{
- return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
-}
-
-extern int ZEXPORT unzOpenCurrentFilePassword (file, password)
- unzFile file;
- const char* password;
-{
- return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
-}
-
-extern int ZEXPORT unzOpenCurrentFile2 (file,method,level,raw)
- unzFile file;
- int* method;
- int* level;
- int raw;
-{
- return unzOpenCurrentFile3(file, method, level, raw, NULL);
-}
-
-/*
- Read bytes from the current file.
- buf contain buffer where data must be copied
- len the size of buf.
-
- return the number of byte copied if somes bytes are copied
- return 0 if the end of file was reached
- return <0 with error code if there is an error
- (UNZ_ERRNO for IO error, or zLib error for uncompress error)
-*/
-extern int ZEXPORT unzReadCurrentFile (file, buf, len)
- unzFile file;
- voidp buf;
- unsigned len;
-{
- int err=UNZ_OK;
- uInt iRead = 0;
- unz_s* s;
- file_in_zip_read_info_s* pfile_in_zip_read_info;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- pfile_in_zip_read_info=s->pfile_in_zip_read;
-
- if (pfile_in_zip_read_info==NULL)
- return UNZ_PARAMERROR;
-
-
- if (pfile_in_zip_read_info->read_buffer == NULL)
- return UNZ_END_OF_LIST_OF_FILE;
- if (len==0)
- return 0;
-
- pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
-
- pfile_in_zip_read_info->stream.avail_out = (uInt)len;
-
- if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
- (!(pfile_in_zip_read_info->raw)))
- pfile_in_zip_read_info->stream.avail_out =
- (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
-
- if ((len>pfile_in_zip_read_info->rest_read_compressed+
- pfile_in_zip_read_info->stream.avail_in) &&
- (pfile_in_zip_read_info->raw))
- pfile_in_zip_read_info->stream.avail_out =
- (uInt)pfile_in_zip_read_info->rest_read_compressed+
- pfile_in_zip_read_info->stream.avail_in;
-
- while (pfile_in_zip_read_info->stream.avail_out>0)
- {
- if ((pfile_in_zip_read_info->stream.avail_in==0) &&
- (pfile_in_zip_read_info->rest_read_compressed>0))
- {
- uInt uReadThis = UNZ_BUFSIZE;
- if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed;
- if (uReadThis == 0)
- return UNZ_EOF;
- if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
- pfile_in_zip_read_info->filestream,
- pfile_in_zip_read_info->pos_in_zipfile +
- pfile_in_zip_read_info->byte_before_the_zipfile,
- ZLIB_FILEFUNC_SEEK_SET)!=0)
- return UNZ_ERRNO;
- if (ZREAD(pfile_in_zip_read_info->z_filefunc,
- pfile_in_zip_read_info->filestream,
- pfile_in_zip_read_info->read_buffer,
- uReadThis)!=uReadThis)
- return UNZ_ERRNO;
-
-
-# ifndef NOUNCRYPT
- if(s->encrypted)
- {
- uInt i;
- for(i=0;iread_buffer[i] =
- zdecode(s->keys,s->pcrc_32_tab,
- pfile_in_zip_read_info->read_buffer[i]);
- }
-# endif
-
-
- pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
-
- pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
-
- pfile_in_zip_read_info->stream.next_in =
- (Bytef*)pfile_in_zip_read_info->read_buffer;
- pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
- }
-
- if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
- {
- uInt uDoCopy,i ;
-
- if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
- (pfile_in_zip_read_info->rest_read_compressed == 0))
- return (iRead==0) ? UNZ_EOF : iRead;
-
- if (pfile_in_zip_read_info->stream.avail_out <
- pfile_in_zip_read_info->stream.avail_in)
- uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
- else
- uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
-
- for (i=0;istream.next_out+i) =
- *(pfile_in_zip_read_info->stream.next_in+i);
-
- pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
- pfile_in_zip_read_info->stream.next_out,
- uDoCopy);
- pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
- pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
- pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
- pfile_in_zip_read_info->stream.next_out += uDoCopy;
- pfile_in_zip_read_info->stream.next_in += uDoCopy;
- pfile_in_zip_read_info->stream.total_out += uDoCopy;
- iRead += uDoCopy;
- }
- else
- {
- uLong uTotalOutBefore,uTotalOutAfter;
- const Bytef *bufBefore;
- uLong uOutThis;
- int flush=Z_SYNC_FLUSH;
-
- uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
- bufBefore = pfile_in_zip_read_info->stream.next_out;
-
- /*
- if ((pfile_in_zip_read_info->rest_read_uncompressed ==
- pfile_in_zip_read_info->stream.avail_out) &&
- (pfile_in_zip_read_info->rest_read_compressed == 0))
- flush = Z_FINISH;
- */
- err=inflate(&pfile_in_zip_read_info->stream,flush);
-
- if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
- err = Z_DATA_ERROR;
-
- uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
- uOutThis = uTotalOutAfter-uTotalOutBefore;
-
- pfile_in_zip_read_info->crc32 =
- crc32(pfile_in_zip_read_info->crc32,bufBefore,
- (uInt)(uOutThis));
-
- pfile_in_zip_read_info->rest_read_uncompressed -=
- uOutThis;
-
- iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
-
- if (err==Z_STREAM_END)
- return (iRead==0) ? UNZ_EOF : iRead;
- if (err!=Z_OK)
- break;
- }
- }
-
- if (err==Z_OK)
- return iRead;
- return err;
-}
-
-
-/*
- Give the current position in uncompressed data
-*/
-extern z_off_t ZEXPORT unztell (file)
- unzFile file;
-{
- unz_s* s;
- file_in_zip_read_info_s* pfile_in_zip_read_info;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- pfile_in_zip_read_info=s->pfile_in_zip_read;
-
- if (pfile_in_zip_read_info==NULL)
- return UNZ_PARAMERROR;
-
- return (z_off_t)pfile_in_zip_read_info->stream.total_out;
-}
-
-
-/*
- return 1 if the end of file was reached, 0 elsewhere
-*/
-extern int ZEXPORT unzeof (file)
- unzFile file;
-{
- unz_s* s;
- file_in_zip_read_info_s* pfile_in_zip_read_info;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- pfile_in_zip_read_info=s->pfile_in_zip_read;
-
- if (pfile_in_zip_read_info==NULL)
- return UNZ_PARAMERROR;
-
- if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
- return 1;
- else
- return 0;
-}
-
-
-
-/*
- Read extra field from the current file (opened by unzOpenCurrentFile)
- This is the local-header version of the extra field (sometimes, there is
- more info in the local-header version than in the central-header)
-
- if buf==NULL, it return the size of the local extra field that can be read
-
- if buf!=NULL, len is the size of the buffer, the extra header is copied in
- buf.
- the return value is the number of bytes copied in buf, or (if <0)
- the error code
-*/
-extern int ZEXPORT unzGetLocalExtrafield (file,buf,len)
- unzFile file;
- voidp buf;
- unsigned len;
-{
- unz_s* s;
- file_in_zip_read_info_s* pfile_in_zip_read_info;
- uInt read_now;
- uLong size_to_read;
-
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- pfile_in_zip_read_info=s->pfile_in_zip_read;
-
- if (pfile_in_zip_read_info==NULL)
- return UNZ_PARAMERROR;
-
- size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
- pfile_in_zip_read_info->pos_local_extrafield);
-
- if (buf==NULL)
- return (int)size_to_read;
-
- if (len>size_to_read)
- read_now = (uInt)size_to_read;
- else
- read_now = (uInt)len ;
-
- if (read_now==0)
- return 0;
-
- if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
- pfile_in_zip_read_info->filestream,
- pfile_in_zip_read_info->offset_local_extrafield +
- pfile_in_zip_read_info->pos_local_extrafield,
- ZLIB_FILEFUNC_SEEK_SET)!=0)
- return UNZ_ERRNO;
-
- if (ZREAD(pfile_in_zip_read_info->z_filefunc,
- pfile_in_zip_read_info->filestream,
- buf,read_now)!=read_now)
- return UNZ_ERRNO;
-
- return (int)read_now;
-}
-
-/*
- Close the file in zip opened with unzipOpenCurrentFile
- Return UNZ_CRCERROR if all the file was read but the CRC is not good
-*/
-extern int ZEXPORT unzCloseCurrentFile (file)
- unzFile file;
-{
- int err=UNZ_OK;
-
- unz_s* s;
- file_in_zip_read_info_s* pfile_in_zip_read_info;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- pfile_in_zip_read_info=s->pfile_in_zip_read;
-
- if (pfile_in_zip_read_info==NULL)
- return UNZ_PARAMERROR;
-
-
- if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
- (!pfile_in_zip_read_info->raw))
- {
- if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
- err=UNZ_CRCERROR;
- }
-
-
- TRYFREE(pfile_in_zip_read_info->read_buffer);
- pfile_in_zip_read_info->read_buffer = NULL;
- if (pfile_in_zip_read_info->stream_initialised)
- inflateEnd(&pfile_in_zip_read_info->stream);
-
- pfile_in_zip_read_info->stream_initialised = 0;
- TRYFREE(pfile_in_zip_read_info);
-
- s->pfile_in_zip_read=NULL;
-
- return err;
-}
-
-
-/*
- Get the global comment string of the ZipFile, in the szComment buffer.
- uSizeBuf is the size of the szComment buffer.
- return the number of byte copied or an error code <0
-*/
-extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf)
- unzFile file;
- char *szComment;
- uLong uSizeBuf;
-{
- unz_s* s;
- uLong uReadThis ;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
-
- uReadThis = uSizeBuf;
- if (uReadThis>s->gi.size_comment)
- uReadThis = s->gi.size_comment;
-
- if (ZSEEK(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
- return UNZ_ERRNO;
-
- if (uReadThis>0)
- {
- *szComment='\0';
- if (ZREAD(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
- return UNZ_ERRNO;
- }
-
- if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
- *(szComment+s->gi.size_comment)='\0';
- return (int)uReadThis;
-}
-
-/* Additions by RX '2004 */
-extern uLong ZEXPORT unzGetOffset (file)
- unzFile file;
-{
- unz_s* s;
-
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- if (!s->current_file_ok)
- return 0;
- if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
- if (s->num_file==s->gi.number_entry)
- return 0;
- return s->pos_in_central_dir;
-}
-
-extern int ZEXPORT unzSetOffset (file, pos)
- unzFile file;
- uLong pos;
-{
- unz_s* s;
- int err;
-
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
-
- s->pos_in_central_dir = pos;
- s->num_file = s->gi.number_entry; /* hack */
- err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
- &s->cur_file_info_internal,
- NULL,0,NULL,0,NULL,0);
- s->current_file_ok = (err == UNZ_OK);
- return err;
-}
diff --git a/attic/programs/ios/WebODF/Classes/minizip/unzip.h b/attic/programs/ios/WebODF/Classes/minizip/unzip.h
deleted file mode 100644
index c3206a058..000000000
--- a/attic/programs/ios/WebODF/Classes/minizip/unzip.h
+++ /dev/null
@@ -1,354 +0,0 @@
-/* unzip.h -- IO for uncompress .zip files using zlib
- Version 1.01e, February 12th, 2005
-
- Copyright (C) 1998-2005 Gilles Vollant
-
- This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g
- WinZip, InfoZip tools and compatible.
-
- Multi volume ZipFile (span) are not supported.
- Encryption compatible with pkzip 2.04g only supported
- Old compressions used by old PKZip 1.x are not supported
-
-
- I WAIT FEEDBACK at mail info@winimage.com
- Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution
-
- Condition of use and distribution are the same than zlib :
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
-
-*/
-
-/* for more info about .ZIP format, see
- http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip
- http://www.info-zip.org/pub/infozip/doc/
- PkWare has also a specification at :
- ftp://ftp.pkware.com/probdesc.zip
-*/
-
-#ifndef _unz_H
-#define _unz_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef _ZLIB_H
-#include "zlib.h"
-#endif
-
-#ifndef _ZLIBIOAPI_H
-#include "ioapi.h"
-#endif
-
-#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
-/* like the STRICT of WIN32, we define a pointer that cannot be converted
- from (void*) without cast */
-typedef struct TagunzFile__ { int unused; } unzFile__;
-typedef unzFile__ *unzFile;
-#else
-typedef voidp unzFile;
-#endif
-
-
-#define UNZ_OK (0)
-#define UNZ_END_OF_LIST_OF_FILE (-100)
-#define UNZ_ERRNO (Z_ERRNO)
-#define UNZ_EOF (0)
-#define UNZ_PARAMERROR (-102)
-#define UNZ_BADZIPFILE (-103)
-#define UNZ_INTERNALERROR (-104)
-#define UNZ_CRCERROR (-105)
-
-/* tm_unz contain date/time info */
-typedef struct tm_unz_s
-{
- uInt tm_sec; /* seconds after the minute - [0,59] */
- uInt tm_min; /* minutes after the hour - [0,59] */
- uInt tm_hour; /* hours since midnight - [0,23] */
- uInt tm_mday; /* day of the month - [1,31] */
- uInt tm_mon; /* months since January - [0,11] */
- uInt tm_year; /* years - [1980..2044] */
-} tm_unz;
-
-/* unz_global_info structure contain global data about the ZIPfile
- These data comes from the end of central dir */
-typedef struct unz_global_info_s
-{
- uLong number_entry; /* total number of entries in
- the central dir on this disk */
- uLong size_comment; /* size of the global comment of the zipfile */
-} unz_global_info;
-
-
-/* unz_file_info contain information about a file in the zipfile */
-typedef struct unz_file_info_s
-{
- uLong version; /* version made by 2 bytes */
- uLong version_needed; /* version needed to extract 2 bytes */
- uLong flag; /* general purpose bit flag 2 bytes */
- uLong compression_method; /* compression method 2 bytes */
- uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
- uLong crc; /* crc-32 4 bytes */
- uLong compressed_size; /* compressed size 4 bytes */
- uLong uncompressed_size; /* uncompressed size 4 bytes */
- uLong size_filename; /* filename length 2 bytes */
- uLong size_file_extra; /* extra field length 2 bytes */
- uLong size_file_comment; /* file comment length 2 bytes */
-
- uLong disk_num_start; /* disk number start 2 bytes */
- uLong internal_fa; /* internal file attributes 2 bytes */
- uLong external_fa; /* external file attributes 4 bytes */
-
- tm_unz tmu_date;
-} unz_file_info;
-
-extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
- const char* fileName2,
- int iCaseSensitivity));
-/*
- Compare two filename (fileName1,fileName2).
- If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
- If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
- or strcasecmp)
- If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
- (like 1 on Unix, 2 on Windows)
-*/
-
-
-extern unzFile ZEXPORT unzOpen OF((const char *path));
-/*
- Open a Zip file. path contain the full pathname (by example,
- on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer
- "zlib/zlib113.zip".
- If the zipfile cannot be opened (file don't exist or in not valid), the
- return value is NULL.
- Else, the return value is a unzFile Handle, usable with other function
- of this unzip package.
-*/
-
-extern unzFile ZEXPORT unzOpen2 OF((const char *path,
- zlib_filefunc_def* pzlib_filefunc_def));
-/*
- Open a Zip file, like unzOpen, but provide a set of file low level API
- for read/write the zip file (see ioapi.h)
-*/
-
-extern int ZEXPORT unzClose OF((unzFile file));
-/*
- Close a ZipFile opened with unzipOpen.
- If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
- these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
- return UNZ_OK if there is no problem. */
-
-extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
- unz_global_info *pglobal_info));
-/*
- Write info about the ZipFile in the *pglobal_info structure.
- No preparation of the structure is needed
- return UNZ_OK if there is no problem. */
-
-
-extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
- char *szComment,
- uLong uSizeBuf));
-/*
- Get the global comment string of the ZipFile, in the szComment buffer.
- uSizeBuf is the size of the szComment buffer.
- return the number of byte copied or an error code <0
-*/
-
-
-/***************************************************************************/
-/* Unzip package allow you browse the directory of the zipfile */
-
-extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
-/*
- Set the current file of the zipfile to the first file.
- return UNZ_OK if there is no problem
-*/
-
-extern int ZEXPORT unzGoToNextFile OF((unzFile file));
-/*
- Set the current file of the zipfile to the next file.
- return UNZ_OK if there is no problem
- return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
-*/
-
-extern int ZEXPORT unzLocateFile OF((unzFile file,
- const char *szFileName,
- int iCaseSensitivity));
-/*
- Try locate the file szFileName in the zipfile.
- For the iCaseSensitivity signification, see unzStringFileNameCompare
-
- return value :
- UNZ_OK if the file is found. It becomes the current file.
- UNZ_END_OF_LIST_OF_FILE if the file is not found
-*/
-
-
-/* ****************************************** */
-/* Ryan supplied functions */
-/* unz_file_info contain information about a file in the zipfile */
-typedef struct unz_file_pos_s
-{
- uLong pos_in_zip_directory; /* offset in zip file directory */
- uLong num_of_file; /* # of file */
-} unz_file_pos;
-
-extern int ZEXPORT unzGetFilePos(
- unzFile file,
- unz_file_pos* file_pos);
-
-extern int ZEXPORT unzGoToFilePos(
- unzFile file,
- unz_file_pos* file_pos);
-
-/* ****************************************** */
-
-extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
- unz_file_info *pfile_info,
- char *szFileName,
- uLong fileNameBufferSize,
- void *extraField,
- uLong extraFieldBufferSize,
- char *szComment,
- uLong commentBufferSize));
-/*
- Get Info about the current file
- if pfile_info!=NULL, the *pfile_info structure will contain somes info about
- the current file
- if szFileName!=NULL, the filemane string will be copied in szFileName
- (fileNameBufferSize is the size of the buffer)
- if extraField!=NULL, the extra field information will be copied in extraField
- (extraFieldBufferSize is the size of the buffer).
- This is the Central-header version of the extra field
- if szComment!=NULL, the comment string of the file will be copied in szComment
- (commentBufferSize is the size of the buffer)
-*/
-
-/***************************************************************************/
-/* for reading the content of the current zipfile, you can open it, read data
- from it, and close it (you can close it before reading all the file)
- */
-
-extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
-/*
- Open for reading data the current file in the zipfile.
- If there is no error, the return value is UNZ_OK.
-*/
-
-extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file,
- const char* password));
-/*
- Open for reading data the current file in the zipfile.
- password is a crypting password
- If there is no error, the return value is UNZ_OK.
-*/
-
-extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file,
- int* method,
- int* level,
- int raw));
-/*
- Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
- if raw==1
- *method will receive method of compression, *level will receive level of
- compression
- note : you can set level parameter as NULL (if you did not want known level,
- but you CANNOT set method parameter as NULL
-*/
-
-extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file,
- int* method,
- int* level,
- int raw,
- const char* password));
-/*
- Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
- if raw==1
- *method will receive method of compression, *level will receive level of
- compression
- note : you can set level parameter as NULL (if you did not want known level,
- but you CANNOT set method parameter as NULL
-*/
-
-
-extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
-/*
- Close the file in zip opened with unzOpenCurrentFile
- Return UNZ_CRCERROR if all the file was read but the CRC is not good
-*/
-
-extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
- voidp buf,
- unsigned len));
-/*
- Read bytes from the current file (opened by unzOpenCurrentFile)
- buf contain buffer where data must be copied
- len the size of buf.
-
- return the number of byte copied if somes bytes are copied
- return 0 if the end of file was reached
- return <0 with error code if there is an error
- (UNZ_ERRNO for IO error, or zLib error for uncompress error)
-*/
-
-extern z_off_t ZEXPORT unztell OF((unzFile file));
-/*
- Give the current position in uncompressed data
-*/
-
-extern int ZEXPORT unzeof OF((unzFile file));
-/*
- return 1 if the end of file was reached, 0 elsewhere
-*/
-
-extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
- voidp buf,
- unsigned len));
-/*
- Read extra field from the current file (opened by unzOpenCurrentFile)
- This is the local-header version of the extra field (sometimes, there is
- more info in the local-header version than in the central-header)
-
- if buf==NULL, it return the size of the local extra field
-
- if buf!=NULL, len is the size of the buffer, the extra header is copied in
- buf.
- the return value is the number of bytes copied in buf, or (if <0)
- the error code
-*/
-
-/***************************************************************************/
-
-/* Get the current file offset */
-extern uLong ZEXPORT unzGetOffset (unzFile file);
-
-/* Set the current file offset */
-extern int ZEXPORT unzSetOffset (unzFile file, uLong pos);
-
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _unz_H */
diff --git a/attic/programs/ios/WebODF/Classes/zip.h b/attic/programs/ios/WebODF/Classes/zip.h
deleted file mode 100644
index a4f071605..000000000
--- a/attic/programs/ios/WebODF/Classes/zip.h
+++ /dev/null
@@ -1,15 +0,0 @@
-//
-// Header.h
-// WebODF
-//
-// Created by KO GmbH on 3/1/12.
-// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
-//
-
-#ifndef WebODF_Header_h
-#define WebODF_Header_h
-
-void readZipEntry(const char* zippath, const char* entrypath) {}
-
-
-#endif
diff --git a/attic/programs/ios/WebODF/Cordova.plist b/attic/programs/ios/WebODF/Cordova.plist
deleted file mode 100644
index 4829e861a..000000000
--- a/attic/programs/ios/WebODF/Cordova.plist
+++ /dev/null
@@ -1,63 +0,0 @@
-
-
-
-
- UIWebViewBounce
-
- TopActivityIndicator
- gray
- EnableLocation
-
- EnableViewportScale
-
- AutoHideSplashScreen
-
- ShowSplashScreenSpinner
-
- MediaPlaybackRequiresUserAction
-
- AllowInlineMediaPlayback
-
- OpenAllWhitelistURLsInWebView
-
- ExternalHosts
-
- zipserver
-
- Plugins
-
- ZipClass
- NativeZip
- Logger
- CDVLogger
- Compass
- CDVLocation
- Accelerometer
- CDVAccelerometer
- Camera
- CDVCamera
- NetworkStatus
- CDVConnection
- Contacts
- CDVContacts
- Debug Console
- CDVDebugConsole
- File
- CDVFile
- FileTransfer
- CDVFileTransfer
- Geolocation
- CDVLocation
- Notification
- CDVNotification
- Media
- CDVSound
- Capture
- CDVCapture
- SplashScreen
- CDVSplashScreen
- Battery
- CDVBattery
-
-
-
diff --git a/attic/programs/ios/WebODF/Resources/en.lproj/Localizable.strings b/attic/programs/ios/WebODF/Resources/en.lproj/Localizable.strings
deleted file mode 100644
index 897268443..000000000
--- a/attic/programs/ios/WebODF/Resources/en.lproj/Localizable.strings
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
- */
-
-// accessibility label for recording button
-"toggle audio recording" = "toggle audio recording";
-// notification spoken by VoiceOver when timed recording finishes
-"timed recording complete" = "timed recording complete";
-// accessibility hint for display of recorded elapsed time
-"recorded time in minutes and seconds" = "recorded time in minutes and seconds";
\ No newline at end of file
diff --git a/attic/programs/ios/WebODF/Resources/icons/icon-72.png b/attic/programs/ios/WebODF/Resources/icons/icon-72.png
deleted file mode 100644
index 1aebf5d34..000000000
Binary files a/attic/programs/ios/WebODF/Resources/icons/icon-72.png and /dev/null differ
diff --git a/attic/programs/ios/WebODF/Resources/icons/icon.png b/attic/programs/ios/WebODF/Resources/icons/icon.png
deleted file mode 100644
index 9e654236c..000000000
Binary files a/attic/programs/ios/WebODF/Resources/icons/icon.png and /dev/null differ
diff --git a/attic/programs/ios/WebODF/Resources/icons/icon@2x.png b/attic/programs/ios/WebODF/Resources/icons/icon@2x.png
deleted file mode 100644
index b7ccb848e..000000000
Binary files a/attic/programs/ios/WebODF/Resources/icons/icon@2x.png and /dev/null differ
diff --git a/attic/programs/ios/WebODF/Resources/splash/Default-Landscape~ipad.png b/attic/programs/ios/WebODF/Resources/splash/Default-Landscape~ipad.png
deleted file mode 100644
index 06bb96b39..000000000
Binary files a/attic/programs/ios/WebODF/Resources/splash/Default-Landscape~ipad.png and /dev/null differ
diff --git a/attic/programs/ios/WebODF/Resources/splash/Default-Portrait~ipad.png b/attic/programs/ios/WebODF/Resources/splash/Default-Portrait~ipad.png
deleted file mode 100644
index dbfed967a..000000000
Binary files a/attic/programs/ios/WebODF/Resources/splash/Default-Portrait~ipad.png and /dev/null differ
diff --git a/attic/programs/ios/WebODF/Resources/splash/Default.png b/attic/programs/ios/WebODF/Resources/splash/Default.png
deleted file mode 100755
index fbf06e22d..000000000
Binary files a/attic/programs/ios/WebODF/Resources/splash/Default.png and /dev/null differ
diff --git a/attic/programs/ios/WebODF/Resources/splash/Default@2x.png b/attic/programs/ios/WebODF/Resources/splash/Default@2x.png
deleted file mode 100755
index e845a3f0b..000000000
Binary files a/attic/programs/ios/WebODF/Resources/splash/Default@2x.png and /dev/null differ
diff --git a/attic/programs/ios/WebODF/WebODF-Info.plist b/attic/programs/ios/WebODF/WebODF-Info.plist
deleted file mode 100644
index 18518ec4c..000000000
--- a/attic/programs/ios/WebODF/WebODF-Info.plist
+++ /dev/null
@@ -1,122 +0,0 @@
-
-
-
-
- CFBundleDevelopmentRegion
- English
- CFBundleDisplayName
- ${PRODUCT_NAME}
- CFBundleDocumentTypes
-
-
- CFBundleTypeIconFiles
-
- icon.png
-
- CFBundleTypeName
- OpenDocument Text
- CFBundleTypeRole
- Viewer
- LSHandlerRank
- Owner
- LSItemContentTypes
-
- org.oasis.opendocument.text
-
-
-
- CFBundleTypeIconFiles
-
- icon.png
-
- CFBundleTypeName
- OpenDocument Presentation
- CFBundleTypeRole
- Viewer
- LSHandlerRank
- Owner
- LSItemContentTypes
-
- org.oasis.opendocument.presentation
-
-
-
- CFBundleExecutable
- ${EXECUTABLE_NAME}
- CFBundleIconFile
- icon.png
- CFBundleIconFiles
-
- icon.png
- icon@2x.png
- icon-72.png
-
- CFBundleIdentifier
- WebODF-03
- CFBundleInfoDictionaryVersion
- 6.0
- CFBundleName
- ${PRODUCT_NAME}
- CFBundlePackageType
- APPL
- CFBundleShortVersionString
- 1.0
- CFBundleSignature
- ????
- CFBundleVersion
- 1.0
- LSRequiresIPhoneOS
-
- UISupportedInterfaceOrientations
-
- UIInterfaceOrientationPortrait
- UIInterfaceOrientationPortraitUpsideDown
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationLandscapeRight
-
- UISupportedInterfaceOrientations~ipad
-
- UIInterfaceOrientationPortrait
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationPortraitUpsideDown
- UIInterfaceOrientationLandscapeRight
-
- UTExportedTypeDeclarations
-
-
- UTTypeConformsTo
-
- org.gnu.gnu-zip-archive
-
- UTTypeDescription
- OpenDocument Text
- UTTypeIdentifier
- org.oasis.opendocument.text
- UTTypeTagSpecification
-
- public.filename-extension
- odt
- public.mime-type
- application/vnd.oasis.opendocument.text
-
-
-
- UTTypeConformsTo
-
- org.gnu.gnu-zip-archive
-
- UTTypeDescription
- OpenDocument Presentation
- UTTypeIdentifier
- org.oasis.opendocument.presentation
- UTTypeTagSpecification
-
- public.filename-extension
- odp
- public.mime-type
- application/vnd.oasis.opendocument.presentation
-
-
-
-
-
diff --git a/attic/programs/ios/WebODF/WebODF-Prefix.pch b/attic/programs/ios/WebODF/WebODF-Prefix.pch
deleted file mode 100644
index da48b6a1f..000000000
--- a/attic/programs/ios/WebODF/WebODF-Prefix.pch
+++ /dev/null
@@ -1,7 +0,0 @@
-//
-// Prefix header for all source files of the 'WebODF' target in the 'WebODF' project
-//
-
-#ifdef __OBJC__
- #import
-#endif
diff --git a/attic/programs/ios/WebODF/en.lproj/InfoPlist.strings b/attic/programs/ios/WebODF/en.lproj/InfoPlist.strings
deleted file mode 100644
index 477b28ff8..000000000
--- a/attic/programs/ios/WebODF/en.lproj/InfoPlist.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* Localized versions of Info.plist keys */
-
diff --git a/attic/programs/ios/WebODF/main.m b/attic/programs/ios/WebODF/main.m
deleted file mode 100644
index bda2f99ea..000000000
--- a/attic/programs/ios/WebODF/main.m
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
- */
-//
-// main.m
-// WebODF
-//
-// Created by KO GmbH on 2/2/12.
-// Copyright __MyCompanyName__ 2012. All rights reserved.
-//
-
-#import
-
-int main(int argc, char *argv[]) {
- int retVal = UIApplicationMain(argc, argv, nil, @"AppDelegate");
- return retVal;
-}
diff --git a/attic/programs/ios/welcome.odt b/attic/programs/ios/welcome.odt
deleted file mode 100644
index 9845da8c6..000000000
Binary files a/attic/programs/ios/welcome.odt and /dev/null differ
diff --git a/attic/programs/ios/www/cordova-1.8.0.js b/attic/programs/ios/www/cordova-1.8.0.js
deleted file mode 100644
index f03b4271e..000000000
--- a/attic/programs/ios/www/cordova-1.8.0.js
+++ /dev/null
@@ -1,5226 +0,0 @@
-// commit 109b8649b0e98597b147842a6f71999d2f7910f2
-
-// File generated at :: Tue Jun 05 2012 14:10:19 GMT-0700 (PDT)
-
-/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
-*/
-
-;(function() {
-
-// file: lib/scripts/require.js
-var require,
- define;
-
-(function () {
- var modules = {};
-
- function build(module) {
- var factory = module.factory;
- module.exports = {};
- delete module.factory;
- factory(require, module.exports, module);
- return module.exports;
- }
-
- require = function (id) {
- if (!modules[id]) {
- throw "module " + id + " not found";
- }
- return modules[id].factory ? build(modules[id]) : modules[id].exports;
- };
-
- define = function (id, factory) {
- if (modules[id]) {
- throw "module " + id + " already defined";
- }
-
- modules[id] = {
- id: id,
- factory: factory
- };
- };
-
- define.remove = function (id) {
- delete modules[id];
- };
-
-})();
-
-//Export for use in node
-if (typeof module === "object" && typeof require === "function") {
- module.exports.require = require;
- module.exports.define = define;
-}
-// file: lib/cordova.js
-define("cordova", function(require, exports, module) {
-var channel = require('cordova/channel');
-
-/**
- * Listen for DOMContentLoaded and notify our channel subscribers.
- */
-document.addEventListener('DOMContentLoaded', function() {
- channel.onDOMContentLoaded.fire();
-}, false);
-if (document.readyState == 'complete' || document.readyState == 'interactive') {
- channel.onDOMContentLoaded.fire();
-}
-
-/**
- * Intercept calls to addEventListener + removeEventListener and handle deviceready,
- * resume, and pause events.
- */
-var m_document_addEventListener = document.addEventListener;
-var m_document_removeEventListener = document.removeEventListener;
-var m_window_addEventListener = window.addEventListener;
-var m_window_removeEventListener = window.removeEventListener;
-
-/**
- * Houses custom event handlers to intercept on document + window event listeners.
- */
-var documentEventHandlers = {},
- windowEventHandlers = {};
-
-document.addEventListener = function(evt, handler, capture) {
- var e = evt.toLowerCase();
- if (typeof documentEventHandlers[e] != 'undefined') {
- if (evt === 'deviceready') {
- documentEventHandlers[e].subscribeOnce(handler);
- } else {
- documentEventHandlers[e].subscribe(handler);
- }
- } else {
- m_document_addEventListener.call(document, evt, handler, capture);
- }
-};
-
-window.addEventListener = function(evt, handler, capture) {
- var e = evt.toLowerCase();
- if (typeof windowEventHandlers[e] != 'undefined') {
- windowEventHandlers[e].subscribe(handler);
- } else {
- m_window_addEventListener.call(window, evt, handler, capture);
- }
-};
-
-document.removeEventListener = function(evt, handler, capture) {
- var e = evt.toLowerCase();
- // If unsubcribing from an event that is handled by a plugin
- if (typeof documentEventHandlers[e] != "undefined") {
- documentEventHandlers[e].unsubscribe(handler);
- } else {
- m_document_removeEventListener.call(document, evt, handler, capture);
- }
-};
-
-window.removeEventListener = function(evt, handler, capture) {
- var e = evt.toLowerCase();
- // If unsubcribing from an event that is handled by a plugin
- if (typeof windowEventHandlers[e] != "undefined") {
- windowEventHandlers[e].unsubscribe(handler);
- } else {
- m_window_removeEventListener.call(window, evt, handler, capture);
- }
-};
-
-function createEvent(type, data) {
- var event = document.createEvent('Events');
- event.initEvent(type, false, false);
- if (data) {
- for (var i in data) {
- if (data.hasOwnProperty(i)) {
- event[i] = data[i];
- }
- }
- }
- return event;
-}
-
-if(typeof window.console === "undefined") {
- window.console = {
- log:function(){}
- };
-}
-
-var cordova = {
- define:define,
- require:require,
- /**
- * Methods to add/remove your own addEventListener hijacking on document + window.
- */
- addWindowEventHandler:function(event, opts) {
- return (windowEventHandlers[event] = channel.create(event, opts));
- },
- addDocumentEventHandler:function(event, opts) {
- return (documentEventHandlers[event] = channel.create(event, opts));
- },
- removeWindowEventHandler:function(event) {
- delete windowEventHandlers[event];
- },
- removeDocumentEventHandler:function(event) {
- delete documentEventHandlers[event];
- },
- /**
- * Retreive original event handlers that were replaced by Cordova
- *
- * @return object
- */
- getOriginalHandlers: function() {
- return {'document': {'addEventListener': m_document_addEventListener, 'removeEventListener': m_document_removeEventListener},
- 'window': {'addEventListener': m_window_addEventListener, 'removeEventListener': m_window_removeEventListener}};
- },
- /**
- * Method to fire event from native code
- */
- fireDocumentEvent: function(type, data) {
- var evt = createEvent(type, data);
- if (typeof documentEventHandlers[type] != 'undefined') {
- documentEventHandlers[type].fire(evt);
- } else {
- document.dispatchEvent(evt);
- }
- },
- fireWindowEvent: function(type, data) {
- var evt = createEvent(type,data);
- if (typeof windowEventHandlers[type] != 'undefined') {
- windowEventHandlers[type].fire(evt);
- } else {
- window.dispatchEvent(evt);
- }
- },
- // TODO: this is Android only; think about how to do this better
- shuttingDown:false,
- UsePolling:false,
- // END TODO
-
- // TODO: iOS only
- // This queue holds the currently executing command and all pending
- // commands executed with cordova.exec().
- commandQueue:[],
- // Indicates if we're currently in the middle of flushing the command
- // queue on the native side.
- commandQueueFlushing:false,
- // END TODO
- /**
- * Plugin callback mechanism.
- */
- callbackId: 0,
- callbacks: {},
- callbackStatus: {
- NO_RESULT: 0,
- OK: 1,
- CLASS_NOT_FOUND_EXCEPTION: 2,
- ILLEGAL_ACCESS_EXCEPTION: 3,
- INSTANTIATION_EXCEPTION: 4,
- MALFORMED_URL_EXCEPTION: 5,
- IO_EXCEPTION: 6,
- INVALID_ACTION: 7,
- JSON_EXCEPTION: 8,
- ERROR: 9
- },
-
- /**
- * Called by native code when returning successful result from an action.
- *
- * @param callbackId
- * @param args
- */
- callbackSuccess: function(callbackId, args) {
- if (cordova.callbacks[callbackId]) {
-
- // If result is to be sent to callback
- if (args.status == cordova.callbackStatus.OK) {
- try {
- if (cordova.callbacks[callbackId].success) {
- cordova.callbacks[callbackId].success(args.message);
- }
- }
- catch (e) {
- console.log("Error in success callback: "+callbackId+" = "+e);
- }
- }
-
- // Clear callback if not expecting any more results
- if (!args.keepCallback) {
- delete cordova.callbacks[callbackId];
- }
- }
- },
-
- /**
- * Called by native code when returning error result from an action.
- *
- * @param callbackId
- * @param args
- */
- callbackError: function(callbackId, args) {
- if (cordova.callbacks[callbackId]) {
- try {
- if (cordova.callbacks[callbackId].fail) {
- cordova.callbacks[callbackId].fail(args.message);
- }
- }
- catch (e) {
- console.log("Error in error callback: "+callbackId+" = "+e);
- }
-
- // Clear callback if not expecting any more results
- if (!args.keepCallback) {
- delete cordova.callbacks[callbackId];
- }
- }
- },
- // TODO: remove in 2.0.
- addPlugin: function(name, obj) {
- console.log("[DEPRECATION NOTICE] window.addPlugin and window.plugins will be removed in version 2.0.");
- if (!window.plugins[name]) {
- window.plugins[name] = obj;
- }
- else {
- console.log("Error: Plugin "+name+" already exists.");
- }
- },
-
- addConstructor: function(func) {
- channel.onCordovaReady.subscribeOnce(function() {
- try {
- func();
- } catch(e) {
- console.log("Failed to run constructor: " + e);
- }
- });
- }
-};
-
-// Register pause, resume and deviceready channels as events on document.
-channel.onPause = cordova.addDocumentEventHandler('pause');
-channel.onResume = cordova.addDocumentEventHandler('resume');
-channel.onDeviceReady = cordova.addDocumentEventHandler('deviceready');
-
-// Adds deprecation warnings to functions of an object (but only logs a message once)
-function deprecateFunctions(obj, objLabel) {
- var newObj = {};
- var logHash = {};
- for (var i in obj) {
- if (obj.hasOwnProperty(i)) {
- if (typeof obj[i] == 'function') {
- newObj[i] = (function(prop){
- var oldFunk = obj[prop];
- var funkId = objLabel + '_' + prop;
- return function() {
- if (!logHash[funkId]) {
- console.log('[DEPRECATION NOTICE] The "' + objLabel + '" global will be removed in version 2.0, please use lowercase "cordova".');
- logHash[funkId] = true;
- }
- oldFunk.apply(obj, arguments);
- };
- })(i);
- } else {
- newObj[i] = (function(prop) { return obj[prop]; })(i);
- }
- }
- }
- return newObj;
-}
-
-/**
- * Legacy variable for plugin support
- * TODO: remove in 2.0.
- */
-if (!window.PhoneGap) {
- window.PhoneGap = deprecateFunctions(cordova, 'PhoneGap');
-}
-if (!window.Cordova) {
- window.Cordova = deprecateFunctions(cordova, 'Cordova');
-}
-
-/**
- * Plugins object
- * TODO: remove in 2.0.
- */
-if (!window.plugins) {
- window.plugins = {};
-}
-
-module.exports = cordova;
-
-});
-
-// file: lib/common/builder.js
-define("cordova/builder", function(require, exports, module) {
-var utils = require('cordova/utils');
-
-function each(objects, func, context) {
- for (var prop in objects) {
- if (objects.hasOwnProperty(prop)) {
- func.apply(context, [objects[prop], prop]);
- }
- }
-}
-
-function include(parent, objects, clobber, merge) {
- each(objects, function (obj, key) {
- try {
- var result = obj.path ? require(obj.path) : {};
-
- if (clobber) {
- // Clobber if it doesn't exist.
- if (typeof parent[key] === 'undefined') {
- parent[key] = result;
- } else if (typeof obj.path !== 'undefined') {
- // If merging, merge properties onto parent, otherwise, clobber.
- if (merge) {
- recursiveMerge(parent[key], result);
- } else {
- parent[key] = result;
- }
- }
- result = parent[key];
- } else {
- // Overwrite if not currently defined.
- if (typeof parent[key] == 'undefined') {
- parent[key] = result;
- } else if (merge && typeof obj.path !== 'undefined') {
- // If merging, merge parent onto result
- recursiveMerge(result, parent[key]);
- parent[key] = result;
- } else {
- // Set result to what already exists, so we can build children into it if they exist.
- result = parent[key];
- }
- }
-
- if (obj.children) {
- include(result, obj.children, clobber, merge);
- }
- } catch(e) {
- utils.alert('Exception building cordova JS globals: ' + e + ' for key "' + key + '"');
- }
- });
-}
-
-/**
- * Merge properties from one object onto another recursively. Properties from
- * the src object will overwrite existing target property.
- *
- * @param target Object to merge properties into.
- * @param src Object to merge properties from.
- */
-function recursiveMerge(target, src) {
- for (var prop in src) {
- if (src.hasOwnProperty(prop)) {
- if (typeof target.prototype !== 'undefined' && target.prototype.constructor === target) {
- // If the target object is a constructor override off prototype.
- target.prototype[prop] = src[prop];
- } else {
- target[prop] = typeof src[prop] === 'object' ? recursiveMerge(
- target[prop], src[prop]) : src[prop];
- }
- }
- }
- return target;
-}
-
-module.exports = {
- build: function (objects) {
- return {
- intoButDontClobber: function (target) {
- include(target, objects, false, false);
- },
- intoAndClobber: function(target) {
- include(target, objects, true, false);
- },
- intoAndMerge: function(target) {
- include(target, objects, true, true);
- }
- };
- }
-};
-
-});
-
-// file: lib/common/channel.js
-define("cordova/channel", function(require, exports, module) {
-var utils = require('cordova/utils');
-
-/**
- * Custom pub-sub "channel" that can have functions subscribed to it
- * This object is used to define and control firing of events for
- * cordova initialization.
- *
- * The order of events during page load and Cordova startup is as follows:
- *
- * onDOMContentLoaded Internal event that is received when the web page is loaded and parsed.
- * onNativeReady Internal event that indicates the Cordova native side is ready.
- * onCordovaReady Internal event fired when all Cordova JavaScript objects have been created.
- * onCordovaInfoReady Internal event fired when device properties are available.
- * onCordovaConnectionReady Internal event fired when the connection property has been set.
- * onDeviceReady User event fired to indicate that Cordova is ready
- * onResume User event fired to indicate a start/resume lifecycle event
- * onPause User event fired to indicate a pause lifecycle event
- * onDestroy Internal event fired when app is being destroyed (User should use window.onunload event, not this one).
- *
- * The only Cordova events that user code should register for are:
- * deviceready Cordova native code is initialized and Cordova APIs can be called from JavaScript
- * pause App has moved to background
- * resume App has returned to foreground
- *
- * Listeners can be registered as:
- * document.addEventListener("deviceready", myDeviceReadyListener, false);
- * document.addEventListener("resume", myResumeListener, false);
- * document.addEventListener("pause", myPauseListener, false);
- *
- * The DOM lifecycle events should be used for saving and restoring state
- * window.onload
- * window.onunload
- *
- */
-
-/**
- * Channel
- * @constructor
- * @param type String the channel name
- * @param opts Object options to pass into the channel, currently
- * supports:
- * onSubscribe: callback that fires when
- * something subscribes to the Channel. Sets
- * context to the Channel.
- * onUnsubscribe: callback that fires when
- * something unsubscribes to the Channel. Sets
- * context to the Channel.
- */
-var Channel = function(type, opts) {
- this.type = type;
- this.handlers = {};
- this.numHandlers = 0;
- this.guid = 1;
- this.fired = false;
- this.enabled = true;
- this.events = {
- onSubscribe:null,
- onUnsubscribe:null
- };
- if (opts) {
- if (opts.onSubscribe) this.events.onSubscribe = opts.onSubscribe;
- if (opts.onUnsubscribe) this.events.onUnsubscribe = opts.onUnsubscribe;
- }
-},
- channel = {
- /**
- * Calls the provided function only after all of the channels specified
- * have been fired.
- */
- join: function (h, c) {
- var i = c.length;
- var len = i;
- var f = function() {
- if (!(--i)) h();
- };
- for (var j=0; j} phoneNumbers array of phone numbers
-* @param {Array.} emails array of email addresses
-* @param {Array.} addresses array of addresses
-* @param {Array.} ims instant messaging user ids
-* @param {Array.} organizations
-* @param {DOMString} birthday contact's birthday
-* @param {DOMString} note user notes about contact
-* @param {Array.} photos
-* @param {Array.} categories
-* @param {Array.} urls contact's web sites
-*/
-var Contact = function (id, displayName, name, nickname, phoneNumbers, emails, addresses,
- ims, organizations, birthday, note, photos, categories, urls) {
- this.id = id || null;
- this.rawId = null;
- this.displayName = displayName || null;
- this.name = name || null; // ContactName
- this.nickname = nickname || null;
- this.phoneNumbers = phoneNumbers || null; // ContactField[]
- this.emails = emails || null; // ContactField[]
- this.addresses = addresses || null; // ContactAddress[]
- this.ims = ims || null; // ContactField[]
- this.organizations = organizations || null; // ContactOrganization[]
- this.birthday = birthday || null;
- this.note = note || null;
- this.photos = photos || null; // ContactField[]
- this.categories = categories || null; // ContactField[]
- this.urls = urls || null; // ContactField[]
-};
-
-/**
-* Removes contact from device storage.
-* @param successCB success callback
-* @param errorCB error callback
-*/
-Contact.prototype.remove = function(successCB, errorCB) {
- var fail = function(code) {
- errorCB(new ContactError(code));
- };
- if (this.id === null) {
- fail(ContactError.UNKNOWN_ERROR);
- }
- else {
- exec(successCB, fail, "Contacts", "remove", [this.id]);
- }
-};
-
-/**
-* Creates a deep copy of this Contact.
-* With the contact ID set to null.
-* @return copy of this Contact
-*/
-Contact.prototype.clone = function() {
- var clonedContact = utils.clone(this);
- var i;
- clonedContact.id = null;
- clonedContact.rawId = null;
- // Loop through and clear out any id's in phones, emails, etc.
- if (clonedContact.phoneNumbers) {
- for (i = 0; i < clonedContact.phoneNumbers.length; i++) {
- clonedContact.phoneNumbers[i].id = null;
- }
- }
- if (clonedContact.emails) {
- for (i = 0; i < clonedContact.emails.length; i++) {
- clonedContact.emails[i].id = null;
- }
- }
- if (clonedContact.addresses) {
- for (i = 0; i < clonedContact.addresses.length; i++) {
- clonedContact.addresses[i].id = null;
- }
- }
- if (clonedContact.ims) {
- for (i = 0; i < clonedContact.ims.length; i++) {
- clonedContact.ims[i].id = null;
- }
- }
- if (clonedContact.organizations) {
- for (i = 0; i < clonedContact.organizations.length; i++) {
- clonedContact.organizations[i].id = null;
- }
- }
- if (clonedContact.categories) {
- for (i = 0; i < clonedContact.categories.length; i++) {
- clonedContact.categories[i].id = null;
- }
- }
- if (clonedContact.photos) {
- for (i = 0; i < clonedContact.photos.length; i++) {
- clonedContact.photos[i].id = null;
- }
- }
- if (clonedContact.urls) {
- for (i = 0; i < clonedContact.urls.length; i++) {
- clonedContact.urls[i].id = null;
- }
- }
- return clonedContact;
-};
-
-/**
-* Persists contact to device storage.
-* @param successCB success callback
-* @param errorCB error callback
-*/
-Contact.prototype.save = function(successCB, errorCB) {
- var fail = function(code) {
- errorCB(new ContactError(code));
- };
- var success = function(result) {
- if (result) {
- if (typeof successCB === 'function') {
- var fullContact = require('cordova/plugin/contacts').create(result);
- successCB(convertIn(fullContact));
- }
- }
- else {
- // no Entry object returned
- fail(ContactError.UNKNOWN_ERROR);
- }
- };
- var dupContact = convertOut(utils.clone(this));
- exec(success, fail, "Contacts", "save", [dupContact]);
-};
-
-
-module.exports = Contact;
-
-});
-
-// file: lib/common/plugin/ContactAddress.js
-define("cordova/plugin/ContactAddress", function(require, exports, module) {
-/**
-* Contact address.
-* @constructor
-* @param {DOMString} id unique identifier, should only be set by native code
-* @param formatted // NOTE: not a W3C standard
-* @param streetAddress
-* @param locality
-* @param region
-* @param postalCode
-* @param country
-*/
-
-var ContactAddress = function(pref, type, formatted, streetAddress, locality, region, postalCode, country) {
- this.id = null;
- this.pref = (typeof pref != 'undefined' ? pref : false);
- this.type = type || null;
- this.formatted = formatted || null;
- this.streetAddress = streetAddress || null;
- this.locality = locality || null;
- this.region = region || null;
- this.postalCode = postalCode || null;
- this.country = country || null;
-};
-
-module.exports = ContactAddress;
-});
-
-// file: lib/common/plugin/ContactError.js
-define("cordova/plugin/ContactError", function(require, exports, module) {
-/**
- * ContactError.
- * An error code assigned by an implementation when an error has occured
- * @constructor
- */
-var ContactError = function(err) {
- this.code = (typeof err != 'undefined' ? err : null);
-};
-
-/**
- * Error codes
- */
-ContactError.UNKNOWN_ERROR = 0;
-ContactError.INVALID_ARGUMENT_ERROR = 1;
-ContactError.TIMEOUT_ERROR = 2;
-ContactError.PENDING_OPERATION_ERROR = 3;
-ContactError.IO_ERROR = 4;
-ContactError.NOT_SUPPORTED_ERROR = 5;
-ContactError.PERMISSION_DENIED_ERROR = 20;
-
-module.exports = ContactError;
-});
-
-// file: lib/common/plugin/ContactField.js
-define("cordova/plugin/ContactField", function(require, exports, module) {
-/**
-* Generic contact field.
-* @constructor
-* @param {DOMString} id unique identifier, should only be set by native code // NOTE: not a W3C standard
-* @param type
-* @param value
-* @param pref
-*/
-var ContactField = function(type, value, pref) {
- this.id = null;
- this.type = (type && type.toString()) || null;
- this.value = (value && value.toString()) || null;
- this.pref = (typeof pref != 'undefined' ? pref : false);
-};
-
-module.exports = ContactField;
-});
-
-// file: lib/common/plugin/ContactFindOptions.js
-define("cordova/plugin/ContactFindOptions", function(require, exports, module) {
-/**
- * ContactFindOptions.
- * @constructor
- * @param filter used to match contacts against
- * @param multiple boolean used to determine if more than one contact should be returned
- */
-
-var ContactFindOptions = function(filter, multiple) {
- this.filter = filter || '';
- this.multiple = (typeof multiple != 'undefined' ? multiple : false);
-};
-
-module.exports = ContactFindOptions;
-});
-
-// file: lib/common/plugin/ContactName.js
-define("cordova/plugin/ContactName", function(require, exports, module) {
-/**
-* Contact name.
-* @constructor
-* @param formatted // NOTE: not part of W3C standard
-* @param familyName
-* @param givenName
-* @param middle
-* @param prefix
-* @param suffix
-*/
-var ContactName = function(formatted, familyName, givenName, middle, prefix, suffix) {
- this.formatted = formatted || null;
- this.familyName = familyName || null;
- this.givenName = givenName || null;
- this.middleName = middle || null;
- this.honorificPrefix = prefix || null;
- this.honorificSuffix = suffix || null;
-};
-
-module.exports = ContactName;
-});
-
-// file: lib/common/plugin/ContactOrganization.js
-define("cordova/plugin/ContactOrganization", function(require, exports, module) {
-/**
-* Contact organization.
-* @constructor
-* @param {DOMString} id unique identifier, should only be set by native code // NOTE: not a W3C standard
-* @param name
-* @param dept
-* @param title
-* @param startDate
-* @param endDate
-* @param location
-* @param desc
-*/
-
-var ContactOrganization = function(pref, type, name, dept, title) {
- this.id = null;
- this.pref = (typeof pref != 'undefined' ? pref : false);
- this.type = type || null;
- this.name = name || null;
- this.department = dept || null;
- this.title = title || null;
-};
-
-module.exports = ContactOrganization;
-});
-
-// file: lib/common/plugin/Coordinates.js
-define("cordova/plugin/Coordinates", function(require, exports, module) {
-/**
- * This class contains position information.
- * @param {Object} lat
- * @param {Object} lng
- * @param {Object} alt
- * @param {Object} acc
- * @param {Object} head
- * @param {Object} vel
- * @param {Object} altacc
- * @constructor
- */
-var Coordinates = function(lat, lng, alt, acc, head, vel, altacc) {
- /**
- * The latitude of the position.
- */
- this.latitude = lat;
- /**
- * The longitude of the position,
- */
- this.longitude = lng;
- /**
- * The accuracy of the position.
- */
- this.accuracy = acc;
- /**
- * The altitude of the position.
- */
- this.altitude = (alt !== undefined ? alt : null);
- /**
- * The direction the device is moving at the position.
- */
- this.heading = (head !== undefined ? head : null);
- /**
- * The velocity with which the device is moving at the position.
- */
- this.speed = (vel !== undefined ? vel : null);
-
- if (this.speed === 0 || this.speed === null) {
- this.heading = NaN;
- }
-
- /**
- * The altitude accuracy of the position.
- */
- this.altitudeAccuracy = (altacc !== undefined) ? altacc : null;
-};
-
-module.exports = Coordinates;
-
-});
-
-// file: lib/common/plugin/DirectoryEntry.js
-define("cordova/plugin/DirectoryEntry", function(require, exports, module) {
-var utils = require('cordova/utils'),
- exec = require('cordova/exec'),
- Entry = require('cordova/plugin/Entry'),
- FileError = require('cordova/plugin/FileError'),
- DirectoryReader = require('cordova/plugin/DirectoryReader');
-
-/**
- * An interface representing a directory on the file system.
- *
- * {boolean} isFile always false (readonly)
- * {boolean} isDirectory always true (readonly)
- * {DOMString} name of the directory, excluding the path leading to it (readonly)
- * {DOMString} fullPath the absolute full path to the directory (readonly)
- * {FileSystem} filesystem on which the directory resides (readonly)
- */
-var DirectoryEntry = function(name, fullPath) {
- DirectoryEntry.__super__.constructor.apply(this, [false, true, name, fullPath]);
-};
-
-utils.extend(DirectoryEntry, Entry);
-
-/**
- * Creates a new DirectoryReader to read entries from this directory
- */
-DirectoryEntry.prototype.createReader = function() {
- return new DirectoryReader(this.fullPath);
-};
-
-/**
- * Creates or looks up a directory
- *
- * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a directory
- * @param {Flags} options to create or excluively create the directory
- * @param {Function} successCallback is called with the new entry
- * @param {Function} errorCallback is called with a FileError
- */
-DirectoryEntry.prototype.getDirectory = function(path, options, successCallback, errorCallback) {
- var win = typeof successCallback !== 'function' ? null : function(result) {
- var entry = new DirectoryEntry(result.name, result.fullPath);
- successCallback(entry);
- };
- var fail = typeof errorCallback !== 'function' ? null : function(code) {
- errorCallback(new FileError(code));
- };
- exec(win, fail, "File", "getDirectory", [this.fullPath, path, options]);
-};
-
-/**
- * Deletes a directory and all of it's contents
- *
- * @param {Function} successCallback is called with no parameters
- * @param {Function} errorCallback is called with a FileError
- */
-DirectoryEntry.prototype.removeRecursively = function(successCallback, errorCallback) {
- var fail = typeof errorCallback !== 'function' ? null : function(code) {
- errorCallback(new FileError(code));
- };
- exec(successCallback, fail, "File", "removeRecursively", [this.fullPath]);
-};
-
-/**
- * Creates or looks up a file
- *
- * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a file
- * @param {Flags} options to create or excluively create the file
- * @param {Function} successCallback is called with the new entry
- * @param {Function} errorCallback is called with a FileError
- */
-DirectoryEntry.prototype.getFile = function(path, options, successCallback, errorCallback) {
- var win = typeof successCallback !== 'function' ? null : function(result) {
- var FileEntry = require('cordova/plugin/FileEntry');
- var entry = new FileEntry(result.name, result.fullPath);
- successCallback(entry);
- };
- var fail = typeof errorCallback !== 'function' ? null : function(code) {
- errorCallback(new FileError(code));
- };
- exec(win, fail, "File", "getFile", [this.fullPath, path, options]);
-};
-
-module.exports = DirectoryEntry;
-
-});
-
-// file: lib/common/plugin/DirectoryReader.js
-define("cordova/plugin/DirectoryReader", function(require, exports, module) {
-var exec = require('cordova/exec'),
- FileError = require('cordova/plugin/FileError') ;
-
-/**
- * An interface that lists the files and directories in a directory.
- */
-function DirectoryReader(path) {
- this.path = path || null;
-}
-
-/**
- * Returns a list of entries from a directory.
- *
- * @param {Function} successCallback is called with a list of entries
- * @param {Function} errorCallback is called with a FileError
- */
-DirectoryReader.prototype.readEntries = function(successCallback, errorCallback) {
- var win = typeof successCallback !== 'function' ? null : function(result) {
- var retVal = [];
- for (var i=0; i][;base64],
- *
- * @param file {File} File object containing file properties
- */
-FileReader.prototype.readAsDataURL = function(file) {
- this.fileName = "";
- if (typeof file.fullPath === "undefined") {
- this.fileName = file;
- } else {
- this.fileName = file.fullPath;
- }
-
- // Already loading something
- if (this.readyState == FileReader.LOADING) {
- throw new FileError(FileError.INVALID_STATE_ERR);
- }
-
- // LOADING state
- this.readyState = FileReader.LOADING;
-
- // If loadstart callback
- if (typeof this.onloadstart === "function") {
- this.onloadstart(new ProgressEvent("loadstart", {target:this}));
- }
-
- var me = this;
-
- // Read file
- exec(
- // Success callback
- function(r) {
- // If DONE (cancelled), then don't do anything
- if (me.readyState === FileReader.DONE) {
- return;
- }
-
- // DONE state
- me.readyState = FileReader.DONE;
-
- // Save result
- me.result = r;
-
- // If onload callback
- if (typeof me.onload === "function") {
- me.onload(new ProgressEvent("load", {target:me}));
- }
-
- // If onloadend callback
- if (typeof me.onloadend === "function") {
- me.onloadend(new ProgressEvent("loadend", {target:me}));
- }
- },
- // Error callback
- function(e) {
- // If DONE (cancelled), then don't do anything
- if (me.readyState === FileReader.DONE) {
- return;
- }
-
- // DONE state
- me.readyState = FileReader.DONE;
-
- me.result = null;
-
- // Save error
- me.error = new FileError(e);
-
- // If onerror callback
- if (typeof me.onerror === "function") {
- me.onerror(new ProgressEvent("error", {target:me}));
- }
-
- // If onloadend callback
- if (typeof me.onloadend === "function") {
- me.onloadend(new ProgressEvent("loadend", {target:me}));
- }
- }, "File", "readAsDataURL", [this.fileName]);
-};
-
-/**
- * Read file and return data as a binary data.
- *
- * @param file {File} File object containing file properties
- */
-FileReader.prototype.readAsBinaryString = function(file) {
- // TODO - Can't return binary data to browser.
- console.log('method "readAsBinaryString" is not supported at this time.');
-};
-
-/**
- * Read file and return data as a binary data.
- *
- * @param file {File} File object containing file properties
- */
-FileReader.prototype.readAsArrayBuffer = function(file) {
- // TODO - Can't return binary data to browser.
- console.log('This method is not supported at this time.');
-};
-
-module.exports = FileReader;
-});
-
-// file: lib/common/plugin/FileSystem.js
-define("cordova/plugin/FileSystem", function(require, exports, module) {
-var DirectoryEntry = require('cordova/plugin/DirectoryEntry');
-
-/**
- * An interface representing a file system
- *
- * @constructor
- * {DOMString} name the unique name of the file system (readonly)
- * {DirectoryEntry} root directory of the file system (readonly)
- */
-var FileSystem = function(name, root) {
- this.name = name || null;
- if (root) {
- this.root = new DirectoryEntry(root.name, root.fullPath);
- }
-};
-
-module.exports = FileSystem;
-});
-
-// file: lib/common/plugin/FileTransfer.js
-define("cordova/plugin/FileTransfer", function(require, exports, module) {
-var exec = require('cordova/exec');
-
-/**
- * FileTransfer uploads a file to a remote server.
- * @constructor
- */
-var FileTransfer = function() {};
-
-/**
-* Given an absolute file path, uploads a file on the device to a remote server
-* using a multipart HTTP request.
-* @param filePath {String} Full path of the file on the device
-* @param server {String} URL of the server to receive the file
-* @param successCallback (Function} Callback to be invoked when upload has completed
-* @param errorCallback {Function} Callback to be invoked upon error
-* @param options {FileUploadOptions} Optional parameters such as file name and mimetype
-* @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false
-*/
-FileTransfer.prototype.upload = function(filePath, server, successCallback, errorCallback, options, trustAllHosts) {
- // check for options
- var fileKey = null;
- var fileName = null;
- var mimeType = null;
- var params = null;
- var chunkedMode = true;
- if (options) {
- fileKey = options.fileKey;
- fileName = options.fileName;
- mimeType = options.mimeType;
- if (options.chunkedMode !== null || typeof options.chunkedMode != "undefined") {
- chunkedMode = options.chunkedMode;
- }
- if (options.params) {
- params = options.params;
- }
- else {
- params = {};
- }
- }
-
- exec(successCallback, errorCallback, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode]);
-};
-
-/**
- * Downloads a file form a given URL and saves it to the specified directory.
- * @param source {String} URL of the server to receive the file
- * @param target {String} Full path of the file on the device
- * @param successCallback (Function} Callback to be invoked when upload has completed
- * @param errorCallback {Function} Callback to be invoked upon error
- */
-FileTransfer.prototype.download = function(source, target, successCallback, errorCallback) {
- var win = function(result) {
- var entry = null;
- if (result.isDirectory) {
- entry = new (require('cordova/plugin/DirectoryEntry'))();
- }
- else if (result.isFile) {
- entry = new (require('cordova/plugin/FileEntry'))();
- }
- entry.isDirectory = result.isDirectory;
- entry.isFile = result.isFile;
- entry.name = result.name;
- entry.fullPath = result.fullPath;
- successCallback(entry);
- };
- exec(win, errorCallback, 'FileTransfer', 'download', [source, target]);
-};
-
-module.exports = FileTransfer;
-
-});
-
-// file: lib/common/plugin/FileTransferError.js
-define("cordova/plugin/FileTransferError", function(require, exports, module) {
-/**
- * FileTransferError
- * @constructor
- */
-var FileTransferError = function(code) {
- this.code = code || null;
-};
-
-FileTransferError.FILE_NOT_FOUND_ERR = 1;
-FileTransferError.INVALID_URL_ERR = 2;
-FileTransferError.CONNECTION_ERR = 3;
-
-module.exports = FileTransferError;
-});
-
-// file: lib/common/plugin/FileUploadOptions.js
-define("cordova/plugin/FileUploadOptions", function(require, exports, module) {
-/**
- * Options to customize the HTTP request used to upload files.
- * @constructor
- * @param fileKey {String} Name of file request parameter.
- * @param fileName {String} Filename to be used by the server. Defaults to image.jpg.
- * @param mimeType {String} Mimetype of the uploaded file. Defaults to image/jpeg.
- * @param params {Object} Object with key: value params to send to the server.
- */
-var FileUploadOptions = function(fileKey, fileName, mimeType, params) {
- this.fileKey = fileKey || null;
- this.fileName = fileName || null;
- this.mimeType = mimeType || null;
- this.params = params || null;
-};
-
-module.exports = FileUploadOptions;
-});
-
-// file: lib/common/plugin/FileUploadResult.js
-define("cordova/plugin/FileUploadResult", function(require, exports, module) {
-/**
- * FileUploadResult
- * @constructor
- */
-var FileUploadResult = function() {
- this.bytesSent = 0;
- this.responseCode = null;
- this.response = null;
-};
-
-module.exports = FileUploadResult;
-});
-
-// file: lib/common/plugin/FileWriter.js
-define("cordova/plugin/FileWriter", function(require, exports, module) {
-var exec = require('cordova/exec'),
- FileError = require('cordova/plugin/FileError'),
- ProgressEvent = require('cordova/plugin/ProgressEvent');
-
-/**
- * This class writes to the mobile device file system.
- *
- * For Android:
- * The root directory is the root of the file system.
- * To write to the SD card, the file name is "sdcard/my_file.txt"
- *
- * @constructor
- * @param file {File} File object containing file properties
- * @param append if true write to the end of the file, otherwise overwrite the file
- */
-var FileWriter = function(file) {
- this.fileName = "";
- this.length = 0;
- if (file) {
- this.fileName = file.fullPath || file;
- this.length = file.size || 0;
- }
- // default is to write at the beginning of the file
- this.position = 0;
-
- this.readyState = 0; // EMPTY
-
- this.result = null;
-
- // Error
- this.error = null;
-
- // Event handlers
- this.onwritestart = null; // When writing starts
- this.onprogress = null; // While writing the file, and reporting partial file data
- this.onwrite = null; // When the write has successfully completed.
- this.onwriteend = null; // When the request has completed (either in success or failure).
- this.onabort = null; // When the write has been aborted. For instance, by invoking the abort() method.
- this.onerror = null; // When the write has failed (see errors).
-};
-
-// States
-FileWriter.INIT = 0;
-FileWriter.WRITING = 1;
-FileWriter.DONE = 2;
-
-/**
- * Abort writing file.
- */
-FileWriter.prototype.abort = function() {
- // check for invalid state
- if (this.readyState === FileWriter.DONE || this.readyState === FileWriter.INIT) {
- throw new FileError(FileError.INVALID_STATE_ERR);
- }
-
- // set error
- this.error = new FileError(FileError.ABORT_ERR);
-
- this.readyState = FileWriter.DONE;
-
- // If abort callback
- if (typeof this.onabort === "function") {
- this.onabort(new ProgressEvent("abort", {"target":this}));
- }
-
- // If write end callback
- if (typeof this.onwriteend === "function") {
- this.onwriteend(new ProgressEvent("writeend", {"target":this}));
- }
-};
-
-/**
- * Writes data to the file
- *
- * @param text to be written
- */
-FileWriter.prototype.write = function(text) {
- // Throw an exception if we are already writing a file
- if (this.readyState === FileWriter.WRITING) {
- throw new FileError(FileError.INVALID_STATE_ERR);
- }
-
- // WRITING state
- this.readyState = FileWriter.WRITING;
-
- var me = this;
-
- // If onwritestart callback
- if (typeof me.onwritestart === "function") {
- me.onwritestart(new ProgressEvent("writestart", {"target":me}));
- }
-
- // Write file
- exec(
- // Success callback
- function(r) {
- // If DONE (cancelled), then don't do anything
- if (me.readyState === FileWriter.DONE) {
- return;
- }
-
- // position always increases by bytes written because file would be extended
- me.position += r;
- // The length of the file is now where we are done writing.
-
- me.length = me.position;
-
- // DONE state
- me.readyState = FileWriter.DONE;
-
- // If onwrite callback
- if (typeof me.onwrite === "function") {
- me.onwrite(new ProgressEvent("write", {"target":me}));
- }
-
- // If onwriteend callback
- if (typeof me.onwriteend === "function") {
- me.onwriteend(new ProgressEvent("writeend", {"target":me}));
- }
- },
- // Error callback
- function(e) {
- // If DONE (cancelled), then don't do anything
- if (me.readyState === FileWriter.DONE) {
- return;
- }
-
- // DONE state
- me.readyState = FileWriter.DONE;
-
- // Save error
- me.error = new FileError(e);
-
- // If onerror callback
- if (typeof me.onerror === "function") {
- me.onerror(new ProgressEvent("error", {"target":me}));
- }
-
- // If onwriteend callback
- if (typeof me.onwriteend === "function") {
- me.onwriteend(new ProgressEvent("writeend", {"target":me}));
- }
- }, "File", "write", [this.fileName, text, this.position]);
-};
-
-/**
- * Moves the file pointer to the location specified.
- *
- * If the offset is a negative number the position of the file
- * pointer is rewound. If the offset is greater than the file
- * size the position is set to the end of the file.
- *
- * @param offset is the location to move the file pointer to.
- */
-FileWriter.prototype.seek = function(offset) {
- // Throw an exception if we are already writing a file
- if (this.readyState === FileWriter.WRITING) {
- throw new FileError(FileError.INVALID_STATE_ERR);
- }
-
- if (!offset && offset !== 0) {
- return;
- }
-
- // See back from end of file.
- if (offset < 0) {
- this.position = Math.max(offset + this.length, 0);
- }
- // Offset is bigger then file size so set position
- // to the end of the file.
- else if (offset > this.length) {
- this.position = this.length;
- }
- // Offset is between 0 and file size so set the position
- // to start writing.
- else {
- this.position = offset;
- }
-};
-
-/**
- * Truncates the file to the size specified.
- *
- * @param size to chop the file at.
- */
-FileWriter.prototype.truncate = function(size) {
- // Throw an exception if we are already writing a file
- if (this.readyState === FileWriter.WRITING) {
- throw new FileError(FileError.INVALID_STATE_ERR);
- }
-
- // WRITING state
- this.readyState = FileWriter.WRITING;
-
- var me = this;
-
- // If onwritestart callback
- if (typeof me.onwritestart === "function") {
- me.onwritestart(new ProgressEvent("writestart", {"target":this}));
- }
-
- // Write file
- exec(
- // Success callback
- function(r) {
- // If DONE (cancelled), then don't do anything
- if (me.readyState === FileWriter.DONE) {
- return;
- }
-
- // DONE state
- me.readyState = FileWriter.DONE;
-
- // Update the length of the file
- me.length = r;
- me.position = Math.min(me.position, r);
-
- // If onwrite callback
- if (typeof me.onwrite === "function") {
- me.onwrite(new ProgressEvent("write", {"target":me}));
- }
-
- // If onwriteend callback
- if (typeof me.onwriteend === "function") {
- me.onwriteend(new ProgressEvent("writeend", {"target":me}));
- }
- },
- // Error callback
- function(e) {
- // If DONE (cancelled), then don't do anything
- if (me.readyState === FileWriter.DONE) {
- return;
- }
-
- // DONE state
- me.readyState = FileWriter.DONE;
-
- // Save error
- me.error = new FileError(e);
-
- // If onerror callback
- if (typeof me.onerror === "function") {
- me.onerror(new ProgressEvent("error", {"target":me}));
- }
-
- // If onwriteend callback
- if (typeof me.onwriteend === "function") {
- me.onwriteend(new ProgressEvent("writeend", {"target":me}));
- }
- }, "File", "truncate", [this.fileName, size]);
-};
-
-module.exports = FileWriter;
-
-});
-
-// file: lib/common/plugin/Flags.js
-define("cordova/plugin/Flags", function(require, exports, module) {
-/**
- * Supplies arguments to methods that lookup or create files and directories.
- *
- * @param create
- * {boolean} file or directory if it doesn't exist
- * @param exclusive
- * {boolean} used with create; if true the command will fail if
- * target path exists
- */
-function Flags(create, exclusive) {
- this.create = create || false;
- this.exclusive = exclusive || false;
-}
-
-module.exports = Flags;
-});
-
-// file: lib/common/plugin/LocalFileSystem.js
-define("cordova/plugin/LocalFileSystem", function(require, exports, module) {
-var exec = require('cordova/exec');
-
-/**
- * Represents a local file system.
- */
-var LocalFileSystem = function() {
-
-};
-
-LocalFileSystem.TEMPORARY = 0; //temporary, with no guarantee of persistence
-LocalFileSystem.PERSISTENT = 1; //persistent
-
-module.exports = LocalFileSystem;
-});
-
-// file: lib/common/plugin/Media.js
-define("cordova/plugin/Media", function(require, exports, module) {
-var utils = require('cordova/utils'),
- exec = require('cordova/exec');
-
-var mediaObjects = {};
-
-/**
- * This class provides access to the device media, interfaces to both sound and video
- *
- * @constructor
- * @param src The file name or url to play
- * @param successCallback The callback to be called when the file is done playing or recording.
- * successCallback()
- * @param errorCallback The callback to be called if there is an error.
- * errorCallback(int errorCode) - OPTIONAL
- * @param statusCallback The callback to be called when media status has changed.
- * statusCallback(int statusCode) - OPTIONAL
- */
-var Media = function(src, successCallback, errorCallback, statusCallback) {
-
- // successCallback optional
- if (successCallback && (typeof successCallback !== "function")) {
- console.log("Media Error: successCallback is not a function");
- return;
- }
-
- // errorCallback optional
- if (errorCallback && (typeof errorCallback !== "function")) {
- console.log("Media Error: errorCallback is not a function");
- return;
- }
-
- // statusCallback optional
- if (statusCallback && (typeof statusCallback !== "function")) {
- console.log("Media Error: statusCallback is not a function");
- return;
- }
-
- this.id = utils.createUUID();
- mediaObjects[this.id] = this;
- this.src = src;
- this.successCallback = successCallback;
- this.errorCallback = errorCallback;
- this.statusCallback = statusCallback;
- this._duration = -1;
- this._position = -1;
- exec(null, this.errorCallback, "Media", "create", [this.id, this.src]);
-};
-
-// Media messages
-Media.MEDIA_STATE = 1;
-Media.MEDIA_DURATION = 2;
-Media.MEDIA_POSITION = 3;
-Media.MEDIA_ERROR = 9;
-
-// Media states
-Media.MEDIA_NONE = 0;
-Media.MEDIA_STARTING = 1;
-Media.MEDIA_RUNNING = 2;
-Media.MEDIA_PAUSED = 3;
-Media.MEDIA_STOPPED = 4;
-Media.MEDIA_MSG = ["None", "Starting", "Running", "Paused", "Stopped"];
-
-// "static" function to return existing objs.
-Media.get = function(id) {
- return mediaObjects[id];
-};
-
-/**
- * Start or resume playing audio file.
- */
-Media.prototype.play = function(options) {
- exec(null, null, "Media", "startPlayingAudio", [this.id, this.src, options]);
-};
-
-/**
- * Stop playing audio file.
- */
-Media.prototype.stop = function() {
- var me = this;
- exec(function() {
- me._position = 0;
- me.successCallback();
- }, this.errorCallback, "Media", "stopPlayingAudio", [this.id]);
-};
-
-/**
- * Seek or jump to a new time in the track..
- */
-Media.prototype.seekTo = function(milliseconds) {
- var me = this;
- exec(function(p) {
- me._position = p;
- }, this.errorCallback, "Media", "seekToAudio", [this.id, milliseconds]);
-};
-
-/**
- * Pause playing audio file.
- */
-Media.prototype.pause = function() {
- exec(null, this.errorCallback, "Media", "pausePlayingAudio", [this.id]);
-};
-
-/**
- * Get duration of an audio file.
- * The duration is only set for audio that is playing, paused or stopped.
- *
- * @return duration or -1 if not known.
- */
-Media.prototype.getDuration = function() {
- return this._duration;
-};
-
-/**
- * Get position of audio.
- */
-Media.prototype.getCurrentPosition = function(success, fail) {
- var me = this;
- exec(function(p) {
- me._position = p;
- success(p);
- }, fail, "Media", "getCurrentPositionAudio", [this.id]);
-};
-
-/**
- * Start recording audio file.
- */
-Media.prototype.startRecord = function() {
- exec(this.successCallback, this.errorCallback, "Media", "startRecordingAudio", [this.id, this.src]);
-};
-
-/**
- * Stop recording audio file.
- */
-Media.prototype.stopRecord = function() {
- exec(this.successCallback, this.errorCallback, "Media", "stopRecordingAudio", [this.id]);
-};
-
-/**
- * Release the resources.
- */
-Media.prototype.release = function() {
- exec(null, this.errorCallback, "Media", "release", [this.id]);
-};
-
-/**
- * Adjust the volume.
- */
-Media.prototype.setVolume = function(volume) {
- exec(null, null, "Media", "setVolume", [this.id, volume]);
-};
-
-/**
- * Audio has status update.
- * PRIVATE
- *
- * @param id The media object id (string)
- * @param status The status code (int)
- * @param msg The status message (string)
- */
-Media.onStatus = function(id, msg, value) {
- var media = mediaObjects[id];
- // If state update
- if (msg === Media.MEDIA_STATE) {
- if (value === Media.MEDIA_STOPPED) {
- if (media.successCallback) {
- media.successCallback();
- }
- }
- if (media.statusCallback) {
- media.statusCallback(value);
- }
- }
- else if (msg === Media.MEDIA_DURATION) {
- media._duration = value;
- }
- else if (msg === Media.MEDIA_ERROR) {
- if (media.errorCallback) {
- // value should be a MediaError object when msg == MEDIA_ERROR
- media.errorCallback(value);
- }
- }
- else if (msg === Media.MEDIA_POSITION) {
- media._position = value;
- }
-};
-
-module.exports = Media;
-});
-
-// file: lib/common/plugin/MediaError.js
-define("cordova/plugin/MediaError", function(require, exports, module) {
-/**
- * This class contains information about any Media errors.
- * @constructor
- */
-var MediaError = function(code, msg) {
- this.code = (code !== undefined ? code : null);
- this.message = msg || "";
-};
-
-MediaError.MEDIA_ERR_NONE_ACTIVE = 0;
-MediaError.MEDIA_ERR_ABORTED = 1;
-MediaError.MEDIA_ERR_NETWORK = 2;
-MediaError.MEDIA_ERR_DECODE = 3;
-MediaError.MEDIA_ERR_NONE_SUPPORTED = 4;
-
-module.exports = MediaError;
-});
-
-// file: lib/common/plugin/MediaFile.js
-define("cordova/plugin/MediaFile", function(require, exports, module) {
-var utils = require('cordova/utils'),
- exec = require('cordova/exec'),
- File = require('cordova/plugin/File'),
- CaptureError = require('cordova/plugin/CaptureError');
-/**
- * Represents a single file.
- *
- * name {DOMString} name of the file, without path information
- * fullPath {DOMString} the full path of the file, including the name
- * type {DOMString} mime type
- * lastModifiedDate {Date} last modified date
- * size {Number} size of the file in bytes
- */
-var MediaFile = function(name, fullPath, type, lastModifiedDate, size){
- MediaFile.__super__.constructor.apply(this, arguments);
-};
-
-utils.extend(MediaFile, File);
-
-/**
- * Request capture format data for a specific file and type
- *
- * @param {Function} successCB
- * @param {Function} errorCB
- */
-MediaFile.prototype.getFormatData = function(successCallback, errorCallback) {
- if (typeof this.fullPath === "undefined" || this.fullPath === null) {
- errorCallback(new CaptureError(CaptureError.CAPTURE_INVALID_ARGUMENT));
- } else {
- exec(successCallback, errorCallback, "Capture", "getFormatData", [this.fullPath, this.type]);
- }
-};
-
-// TODO: can we axe this?
-/**
- * Casts a PluginResult message property (array of objects) to an array of MediaFile objects
- * (used in Objective-C and Android)
- *
- * @param {PluginResult} pluginResult
- */
-MediaFile.cast = function(pluginResult) {
- var mediaFiles = [];
- for (var i=0; i.dispatchEvent
- // need to first figure out how to implement EventTarget
- }
- }
- return event;
- };
- try {
- var ev = createEvent({type:"abort",target:document});
- return function ProgressEvent(type, data) {
- data.type = type;
- return createEvent(data);
- };
- } catch(e){
- */
- return function ProgressEvent(type, dict) {
- this.type = type;
- this.bubbles = false;
- this.cancelBubble = false;
- this.cancelable = false;
- this.lengthComputable = false;
- this.loaded = dict && dict.loaded ? dict.loaded : 0;
- this.total = dict && dict.total ? dict.total : 0;
- this.target = dict && dict.target ? dict.target : null;
- };
- //}
-})();
-
-module.exports = ProgressEvent;
-});
-
-// file: lib/common/plugin/accelerometer.js
-define("cordova/plugin/accelerometer", function(require, exports, module) {
-/**
- * This class provides access to device accelerometer data.
- * @constructor
- */
-var utils = require("cordova/utils"),
- exec = require("cordova/exec"),
- Acceleration = require('cordova/plugin/Acceleration');
-
-// Is the accel sensor running?
-var running = false;
-
-// Keeps reference to watchAcceleration calls.
-var timers = {};
-
-// Array of listeners; used to keep track of when we should call start and stop.
-var listeners = [];
-
-// Last returned acceleration object from native
-var accel = null;
-
-// Tells native to start.
-function start() {
- exec(function(a) {
- var tempListeners = listeners.slice(0);
- accel = new Acceleration(a.x, a.y, a.z, a.timestamp);
- for (var i = 0, l = tempListeners.length; i < l; i++) {
- tempListeners[i].win(accel);
- }
- }, function(e) {
- var tempListeners = listeners.slice(0);
- for (var i = 0, l = tempListeners.length; i < l; i++) {
- tempListeners[i].fail(e);
- }
- }, "Accelerometer", "start", []);
- running = true;
-}
-
-// Tells native to stop.
-function stop() {
- exec(null, null, "Accelerometer", "stop", []);
- running = false;
-}
-
-// Adds a callback pair to the listeners array
-function createCallbackPair(win, fail) {
- return {win:win, fail:fail};
-}
-
-// Removes a win/fail listener pair from the listeners array
-function removeListeners(l) {
- var idx = listeners.indexOf(l);
- if (idx > -1) {
- listeners.splice(idx, 1);
- if (listeners.length === 0) {
- stop();
- }
- }
-}
-
-var accelerometer = {
- /**
- * Asynchronously aquires the current acceleration.
- *
- * @param {Function} successCallback The function to call when the acceleration data is available
- * @param {Function} errorCallback The function to call when there is an error getting the acceleration data. (OPTIONAL)
- * @param {AccelerationOptions} options The options for getting the accelerometer data such as timeout. (OPTIONAL)
- */
- getCurrentAcceleration: function(successCallback, errorCallback, options) {
- // successCallback required
- if (typeof successCallback !== "function") {
- throw "getCurrentAcceleration must be called with at least a success callback function as first parameter.";
- }
-
- var p;
- var win = function(a) {
- successCallback(a);
- removeListeners(p);
- };
- var fail = function(e) {
- errorCallback(e);
- removeListeners(p);
- };
-
- p = createCallbackPair(win, fail);
- listeners.push(p);
-
- if (!running) {
- start();
- }
- },
-
- /**
- * Asynchronously aquires the acceleration repeatedly at a given interval.
- *
- * @param {Function} successCallback The function to call each time the acceleration data is available
- * @param {Function} errorCallback The function to call when there is an error getting the acceleration data. (OPTIONAL)
- * @param {AccelerationOptions} options The options for getting the accelerometer data such as timeout. (OPTIONAL)
- * @return String The watch id that must be passed to #clearWatch to stop watching.
- */
- watchAcceleration: function(successCallback, errorCallback, options) {
- // Default interval (10 sec)
- var frequency = (options && options.frequency && typeof options.frequency == 'number') ? options.frequency : 10000;
-
- // successCallback required
- if (typeof successCallback !== "function") {
- throw "watchAcceleration must be called with at least a success callback function as first parameter.";
- }
-
- // Keep reference to watch id, and report accel readings as often as defined in frequency
- var id = utils.createUUID();
-
- var p = createCallbackPair(function(){}, function(e) {
- errorCallback(e);
- removeListeners(p);
- });
- listeners.push(p);
-
- timers[id] = {
- timer:window.setInterval(function() {
- if (accel) {
- successCallback(accel);
- }
- }, frequency),
- listeners:p
- };
-
- if (running) {
- // If we're already running then immediately invoke the success callback
- successCallback(accel);
- } else {
- start();
- }
-
- return id;
- },
-
- /**
- * Clears the specified accelerometer watch.
- *
- * @param {String} id The id of the watch returned from #watchAcceleration.
- */
- clearWatch: function(id) {
- // Stop javascript timer & remove from timer list
- if (id && timers[id]) {
- window.clearInterval(timers[id].timer);
- removeListeners(timers[id].listeners);
- delete timers[id];
- }
- }
-};
-
-module.exports = accelerometer;
-
-});
-
-// file: lib/common/plugin/battery.js
-define("cordova/plugin/battery", function(require, exports, module) {
-/**
- * This class contains information about the current battery status.
- * @constructor
- */
-var cordova = require('cordova'),
- exec = require('cordova/exec');
-
-function handlers() {
- return battery.channels.batterystatus.numHandlers +
- battery.channels.batterylow.numHandlers +
- battery.channels.batterycritical.numHandlers;
-}
-
-var Battery = function() {
- this._level = null;
- this._isPlugged = null;
- // Create new event handlers on the window (returns a channel instance)
- var subscriptionEvents = {
- onSubscribe:this.onSubscribe,
- onUnsubscribe:this.onUnsubscribe
- };
- this.channels = {
- batterystatus:cordova.addWindowEventHandler("batterystatus", subscriptionEvents),
- batterylow:cordova.addWindowEventHandler("batterylow", subscriptionEvents),
- batterycritical:cordova.addWindowEventHandler("batterycritical", subscriptionEvents)
- };
-};
-/**
- * Event handlers for when callbacks get registered for the battery.
- * Keep track of how many handlers we have so we can start and stop the native battery listener
- * appropriately (and hopefully save on battery life!).
- */
-Battery.prototype.onSubscribe = function() {
- var me = battery;
- // If we just registered the first handler, make sure native listener is started.
- if (handlers() === 1) {
- exec(me._status, me._error, "Battery", "start", []);
- }
-};
-
-Battery.prototype.onUnsubscribe = function() {
- var me = battery;
-
- // If we just unregistered the last handler, make sure native listener is stopped.
- if (handlers() === 0) {
- exec(null, null, "Battery", "stop", []);
- }
-};
-
-/**
- * Callback for battery status
- *
- * @param {Object} info keys: level, isPlugged
- */
-Battery.prototype._status = function(info) {
- if (info) {
- var me = battery;
- var level = info.level;
- if (me._level !== level || me._isPlugged !== info.isPlugged) {
- // Fire batterystatus event
- cordova.fireWindowEvent("batterystatus", info);
-
- // Fire low battery event
- if (level === 20 || level === 5) {
- if (level === 20) {
- cordova.fireWindowEvent("batterylow", info);
- }
- else {
- cordova.fireWindowEvent("batterycritical", info);
- }
- }
- }
- me._level = level;
- me._isPlugged = info.isPlugged;
- }
-};
-
-/**
- * Error callback for battery start
- */
-Battery.prototype._error = function(e) {
- console.log("Error initializing Battery: " + e);
-};
-
-var battery = new Battery();
-
-module.exports = battery;
-});
-
-// file: lib/common/plugin/capture.js
-define("cordova/plugin/capture", function(require, exports, module) {
-var exec = require('cordova/exec'),
- MediaFile = require('cordova/plugin/MediaFile');
-
-/**
- * Launches a capture of different types.
- *
- * @param (DOMString} type
- * @param {Function} successCB
- * @param {Function} errorCB
- * @param {CaptureVideoOptions} options
- */
-function _capture(type, successCallback, errorCallback, options) {
- var win = function(pluginResult) {
- var mediaFiles = [];
- var i;
- for (i = 0; i < pluginResult.length; i++) {
- var mediaFile = new MediaFile();
- mediaFile.name = pluginResult[i].name;
- mediaFile.fullPath = pluginResult[i].fullPath;
- mediaFile.type = pluginResult[i].type;
- mediaFile.lastModifiedDate = pluginResult[i].lastModifiedDate;
- mediaFile.size = pluginResult[i].size;
- mediaFiles.push(mediaFile);
- }
- successCallback(mediaFiles);
- };
- exec(win, errorCallback, "Capture", type, [options]);
-}
-/**
- * The Capture interface exposes an interface to the camera and microphone of the hosting device.
- */
-function Capture() {
- this.supportedAudioModes = [];
- this.supportedImageModes = [];
- this.supportedVideoModes = [];
-}
-
-/**
- * Launch audio recorder application for recording audio clip(s).
- *
- * @param {Function} successCB
- * @param {Function} errorCB
- * @param {CaptureAudioOptions} options
- */
-Capture.prototype.captureAudio = function(successCallback, errorCallback, options){
- _capture("captureAudio", successCallback, errorCallback, options);
-};
-
-/**
- * Launch camera application for taking image(s).
- *
- * @param {Function} successCB
- * @param {Function} errorCB
- * @param {CaptureImageOptions} options
- */
-Capture.prototype.captureImage = function(successCallback, errorCallback, options){
- _capture("captureImage", successCallback, errorCallback, options);
-};
-
-/**
- * Launch device camera application for recording video(s).
- *
- * @param {Function} successCB
- * @param {Function} errorCB
- * @param {CaptureVideoOptions} options
- */
-Capture.prototype.captureVideo = function(successCallback, errorCallback, options){
- _capture("captureVideo", successCallback, errorCallback, options);
-};
-
-
-module.exports = new Capture();
-
-});
-
-// file: lib/common/plugin/compass.js
-define("cordova/plugin/compass", function(require, exports, module) {
-var exec = require('cordova/exec'),
- utils = require('cordova/utils'),
- CompassHeading = require('cordova/plugin/CompassHeading'),
- CompassError = require('cordova/plugin/CompassError'),
- timers = {},
- compass = {
- /**
- * Asynchronously acquires the current heading.
- * @param {Function} successCallback The function to call when the heading
- * data is available
- * @param {Function} errorCallback The function to call when there is an error
- * getting the heading data.
- * @param {CompassOptions} options The options for getting the heading data (not used).
- */
- getCurrentHeading:function(successCallback, errorCallback, options) {
- // successCallback required
- if (typeof successCallback !== "function") {
- console.log("Compass Error: successCallback is not a function");
- return;
- }
-
- // errorCallback optional
- if (errorCallback && (typeof errorCallback !== "function")) {
- console.log("Compass Error: errorCallback is not a function");
- return;
- }
-
- var win = function(result) {
- var ch = new CompassHeading(result.magneticHeading, result.trueHeading, result.headingAccuracy, result.timestamp);
- successCallback(ch);
- };
- var fail = function(code) {
- var ce = new CompassError(code);
- errorCallback(ce);
- };
-
- // Get heading
- exec(win, fail, "Compass", "getHeading", [options]);
- },
-
- /**
- * Asynchronously acquires the heading repeatedly at a given interval.
- * @param {Function} successCallback The function to call each time the heading
- * data is available
- * @param {Function} errorCallback The function to call when there is an error
- * getting the heading data.
- * @param {HeadingOptions} options The options for getting the heading data
- * such as timeout and the frequency of the watch. For iOS, filter parameter
- * specifies to watch via a distance filter rather than time.
- */
- watchHeading:function(successCallback, errorCallback, options) {
- // Default interval (100 msec)
- var frequency = (options !== undefined && options.frequency !== undefined) ? options.frequency : 100;
- var filter = (options !== undefined && options.filter !== undefined) ? options.filter : 0;
-
- // successCallback required
- if (typeof successCallback !== "function") {
- console.log("Compass Error: successCallback is not a function");
- return;
- }
-
- // errorCallback optional
- if (errorCallback && (typeof errorCallback !== "function")) {
- console.log("Compass Error: errorCallback is not a function");
- return;
- }
-
- var id = utils.createUUID();
- if (filter > 0) {
- // is an iOS request for watch by filter, no timer needed
- timers[id] = "iOS";
- compass.getCurrentHeading(successCallback, errorCallback, options);
- } else {
- // Start watch timer to get headings
- timers[id] = window.setInterval(function() {
- compass.getCurrentHeading(successCallback, errorCallback);
- }, frequency);
- }
-
- return id;
- },
-
- /**
- * Clears the specified heading watch.
- * @param {String} watchId The ID of the watch returned from #watchHeading.
- */
- clearWatch:function(id) {
- // Stop javascript timer & remove from timer list
- if (id && timers[id]) {
- if (timers[id] != "iOS") {
- clearInterval(timers[id]);
- } else {
- // is iOS watch by filter so call into device to stop
- exec(null, null, "Compass", "stopHeading", []);
- }
- delete timers[id];
- }
- }
- };
-
-module.exports = compass;
-});
-
-// file: lib/common/plugin/console-via-logger.js
-define("cordova/plugin/console-via-logger", function(require, exports, module) {
-//------------------------------------------------------------------------------
-
-var logger = require("cordova/plugin/logger");
-var utils = require("cordova/utils");
-
-//------------------------------------------------------------------------------
-// object that we're exporting
-//------------------------------------------------------------------------------
-var console = module.exports;
-
-//------------------------------------------------------------------------------
-// copy of the original console object
-//------------------------------------------------------------------------------
-var WinConsole = window.console;
-
-//------------------------------------------------------------------------------
-// whether to use the logger
-//------------------------------------------------------------------------------
-var UseLogger = false;
-
-//------------------------------------------------------------------------------
-// Timers
-//------------------------------------------------------------------------------
-var Timers = {};
-
-//------------------------------------------------------------------------------
-// used for unimplemented methods
-//------------------------------------------------------------------------------
-function noop() {}
-
-//------------------------------------------------------------------------------
-// used for unimplemented methods
-//------------------------------------------------------------------------------
-console.useLogger = function (value) {
- if (arguments.length) UseLogger = !!value;
-
- if (UseLogger) {
- if (logger.useConsole()) {
- throw new Error("console and logger are too intertwingly");
- }
- }
-
- return UseLogger;
-};
-
-//------------------------------------------------------------------------------
-console.log = function() {
- if (logger.useConsole()) return;
- logger.log.apply(logger, [].slice.call(arguments));
-};
-
-//------------------------------------------------------------------------------
-console.error = function() {
- if (logger.useConsole()) return;
- logger.error.apply(logger, [].slice.call(arguments));
-};
-
-//------------------------------------------------------------------------------
-console.warn = function() {
- if (logger.useConsole()) return;
- logger.warn.apply(logger, [].slice.call(arguments));
-};
-
-//------------------------------------------------------------------------------
-console.info = function() {
- if (logger.useConsole()) return;
- logger.info.apply(logger, [].slice.call(arguments));
-};
-
-//------------------------------------------------------------------------------
-console.debug = function() {
- if (logger.useConsole()) return;
- logger.debug.apply(logger, [].slice.call(arguments));
-};
-
-//------------------------------------------------------------------------------
-console.assert = function(expression) {
- if (expression) return;
-
- var message = utils.vformat(arguments[1], [].slice.call(arguments, 2));
- console.log("ASSERT: " + message);
-};
-
-//------------------------------------------------------------------------------
-console.clear = function() {};
-
-//------------------------------------------------------------------------------
-console.dir = function(object) {
- console.log("%o", object);
-};
-
-//------------------------------------------------------------------------------
-console.dirxml = function(node) {
- console.log(node.innerHTML);
-};
-
-//------------------------------------------------------------------------------
-console.trace = noop;
-
-//------------------------------------------------------------------------------
-console.group = console.log;
-
-//------------------------------------------------------------------------------
-console.groupCollapsed = console.log;
-
-//------------------------------------------------------------------------------
-console.groupEnd = noop;
-
-//------------------------------------------------------------------------------
-console.time = function(name) {
- Timers[name] = new Date().valueOf();
-};
-
-//------------------------------------------------------------------------------
-console.timeEnd = function(name) {
- var timeStart = Timers[name];
- if (!timeStart) {
- console.warn("unknown timer: " + name);
- return;
- }
-
- var timeElapsed = new Date().valueOf() - timeStart;
- console.log(name + ": " + timeElapsed + "ms");
-};
-
-//------------------------------------------------------------------------------
-console.timeStamp = noop;
-
-//------------------------------------------------------------------------------
-console.profile = noop;
-
-//------------------------------------------------------------------------------
-console.profileEnd = noop;
-
-//------------------------------------------------------------------------------
-console.count = noop;
-
-//------------------------------------------------------------------------------
-console.exception = console.log;
-
-//------------------------------------------------------------------------------
-console.table = function(data, columns) {
- console.log("%o", data);
-};
-
-//------------------------------------------------------------------------------
-// return a new function that calls both functions passed as args
-//------------------------------------------------------------------------------
-function wrapperedOrigCall(orgFunc, newFunc) {
- return function() {
- var args = [].slice.call(arguments);
- try { orgFunc.apply(WinConsole, args); } catch (e) {}
- try { newFunc.apply(console, args); } catch (e) {}
- };
-}
-
-//------------------------------------------------------------------------------
-// For every function that exists in the original console object, that
-// also exists in the new console object, wrap the new console method
-// with one that calls both
-//------------------------------------------------------------------------------
-for (var key in console) {
- if (typeof WinConsole[key] == "function") {
- console[key] = wrapperedOrigCall(WinConsole[key], console[key]);
- }
-}
-
-});
-
-// file: lib/common/plugin/contacts.js
-define("cordova/plugin/contacts", function(require, exports, module) {
-var exec = require('cordova/exec'),
- ContactError = require('cordova/plugin/ContactError'),
- utils = require('cordova/utils'),
- Contact = require('cordova/plugin/Contact');
-
-/**
-* Represents a group of Contacts.
-* @constructor
-*/
-var contacts = {
- /**
- * Returns an array of Contacts matching the search criteria.
- * @param fields that should be searched
- * @param successCB success callback
- * @param errorCB error callback
- * @param {ContactFindOptions} options that can be applied to contact searching
- * @return array of Contacts matching search criteria
- */
- find:function(fields, successCB, errorCB, options) {
- if (!successCB) {
- throw new TypeError("You must specify a success callback for the find command.");
- }
- if (!fields || (utils.isArray(fields) && fields.length === 0)) {
- if (typeof errorCB === "function") {
- errorCB(new ContactError(ContactError.INVALID_ARGUMENT_ERROR));
- }
- } else {
- var win = function(result) {
- var cs = [];
- for (var i = 0, l = result.length; i < l; i++) {
- cs.push(contacts.create(result[i]));
- }
- successCB(cs);
- };
- exec(win, errorCB, "Contacts", "search", [fields, options]);
- }
- },
-
- /**
- * This function creates a new contact, but it does not persist the contact
- * to device storage. To persist the contact to device storage, invoke
- * contact.save().
- * @param properties an object who's properties will be examined to create a new Contact
- * @returns new Contact object
- */
- create:function(properties) {
- var i;
- var contact = new Contact();
- for (i in properties) {
- if (typeof contact[i] !== 'undefined' && properties.hasOwnProperty(i)) {
- contact[i] = properties[i];
- }
- }
- return contact;
- }
-};
-
-module.exports = contacts;
-
-});
-
-// file: lib/common/plugin/geolocation.js
-define("cordova/plugin/geolocation", function(require, exports, module) {
-var utils = require('cordova/utils'),
- exec = require('cordova/exec'),
- PositionError = require('cordova/plugin/PositionError'),
- Position = require('cordova/plugin/Position');
-
-var timers = {}; // list of timers in use
-
-// Returns default params, overrides if provided with values
-function parseParameters(options) {
- var opt = {
- maximumAge: 0,
- enableHighAccuracy: false,
- timeout: Infinity
- };
-
- if (options) {
- if (options.maximumAge !== undefined && !isNaN(options.maximumAge) && options.maximumAge > 0) {
- opt.maximumAge = options.maximumAge;
- }
- if (options.enableHighAccuracy !== undefined) {
- opt.enableHighAccuracy = options.enableHighAccuracy;
- }
- if (options.timeout !== undefined && !isNaN(options.timeout)) {
- if (options.timeout < 0) {
- opt.timeout = 0;
- } else {
- opt.timeout = options.timeout;
- }
- }
- }
-
- return opt;
-}
-
-// Returns a timeout failure, closed over a specified timeout value and error callback.
-function createTimeout(errorCallback, timeout) {
- var t = setTimeout(function() {
- clearTimeout(t);
- t = null;
- errorCallback({
- code:PositionError.TIMEOUT,
- message:"Position retrieval timed out."
- });
- }, timeout);
- return t;
-}
-
-var geolocation = {
- lastPosition:null, // reference to last known (cached) position returned
- /**
- * Asynchronously aquires the current position.
- *
- * @param {Function} successCallback The function to call when the position data is available
- * @param {Function} errorCallback The function to call when there is an error getting the heading position. (OPTIONAL)
- * @param {PositionOptions} options The options for getting the position data. (OPTIONAL)
- */
- getCurrentPosition:function(successCallback, errorCallback, options) {
- if (arguments.length === 0) {
- throw new Error("getCurrentPosition must be called with at least one argument.");
- }
- options = parseParameters(options);
-
- // Timer var that will fire an error callback if no position is retrieved from native
- // before the "timeout" param provided expires
- var timeoutTimer = null;
-
- var win = function(p) {
- clearTimeout(timeoutTimer);
- if (!timeoutTimer) {
- // Timeout already happened, or native fired error callback for
- // this geo request.
- // Don't continue with success callback.
- return;
- }
- var pos = new Position(
- {
- latitude:p.latitude,
- longitude:p.longitude,
- altitude:p.altitude,
- accuracy:p.accuracy,
- heading:p.heading,
- velocity:p.velocity,
- altitudeAccuracy:p.altitudeAccuracy
- },
- (p.timestamp === undefined ? new Date() : ((p.timestamp instanceof Date) ? p.timestamp : new Date(p.timestamp)))
- );
- geolocation.lastPosition = pos;
- successCallback(pos);
- };
- var fail = function(e) {
- clearTimeout(timeoutTimer);
- timeoutTimer = null;
- var err = new PositionError(e.code, e.message);
- if (errorCallback) {
- errorCallback(err);
- }
- };
-
- // Check our cached position, if its timestamp difference with current time is less than the maximumAge, then just
- // fire the success callback with the cached position.
- if (geolocation.lastPosition && options.maximumAge && (((new Date()).getTime() - geolocation.lastPosition.timestamp.getTime()) <= options.maximumAge)) {
- successCallback(geolocation.lastPosition);
- // If the cached position check failed and the timeout was set to 0, error out with a TIMEOUT error object.
- } else if (options.timeout === 0) {
- fail({
- code:PositionError.TIMEOUT,
- message:"timeout value in PositionOptions set to 0 and no cached Position object available, or cached Position object's age exceed's provided PositionOptions' maximumAge parameter."
- });
- // Otherwise we have to call into native to retrieve a position.
- } else {
- if (options.timeout !== Infinity) {
- // If the timeout value was not set to Infinity (default), then
- // set up a timeout function that will fire the error callback
- // if no successful position was retrieved before timeout expired.
- timeoutTimer = createTimeout(fail, options.timeout);
- } else {
- // This is here so the check in the win function doesn't mess stuff up
- // may seem weird but this guarantees timeoutTimer is
- // always truthy before we call into native
- timeoutTimer = true;
- }
- exec(win, fail, "Geolocation", "getLocation", [options.enableHighAccuracy, options.maximumAge]);
- }
- return timeoutTimer;
- },
- /**
- * Asynchronously watches the geolocation for changes to geolocation. When a change occurs,
- * the successCallback is called with the new location.
- *
- * @param {Function} successCallback The function to call each time the location data is available
- * @param {Function} errorCallback The function to call when there is an error getting the location data. (OPTIONAL)
- * @param {PositionOptions} options The options for getting the location data such as frequency. (OPTIONAL)
- * @return String The watch id that must be passed to #clearWatch to stop watching.
- */
- watchPosition:function(successCallback, errorCallback, options) {
- if (arguments.length === 0) {
- throw new Error("watchPosition must be called with at least one argument.");
- }
- options = parseParameters(options);
-
- var id = utils.createUUID();
-
- // Tell device to get a position ASAP, and also retrieve a reference to the timeout timer generated in getCurrentPosition
- timers[id] = geolocation.getCurrentPosition(successCallback, errorCallback, options);
-
- var fail = function(e) {
- clearTimeout(timers[id]);
- var err = new PositionError(e.code, e.message);
- if (errorCallback) {
- errorCallback(err);
- }
- };
-
- var win = function(p) {
- clearTimeout(timers[id]);
- if (options.timeout !== Infinity) {
- timers[id] = createTimeout(fail, options.timeout);
- }
- var pos = new Position(
- {
- latitude:p.latitude,
- longitude:p.longitude,
- altitude:p.altitude,
- accuracy:p.accuracy,
- heading:p.heading,
- velocity:p.velocity,
- altitudeAccuracy:p.altitudeAccuracy
- },
- (p.timestamp === undefined ? new Date() : ((p.timestamp instanceof Date) ? p.timestamp : new Date(p.timestamp)))
- );
- geolocation.lastPosition = pos;
- successCallback(pos);
- };
-
- exec(win, fail, "Geolocation", "addWatch", [id, options.enableHighAccuracy]);
-
- return id;
- },
- /**
- * Clears the specified heading watch.
- *
- * @param {String} id The ID of the watch returned from #watchPosition
- */
- clearWatch:function(id) {
- if (id && timers[id] !== undefined) {
- clearTimeout(timers[id]);
- delete timers[id];
- exec(null, null, "Geolocation", "clearWatch", [id]);
- }
- }
-};
-
-module.exports = geolocation;
-
-});
-
-// file: lib/ios/plugin/ios/Contact.js
-define("cordova/plugin/ios/Contact", function(require, exports, module) {
-var exec = require('cordova/exec'),
- ContactError = require('cordova/plugin/ContactError');
-
-/**
- * Provides iOS Contact.display API.
- */
-module.exports = {
- display : function(errorCB, options) {
- /*
- * Display a contact using the iOS Contact Picker UI
- * NOT part of W3C spec so no official documentation
- *
- * @param errorCB error callback
- * @param options object
- * allowsEditing: boolean AS STRING
- * "true" to allow editing the contact
- * "false" (default) display contact
- */
-
- if (this.id === null) {
- if (typeof errorCB === "function") {
- var errorObj = new ContactError(ContactError.UNKNOWN_ERROR);
- errorCB(errorObj);
- }
- }
- else {
- exec(null, errorCB, "Contacts","displayContact", [this.id, options]);
- }
- }
-};
-});
-
-// file: lib/ios/plugin/ios/Entry.js
-define("cordova/plugin/ios/Entry", function(require, exports, module) {
-module.exports = {
- toURL:function() {
- // TODO: refactor path in a cross-platform way so we can eliminate
- // these kinds of platform-specific hacks.
- return "file://localhost" + this.fullPath;
- },
- toURI: function() {
- console.log("DEPRECATED: Update your code to use 'toURL'");
- return "file://localhost" + this.fullPath;
- }
-};
-});
-
-// file: lib/ios/plugin/ios/FileReader.js
-define("cordova/plugin/ios/FileReader", function(require, exports, module) {
-var exec = require('cordova/exec'),
- FileError = require('cordova/plugin/FileError'),
- FileReader = require('cordova/plugin/FileReader'),
- ProgressEvent = require('cordova/plugin/ProgressEvent');
-
-module.exports = {
- readAsText:function(file, encoding) {
- // Figure out pathing
- this.fileName = '';
- if (typeof file.fullPath === 'undefined') {
- this.fileName = file;
- } else {
- this.fileName = file.fullPath;
- }
-
- // Already loading something
- if (this.readyState == FileReader.LOADING) {
- throw new FileError(FileError.INVALID_STATE_ERR);
- }
-
- // LOADING state
- this.readyState = FileReader.LOADING;
-
- // If loadstart callback
- if (typeof this.onloadstart === "function") {
- this.onloadstart(new ProgressEvent("loadstart", {target:this}));
- }
-
- // Default encoding is UTF-8
- var enc = encoding ? encoding : "UTF-8";
-
- var me = this;
-
- // Read file
- exec(
- // Success callback
- function(r) {
- // If DONE (cancelled), then don't do anything
- if (me.readyState === FileReader.DONE) {
- return;
- }
-
- // Save result
- me.result = decodeURIComponent(r);
-
- // If onload callback
- if (typeof me.onload === "function") {
- me.onload(new ProgressEvent("load", {target:me}));
- }
-
- // DONE state
- me.readyState = FileReader.DONE;
-
- // If onloadend callback
- if (typeof me.onloadend === "function") {
- me.onloadend(new ProgressEvent("loadend", {target:me}));
- }
- },
- // Error callback
- function(e) {
- // If DONE (cancelled), then don't do anything
- if (me.readyState === FileReader.DONE) {
- return;
- }
-
- // DONE state
- me.readyState = FileReader.DONE;
-
- // null result
- me.result = null;
-
- // Save error
- me.error = new FileError(e);
-
- // If onerror callback
- if (typeof me.onerror === "function") {
- me.onerror(new ProgressEvent("error", {target:me}));
- }
-
- // If onloadend callback
- if (typeof me.onloadend === "function") {
- me.onloadend(new ProgressEvent("loadend", {target:me}));
- }
- },
- "File", "readAsText", [this.fileName, enc]);
- }
-};
-});
-
-// file: lib/ios/plugin/ios/console.js
-define("cordova/plugin/ios/console", function(require, exports, module) {
-var exec = require('cordova/exec');
-
-/**
- * This class provides access to the debugging console.
- * @constructor
- */
-var DebugConsole = function() {
- this.winConsole = window.console;
- this.logLevel = DebugConsole.INFO_LEVEL;
-};
-
-// from most verbose, to least verbose
-DebugConsole.ALL_LEVEL = 1; // same as first level
-DebugConsole.INFO_LEVEL = 1;
-DebugConsole.WARN_LEVEL = 2;
-DebugConsole.ERROR_LEVEL = 4;
-DebugConsole.NONE_LEVEL = 8;
-
-DebugConsole.prototype.setLevel = function(level) {
- this.logLevel = level;
-};
-
-var stringify = function(message) {
- try {
- if (typeof message === "object" && JSON && JSON.stringify) {
- try {
- return JSON.stringify(message);
- }
- catch (e) {
- return "error JSON.stringify()ing argument: " + e;
- }
- } else {
- return message.toString();
- }
- } catch (e) {
- return e.toString();
- }
-};
-
-/**
- * Print a normal log message to the console
- * @param {Object|String} message Message or object to print to the console
- */
-DebugConsole.prototype.log = function(message) {
- if (this.logLevel <= DebugConsole.INFO_LEVEL) {
- exec(null, null, 'Debug Console', 'log', [ stringify(message), { logLevel: 'INFO' } ]);
- }
- else if (this.winConsole && this.winConsole.log) {
- this.winConsole.log(message);
- }
-};
-
-/**
- * Print a warning message to the console
- * @param {Object|String} message Message or object to print to the console
- */
-DebugConsole.prototype.warn = function(message) {
- if (this.logLevel <= DebugConsole.WARN_LEVEL) {
- exec(null, null, 'Debug Console', 'log', [ stringify(message), { logLevel: 'WARN' } ]);
- }
- else if (this.winConsole && this.winConsole.warn) {
- this.winConsole.warn(message);
- }
-};
-
-/**
- * Print an error message to the console
- * @param {Object|String} message Message or object to print to the console
- */
-DebugConsole.prototype.error = function(message) {
- if (this.logLevel <= DebugConsole.ERROR_LEVEL) {
- exec(null, null, 'Debug Console', 'log', [ stringify(message), { logLevel: 'ERROR' } ]);
- }
- else if (this.winConsole && this.winConsole.error){
- this.winConsole.error(message);
- }
-};
-
-module.exports = new DebugConsole();
-});
-
-// file: lib/ios/plugin/ios/contacts.js
-define("cordova/plugin/ios/contacts", function(require, exports, module) {
-var exec = require('cordova/exec');
-
-/**
- * Provides iOS enhanced contacts API.
- */
-module.exports = {
- newContactUI : function(successCallback) {
- /*
- * Create a contact using the iOS Contact Picker UI
- * NOT part of W3C spec so no official documentation
- *
- * returns: the id of the created contact as param to successCallback
- */
- exec(successCallback, null, "Contacts","newContact", []);
- },
- chooseContact : function(successCallback, options) {
- /*
- * Select a contact using the iOS Contact Picker UI
- * NOT part of W3C spec so no official documentation
- *
- * @param errorCB error callback
- * @param options object
- * allowsEditing: boolean AS STRING
- * "true" to allow editing the contact
- * "false" (default) display contact
- *
- * returns: the id of the selected contact as param to successCallback
- */
- exec(successCallback, null, "Contacts","chooseContact", [options]);
- }
-};
-});
-
-// file: lib/ios/plugin/ios/device.js
-define("cordova/plugin/ios/device", function(require, exports, module) {
-/**
- * this represents the mobile device, and provides properties for inspecting the model, version, UUID of the
- * phone, etc.
- * @constructor
- */
-var exec = require('cordova/exec'),
- utils = require('cordova/utils'),
- channel = require('cordova/channel');
-
-var Device = function() {
- this.platform = null;
- this.version = null;
- this.name = null;
- this.cordova = null;
- this.uuid = null;
-};
-
-Device.prototype.setInfo = function(info) {
- try {
- this.platform = info.platform;
- this.version = info.version;
- this.name = info.name;
- this.cordova = info.cordova;
- this.uuid = info.uuid;
- channel.onCordovaInfoReady.fire();
- } catch(e) {
- utils.alert('Error during device info setting in cordova/plugin/ios/device!');
- }
-};
-
-module.exports = new Device();
-
-});
-
-// file: lib/ios/plugin/ios/nativecomm.js
-define("cordova/plugin/ios/nativecomm", function(require, exports, module) {
-var cordova = require('cordova');
-
-/**
- * Called by native code to retrieve all queued commands and clear the queue.
- */
-module.exports = function() {
- var json = JSON.stringify(cordova.commandQueue);
- cordova.commandQueue = [];
- return json;
-};
-});
-
-// file: lib/ios/plugin/ios/notification.js
-define("cordova/plugin/ios/notification", function(require, exports, module) {
-var Media = require('cordova/plugin/Media');
-
-module.exports = {
- beep:function(count) {
- (new Media('beep.wav')).play();
- }
-};
-});
-
-// file: lib/common/plugin/logger.js
-define("cordova/plugin/logger", function(require, exports, module) {
-//------------------------------------------------------------------------------
-// The logger module exports the following properties/functions:
-//
-// LOG - constant for the level LOG
-// ERROR - constant for the level ERROR
-// WARN - constant for the level WARN
-// INFO - constant for the level INFO
-// DEBUG - constant for the level DEBUG
-// logLevel() - returns current log level
-// logLevel(value) - sets and returns a new log level
-// useConsole() - returns whether logger is using console
-// useConsole(value) - sets and returns whether logger is using console
-// log(message,...) - logs a message at level LOG
-// error(message,...) - logs a message at level ERROR
-// warn(message,...) - logs a message at level WARN
-// info(message,...) - logs a message at level INFO
-// debug(message,...) - logs a message at level DEBUG
-// logLevel(level,message,...) - logs a message specified level
-//
-//------------------------------------------------------------------------------
-
-var logger = exports;
-
-var exec = require('cordova/exec');
-var utils = require('cordova/utils');
-
-var UseConsole = true;
-var Queued = [];
-var DeviceReady = false;
-var CurrentLevel;
-
-/**
- * Logging levels
- */
-
-var Levels = [
- "LOG",
- "ERROR",
- "WARN",
- "INFO",
- "DEBUG"
-];
-
-/*
- * add the logging levels to the logger object and
- * to a separate levelsMap object for testing
- */
-
-var LevelsMap = {};
-for (var i=0; i CurrentLevel) return;
-
- // queue the message if not yet at deviceready
- if (!DeviceReady && !UseConsole) {
- Queued.push([level, message]);
- return;
- }
-
- // if not using the console, use the native logger
- if (!UseConsole) {
- exec(null, null, "Logger", "logLevel", [level, message]);
- return;
- }
-
- // make sure console is not using logger
- if (console.__usingCordovaLogger) {
- throw new Error("console and logger are too intertwingly");
- }
-
- // log to the console
- switch (level) {
- case logger.LOG: console.log(message); break;
- case logger.ERROR: console.log("ERROR: " + message); break;
- case logger.WARN: console.log("WARN: " + message); break;
- case logger.INFO: console.log("INFO: " + message); break;
- case logger.DEBUG: console.log("DEBUG: " + message); break;
- }
-};
-
-// when deviceready fires, log queued messages
-logger.__onDeviceReady = function() {
- if (DeviceReady) return;
-
- DeviceReady = true;
-
- for (var i=0; i 3) {
- fail(FileError.SYNTAX_ERR);
- } else {
- // if successful, return a FileSystem object
- var success = function(file_system) {
- if (file_system) {
- if (typeof successCallback === 'function') {
- // grab the name and root from the file system object
- var result = new FileSystem(file_system.name, file_system.root);
- successCallback(result);
- }
- }
- else {
- // no FileSystem object returned
- fail(FileError.NOT_FOUND_ERR);
- }
- };
- exec(success, fail, "File", "requestFileSystem", [type, size]);
- }
-};
-
-module.exports = requestFileSystem;
-});
-
-// file: lib/common/plugin/resolveLocalFileSystemURI.js
-define("cordova/plugin/resolveLocalFileSystemURI", function(require, exports, module) {
-var DirectoryEntry = require('cordova/plugin/DirectoryEntry'),
- FileEntry = require('cordova/plugin/FileEntry'),
- FileError = require('cordova/plugin/FileError'),
- exec = require('cordova/exec');
-
-/**
- * Look up file system Entry referred to by local URI.
- * @param {DOMString} uri URI referring to a local file or directory
- * @param successCallback invoked with Entry object corresponding to URI
- * @param errorCallback invoked if error occurs retrieving file system entry
- */
-module.exports = function(uri, successCallback, errorCallback) {
- // error callback
- var fail = function(error) {
- if (typeof errorCallback === 'function') {
- errorCallback(new FileError(error));
- }
- };
- // sanity check for 'not:valid:filename'
- if(!uri || uri.split(":").length > 2) {
- setTimeout( function() {
- fail(FileError.ENCODING_ERR);
- },0);
- return;
- }
- // if successful, return either a file or directory entry
- var success = function(entry) {
- var result;
- if (entry) {
- if (typeof successCallback === 'function') {
- // create appropriate Entry object
- result = (entry.isDirectory) ? new DirectoryEntry(entry.name, entry.fullPath) : new FileEntry(entry.name, entry.fullPath);
- try {
- successCallback(result);
- }
- catch (e) {
- console.log('Error invoking callback: ' + e);
- }
- }
- }
- else {
- // no Entry object returned
- fail(FileError.NOT_FOUND_ERR);
- }
- };
-
- exec(success, fail, "File", "resolveLocalFileSystemURI", [uri]);
-};
-
-});
-
-// file: lib/common/plugin/splashscreen.js
-define("cordova/plugin/splashscreen", function(require, exports, module) {
-var exec = require('cordova/exec');
-
-var splashscreen = {
- hide:function() {
- exec(null, null, "SplashScreen", "hide", []);
- }
-};
-
-module.exports = splashscreen;
-});
-
-// file: lib/common/utils.js
-define("cordova/utils", function(require, exports, module) {
-var utils = exports;
-
-/**
- * Returns an indication of whether the argument is an array or not
- */
-utils.isArray = function(a) {
- return Object.prototype.toString.call(a) == '[object Array]';
-};
-
-/**
- * Returns an indication of whether the argument is a Date or not
- */
-utils.isDate = function(d) {
- return Object.prototype.toString.call(d) == '[object Date]';
-};
-
-/**
- * Does a deep clone of the object.
- */
-utils.clone = function(obj) {
- if(!obj || typeof obj == 'function' || utils.isDate(obj) || typeof obj != 'object') {
- return obj;
- }
-
- var retVal, i;
-
- if(utils.isArray(obj)){
- retVal = [];
- for(i = 0; i < obj.length; ++i){
- retVal.push(utils.clone(obj[i]));
- }
- return retVal;
- }
-
- retVal = {};
- for(i in obj){
- if(!(i in retVal) || retVal[i] != obj[i]) {
- retVal[i] = utils.clone(obj[i]);
- }
- }
- return retVal;
-};
-
-/**
- * Returns a wrappered version of the function
- */
-utils.close = function(context, func, params) {
- if (typeof params == 'undefined') {
- return function() {
- return func.apply(context, arguments);
- };
- } else {
- return function() {
- return func.apply(context, params);
- };
- }
-};
-
-/**
- * Create a UUID
- */
-utils.createUUID = function() {
- return UUIDcreatePart(4) + '-' +
- UUIDcreatePart(2) + '-' +
- UUIDcreatePart(2) + '-' +
- UUIDcreatePart(2) + '-' +
- UUIDcreatePart(6);
-};
-
-/**
- * Extends a child object from a parent object using classical inheritance
- * pattern.
- */
-utils.extend = (function() {
- // proxy used to establish prototype chain
- var F = function() {};
- // extend Child from Parent
- return function(Child, Parent) {
- F.prototype = Parent.prototype;
- Child.prototype = new F();
- Child.__super__ = Parent.prototype;
- Child.prototype.constructor = Child;
- };
-}());
-
-/**
- * Alerts a message in any available way: alert or console.log.
- */
-utils.alert = function(msg) {
- if (alert) {
- alert(msg);
- } else if (console && console.log) {
- console.log(msg);
- }
-};
-
-/**
- * Formats a string and arguments following it ala sprintf()
- *
- * see utils.vformat() for more information
- */
-utils.format = function(formatString /* ,... */) {
- var args = [].slice.call(arguments, 1);
- return utils.vformat(formatString, args);
-};
-
-/**
- * Formats a string and arguments following it ala vsprintf()
- *
- * format chars:
- * %j - format arg as JSON
- * %o - format arg as JSON
- * %c - format arg as ''
- * %% - replace with '%'
- * any other char following % will format it's
- * arg via toString().
- *
- * for rationale, see FireBug's Console API:
- * http://getfirebug.com/wiki/index.php/Console_API
- */
-utils.vformat = function(formatString, args) {
- if (formatString === null || formatString === undefined) return "";
- if (arguments.length == 1) return formatString.toString();
- if (typeof formatString != "string") return formatString.toString();
-
- var pattern = /(.*?)%(.)(.*)/;
- var rest = formatString;
- var result = [];
-
- while (args.length) {
- var arg = args.shift();
- var match = pattern.exec(rest);
-
- if (!match) break;
-
- rest = match[3];
-
- result.push(match[1]);
-
- if (match[2] == '%') {
- result.push('%');
- args.unshift(arg);
- continue;
- }
-
- result.push(formatted(arg, match[2]));
- }
-
- result.push(rest);
-
- return result.join('');
-};
-
-//------------------------------------------------------------------------------
-function UUIDcreatePart(length) {
- var uuidpart = "";
- for (var i=0; i
-
-
- WebODF
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/attic/programs/ios/www/nativezip.js b/attic/programs/ios/www/nativezip.js
deleted file mode 100644
index 5c548fb87..000000000
--- a/attic/programs/ios/www/nativezip.js
+++ /dev/null
@@ -1,102 +0,0 @@
-/**
- * Copyright (C) 2012 KO GmbH
-
- * @licstart
- * The JavaScript code in this page is free software: you can redistribute it
- * and/or modify it under the terms of the GNU Affero General Public License
- * (GNU AGPL) as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version. The code is distributed
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this code. If not, see .
- *
- * As additional permission under GNU AGPL version 3 section 7, you
- * may distribute non-source (e.g., minimized or compacted) forms of
- * that code without the copy of the GNU GPL normally required by
- * section 4, provided you include this license notice and a URL
- * through which recipients can access the Corresponding Source.
- *
- * As a special exception to the AGPL, any HTML file which merely makes function
- * calls to this code, and for that purpose includes it by reference shall be
- * deemed a separate work for copyright law purposes. In addition, the copyright
- * holders of this code give you permission to combine this code with free
- * software libraries that are released under the GNU LGPL. You may copy and
- * distribute such a system following the terms of the GNU AGPL for this code
- * and the LGPL for the libraries. If you modify this code, you may extend this
- * exception to your version of the code, but you are not obligated to do so.
- * If you do not wish to do so, delete this exception statement from your
- * version.
- *
- * This license applies to this entire compilation.
- * @licend
- * @source: http://www.webodf.org/
- * @source: https://github.com/kogmbh/WebODF/
- */
-/*global runtime, core, XMLHttpRequest*/
-
-core.Zip = function (url, entriesReadCallback) {
- "use strict";
- // remove 'odf:' prefix
- url = url.substr(4);
- var zip = this;
- this.load = function (filename, callback) {
- //alert(filename);
- callback(null, "");
- };
- this.loadAsString = function (filename, callback) {
- alert("loadAsString");
- };
- this.loadAsDOM = function (filename, callback) {
- var xhr = new XMLHttpRequest();
- function handleResult() {
- var xml;
- runtime.log("loading " + filename + " status " + xhr.status + " readyState " + xhr.readyState);
- if (xhr.readyState === 4) {
- xml = xhr.responseXML;
- runtime.log("done accessing responseXML " + xml + " " + (xhr.responseText && xhr.responseText.length)
- + " " + xhr.statusText);
- runtime.log("statusText " + xhr.statusText);
- if (xhr.status === 0 && !xml) {
- // empty files are considered as errors
- callback("File " + filename + " is not valid XML.");
- } else if (xhr.status === 200 || xhr.status === 0) {
- try {
- callback(null, xml);
- } catch (e) {
- runtime.log(e);
- }
- } else {
- // report error
- callback(xhr.responseText || xhr.statusText);
- }
- }
- }
- xhr.open('GET', "http://zipserver" + url + "?" + filename, true);
- xhr.onreadystatechange = handleResult;
- xhr.send(null);
- };
- this.loadAsDataURL = function (filename, mimetype, callback) {
- callback(null, "http://zipserver" + url + "?" + filename);
- };
- this.getEntries = function () {
- alert("getEntries");
- };
- this.loadContentXmlAsFragments = function (filename, handler) {
- // the javascript implementation simply reads the file
- zip.loadAsString(filename, function (err, data) {
- if (err) {
- return handler.rootElementReady(err);
- }
- handler.rootElementReady(null, data, true);
- });
- };
- this.save = function () {
- alert("save");
- };
- this.write = function () {
- alert("write");
- };
- entriesReadCallback(null, this);
-};
diff --git a/attic/programs/nativeQtClient/CMakeLists.txt b/attic/programs/nativeQtClient/CMakeLists.txt
deleted file mode 100644
index dd72fad52..000000000
--- a/attic/programs/nativeQtClient/CMakeLists.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-include(${QT_USE_FILE})
-include_directories(${CMAKE_CURRENT_BINARY_DIR} ${QT_QTCORE_INCLUDE_DIR})
-QT4_WRAP_CPP(NATIVEQTCLIENT_MOC
- odfview.h
- ../qtjsruntime/nativeio.h
- ../qtjsruntime/nam.h
-)
-file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/application.qrc
- "")
-foreach(FILE ${TOUCHUI_FILES} index.html scripts.js webodf.js)
- if (IS_ABSOLUTE ${FILE})
- GET_FILENAME_COMPONENT(_wwwfile ${FILE} NAME)
- else (IS_ABSOLUTE ${FILE})
- SET(_wwwfile ${FILE})
- endif (IS_ABSOLUTE ${FILE})
- file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/application.qrc "www/${_wwwfile}\n")
-endforeach(FILE ${TOUCHUI_FILES})
-file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/application.qrc
- "")
-COPY_FILES(NATIVEDEPS ${CMAKE_SOURCE_DIR}/programs/touchui
- ${CMAKE_CURRENT_BINARY_DIR}/www ${TOUCHUI_FILES})
-COPY_FILES(NATIVEDEPS ${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_CURRENT_BINARY_DIR}/www scripts.js)
-COPY_FILES(NATIVEDEPS ${CMAKE_SOURCE_DIR}/programs/touchui
- ${CMAKE_CURRENT_BINARY_DIR}/www index.html)
-QT4_ADD_RESOURCES(NATIVEQTCLIENT_RES
- ${CMAKE_CURRENT_BINARY_DIR}/application.qrc)
-
-add_custom_target(nativeQtClientDepencencies DEPENDS ${NATIVEDEPS})
-
-# creates a copy of the compiled webodf.js in the nativeQtClient build dir
-add_custom_target(nativeQtClient-webodf.js-target
- COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/webodf/webodf.js ${CMAKE_CURRENT_BINARY_DIR}/www
-)
-add_dependencies(nativeQtClient-webodf.js-target webodf.js-target)
-
-add_executable(nativeQtClient EXCLUDE_FROM_ALL
- main.cpp
- odfview.cpp
- ../qtjsruntime/nativeio.cpp
- odfpage.cpp ${NATIVEQTCLIENT_MOC} ${NATIVEQTCLIENT_UI}
- ${NATIVEQTCLIENT_RES})
-
-target_link_libraries(nativeQtClient ${QT_LIBRARIES})
-add_dependencies(nativeQtClient nativeQtClient-webodf.js-target nativeQtClientDepencencies)
diff --git a/attic/programs/nativeQtClient/README b/attic/programs/nativeQtClient/README
deleted file mode 100644
index 4860fa1b0..000000000
--- a/attic/programs/nativeQtClient/README
+++ /dev/null
@@ -1 +0,0 @@
-This is a small app that can show ODF documents using mainly javascript. Some functions that are not fast in browers are provided in C++ and it gives the ability to open files on the file system.
diff --git a/attic/programs/nativeQtClient/application.qrc b/attic/programs/nativeQtClient/application.qrc
deleted file mode 100644
index 5010cdb8a..000000000
--- a/attic/programs/nativeQtClient/application.qrc
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
- www/app/app.js
- www/app/controller/Files.js
- www/app/model/FileSystem.js
- www/app/store/FileStore.js
- www/app/views/FileDetail.js
- www/app/views/FilesList.js
- www/app/views/OdfView.js
- www/app/views/Viewport.js
- www/index.html
- www/scripts.js
- www/sencha-touch.css
- www/sencha-touch.js
- www/webodf.css
- www/webodf.js
-
-
diff --git a/attic/programs/nativeQtClient/main.cpp b/attic/programs/nativeQtClient/main.cpp
deleted file mode 100644
index 62e5fa18b..000000000
--- a/attic/programs/nativeQtClient/main.cpp
+++ /dev/null
@@ -1,10 +0,0 @@
-#include "odfview.h"
-#include
-#include
-
-int main(int argc, char *argv[]) {
- QApplication a(argc, argv);
- OdfView view;
- view.show();
- return a.exec();
-}
diff --git a/attic/programs/nativeQtClient/mainwindow.cpp b/attic/programs/nativeQtClient/mainwindow.cpp
deleted file mode 100644
index 861014399..000000000
--- a/attic/programs/nativeQtClient/mainwindow.cpp
+++ /dev/null
@@ -1,173 +0,0 @@
-#include "mainwindow.h"
-#include "ui_mainwindow.h"
-#include "odfview.h"
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-MainWindow::MainWindow(QWidget *parent) :
- QMainWindow(parent),
- ui(new Ui::MainWindow)
-{
- ui->setupUi(this);
-
- createActions();
- createToolBars();
-
- QCoreApplication::setOrganizationName("KO");
- //QCoreApplication::setOrganizationDomain("example.com");
- QCoreApplication::setApplicationName("Odf Viewer");
-
- QSettings settings;
-
- setWindowTitle(tr("Odf Viewer"));
- setUnifiedTitleAndToolBarOnMac(true);
-
- QStringList odfNameFilter;
- odfNameFilter << "*.odt" << "*.ods" << "*.odp";
- dirmodel = new QFileSystemModel(this);
- dirmodel->setNameFilters(odfNameFilter);
- dirmodel->setFilter(QDir::AllDirs|QDir::AllEntries|QDir::NoDotAndDotDot);
- dirview = new QTreeView(this);
- dirview->setModel(dirmodel);
- dirview->setHeaderHidden(true);
- dirview->setAnimated(true);
- for (int i = 1; i < dirmodel->columnCount(); i++) {
- dirview->setColumnHidden(i, true);
- }
- QString rootpath = settings.value("rootpath", QDir::homePath()).toString();
- dirmodel->setRootPath(rootpath);
- const QModelIndex rootindex = dirmodel->index(rootpath);
- dirview->setRootIndex(rootindex);
- QLineEdit *dirPath = new QLineEdit(rootpath, this);
- dirdock = new QDockWidget(this);
- QWidget *w = new QWidget(dirdock);
- QVBoxLayout *layout = new QVBoxLayout(w);
- dirdock->setWidget(w);
- layout->addWidget(dirPath);
- layout->addWidget(dirview);
- addDockWidget(Qt::LeftDockWidgetArea, dirdock);
-
- connect(dirview, SIGNAL(clicked(QModelIndex)), this, SLOT(loadOdf(QModelIndex)));
- connect(dirPath, SIGNAL(textChanged(QString)), this, SLOT(setPath(QString)));
-}
-
-MainWindow::~MainWindow()
-{
- delete ui;
-}
-
-void
-MainWindow::openFile(const QString& path)
-{
- QMdiSubWindow* w = findMdiChild(path);
- OdfView* v = (w) ?dynamic_cast(w->widget()) :0;
- if (v == 0) {
- w = ui->mdiArea->activeSubWindow();
- v = (w) ?dynamic_cast(w->widget()) :0;
- }
- if (v == 0) {
- v = new OdfView(this);
- v->showMaximized();
- w = ui->mdiArea->addSubWindow(v);
- w->showMaximized();
- }
- ui->mdiArea->setActiveSubWindow(w);
- v->loadFile(path);
-}
-
-void MainWindow::changeEvent(QEvent *e)
-{
- QMainWindow::changeEvent(e);
- switch (e->type()) {
- case QEvent::LanguageChange:
- ui->retranslateUi(this);
- break;
- default:
- break;
- }
-}
-void MainWindow::open()
-{
- QString fileName = QFileDialog::getOpenFileName(this, QString(), QString(),
- tr("Office Files (*.odt *.odp *.ods)"));
- if (!fileName.isEmpty()) {
- QMdiSubWindow *existing = findMdiChild(fileName);
- if (existing) {
- ui->mdiArea->setActiveSubWindow(existing);
- return;
- }
-
- OdfView *child = createOdfView();
- if (child->loadFile(fileName)) {
- statusBar()->showMessage(tr("File loaded"), 2000);
- child->showMaximized();
- } else {
- child->close();
- }
- }
-}
-void MainWindow::createActions()
-{
- //openAct = new QAction(QIcon(":/images/open.png"), tr("&Open..."), this);
- openAct = new QAction(tr("&Open..."), this);
- openAct->setShortcuts(QKeySequence::Open);
- openAct->setStatusTip(tr("Open an existing file"));
- connect(openAct, SIGNAL(triggered()), this, SLOT(open()));
-}
-void MainWindow::createToolBars()
-{
- fileToolBar = addToolBar(tr("File"));
- fileToolBar->addAction(openAct);
-}
-QMdiSubWindow *MainWindow::findMdiChild(const QString &fileName)
-{
- QString canonicalFilePath = QFileInfo(fileName).canonicalFilePath();
-
- foreach (QMdiSubWindow *window, ui->mdiArea->subWindowList()) {
- OdfView *odfView = qobject_cast(window->widget());
- if (odfView->currentFile() == canonicalFilePath)
- return window;
- }
- return 0;
-}
-
-OdfView *MainWindow::createOdfView()
-{
- OdfView *view = new OdfView(this);
- ui->mdiArea->addSubWindow(view);
- return view;
-}
-
-void
-MainWindow::loadOdf(const QModelIndex& index) {
- if (dirmodel->isDir(index)) {
- if (dirview->isExpanded(index)) {
- dirview->collapse(index);
- } else {
- dirview->expand(index);
- }
- return;
- }
- QString path = dirmodel->filePath(index);
- path = QFileInfo(path).canonicalFilePath();
- openFile(path);
-}
-
-void MainWindow::setPath(const QString &path)
-{
- dirmodel->setRootPath(path);
- const QModelIndex rootindex = dirmodel->index(path);
- dirview->setRootIndex(rootindex);
- QSettings settings;
- settings.setValue("rootpath", path);
-}
-
-
-
diff --git a/attic/programs/nativeQtClient/mainwindow.h b/attic/programs/nativeQtClient/mainwindow.h
deleted file mode 100644
index d0bc822d0..000000000
--- a/attic/programs/nativeQtClient/mainwindow.h
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef MAINWINDOW_H
-#define MAINWINDOW_H
-
-#include
-#include
-
-namespace Ui {
- class MainWindow;
-}
-
-class OdfView;
-class QFileSystemModel;
-class QTreeView;
-class QDockWidget;
-class QModelIndex;
-
-class MainWindow : public QMainWindow {
- Q_OBJECT
-public:
- MainWindow(QWidget *parent = 0);
- ~MainWindow();
- void openFile(const QString& path);
-
-private slots:
- void open();
- OdfView *createOdfView();
- void loadOdf(const QModelIndex& index);
- void setPath(const QString &path);
-
-private:
- QMdiSubWindow *findMdiChild(const QString &fileName);
- void createActions();
- void createToolBars();
- QToolBar *fileToolBar;
- QAction *openAct;
-protected:
- void changeEvent(QEvent *e);
-
-private:
- Ui::MainWindow *ui;
- QFileSystemModel* dirmodel;
- QTreeView* dirview;
- QDockWidget* dirdock;
-};
-
-#endif // MAINWINDOW_H
diff --git a/attic/programs/nativeQtClient/mainwindow.ui b/attic/programs/nativeQtClient/mainwindow.ui
deleted file mode 100644
index 38682c701..000000000
--- a/attic/programs/nativeQtClient/mainwindow.ui
+++ /dev/null
@@ -1,46 +0,0 @@
-
-
- MainWindow
-
-
-
- 0
- 0
- 800
- 600
-
-
-
- MainWindow
-
-
-
-
-
-
-
-
-
-
-
- 0
- 0
- 800
- 23
-
-
-
-
-
- TopToolBarArea
-
-
- false
-
-
-
-
-
-
-
-
diff --git a/attic/programs/nativeQtClient/odfpage.cpp b/attic/programs/nativeQtClient/odfpage.cpp
deleted file mode 100644
index d87a8baa2..000000000
--- a/attic/programs/nativeQtClient/odfpage.cpp
+++ /dev/null
@@ -1 +0,0 @@
-#include "odfpage.h"
diff --git a/attic/programs/nativeQtClient/odfpage.h b/attic/programs/nativeQtClient/odfpage.h
deleted file mode 100644
index 487d16991..000000000
--- a/attic/programs/nativeQtClient/odfpage.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef ODFPAGE_H
-#define ODFPAGE_H
-
-#include
-#include
-
-class OdfPage : public QWebPage {
-public:
- OdfPage(QObject* parent) :QWebPage(parent) {}
- void javaScriptConsoleMessage(const QString& message, int lineNumber, const QString & sourceID) {
- qDebug() << sourceID << ":" << lineNumber << ":" << message;
- }
-};
-
-#endif // ODFPAGE_H
diff --git a/attic/programs/nativeQtClient/odfview.cpp b/attic/programs/nativeQtClient/odfview.cpp
deleted file mode 100644
index 60da5c9ef..000000000
--- a/attic/programs/nativeQtClient/odfview.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-#include "odfview.h"
-
-#include "../qtjsruntime/nativeio.h"
-#include "../qtjsruntime/nam.h"
-
-#include "odfpage.h"
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-OdfView::OdfView(QWidget* parent) :QWebView(parent)
-{
- QString prefix = "../android/assets/"; // set this to the right value when debugging
- QString htmlfile = QDir(prefix).absoluteFilePath("www/index.html");
- if (!QFileInfo(htmlfile).exists()) {
- prefix = "qrc:/";
- htmlfile = "qrc:/www/index.html";
- }
- setPage(new OdfPage(this));
- nativeio = new NativeIO(this, QDir(prefix), QDir::current());
- connect(page(), SIGNAL(loadFinished(bool)), this, SLOT(slotLoadFinished(bool)));
- page()->settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true);
-
- connect(page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()),
- this, SLOT(slotInitWindowObjects()));
-
- // use our own networkaccessmanager that gives limited access to the local
- // file system
- networkaccessmanager = new NAM(this);
- page()->setNetworkAccessManager(networkaccessmanager);
- setUrl(QUrl(htmlfile));
- loaded = false;
-}
-
-OdfView::~OdfView() {
-}
-
-void
-OdfView::slotInitWindowObjects()
-{
- QWebFrame *frame = page()->mainFrame();
- frame->addToJavaScriptWindowObject("nativeio", nativeio);
-}
-
-bool
-OdfView::loadFile(const QString &fileName) {
- curFile = fileName;
- // odf->addFile(identifier, fileName);
- // networkaccessmanager->setCurrentFile(odf->getOpenContainer(identifier));
- if (loaded) {
- slotLoadFinished(true);
- }
- return true;
-}
-void
-OdfView::slotLoadFinished(bool ok) {
- if (!ok) return;
- loaded = true;
- QWebFrame *frame = page()->mainFrame();
- QString js =
- "var originalReadFileSync = runtime.readFileSync;"
- "runtime.readFileSync = function (path, encoding) {"
- " if (path.substr(path.length - 3) === '.js') {"
- " return originalReadFileSync.apply(runtime,"
- " [path, encoding]);"
- " }"
- " return nativeio.readFileSync(path, encoding);"
- "};"
- "runtime.read = function (path, offset, length, callback) {"
- " var data = nativeio.read(path, offset, length);"
- " data = runtime.byteArrayFromString(data, 'binary');"
- " callback(nativeio.error()||null, data);"
- "};";
- frame->evaluateJavaScript(js);
-}
diff --git a/attic/programs/nativeQtClient/odfview.h b/attic/programs/nativeQtClient/odfview.h
deleted file mode 100644
index f61ba3c92..000000000
--- a/attic/programs/nativeQtClient/odfview.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef ODFVIEW_H
-#define ODFVIEW_H
-
-#include
-#include
-class NativeIO;
-
-class OdfView : public QWebView {
-Q_OBJECT
-public:
- OdfView(QWidget* parent = 0);
- ~OdfView();
- QString currentFile() { return curFile; }
-
-public slots:
- bool loadFile(const QString &fileName);
-
-private slots:
- void slotLoadFinished(bool ok);
- void slotInitWindowObjects();
-
-private:
- bool loaded;
- QString curFile;
- QNetworkAccessManager* networkaccessmanager;
- NativeIO* nativeio;
-};
-
-#endif // ODFVIEW_H
diff --git a/attic/programs/nativeQtClient/scripts.js b/attic/programs/nativeQtClient/scripts.js
deleted file mode 100644
index 120a641d9..000000000
--- a/attic/programs/nativeQtClient/scripts.js
+++ /dev/null
@@ -1,129 +0,0 @@
-/**
- * Copyright (C) 2012 KO GmbH
-
- * @licstart
- * The JavaScript code in this page is free software: you can redistribute it
- * and/or modify it under the terms of the GNU Affero General Public License
- * (GNU AGPL) as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version. The code is distributed
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this code. If not, see .
- *
- * As additional permission under GNU AGPL version 3 section 7, you
- * may distribute non-source (e.g., minimized or compacted) forms of
- * that code without the copy of the GNU GPL normally required by
- * section 4, provided you include this license notice and a URL
- * through which recipients can access the Corresponding Source.
- *
- * As a special exception to the AGPL, any HTML file which merely makes function
- * calls to this code, and for that purpose includes it by reference shall be
- * deemed a separate work for copyright law purposes. In addition, the copyright
- * holders of this code give you permission to combine this code with free
- * software libraries that are released under the GNU LGPL. You may copy and
- * distribute such a system following the terms of the GNU AGPL for this code
- * and the LGPL for the libraries. If you modify this code, you may extend this
- * exception to your version of the code, but you are not obligated to do so.
- * If you do not wish to do so, delete this exception statement from your
- * version.
- *
- * This license applies to this entire compilation.
- * @licend
- * @source: http://www.webodf.org/
- * @source: https://github.com/kogmbh/WebODF/
- */
-/*global alert, app, window, runtime*/
-var LocalFileSystem = {
- PERSISTENT: 0,
- TEMPORARY: 1
-};
-function FileEntry(name, fullPath) {
- "use strict";
- this.isFile = true;
- this.isDirectory = false;
- this.name = name;
- this.fullPath = fullPath;
- this.file = function (onsuccess, onerror) {
- function File(fullPath) {
- this.name = name;
- this.fullPath = fullPath;
- this.type = "";
- this.size = -1;
- this.lastModifiedDate = -1;
- }
- var file = new File(fullPath);
- try {
- onsuccess(file);
- } catch (e) {
- alert("Error on determining file properties: " + e);
- onerror(e);
- }
- };
-}
-function FileReader() {
- "use strict";
- var fr = this;
- this.readAsArrayBuffer = function (file) {
- var path = file.fullPath.substr(7),
- data = runtime.readFileSync(path, 'binary');
- data = runtime.byteArrayFromString(data, "binary");
- window.setTimeout(function () {
- fr.onloadend({target: {result: data}});
- }, 1);
- };
-}
-var DirectoryReader;
-function DirectoryEntry(name, fullPath) {
- "use strict";
- this.isFile = false;
- this.isDirectory = true;
- this.name = name;
- this.fullPath = fullPath;
- this.createReader = function () {
- var reader = new DirectoryReader(fullPath);
- return reader;
- };
-}
-function DirectoryReader(fullPath) {
- "use strict";
- this.readEntries = function (onsuccess, onerror) {
- window.setTimeout(function () {
- var entries = [];
- entries[entries.length] = new FileEntry("welcome.odt",
- "welcome.odt");
- entries[entries.length] = new FileEntry("Traktatenblad.odt",
- "Traktatenblad.odt");
- try {
- onsuccess(entries);
- } catch (e) {
- onerror(e);
- }
- }, 1);
- };
-}
-window.resolveLocalFileSystemURI = function (path, onsuccess, onerror) {
- "use strict";
- var p = path.lastIndexOf("/"),
- name = (p === -1) ? path : path.substr(p + 1);
- onsuccess(new FileEntry(name, path));
-};
-window.requestFileSystem = function (filesystem, id, onsuccess, onerror) {
- "use strict";
- var dirs = [], shared, subfolder, path;
- try {
- if (filesystem === LocalFileSystem.PERSISTENT) {
- path = "";
- onsuccess({
- name: "root",
- root: new DirectoryEntry("root", path)
- });
- } else {
- onerror("not defined");
- }
- } catch (e) {
- onerror(e);
- }
-};
-var device = {};
diff --git a/attic/programs/playbook/CMakeLists.txt b/attic/programs/playbook/CMakeLists.txt
deleted file mode 100644
index e69de29bb..000000000
diff --git a/attic/programs/playbook/build_sign.bat b/attic/programs/playbook/build_sign.bat
deleted file mode 100644
index 34e8deeab..000000000
--- a/attic/programs/playbook/build_sign.bat
+++ /dev/null
@@ -1,23 +0,0 @@
-@echo on
-set WWSDK=M:\blackberrysdk\webworkssdk
-set BBWP=%WWSDK%\bbwp\bbwp
-set DEPLOY=%WWSDK%\bbwp\blackberry-tablet-sdk\bin\blackberry-deploy
-set JAVA_HOME=%WWSDK%\jre
-set PATH=%PATH%;%JAVA_HOME%\bin
-
-mkdir bin
-mkdir signed
-
-zip -r webodf.zip config.xml index.html icon.png scripts.js app sencha-touch.js sencha-touch.css webodf.js webodf.css ZoomIn.png ZoomOut.png
-
-rem MAKE A DEBUG VERSION
-del bin\webodf.bar
-%BBWP% webodf.zip -d -o bin
-if %errorlevel% neq 0 exit /b %errorlevel%
-
-%DEPLOY% -installApp -password ko -device 192.168.1.111 -package bin\webodf.bar
-if %errorlevel% neq 0 exit /b %errorlevel%
-
-rem MAKE A SIGNED VERSION, (can be done only once for each buildId!)
-rem %BBWP% webodf.zip -g U9gXpJXbGC -buildId 2 -o signed
-
diff --git a/attic/programs/playbook/config.xml b/attic/programs/playbook/config.xml
deleted file mode 100644
index cab778831..000000000
--- a/attic/programs/playbook/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
- KO GmbH
- WebODF
-
- Viewer for OpenDocument files.
-
-
-
-
-
-
-
-
- access_shared
-
-
-
-
-
-
-
-
-
diff --git a/attic/programs/playbook/ext/blackberry.custom.filereader/js/common/custom_filereader_dispatcher.js b/attic/programs/playbook/ext/blackberry.custom.filereader/js/common/custom_filereader_dispatcher.js
deleted file mode 100644
index c707e32ac..000000000
--- a/attic/programs/playbook/ext/blackberry.custom.filereader/js/common/custom_filereader_dispatcher.js
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * Copyright (C) 2012 KO GmbH
-
- * @licstart
- * The JavaScript code in this page is free software: you can redistribute it
- * and/or modify it under the terms of the GNU Affero General Public License
- * (GNU AGPL) as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version. The code is distributed
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this code. If not, see .
- *
- * As additional permission under GNU AGPL version 3 section 7, you
- * may distribute non-source (e.g., minimized or compacted) forms of
- * that code without the copy of the GNU GPL normally required by
- * section 4, provided you include this license notice and a URL
- * through which recipients can access the Corresponding Source.
- *
- * As a special exception to the AGPL, any HTML file which merely makes function
- * calls to this code, and for that purpose includes it by reference shall be
- * deemed a separate work for copyright law purposes. In addition, the copyright
- * holders of this code give you permission to combine this code with free
- * software libraries that are released under the GNU LGPL. You may copy and
- * distribute such a system following the terms of the GNU AGPL for this code
- * and the LGPL for the libraries. If you modify this code, you may extend this
- * exception to your version of the code, but you are not obligated to do so.
- * If you do not wish to do so, delete this exception statement from your
- * version.
- *
- * This license applies to this entire compilation.
- * @licend
- * @source: http://www.webodf.org/
- * @source: https://github.com/kogmbh/WebODF/
- */
-(function () {
- var CUSTOM_FILEREADER_API_URL = "blackberry/custom/filereader";
-
- var ARGS_PATH = "path";
- var ARGS_DATA = "data";
-
- function CustomFileReader() {
- };
-
- CustomFileReader.prototype.readAsDataURL = function(path) {
- var remoteCall = new blackberry.transport.RemoteFunctionCall(CUSTOM_FILEREADER_API_URL + "/readAsDataURL");
- remoteCall.addParam(ARGS_PATH, path);
- return remoteCall.makeSyncCall();
- };
-
- blackberry.Loader.javascriptLoaded("blackberry.custom.filereader", CustomFileReader);
-})();
diff --git a/attic/programs/playbook/ext/blackberry.custom.filereader/js/common/custom_filereader_ns.js b/attic/programs/playbook/ext/blackberry.custom.filereader/js/common/custom_filereader_ns.js
deleted file mode 100644
index 4d677965c..000000000
--- a/attic/programs/playbook/ext/blackberry.custom.filereader/js/common/custom_filereader_ns.js
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * Copyright (C) 2012 KO GmbH
-
- * @licstart
- * The JavaScript code in this page is free software: you can redistribute it
- * and/or modify it under the terms of the GNU Affero General Public License
- * (GNU AGPL) as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version. The code is distributed
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this code. If not, see .
- *
- * As additional permission under GNU AGPL version 3 section 7, you
- * may distribute non-source (e.g., minimized or compacted) forms of
- * that code without the copy of the GNU GPL normally required by
- * section 4, provided you include this license notice and a URL
- * through which recipients can access the Corresponding Source.
- *
- * As a special exception to the AGPL, any HTML file which merely makes function
- * calls to this code, and for that purpose includes it by reference shall be
- * deemed a separate work for copyright law purposes. In addition, the copyright
- * holders of this code give you permission to combine this code with free
- * software libraries that are released under the GNU LGPL. You may copy and
- * distribute such a system following the terms of the GNU AGPL for this code
- * and the LGPL for the libraries. If you modify this code, you may extend this
- * exception to your version of the code, but you are not obligated to do so.
- * If you do not wish to do so, delete this exception statement from your
- * version.
- *
- * This license applies to this entire compilation.
- * @licend
- * @source: http://www.webodf.org/
- * @source: https://github.com/kogmbh/WebODF/
- */
-(function () {
-
- function CustomFileReader(disp) {
- this.constructor.prototype.readAsDataURL = function(path) { return disp.readAsDataURL(path); };
- };
-
- blackberry.Loader.javascriptLoaded("blackberry.custom.filereader", CustomFileReader);
-})();
diff --git a/attic/programs/playbook/ext/blackberry.custom.filereader/library.xml b/attic/programs/playbook/ext/blackberry.custom.filereader/library.xml
deleted file mode 100644
index a5a24c3d8..000000000
--- a/attic/programs/playbook/ext/blackberry.custom.filereader/library.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
- blackberry.custom.filereader.CustomFileReader
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/attic/programs/playbook/ext/blackberry.custom.filereader/src/AIR/CustomFileReader/src/blackberry/custom/filereader/CustomFileReader.as b/attic/programs/playbook/ext/blackberry.custom.filereader/src/AIR/CustomFileReader/src/blackberry/custom/filereader/CustomFileReader.as
deleted file mode 100644
index 3261fbcf4..000000000
--- a/attic/programs/playbook/ext/blackberry.custom.filereader/src/AIR/CustomFileReader/src/blackberry/custom/filereader/CustomFileReader.as
+++ /dev/null
@@ -1,34 +0,0 @@
-package blackberry.custom.filereader {
- import flash.filesystem.File;
- import flash.filesystem.FileMode;
- import flash.filesystem.FileStream;
- import flash.utils.ByteArray;
- import mx.utils.Base64Encoder;
- import webworks.extension.DefaultExtension;
-
- public class CustomFileReader extends DefaultExtension {
-
- public function CustomFileReader() {
- super();
- }
-
- override public function getFeatureList():Array {
- return new Array ("blackberry.custom.filereader");
- }
-
- public function readAsDataURL(path:String):String {
- var file:File = new File(path);
- if (!file.exists) {
- return "";
- }
- var bytes:ByteArray = new ByteArray();
- var stream:FileStream = new FileStream();
- stream.open(file, FileMode.READ);
- stream.readBytes(bytes);
- var btoa:Base64Encoder = new Base64Encoder();
- btoa.encodeBytes(bytes);
- stream.close();
- return "data:;base64," + btoa.toString();
- }
- }
-}
\ No newline at end of file
diff --git a/attic/programs/playbook/icon.png b/attic/programs/playbook/icon.png
deleted file mode 100644
index b7ccb848e..000000000
Binary files a/attic/programs/playbook/icon.png and /dev/null differ
diff --git a/attic/programs/playbook/index.html b/attic/programs/playbook/index.html
deleted file mode 100644
index 77d331c12..000000000
--- a/attic/programs/playbook/index.html
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- WebODF
-
-
-
-
-
diff --git a/attic/programs/playbook/scripts.js b/attic/programs/playbook/scripts.js
deleted file mode 100644
index b67c1b3fb..000000000
--- a/attic/programs/playbook/scripts.js
+++ /dev/null
@@ -1,182 +0,0 @@
-/**
- * Copyright (C) 2012 KO GmbH
-
- * @licstart
- * The JavaScript code in this page is free software: you can redistribute it
- * and/or modify it under the terms of the GNU Affero General Public License
- * (GNU AGPL) as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version. The code is distributed
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this code. If not, see .
- *
- * As additional permission under GNU AGPL version 3 section 7, you
- * may distribute non-source (e.g., minimized or compacted) forms of
- * that code without the copy of the GNU GPL normally required by
- * section 4, provided you include this license notice and a URL
- * through which recipients can access the Corresponding Source.
- *
- * As a special exception to the AGPL, any HTML file which merely makes function
- * calls to this code, and for that purpose includes it by reference shall be
- * deemed a separate work for copyright law purposes. In addition, the copyright
- * holders of this code give you permission to combine this code with free
- * software libraries that are released under the GNU LGPL. You may copy and
- * distribute such a system following the terms of the GNU AGPL for this code
- * and the LGPL for the libraries. If you modify this code, you may extend this
- * exception to your version of the code, but you are not obligated to do so.
- * If you do not wish to do so, delete this exception statement from your
- * version.
- *
- * This license applies to this entire compilation.
- * @licend
- * @source: http://www.webodf.org/
- * @source: https://github.com/kogmbh/WebODF/
- */
-/*global blackberry, alert, document, window, app*/
-var LocalFileSystem = {
- PERSISTENT: 0,
- TEMPORARY: 1
-};
-function FileWriter(fullPath) {
- "use strict";
- this.write = function (data) {
- var blob;
- try {
- blob = blackberry.utils.stringToBlob(data, "UTF-8");
- blackberry.io.file.saveFile(fullPath, blob);
- } catch (e) {
- }
- };
-}
-function FileEntry(name, fullPath) {
- "use strict";
- this.isFile = true;
- this.isDirectory = false;
- this.name = name;
- this.fullPath = fullPath;
- this.file = function (onsuccess, onerror) {
- function File(fullPath) {
- this.name = name;
- this.fullPath = fullPath;
- this.type = "";
- this.size = -1;
- this.lastModifiedDate = -1;
- }
- var file = new File(fullPath),
- properties;
- try {
- properties = blackberry.io.file.getFileProperties(fullPath);
- file.type = properties.mimeType;
- file.size = properties.size;
- file.lastModifiedDate = properties.dateModified;
- onsuccess(file);
- } catch (e) {
- alert("Error on determining file properties: " + e);
- onerror(e);
- }
- };
- this.createWriter = function (onsuccess, onerror) {
- onsuccess(new FileWriter(fullPath));
- };
-}
-function FileReader() {
- "use strict";
- var fr = this;
- this.readAsDataURL = function (file) {
- var path = file.fullPath.substr(7);
- window.setTimeout(function () {
- try {
- var data = blackberry.custom.filereader.readAsDataURL(path);
- fr.onloadend({target: {result: data}});
- } catch (e) {
- alert("Error on reading file: " + e + " " + file.fullPath);
- }
- }, 1);
- };
- this.readAsText = function (file) {
- var path = file.fullPath.substr(7);
- try {
- blackberry.io.file.readFile(path, function (fullPath, blob) {
- var str = blackberry.utils.blobToString(blob, "UTF-8");
- fr.onloadend({target: {result: str}});
- }, true);
- } catch (e) {
- fr.onloadend({target: {result: "[]"}});
- }
- };
-}
-var DirectoryReader;
-function DirectoryEntry(name, fullPath) {
- "use strict";
- this.isFile = false;
- this.isDirectory = true;
- this.name = name;
- this.fullPath = fullPath;
- this.createReader = function () {
- var reader = new DirectoryReader(fullPath);
- return reader;
- };
-}
-function DirectoryReader(fullPath) {
- "use strict";
- this.readEntries = function (onsuccess, onerror) {
- window.setTimeout(function () {
- var entries = [],
- dirs = blackberry.io.dir.listDirectories(fullPath),
- files = blackberry.io.dir.listFiles(fullPath),
- i;
- try {
- for (i = 0; i < dirs.length; i += 1) {
- entries[entries.length] = new DirectoryEntry(dirs[i],
- fullPath + "/" + dirs[i]);
- }
- for (i = 0; i < files.length; i += 1) {
- entries[entries.length] = new FileEntry(files[i],
- fullPath + "/" + files[i]);
- }
- onsuccess(entries);
- } catch (e) {
- onerror(e);
- }
- }, 1);
- };
-}
-window.resolveLocalFileSystemURI = function (path, onsuccess, onerror) {
- "use strict";
- var p = path.lastIndexOf("/"),
- name;
- if (p === -1) {
- name = path;
- path = blackberry.io.dir.appDirs.shared.documents.path + "/" + path;
- } else {
- name = path.substr(p + 1);
- }
- onsuccess(new FileEntry(name, path));
-};
-window.requestFileSystem = function (filesystem, id, onsuccess, onerror) {
- "use strict";
- var dirs = [], shared, subfolder;
- try {
- if (filesystem === LocalFileSystem.PERSISTENT) {
- shared = blackberry.io.dir.appDirs.shared;
- for (subfolder in shared) {
- if (shared.hasOwnProperty(subfolder)) {
- dirs[dirs.length] = subfolder;
- }
- }
- onsuccess({
- name: "root",
- root: new DirectoryEntry("root", shared.documents.path
- //+ "/kofficetests/odf/odt"
- )
- });
- } else {
- onerror("not defined");
- }
- } catch (e) {
- onerror(e);
- }
-};
-var device = {};
diff --git a/node_modules/.package-lock.json b/node_modules/.package-lock.json
new file mode 100644
index 000000000..b2ebc29f0
--- /dev/null
+++ b/node_modules/.package-lock.json
@@ -0,0 +1,2079 @@
+{
+ "name": "node-webodf",
+ "version": "0.6.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "node_modules/@asamuzakjp/css-color": {
+ "version": "6.0.7",
+ "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-6.0.7.tgz",
+ "integrity": "sha512-vC/bk1Lz7Tn/EfU9/apOTBk80/8dyGyWMowPoV1tJ52muDGsDqt2HPT2klrFUiY60MQmQv9q8yIht15JnBgDGw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@csstools/css-calc": "^3.3.0",
+ "@csstools/css-color-parser": "^4.1.10",
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0",
+ "lru-cache": "^11.5.2"
+ },
+ "engines": {
+ "node": "^22.13.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@asamuzakjp/dom-selector": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-8.3.2.tgz",
+ "integrity": "sha512-93Z1N+BQNXysodoicpOIyNh2drHfz/CTf9nnT0FEx72GJcIiwgydD7tGAr78j41LsYn3hlRn+LdGPuBLn1Bl8Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bidi-js": "^1.0.3",
+ "css-tree": "^3.2.1",
+ "is-potential-custom-element-name": "^1.0.1",
+ "lru-cache": "^11.5.2"
+ },
+ "engines": {
+ "node": "^22.13.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz",
+ "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz",
+ "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.29.8",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.8.tgz",
+ "integrity": "sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.29.8"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.29.8",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz",
+ "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.29.7",
+ "@babel/helper-validator-identifier": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@bcoe/v8-coverage": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz",
+ "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@bramus/specificity": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/@bramus/specificity/-/specificity-2.4.2.tgz",
+ "integrity": "sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "css-tree": "^3.0.0"
+ },
+ "bin": {
+ "specificity": "bin/cli.js"
+ }
+ },
+ "node_modules/@csstools/color-helpers": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-6.1.1.tgz",
+ "integrity": "sha512-gLNsunvwf3mCi5u5o46/Z/JcJMnhbHSaZ69rkgPzNM3J4s8hWwpPUQB6/tt0EDFyCiWzxANlx+2LJwpYj4zS1w==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "engines": {
+ "node": ">=20.19.0"
+ }
+ },
+ "node_modules/@csstools/css-calc": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.3.0.tgz",
+ "integrity": "sha512-c5ihYsPkdG6JCkU2zTMm4+k6r7RXuGxtWYhu5DHMIiF1FHzrfmHL5so11AoFpUv/tu61xfcmT4AmKoFfMPoqdQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=20.19.0"
+ },
+ "peerDependencies": {
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0"
+ }
+ },
+ "node_modules/@csstools/css-color-parser": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.2.1.tgz",
+ "integrity": "sha512-YpAJZhaHplYQkG8ib+/Fx5Y0eF2lVWi3tIvMJA6i39TLyUNp2439cifzW8VMjhlqrBjHzK5hVGugRRm2zTKI/A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@csstools/color-helpers": "^6.1.1",
+ "@csstools/css-calc": "^3.3.0"
+ },
+ "engines": {
+ "node": ">=20.19.0"
+ },
+ "peerDependencies": {
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0"
+ }
+ },
+ "node_modules/@csstools/css-parser-algorithms": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-4.0.0.tgz",
+ "integrity": "sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=20.19.0"
+ },
+ "peerDependencies": {
+ "@csstools/css-tokenizer": "^4.0.0"
+ }
+ },
+ "node_modules/@csstools/css-syntax-patches-for-csstree": {
+ "version": "1.1.9",
+ "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.9.tgz",
+ "integrity": "sha512-iGGw4OsAYsS6pD29MdJ2bX/nJx65a04ZZiw6x+VwWlP2DdXf6f++Zmuv/OzALpdyfVhjbduIIF2cXM7HWBIe9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "peerDependencies": {
+ "css-tree": "^3.2.1"
+ },
+ "peerDependenciesMeta": {
+ "css-tree": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@csstools/css-tokenizer": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-4.0.0.tgz",
+ "integrity": "sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=20.19.0"
+ }
+ },
+ "node_modules/@exodus/bytes": {
+ "version": "1.15.1",
+ "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.15.1.tgz",
+ "integrity": "sha512-S6mL0yNB/Abt9Ei4tq8gDhcczc4S3+vQ4ra7vxnAf+YHC02srtqxKKZghx2Dq6p0e66THKwR6r8N6P95wEty7Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^20.19.0 || ^22.12.0 || >=24.0.0"
+ },
+ "peerDependencies": {
+ "@noble/hashes": "^1.8.0 || ^2.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@noble/hashes": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@isaacs/cliui": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
+ "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^5.1.2",
+ "string-width-cjs": "npm:string-width@^4.2.0",
+ "strip-ansi": "^7.0.1",
+ "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
+ "wrap-ansi": "^8.1.0",
+ "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@istanbuljs/schema": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.6.tgz",
+ "integrity": "sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.13",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
+ "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/source-map": {
+ "version": "0.3.11",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz",
+ "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.31",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
+ "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@jsdoc/salty": {
+ "version": "0.2.12",
+ "resolved": "https://registry.npmjs.org/@jsdoc/salty/-/salty-0.2.12.tgz",
+ "integrity": "sha512-TuB0x50EoAvEX/UEWITd8Mkn3WhiTjSvbTMCLj0BhsQEl5iUzjXdA0bETEVpTk+5TGTLR6QktI9H4hLviVeaAQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "lodash": "^4.18.1"
+ },
+ "engines": {
+ "node": ">=v12.0.0"
+ }
+ },
+ "node_modules/@pkgjs/parseargs": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
+ "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/@types/istanbul-lib-coverage": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
+ "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/linkify-it": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz",
+ "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/markdown-it": {
+ "version": "14.2.0",
+ "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.2.0.tgz",
+ "integrity": "sha512-NoQ2yGlLWj4wpxMs+TYmRKk3thDrQ97agr7sFqfLsAlvoS8SNQuTrlObhFqG9iugdTtgOE9jpJ6FNM4ZGsa5xQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/linkify-it": "^5",
+ "@types/mdurl": "^2"
+ }
+ },
+ "node_modules/@types/mdurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz",
+ "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@xmldom/xmldom": {
+ "version": "0.9.12",
+ "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.12.tgz",
+ "integrity": "sha512-5AXjrcMClTryPe9LgZrygpB1lj7s0S9E0+W+AHaVKAVyHanafK86iPSvG5xHVSp/jC+VH1UXu0TAEmY279xH7A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.6"
+ }
+ },
+ "node_modules/acorn": {
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz",
+ "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.3.0.tgz",
+ "integrity": "sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
+ "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true,
+ "license": "Python-2.0"
+ },
+ "node_modules/balanced-match": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
+ "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "18 || 20 || >=22"
+ }
+ },
+ "node_modules/bidi-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz",
+ "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "require-from-string": "^2.0.2"
+ }
+ },
+ "node_modules/bluebird": {
+ "version": "3.7.2",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
+ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/brace-expansion": {
+ "version": "5.0.9",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz",
+ "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^4.0.2"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ }
+ },
+ "node_modules/buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/c8": {
+ "version": "10.1.3",
+ "resolved": "https://registry.npmjs.org/c8/-/c8-10.1.3.tgz",
+ "integrity": "sha512-LvcyrOAaOnrrlMpW22n690PUvxiq4Uf9WMhQwNJ9vgagkL/ph1+D4uvjvDA5XCbykrc0sx+ay6pVi9YZ1GnhyA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "@bcoe/v8-coverage": "^1.0.1",
+ "@istanbuljs/schema": "^0.1.3",
+ "find-up": "^5.0.0",
+ "foreground-child": "^3.1.1",
+ "istanbul-lib-coverage": "^3.2.0",
+ "istanbul-lib-report": "^3.0.1",
+ "istanbul-reports": "^3.1.6",
+ "test-exclude": "^7.0.1",
+ "v8-to-istanbul": "^9.0.0",
+ "yargs": "^17.7.2",
+ "yargs-parser": "^21.1.1"
+ },
+ "bin": {
+ "c8": "bin/c8.js"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "monocart-coverage-reports": "^2"
+ },
+ "peerDependenciesMeta": {
+ "monocart-coverage-reports": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/catharsis": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz",
+ "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lodash": "^4.17.15"
+ },
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/cliui": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.1",
+ "wrap-ansi": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/cliui/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cliui/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/cliui/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cliui/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cliui/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cliui/node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/css-tree": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz",
+ "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mdn-data": "2.27.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
+ }
+ },
+ "node_modules/data-urls": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-7.0.0.tgz",
+ "integrity": "sha512-23XHcCF+coGYevirZceTVD7NdJOqVn+49IHyxgszm+JIiHLoB2TkmPtsYkNWT1pvRSGkc35L6NHs0yHkN2SumA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "whatwg-mimetype": "^5.0.0",
+ "whatwg-url": "^16.0.0"
+ },
+ "engines": {
+ "node": "^20.19.0 || ^22.12.0 || >=24.0.0"
+ }
+ },
+ "node_modules/data-urls/node_modules/whatwg-url": {
+ "version": "16.0.1",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-16.0.1.tgz",
+ "integrity": "sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@exodus/bytes": "^1.11.0",
+ "tr46": "^6.0.0",
+ "webidl-conversions": "^8.0.1"
+ },
+ "engines": {
+ "node": "^20.19.0 || ^22.12.0 || >=24.0.0"
+ }
+ },
+ "node_modules/decimal.js": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz",
+ "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/eastasianwidth": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
+ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/emoji-regex": {
+ "version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/entities": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
+ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/foreground-child": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
+ "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "cross-spawn": "^7.0.6",
+ "signal-exit": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
+ },
+ "node_modules/glob": {
+ "version": "10.5.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
+ "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
+ "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^1.11.1"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob/node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/glob/node_modules/brace-expansion": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.4.tgz",
+ "integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/glob/node_modules/minimatch": {
+ "version": "9.0.9",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
+ "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/html-encoding-sniffer": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-6.0.0.tgz",
+ "integrity": "sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@exodus/bytes": "^1.6.0"
+ },
+ "engines": {
+ "node": "^20.19.0 || ^22.12.0 || >=24.0.0"
+ }
+ },
+ "node_modules/html-escaper": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
+ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-potential-custom-element-name": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
+ "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/istanbul-lib-coverage": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
+ "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-report": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
+ "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "istanbul-lib-coverage": "^3.0.0",
+ "make-dir": "^4.0.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-reports": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz",
+ "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "html-escaper": "^2.0.0",
+ "istanbul-lib-report": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jackspeak": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
+ "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "@isaacs/cliui": "^8.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ },
+ "optionalDependencies": {
+ "@pkgjs/parseargs": "^0.11.0"
+ }
+ },
+ "node_modules/js2xmlparser": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz",
+ "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "xmlcreate": "^2.0.4"
+ }
+ },
+ "node_modules/jsdoc": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-4.0.5.tgz",
+ "integrity": "sha512-P4C6MWP9yIlMiK8nwoZvxN84vb6MsnXcHuy7XzVOvQoCizWX5JFCBsWIIWKXBltpoRZXddUOVQmCTOZt9yDj9g==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@babel/parser": "^7.20.15",
+ "@jsdoc/salty": "^0.2.1",
+ "@types/markdown-it": "^14.1.1",
+ "bluebird": "^3.7.2",
+ "catharsis": "^0.9.0",
+ "escape-string-regexp": "^2.0.0",
+ "js2xmlparser": "^4.0.2",
+ "klaw": "^3.0.0",
+ "markdown-it": "^14.1.0",
+ "markdown-it-anchor": "^8.6.7",
+ "marked": "^4.0.10",
+ "mkdirp": "^1.0.4",
+ "requizzle": "^0.2.3",
+ "strip-json-comments": "^3.1.0",
+ "underscore": "~1.13.2"
+ },
+ "bin": {
+ "jsdoc": "jsdoc.js"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/jsdom": {
+ "version": "30.0.1",
+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-30.0.1.tgz",
+ "integrity": "sha512-52v7mUVUfNQVYYqE1lcdaymWL0njO7lTLUog6ZvW2U5KsbiLk/GnZlVJ+qx0xfNJZ6Gn+KSpPNE52vurbxZwrA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@asamuzakjp/css-color": "^6.0.5",
+ "@asamuzakjp/dom-selector": "^8.3.0",
+ "@bramus/specificity": "^2.4.2",
+ "@csstools/css-syntax-patches-for-csstree": "^1.1.7",
+ "@exodus/bytes": "^1.15.1",
+ "css-tree": "^3.2.1",
+ "data-urls": "^7.0.0",
+ "decimal.js": "^10.6.0",
+ "html-encoding-sniffer": "^6.0.0",
+ "is-potential-custom-element-name": "^1.0.1",
+ "lru-cache": "^11.5.2",
+ "parse5": "^8.0.1",
+ "saxes": "^6.0.0",
+ "symbol-tree": "^3.2.4",
+ "tough-cookie": "^6.0.2",
+ "undici": "^8.9.0",
+ "w3c-xmlserializer": "^5.0.0",
+ "webidl-conversions": "^8.0.1",
+ "whatwg-mimetype": "^5.0.0",
+ "whatwg-url": "^17.1.0",
+ "xml-name-validator": "^5.0.0"
+ },
+ "engines": {
+ "node": "^22.22.2 || ^24.15.0 || >=26.0.0"
+ },
+ "peerDependencies": {
+ "canvas": "^3.2.3"
+ },
+ "peerDependenciesMeta": {
+ "canvas": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/klaw": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz",
+ "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.1.9"
+ }
+ },
+ "node_modules/linkify-it": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.2.tgz",
+ "integrity": "sha512-ONTm2jCMAVZjgQa/Fy1kScXsuOoF5NPTsoFBdE1KVIZ2vAh/r9+Bqo+0jINCBYnavTPQZz38QzFTme79ENoN3Q==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/puzrin"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/markdown-it"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "uc.micro": "^2.0.0"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lodash": {
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz",
+ "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lru-cache": {
+ "version": "11.5.2",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz",
+ "integrity": "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "engines": {
+ "node": "20 || >=22"
+ }
+ },
+ "node_modules/make-dir": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
+ "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "semver": "^7.5.3"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/markdown-it": {
+ "version": "14.3.0",
+ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.3.0.tgz",
+ "integrity": "sha512-RCEsPjR+sr0x+AuYp601tKTkgFG4YEPLCzHST3cQ/fhlJkqAkz1L2/Qbp1j9qw5SBwQHFBoW8+hoN5xssOF0Tw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/puzrin"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/markdown-it"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1",
+ "entities": "^4.5.0",
+ "linkify-it": "^5.0.2",
+ "mdurl": "^2.0.0",
+ "punycode.js": "^2.3.1",
+ "uc.micro": "^2.1.0"
+ },
+ "bin": {
+ "markdown-it": "bin/markdown-it.mjs"
+ }
+ },
+ "node_modules/markdown-it-anchor": {
+ "version": "8.6.7",
+ "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.7.tgz",
+ "integrity": "sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==",
+ "dev": true,
+ "license": "Unlicense",
+ "peerDependencies": {
+ "@types/markdown-it": "*",
+ "markdown-it": "*"
+ }
+ },
+ "node_modules/marked": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz",
+ "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "marked": "bin/marked.js"
+ },
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "node_modules/mdn-data": {
+ "version": "2.27.1",
+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz",
+ "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==",
+ "dev": true,
+ "license": "CC0-1.0"
+ },
+ "node_modules/mdurl": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.1.0.tgz",
+ "integrity": "sha512-1+HBaOx0zi/dQWht8rNv9MYf9qqpqL/kxI0hXImU6Y547zM6Sni8BQibt7ifgMcYtQg41ao3Ivd6cnSM86inpg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/minimatch": {
+ "version": "10.2.6",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz",
+ "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "brace-expansion": "^5.0.8"
+ },
+ "engines": {
+ "node": "18 || 20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/minipass": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz",
+ "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/mkdirp": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "mkdirp": "bin/cmd.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/package-json-from-dist": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
+ "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
+ "dev": true,
+ "license": "BlueOak-1.0.0"
+ },
+ "node_modules/parse5": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.1.tgz",
+ "integrity": "sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "entities": "^8.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
+ },
+ "node_modules/parse5/node_modules/entities": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-8.0.0.tgz",
+ "integrity": "sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=20.19.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-scurry": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
+ "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "lru-cache": "^10.2.0",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/path-scurry/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/playwright-core": {
+ "version": "1.62.1",
+ "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.62.1.tgz",
+ "integrity": "sha512-wPYSwEBJY9GHraISXqyqtx0na0LpO3XEX7jNDhntbex7tzUS7kLnZsOlFruFJB4Hi/rhDMjXGqHewDZ68nYZVw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "playwright-core": "cli.js"
+ },
+ "engines": {
+ "node": ">=20"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/punycode.js": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz",
+ "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/requizzle": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.4.tgz",
+ "integrity": "sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lodash": "^4.17.21"
+ }
+ },
+ "node_modules/saxes": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz",
+ "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "xmlchars": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=v12.22.7"
+ }
+ },
+ "node_modules/semver": {
+ "version": "7.8.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz",
+ "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/signal-exit": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-support": {
+ "version": "0.5.21",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+ "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "node_modules/string-width": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eastasianwidth": "^0.2.0",
+ "emoji-regex": "^9.2.2",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/string-width-cjs": {
+ "name": "string-width",
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width-cjs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width-cjs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/string-width-cjs/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz",
+ "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^6.2.2"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "node_modules/strip-ansi-cjs": {
+ "name": "strip-ansi",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi-cjs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/symbol-tree": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
+ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/terser": {
+ "version": "5.51.0",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.51.0.tgz",
+ "integrity": "sha512-myiQ6aFnxDOjdiXdTlC8ngVccQD88uHXTx5RUQOSEnarDYgJMjDagwAQszcOusjvmf4YqWsxoD1+MY+oAJRmpw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "@jridgewell/source-map": "^0.3.3",
+ "acorn": "^8.15.0",
+ "commander": "^2.20.0",
+ "source-map-support": "~0.5.20"
+ },
+ "bin": {
+ "terser": "bin/terser"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/test-exclude": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.2.tgz",
+ "integrity": "sha512-u9E6A+ZDYdp7a4WnarkXPZOx8Ilz46+kby6p1yZ8zsGTz9gYa6FIS7lj2oezzNKmtdyyJNNmmXDppga5GB7kSw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "@istanbuljs/schema": "^0.1.2",
+ "glob": "^10.4.1",
+ "minimatch": "^10.2.2"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tldts": {
+ "version": "7.4.11",
+ "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.4.11.tgz",
+ "integrity": "sha512-aBiNayCfTQxuIJBm06M+xR14cYaYlDlSXZbgsnKzKNxDKUVq7KFwTjwBSsb7m9Y5xO8WfPnBc63WaYFMTGlvqw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tldts-core": "^7.4.11"
+ },
+ "bin": {
+ "tldts": "bin/cli.js"
+ }
+ },
+ "node_modules/tldts-core": {
+ "version": "7.4.11",
+ "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.4.11.tgz",
+ "integrity": "sha512-CW3WN2rIIE/Of21mulhgnGOwoDyEFNygyIBOONSdyAuSATgMMUCpLeUlB+E8sAwA5xRV9hYPl+kyZ9citHCaKg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tough-cookie": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.2.tgz",
+ "integrity": "sha512-exgYmnmL/sJpR3upZfXG5PoatXQii55xAiXGXzY+sROLZ/Y+SLcp9PgJNI9Vz37HpQ74WvDcLT8eqm+kV3FzrA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "tldts": "^7.0.5"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/tr46": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-6.0.0.tgz",
+ "integrity": "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "punycode": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=20"
+ }
+ },
+ "node_modules/uc.micro": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
+ "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/underscore": {
+ "version": "1.13.8",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.8.tgz",
+ "integrity": "sha512-DXtD3ZtEQzc7M8m4cXotyHR+FAS18C64asBYY5vqZexfYryNNnDc02W4hKg3rdQuqOYas1jkseX0+nZXjTXnvQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/undici": {
+ "version": "8.10.0",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-8.10.0.tgz",
+ "integrity": "sha512-HvltHd7avK13QIw/oLe4qoOLyoVSoafqJ2jYOrtMRBkbYT31eiBQ8O0ehRKZiEZCMEyLFQNIADpgCWC5fALvYQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=22.19.0"
+ }
+ },
+ "node_modules/v8-to-istanbul": {
+ "version": "9.3.0",
+ "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz",
+ "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.12",
+ "@types/istanbul-lib-coverage": "^2.0.1",
+ "convert-source-map": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10.12.0"
+ }
+ },
+ "node_modules/w3c-xmlserializer": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz",
+ "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "xml-name-validator": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/webidl-conversions": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz",
+ "integrity": "sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=20"
+ }
+ },
+ "node_modules/whatwg-mimetype": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-5.0.0.tgz",
+ "integrity": "sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=20"
+ }
+ },
+ "node_modules/whatwg-url": {
+ "version": "17.1.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-17.1.0.tgz",
+ "integrity": "sha512-3GeworPmc2ZfEEHP7lEbUfBX/L75wdEsi0rLNhXcXxnoN5jyq0SL5gCy06SGW2cyTIZdTvWIDQNQoza++vKeaw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@exodus/bytes": "^1.15.1",
+ "tr46": "^6.0.0",
+ "webidl-conversions": "^8.0.1"
+ },
+ "engines": {
+ "node": "^22.14.0 || >=24.0.0"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/wrap-ansi": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
+ "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.1.0",
+ "string-width": "^5.0.1",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs": {
+ "name": "wrap-ansi",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/xml-name-validator": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz",
+ "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/xmlchars": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
+ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/xmlcreate": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz",
+ "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yargs": {
+ "version": "17.7.3",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz",
+ "integrity": "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cliui": "^8.0.1",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.3",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^21.1.1"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yargs-parser": {
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yargs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/yargs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/yargs/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/yargs/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ }
+ }
+}
diff --git a/node_modules/@xmldom/xmldom/CHANGELOG.md b/node_modules/@xmldom/xmldom/CHANGELOG.md
new file mode 100644
index 000000000..153494a5c
--- /dev/null
+++ b/node_modules/@xmldom/xmldom/CHANGELOG.md
@@ -0,0 +1,1132 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## [0.9.12](https://github.com/xmldom/xmldom/compare/0.9.11...0.9.12)
+
+### Fixed
+
+- Security: parsing a deeply or repeatedly namespaced document no longer consumes quadratic memory; the in-scope namespace map is inherited through the prototype chain instead of being copied for every prefix-declaring element (O(N) instead of O(N²)), preventing a denial-of-service reachable from `DOMParser.parseFromString` with default options. Serialized output is byte-identical. [`GHSA-965w-775f-mr7g`](https://github.com/xmldom/xmldom/security/advisories/GHSA-965w-775f-mr7g)
+- Security: attribute de-duplication during parsing is now O(M) instead of O(M²); the `NamedNodeMap` parse-time dedup path uses a null-prototype membership index, so a well-formed document with a hostile number of duplicate attributes can no longer wedge the parse. Attribute order and duplicate resolution (last value wins, first position kept) are byte-identical, preserving the XML [no-duplicate-attributes well-formedness constraint](https://www.w3.org/TR/xml/#uniqattspec). [`GHSA-8344-3jmq-59r6`](https://github.com/xmldom/xmldom/security/advisories/GHSA-8344-3jmq-59r6)
+- Security: HTML raw-text parsing no longer amplifies output on a missing or case-mismatched closing tag; the closing tag is matched case-insensitively per the WHATWG HTML [RAWTEXT end-tag rule](https://html.spec.whatwg.org/multipage/parsing.html#rawtext-end-tag-name-state) and a missing closing tag is handled explicitly, preventing a denial-of-service. Output for well-formed input is unchanged. [`GHSA-6mj3-qw4j-hgrw`](https://github.com/xmldom/xmldom/security/advisories/GHSA-6mj3-qw4j-hgrw)
+- Security: malformed-input recovery is now linear instead of quadratic — the malformed tag-name scan terminates at an embedded `<`, and `Node.prototype.normalize()` merges adjacent text nodes in O(K) instead of O(K²) (also reachable programmatically), per [`normalize()`](https://dom.spec.whatwg.org/#dom-node-normalize) in the WHATWG DOM spec. DOM output is unchanged; only the reported error text differs. [`GHSA-93r5-fhx6-vmg9`](https://github.com/xmldom/xmldom/security/advisories/GHSA-93r5-fhx6-vmg9)
+- Security: `XMLSerializer.serializeToString()` under `{ requireWellFormed: true }` now rejects a DocType `name` that is not a valid XML [`Name`](https://www.w3.org/TR/xml/#NT-Name), throwing `InvalidStateError` — matching the sibling `publicId`/`systemId`/`internalSubset` checks and preventing XML injection via `DocumentType.name`. [`GHSA-27p8-2357-5qqv`](https://github.com/xmldom/xmldom/security/advisories/GHSA-27p8-2357-5qqv)
+- Security: `XMLSerializer.serializeToString()` under `{ requireWellFormed: true }` now validates a processing-instruction target as an XML [`NCName`](https://www.w3.org/TR/xml-names/#NT-NCName) and rejects a case-insensitive `xml`, throwing `InvalidStateError` — preventing PI-target injection via `>`, `?`, or whitespace. [`GHSA-c7q8-3ch8-vqpv`](https://github.com/xmldom/xmldom/security/advisories/GHSA-c7q8-3ch8-vqpv)
+- Security: `Document.createEntityReference()` now rejects an invalid XML [`Name`](https://www.w3.org/TR/xml/#NT-Name) at creation, and `XMLSerializer.serializeToString()` under `{ requireWellFormed: true }` validates an `EntityReference` `nodeName` as an XML `Name`, throwing `InvalidStateError` — preventing XML injection via an entity-reference name. [`GHSA-6gmq-8vp8-gcm6`](https://github.com/xmldom/xmldom/security/advisories/GHSA-6gmq-8vp8-gcm6)
+- Security: the `requireWellFormed` serializer's element- and attribute-name validators no longer treat an interior line terminator as satisfying the name anchors, so a name containing a line terminator is rejected with `InvalidStateError` — closing a bypass of the XML [`QName`](https://www.w3.org/TR/xml-names/#NT-QName) check. [`GHSA-jxjr-3g7g-3944`](https://github.com/xmldom/xmldom/security/advisories/GHSA-jxjr-3g7g-3944)
+- Security: the `requireWellFormed` serializer's DocType `publicId`/`systemId` validators no longer treat an interior line terminator as satisfying the anchor, so an identifier containing an ECMAScript line terminator is rejected with `InvalidStateError` — closing a bypass of the XML [`PubidLiteral`](https://www.w3.org/TR/xml/#NT-PubidLiteral)/`SystemLiteral` check. [`GHSA-vr34-hp96-76pp`](https://github.com/xmldom/xmldom/security/advisories/GHSA-vr34-hp96-76pp)
+- Security: `createElementNS()`, `createAttributeNS()`, `createDocumentType()`, and `createAttribute()` now reject a name containing a line terminator with `InvalidCharacterError`, because name validation applies to the whole string — closing a creation-time bypass of the XML [`Name`/`QName`](https://www.w3.org/TR/xml-names/#NT-QName) production on the default serialization path. [`GHSA-3px3-54cx-rmw9`](https://github.com/xmldom/xmldom/security/advisories/GHSA-3px3-54cx-rmw9)
+- Security: the parser now reports a not-well-formed end tag whose valid name is followed by trailing content (a recoverable `error` in XML, a `warning` in HTML) instead of accepting it silently, per the XML [`ETag`](https://www.w3.org/TR/xml/#NT-ETag) production; parsing recovers to the byte-identical DOM. Consumers that want strict rejection can escalate the reported `error` to fatal via the parser's `onError` handler. [`GHSA-6h8r-xr42-gp59`](https://github.com/xmldom/xmldom/security/advisories/GHSA-6h8r-xr42-gp59)
+- `DOMException`s raised during parsing are now reported as a `fatalError`, and the originating error is preserved as the `cause` on the resulting `ParseError`.
+
+### Chore
+
+- updated dependencies
+
+Thank you,
+[@ericchiang](https://github.com/ericchiang),
+[@KarimTantawey](https://github.com/KarimTantawey),
+[@bhaswanthc](https://github.com/bhaswanthc),
+[@arpitjain099](https://github.com/arpitjain099),
+[@Paranoidgrinch](https://github.com/Paranoidgrinch),
+for your contributions
+
+## [0.8.15](https://github.com/xmldom/xmldom/compare/0.8.14...0.8.15)
+
+### Fixed
+
+- Security: parsing a deeply or repeatedly namespaced document no longer consumes quadratic memory; the in-scope namespace map is inherited through the prototype chain instead of being copied for every prefix-declaring element (O(N) instead of O(N²)), preventing a denial-of-service reachable from `DOMParser.parseFromString` with default options. Serialized output is byte-identical. [`GHSA-965w-775f-mr7g`](https://github.com/xmldom/xmldom/security/advisories/GHSA-965w-775f-mr7g)
+- Security: attribute de-duplication during parsing is now O(M) instead of O(M²); the `NamedNodeMap` parse-time dedup path uses a null-prototype membership index, so a well-formed document with a hostile number of duplicate attributes can no longer wedge the parse. Attribute order and duplicate resolution (last value wins, first position kept) are byte-identical, preserving the XML [no-duplicate-attributes well-formedness constraint](https://www.w3.org/TR/xml/#uniqattspec). [`GHSA-8344-3jmq-59r6`](https://github.com/xmldom/xmldom/security/advisories/GHSA-8344-3jmq-59r6)
+- Security: trimming trailing whitespace from an XML end tag ([`ETag`](https://www.w3.org/TR/xml/#NT-ETag)) is now anchored so it runs in linear time instead of backtracking quadratically on a long whitespace run, preventing a ReDoS reachable from `DOMParser.parseFromString`. Trimmed output is byte-identical. [`GHSA-x4fp-j954-r2f4`](https://github.com/xmldom/xmldom/security/advisories/GHSA-x4fp-j954-r2f4)
+- Security: malformed-input recovery is now linear instead of quadratic — the malformed tag-name scan terminates at an embedded `<`, and `Node.prototype.normalize()` merges adjacent text nodes in O(K) instead of O(K²) (also reachable programmatically), per [`normalize()`](https://dom.spec.whatwg.org/#dom-node-normalize) in the WHATWG DOM spec. DOM output is unchanged; only the reported error text differs. [`GHSA-93r5-fhx6-vmg9`](https://github.com/xmldom/xmldom/security/advisories/GHSA-93r5-fhx6-vmg9)
+- Security: `XMLSerializer.serializeToString()` under `{ requireWellFormed: true }` now rejects a DocType `name` that is not a valid XML [`Name`](https://www.w3.org/TR/xml/#NT-Name), throwing `InvalidStateError` — matching the sibling `publicId`/`systemId`/`internalSubset` checks and preventing XML injection via `DocumentType.name`. [`GHSA-27p8-2357-5qqv`](https://github.com/xmldom/xmldom/security/advisories/GHSA-27p8-2357-5qqv)
+- Security: `XMLSerializer.serializeToString()` under `{ requireWellFormed: true }` now validates a processing-instruction target as an XML [`NCName`](https://www.w3.org/TR/xml-names/#NT-NCName) and rejects a case-insensitive `xml`, throwing `InvalidStateError` — a check `0.8.x` did not previously perform, preventing PI-target injection via `>`, `?`, or whitespace. [`GHSA-c7q8-3ch8-vqpv`](https://github.com/xmldom/xmldom/security/advisories/GHSA-c7q8-3ch8-vqpv)
+- Security: `Document.createEntityReference()` now rejects an invalid XML [`Name`](https://www.w3.org/TR/xml/#NT-Name) at creation, and `XMLSerializer.serializeToString()` under `{ requireWellFormed: true }` validates an `EntityReference` `nodeName` as an XML `Name`, throwing `InvalidStateError` — preventing XML injection via an entity-reference name. [`GHSA-6gmq-8vp8-gcm6`](https://github.com/xmldom/xmldom/security/advisories/GHSA-6gmq-8vp8-gcm6)
+- Security: the parser now reports a not-well-formed end tag whose valid name is followed by trailing content as a recoverable `error` instead of accepting it silently, per the XML [`ETag`](https://www.w3.org/TR/xml/#NT-ETag) production; parsing recovers to the byte-identical DOM. Consumers that want strict rejection can escalate the reported `error` to fatal via the parser's `errorHandler`. [`GHSA-6h8r-xr42-gp59`](https://github.com/xmldom/xmldom/security/advisories/GHSA-6h8r-xr42-gp59)
+
+Thank you,
+[@ericchiang](https://github.com/ericchiang),
+[@bhaswanthc](https://github.com/bhaswanthc),
+[@arpitjain099](https://github.com/arpitjain099),
+[@Paranoidgrinch](https://github.com/Paranoidgrinch),
+for your contributions
+
+## [0.9.11](https://github.com/xmldom/xmldom/compare/0.9.10...0.9.11)
+
+### Fixed
+
+- Security: `XMLSerializer.serializeToString()` now also rejects invalid element and attribute names when `{ requireWellFormed: true }` is passed, throwing `InvalidStateError` for a name that is not a valid XML [`QName`](https://www.w3.org/TR/xml-names/#NT-QName) (this covers the namespace prefix, which surfaces in the element qualified name or in a synthesized `xmlns:` declaration). This prevents XML injection via `createElement()` / `setAttribute()`, extending the existing `requireWellFormed` checks to the serialized name set. [`GHSA-w2rr-34g9-rvrj`](https://github.com/xmldom/xmldom/security/advisories/GHSA-w2rr-34g9-rvrj) [`GHSA-4w3w-2rp5-g8jm`](https://github.com/xmldom/xmldom/security/advisories/GHSA-4w3w-2rp5-g8jm)
+- Security: the processing-instruction grammar regex no longer backtracks quadratically on an unterminated processing instruction (`…` with no closing `?>`), preventing a denial-of-service (ReDoS) reachable from `DOMParser.parseFromString` with default options. [`GHSA-g53g-w8rj-fmg7`](https://github.com/xmldom/xmldom/security/advisories/GHSA-g53g-w8rj-fmg7)
+- `CharacterData` `nodeValue` and `data` are now kept in sync [`#990`](https://github.com/xmldom/xmldom/pull/990)
+
+### Chore
+
+- updated dependencies
+
+Thank you,
+[@bhaswanthc](https://github.com/bhaswanthc),
+[@jmestwa-coder](https://github.com/jmestwa-coder),
+[@stevenobiajulu](https://github.com/stevenobiajulu),
+for your contributions
+
+## [0.8.14](https://github.com/xmldom/xmldom/compare/0.8.13...0.8.14)
+
+### Fixed
+
+- Security: `XMLSerializer.serializeToString()` now also rejects invalid element and attribute names when `{ requireWellFormed: true }` is passed, throwing `InvalidStateError` for a name that is not a valid XML [`QName`](https://www.w3.org/TR/xml-names/#NT-QName) (this covers the namespace prefix, which surfaces in the element qualified name or in a synthesized `xmlns:` declaration). This prevents XML injection via `createElement()` / `setAttribute()`, extending the existing `requireWellFormed` checks to the serialized name set. [`GHSA-w2rr-34g9-rvrj`](https://github.com/xmldom/xmldom/security/advisories/GHSA-w2rr-34g9-rvrj) [`GHSA-4w3w-2rp5-g8jm`](https://github.com/xmldom/xmldom/security/advisories/GHSA-4w3w-2rp5-g8jm)
+
+Thank you,
+[@bhaswanthc](https://github.com/bhaswanthc),
+[@jmestwa-coder](https://github.com/jmestwa-coder),
+for your contributions
+
+## [0.9.10](https://github.com/xmldom/xmldom/compare/0.9.9...0.9.10)
+
+### Fixed
+
+- Security: `XMLSerializer.serializeToString()` (and `Node.toString()`, `NodeList.toString()`) now accept a `requireWellFormed` option. When `{ requireWellFormed: true }` is passed, the serializer throws `InvalidStateError` for injection-prone node content, preventing XML injection via attacker-controlled node data. [`GHSA-j759-j44w-7fr8`](https://github.com/xmldom/xmldom/security/advisories/GHSA-j759-j44w-7fr8) [`GHSA-x6wf-f3px-wcqx`](https://github.com/xmldom/xmldom/security/advisories/GHSA-x6wf-f3px-wcqx) [`GHSA-f6ww-3ggp-fr8h`](https://github.com/xmldom/xmldom/security/advisories/GHSA-f6ww-3ggp-fr8h)
+ - Comment: throws when `data` contains `--` anywhere, ends with `-`, or contains characters outside the XML `Char` production
+ - ProcessingInstruction: throws when target contains `:` or matches `xml` (case-insensitive), or `data` contains characters outside the XML `Char` production or contains `?>`
+ - DocumentType: throws when `publicId` fails `PubidLiteral`, `systemId` fails `SystemLiteral`, or `internalSubset` contains `]>`
+- Security: DOM traversal operations (`XMLSerializer.serializeToString()`, `Node.prototype.normalize()`, `Node.prototype.cloneNode(true)`, `Document.prototype.importNode(node, true)`, `node.textContent` getter, `getElementsByTagName()` / `getElementsByTagNameNS()` / `getElementsByClassName()` / `getElementById()`, `Node.prototype.isEqualNode()`) are now iterative. Previously, deeply nested DOM trees would exhaust the JavaScript call stack and throw an unrecoverable `RangeError`. [`GHSA-2v35-w6hq-6mfw`](https://github.com/xmldom/xmldom/security/advisories/GHSA-2v35-w6hq-6mfw)
+- `isEqualNode` now correctly returns `false` for CDATASection nodes with different `data`
+
+### Deprecated
+
+- The `splitCDATASections` serializer option is deprecated and will be removed in the next breaking release. The automatic splitting of `"]]>"` in `CDATASection` data was introduced as a workaround; use `requireWellFormed: true` or ensure `CDATASection` data does not contain `"]]>"` before serialization.
+
+### Chore
+
+- updated dependencies
+
+Thank you,
+[@Jvr2022](https://github.com/Jvr2022),
+[@praveen-kv](https://github.com/praveen-kv),
+[@TharVid](https://github.com/TharVid),
+[@decsecre583](https://github.com/decsecre583),
+[@tlsbollei](https://github.com/tlsbollei),
+[@KarimTantawey](https://github.com/KarimTantawey),
+for your contributions
+
+## [0.8.13](https://github.com/xmldom/xmldom/compare/0.8.12...0.8.13)
+
+### Fixed
+
+- Security: `XMLSerializer.serializeToString()` (and `Node.toString()`, `NodeList.toString()`) now accept a `requireWellFormed` option (fourth argument, after `isHtml` and `nodeFilter`). When `{ requireWellFormed: true }` is passed, the serializer throws `InvalidStateError` for injection-prone node content, preventing XML injection via attacker-controlled node data. [`GHSA-j759-j44w-7fr8`](https://github.com/xmldom/xmldom/security/advisories/GHSA-j759-j44w-7fr8) [`GHSA-x6wf-f3px-wcqx`](https://github.com/xmldom/xmldom/security/advisories/GHSA-x6wf-f3px-wcqx) [`GHSA-f6ww-3ggp-fr8h`](https://github.com/xmldom/xmldom/security/advisories/GHSA-f6ww-3ggp-fr8h)
+ - Comment: throws when `data` contains `-->`
+ - ProcessingInstruction: throws when `data` contains `?>`
+ - DocumentType: throws when `publicId` fails `PubidLiteral`, `systemId` fails `SystemLiteral`, or `internalSubset` contains `]>`
+- Security: DOM traversal operations (`XMLSerializer.serializeToString()`, `Node.prototype.normalize()`, `Node.prototype.cloneNode(true)`, `Document.prototype.importNode(node, true)`, `node.textContent` getter, `getElementsByTagName()` / `getElementsByTagNameNS()` / `getElementsByClassName()` / `getElementById()`) are now iterative. Previously, deeply nested DOM trees would exhaust the JavaScript call stack and throw an unrecoverable `RangeError`. [`GHSA-2v35-w6hq-6mfw`](https://github.com/xmldom/xmldom/security/advisories/GHSA-2v35-w6hq-6mfw)
+
+Thank you,
+[@Jvr2022](https://github.com/Jvr2022),
+[@praveen-kv](https://github.com/praveen-kv),
+[@TharVid](https://github.com/TharVid),
+[@decsecre583](https://github.com/decsecre583),
+[@tlsbollei](https://github.com/tlsbollei),
+[@KarimTantawey](https://github.com/KarimTantawey),
+for your contributions
+
+
+## [0.9.9](https://github.com/xmldom/xmldom/compare/0.9.8...0.9.9)
+
+### Added
+
+- implement `ParentNode.children` getter [`#960`](https://github.com/xmldom/xmldom/pull/960) / [`#410`](https://github.com/xmldom/xmldom/issues/410)
+
+### Fixed
+
+- Security: `createCDATASection` now throws `InvalidCharacterError` when `data` contains `"]]>"`, as required by the [WHATWG DOM spec](https://dom.spec.whatwg.org/#dom-document-createcdatasection). [`GHSA-wh4c-j3r5-mjhp`](https://github.com/xmldom/xmldom/security/advisories/GHSA-wh4c-j3r5-mjhp)
+- Security: `XMLSerializer` now splits CDATASection nodes whose data contains `"]]>"` into adjacent CDATA sections at serialization time, preventing XML injection via mutation methods (`appendData`, `replaceData`, `.data =`, `.textContent =`). [`GHSA-wh4c-j3r5-mjhp`](https://github.com/xmldom/xmldom/security/advisories/GHSA-wh4c-j3r5-mjhp)
+- correctly traverse ancestor chain in `Node.contains` [`#931`](https://github.com/xmldom/xmldom/pull/931)
+
+Code that passes a string containing `"]]>"` to `createCDATASection` and relied on the previously unsafe behavior will now receive `InvalidCharacterError`. Use a mutation method such as `appendData` if you intentionally need `"]]>"` in a CDATASection node's data.
+
+### Chore
+
+- updated dependencies
+
+Thank you,
+[@stevenobiajulu](https://github.com/stevenobiajulu),
+[@yoshi389111](https://github.com/yoshi389111),
+[@thesmartshadow](https://github.com/thesmartshadow),
+for your contributions
+
+
+## [0.8.12](https://github.com/xmldom/xmldom/compare/0.8.11...0.8.12)
+
+### Fixed
+
+- preserve trailing whitespace in ProcessingInstruction data [`#962`](https://github.com/xmldom/xmldom/pull/962) / [`#42`](https://github.com/xmldom/xmldom/issues/42)
+- Security: `createCDATASection` now throws `InvalidCharacterError` when `data` contains `"]]>"`, as required by the [WHATWG DOM spec](https://dom.spec.whatwg.org/#dom-document-createcdatasection). [`GHSA-wh4c-j3r5-mjhp`](https://github.com/xmldom/xmldom/security/advisories/GHSA-wh4c-j3r5-mjhp)
+- Security: `XMLSerializer` now splits CDATASection nodes whose data contains `"]]>"` into adjacent CDATA sections at serialization time, preventing XML injection via mutation methods (`appendData`, `replaceData`, `.data =`, `.textContent =`). [`GHSA-wh4c-j3r5-mjhp`](https://github.com/xmldom/xmldom/security/advisories/GHSA-wh4c-j3r5-mjhp)
+
+Code that passes a string containing `"]]>"` to `createCDATASection` and relied on the previously unsafe behavior will now receive `InvalidCharacterError`. Use a mutation method such as `appendData` if you intentionally need `"]]>"` in a CDATASection node's data.
+
+Thank you,
+[@thesmartshadow](https://github.com/thesmartshadow),
+[@stevenobiajulu](https://github.com/stevenobiajulu),
+for your contributions
+
+## [0.8.11](https://github.com/xmldom/xmldom/compare/0.8.10...0.8.11)
+
+### Fixed
+
+- update `ownerDocument` when moving nodes between documents [`#933`](https://github.com/xmldom/xmldom/pull/933) / [`#932`](https://github.com/xmldom/xmldom/issues/932)
+
+Thank you, [@shunkica](https://github.com/shunkica), for your contributions
+
+## [0.9.8](https://github.com/xmldom/xmldom/compare/0.9.7...0.9.8)
+
+### Fixed
+
+- fix: replace \u2029 as part of normalizeLineEndings [`#839`](https://github.com/xmldom/xmldom/pull/839) / [`#838`](https://github.com/xmldom/xmldom/issues/838)
+- perf: speed up line detection [`#847`](https://github.com/xmldom/xmldom/pull/847) / [`#838`](https://github.com/xmldom/xmldom/issues/838)
+
+### Chore
+
+- updated dependencies
+- drop jazzer and rxjs devDependencies [`#845`](https://github.com/xmldom/xmldom/pull/845)
+
+Thank you,
+[@kboshold](https://github.com/kboshold),
+[@Ponynjaa](https://github.com/Ponynjaa),
+for your contributions.
+
+
+## [0.9.7](https://github.com/xmldom/xmldom/compare/0.9.6...0.9.7)
+
+### Added
+
+- Implementation of `hasAttributes` [`#804`](https://github.com/xmldom/xmldom/pull/804)
+
+### Fixed
+
+- locator is now true even when other options are being used for the DOMParser [`#802`](https://github.com/xmldom/xmldom/issues/802) / [`#803`](https://github.com/xmldom/xmldom/pull/803)
+- allow case-insensitive DOCTYPE in HTML [`#817`](https://github.com/xmldom/xmldom/issues/817) / [`#819`](https://github.com/xmldom/xmldom/pull/819)
+
+### Performance
+
+- simplify `DOM.compareDocumentPosition` [`#805`](https://github.com/xmldom/xmldom/pull/805)
+
+### Chore
+
+- updated devDependencies
+
+Thank you,
+[@zorkow](https://github.com/zorkow),
+[@Ponynjaa](https://github.com/Ponynjaa),
+[@WesselKroos](https://github.com/WesselKroos),
+for your contributions.
+
+
+## [0.9.6](https://github.com/xmldom/xmldom/compare/0.9.5...0.9.6)
+
+### Fixed
+
+- lower error level for unicode replacement character [`#790`](https://github.com/xmldom/xmldom/issues/790) / [`#794`](https://github.com/xmldom/xmldom/pull/794) / [`#797`](https://github.com/xmldom/xmldom/pull/797)
+
+### Chore
+
+- updated devDependencies
+- migrate renovate config [`#792`](https://github.com/xmldom/xmldom/pull/792)
+
+Thank you, [@eglitise](https://github.com/eglitise), for your contributions.
+
+
+## [0.9.5](https://github.com/xmldom/xmldom/compare/0.9.4...0.9.5)
+
+### Fixed
+
+- fix: re-index childNodes on insertBefore [`#763`](https://github.com/xmldom/xmldom/issues/763) / [`#766`](https://github.com/xmldom/xmldom/pull/766)
+
+Thank you,
+[@mureinik](https://github.com/mureinik),
+for your contributions.
+
+
+## [0.9.4](https://github.com/xmldom/xmldom/compare/0.9.3...0.9.4)
+
+### Fixed
+
+- restore performance for large amount of child nodes [`#748`](https://github.com/xmldom/xmldom/issues/748) / [`#760`](https://github.com/xmldom/xmldom/pull/760)
+- types: correct error handler level to `warning` (#759) [`#754`](https://github.com/xmldom/xmldom/issues/754) / [`#759`](https://github.com/xmldom/xmldom/pull/759)
+
+### Docs
+
+- test: verify BOM handling [`#758`](https://github.com/xmldom/xmldom/pull/758)
+
+Thank you,
+[@luffynando](https://github.com/luffynando),
+[@mattiasw](https://github.com/mattiasw),
+[@JoinerDev](https://github.com/JoinerDev),
+for your contributions.
+
+
+## [0.9.3](https://github.com/xmldom/xmldom/compare/0.9.2...0.9.3)
+
+### Fixed
+
+- restore more `Node` and `ProcessingInstruction` types [`#725`](https://github.com/xmldom/xmldom/issues/725) / [`#726`](https://github.com/xmldom/xmldom/pull/726)
+- `getElements*` methods return `LiveNodeList<Element>` [`#731`](https://github.com/xmldom/xmldom/issues/731) / [`#734`](https://github.com/xmldom/xmldom/pull/734)
+- Add more missing `Node` props [`#728`](https://github.com/xmldom/xmldom/pull/728), triggered by unclosed [`#724`](https://github.com/xmldom/xmldom/pull/724)
+
+### Docs
+
+- Update supported runtimes in readme (NodeJS >= 14.6 and other [ES5 compatible runtimes](https://compat-table.github.io/compat-table/es5/))
+
+### Chore
+
+- updates devDependencies
+
+Thank you,
+[@Ponynjaa](https://github.com/Ponynjaa),
+[@ayZagen](https://github.com/ayZagen),
+[@sserdyuk](https://github.com/sserdyuk),
+[@wydengyre](https://github.com/wydengyre),
+[@mykola-mokhnach](https://github.com/mykola-mokhnach),
+[@benkroeger](https://github.com/benkroeger),
+for your contributions.
+
+
+## [0.9.2](https://github.com/xmldom/xmldom/compare/0.9.1...0.9.2)
+
+### Feature
+
+- add `Element.getElementsByClassName` [`#722`](https://github.com/xmldom/xmldom/pull/722)
+
+### Fixed
+
+- add missing types for `Document.documentElement` and `Element.tagName` [`#721`](https://github.com/xmldom/xmldom/pull/721) [`#720`](https://github.com/xmldom/xmldom/issues/720)
+
+Thank you, [@censujiang](https://github.com/censujiang), [@Mathias-S](https://github.com/Mathias-S), for your contributions
+
+
+## [0.9.1](https://github.com/xmldom/xmldom/compare/0.9.0...0.9.1)
+
+### Fixed
+
+- DOMParser.parseFromString requires mimeType as second argument [`#713`](https://github.com/xmldom/xmldom/pull/713)
+- correct spelling of `isHTMLMimeType` in type definition [`#715`](https://github.com/xmldom/xmldom/pull/715) / [`#712`](https://github.com/xmldom/xmldom/issues/712)
+- sync types with exports [`#717`](https://github.com/xmldom/xmldom/pull/717) / [`#285`](https://github.com/xmldom/xmldom/issues/285) / [`#695`](https://github.com/xmldom/xmldom/issues/695)
+
+### Other
+
+- minimum tested node version is 14 [`#710`](https://github.com/xmldom/xmldom/pull/710)
+
+Thank you, [@krystofwoldrich](https://github.com/krystofwoldrich), [@marvinruder](https://github.com/marvinruder), [@amacneil](https://github.com/amacneil), [@defunctzombie](https://github.com/defunctzombie),
+[@tjhorner](https://github.com/tjhorner), [@danon](https://github.com/danon), for your contributions
+
+
+## [0.9.0](https://github.com/xmldom/xmldom/compare/0.9.0-beta.11...0.9.0)
+
+- [Discussion](https://github.com/xmldom/xmldom/discussions/435)
+- [Summary on dev.to](https://dev.to/karfau/release-090-of-xmldomxmldom-4106)
+
+### Features
+
+- feat: expose all DOM level 2 element prototypes [`#637`](https://github.com/xmldom/xmldom/pull/637) / [`#40`](https://github.com/xmldom/xmldom/issues/40)
+- feat: add iterator function to NodeList and NamedNodeMap [`#634`](https://github.com/xmldom/xmldom/pull/634) / [`#633`](https://github.com/xmldom/xmldom/issues/633)
+
+### Fixed
+
+- parse empty/whitspace only doctype internal subset [`#692`](https://github.com/xmldom/xmldom/pull/692)
+- avoid prototype clash in namespace prefix [`#554`](https://github.com/xmldom/xmldom/pull/554)
+- report fatalError when doctype is inside elements [`#550`](https://github.com/xmldom/xmldom/pull/550)
+
+### Other
+
+- test: add fuzz target and regression tests [`#556`](https://github.com/xmldom/xmldom/pull/556)
+- chore: improve .gitignore and provide .envrc.template [`#697`](https://github.com/xmldom/xmldom/pull/697)
+- chore: Apply security best practices [`#546`](https://github.com/xmldom/xmldom/pull/546)
+- ci: check test coverage in PRs [`#524`](https://github.com/xmldom/xmldom/pull/524)
+- docs: add missing commas to readme [`#566`](https://github.com/xmldom/xmldom/pull/566)
+- docs: click to copy install command in readme [`#644`](https://github.com/xmldom/xmldom/pull/644)
+- docs: enhance jsdoc comments [`#511`](https://github.com/xmldom/xmldom/pull/511)
+
+Thank you, [@kboshold](https://github.com/kboshold), [@edi9999](https://github.com/edi9999), [@apupier](https://github.com/apupier),
+[@shunkica](https://github.com/shunkica), [@homer0](https://github.com/homer0), [@jhauga](https://github.com/jhauga),
+[@UdayKharatmol](https://github.com/UdayKharatmol), for your contributions
+
+
+## [0.9.0-beta.11](https://github.com/xmldom/xmldom/compare/0.9.0-beta.10...0.9.0-beta.11)
+
+### Fixed
+
+- report more non well-formed cases [`#519`](https://github.com/xmldom/xmldom/pull/519) / [`#45`](https://github.com/xmldom/xmldom/issues/45) / [`#125`](https://github.com/xmldom/xmldom/issues/125) / [`#467`](https://github.com/xmldom/xmldom/issues/467)
+ BREAKING-CHANGE: Reports more not well-formed documents as fatalError
+ and drop broken support for optional and unclosed tags in HTML.
+
+### Other
+
+- Translate/drop non English comments [`#518`](https://github.com/xmldom/xmldom/pull/518)
+- use node v16 for development [`#517`](https://github.com/xmldom/xmldom/pull/517)
+
+Thank you, [@brodybits](https://github.com/brodybits), [@cbettinger](https://github.com/cbettinger), [@josecarlosrx](https://github.com/josecarlosrx), for your contributions
+
+
+## [0.9.0-beta.10](https://github.com/xmldom/xmldom/compare/0.9.0-beta.9...0.9.0-beta.10)
+
+### Fixed
+
+- dom: prevent iteration over deleted items [`#514`](https://github.com/xmldom/xmldom/pull/514)/ [`#499`](https://github.com/xmldom/xmldom/issues/499)
+
+### Chore
+
+- use prettier plugin for jsdoc [`#513`](https://github.com/xmldom/xmldom/pull/513)
+
+Thank you, [@qtow](https://github.com/qtow), [@shunkica](https://github.com/shunkica), [@homer0](https://github.com/homer0), for your contributions
+
+
+## [0.8.10](https://github.com/xmldom/xmldom/compare/0.8.9...0.8.10)
+
+### Fixed
+
+- dom: prevent iteration over deleted items [`#514`](https://github.com/xmldom/xmldom/pull/514)/ [`#499`](https://github.com/xmldom/xmldom/issues/499)
+
+Thank you, [@qtow](https://github.com/qtow), for your contributions
+
+
+## [0.7.13](https://github.com/xmldom/xmldom/compare/0.7.12...0.7.13)
+
+### Fixed
+
+- dom: prevent iteration over deleted items [`#514`](https://github.com/xmldom/xmldom/pull/514)/ [`#499`](https://github.com/xmldom/xmldom/issues/499)
+
+Thank you, [@qtow](https://github.com/qtow), for your contributions
+
+
+## [0.9.0-beta.9](https://github.com/xmldom/xmldom/compare/0.9.0-beta.8...0.9.0-beta.9)
+
+### Fixed
+
+- Set nodeName property in ProcessingInstruction [`#509`](https://github.com/xmldom/xmldom/pull/509) / [`#505`](https://github.com/xmldom/xmldom/issues/505)
+- preserve DOCTYPE internal subset [`#498`](https://github.com/xmldom/xmldom/pull/498) / [`#497`](https://github.com/xmldom/xmldom/pull/497) / [`#117`](https://github.com/xmldom/xmldom/issues/117)\
+ BREAKING CHANGES: Many documents that were previously accepted by xmldom, esecially non well-formed ones are no longer accepted. Some issues that were formerly reported as errors are now a fatalError.
+- DOMParser: Align parseFromString errors with specs [`#454`](https://github.com/xmldom/xmldom/pull/454)
+
+### Chore
+
+- stop running mutation tests using stryker [`#496`](https://github.com/xmldom/xmldom/pull/496)
+- make `toErrorSnapshot` windows compatible [`#503`](https://github.com/xmldom/xmldom/pull/503)
+
+Thank you, [@cjbarth](https://github.com/cjbarth), [@shunkica](https://github.com/shunkica), [@pmahend1](https://github.com/pmahend1), [@niklasl](https://github.com/niklasl), for your contributions
+
+
+## [0.8.9](https://github.com/xmldom/xmldom/compare/0.8.8...0.8.9)
+
+### Fixed
+
+- Set nodeName property in ProcessingInstruction [`#509`](https://github.com/xmldom/xmldom/pull/509) / [`#505`](https://github.com/xmldom/xmldom/issues/505)
+
+Thank you, [@cjbarth](https://github.com/cjbarth), for your contributions
+
+
+## [0.7.12](https://github.com/xmldom/xmldom/compare/0.7.11...0.7.12)
+
+### Fixed
+
+- Set nodeName property in ProcessingInstruction [`#509`](https://github.com/xmldom/xmldom/pull/509) / [`#505`](https://github.com/xmldom/xmldom/issues/505)
+
+Thank you, [@cjbarth](https://github.com/cjbarth), for your contributions
+
+
+## [0.9.0-beta.8](https://github.com/xmldom/xmldom/compare/0.9.0-beta.7...0.9.0-beta.8)
+
+### Fixed
+
+- Throw DOMException when calling removeChild with invalid parameter [`#494`](https://github.com/xmldom/xmldom/pull/494) / [`#135`](https://github.com/xmldom/xmldom/issues/135)
+
+BREAKING CHANGE: Previously it was possible (but not documented) to call `Node.removeChild` with any node in the tree,
+and with certain exceptions, it would work. This is no longer the case: calling `Node.removeChild` with an argument that is not a direct child of the node that it is called from, will throw a NotFoundError DOMException, as it is described by the specs.
+
+Thank you, [@noseworthy](https://github.com/noseworthy), [@davidmc24](https://github.com/davidmc24), for your contributions
+
+
+## [0.9.0-beta.7](https://github.com/xmldom/xmldom/compare/0.9.0-beta.6...0.9.0-beta.7)
+
+### Feature
+
+- Add `compareDocumentPosition` method from level 3 spec. [`#488`](https://github.com/xmldom/xmldom/pull/488)
+
+### Fixed
+
+- `getAttribute` and `getAttributeNS` should return `null` (#477) [`#46`](https://github.com/xmldom/xmldom/issues/46)
+- several issues in NamedNodeMap and Element (#482) [`#46`](https://github.com/xmldom/xmldom/issues/46)
+- properly parse closing where the last attribute has no value [`#485`](https://github.com/xmldom/xmldom/pull/485) / [`#486`](https://github.com/xmldom/xmldom/issues/486)
+- extend list of HTML entities [`#489`](https://github.com/xmldom/xmldom/pull/489)
+
+BREAKING CHANGE: Iteration over attributes now happens in the right order and non-existing attributes now return `null` instead of undefined. THe same is true for the `namepsaceURI` and `prefix` of Attr nodes.
+All of the changes are fixing misalignment with the DOM specs, so if you expected it to work as specified,
+nothing should break for you.
+
+### Chore
+
+- update multiple devDependencies
+- Configure jest (correctly) and wallaby [`#481`](https://github.com/xmldom/xmldom/pull/481) / [`#483`](https://github.com/xmldom/xmldom/pull/483)
+
+Thank you, [@bulandent](https://github.com/bulandent), [@zorkow](https://github.com/zorkow), for your contributions
+
+
+## [0.8.8](https://github.com/xmldom/xmldom/compare/0.8.7...0.8.8)
+
+### Fixed
+
+- extend list of HTML entities [`#489`](https://github.com/xmldom/xmldom/pull/489)
+
+Thank you, [@zorkow](https://github.com/zorkow), for your contributions
+
+## [0.7.11](https://github.com/xmldom/xmldom/compare/0.7.10...0.7.11)
+
+### Fixed
+
+- extend list of HTML entities [`#489`](https://github.com/xmldom/xmldom/pull/489)
+
+Thank you, [@zorkow](https://github.com/zorkow), for your contributions
+
+
+## [0.8.7](https://github.com/xmldom/xmldom/compare/0.8.6...0.8.7)
+
+### Fixed
+
+- properly parse closing where the last attribute has no value [`#485`](https://github.com/xmldom/xmldom/pull/485) / [`#486`](https://github.com/xmldom/xmldom/issues/486)
+
+Thank you, [@bulandent](https://github.com/bulandent), for your contributions
+
+
+## [0.7.10](https://github.com/xmldom/xmldom/compare/0.7.9...0.7.10)
+
+### Fixed
+
+- properly parse closing where the last attribute has no value [`#485`](https://github.com/xmldom/xmldom/pull/485) / [`#486`](https://github.com/xmldom/xmldom/issues/486)
+
+Thank you, [@bulandent](https://github.com/bulandent), for your contributions
+
+
+## [0.8.6](https://github.com/xmldom/xmldom/compare/0.8.5...0.8.6)
+
+### Fixed
+
+- Properly check nodes before replacement [`#457`](https://github.com/xmldom/xmldom/pull/457) / [`#455`](https://github.com/xmldom/xmldom/issues/455) / [`#456`](https://github.com/xmldom/xmldom/issues/456)
+
+Thank you, [@edemaine](https://github.com/edemaine), [@pedro-l9](https://github.com/pedro-l9), for your contributions
+
+
+## [0.7.9](https://github.com/xmldom/xmldom/compare/0.7.8...0.7.9)
+
+### Fixed
+
+- Properly check nodes before replacement [`#457`](https://github.com/xmldom/xmldom/pull/457) / [`#455`](https://github.com/xmldom/xmldom/issues/455) / [`#456`](https://github.com/xmldom/xmldom/issues/456)
+
+Thank you, [@edemaine](https://github.com/edemaine), [@pedro-l9](https://github.com/pedro-l9), for your contributions
+
+
+## [0.9.0-beta.6](https://github.com/xmldom/xmldom/compare/0.9.0-beta.5...0.9.0-beta.6)
+
+### Fixed
+
+- Properly check nodes before replacement [`#457`](https://github.com/xmldom/xmldom/pull/457) / [`#455`](https://github.com/xmldom/xmldom/issues/455) / [`#456`](https://github.com/xmldom/xmldom/issues/456)
+
+Thank you, [@edemaine](https://github.com/edemaine), [@pedro-l9](https://github.com/pedro-l9), for your contributions
+
+
+## [0.9.0-beta.5](https://github.com/xmldom/xmldom/compare/0.9.0-beta.4...0.9.0-beta.5)
+
+### Fixed
+
+- fix: Restore ES5 compatibility [`#452`](https://github.com/xmldom/xmldom/pull/452) / [`#453`](https://github.com/xmldom/xmldom/issues/453)
+
+Thank you, [@fengxinming](https://github.com/fengxinming), for your contributions
+
+
+## [0.8.5](https://github.com/xmldom/xmldom/compare/0.8.4...0.8.5)
+
+### Fixed
+
+- fix: Restore ES5 compatibility [`#452`](https://github.com/xmldom/xmldom/pull/452) / [`#453`](https://github.com/xmldom/xmldom/issues/453)
+
+Thank you, [@fengxinming](https://github.com/fengxinming), for your contributions
+
+
+## [0.7.8](https://github.com/xmldom/xmldom/compare/0.7.7...0.7.8)
+
+### Fixed
+
+- fix: Restore ES5 compatibility [`#452`](https://github.com/xmldom/xmldom/pull/452) / [`#453`](https://github.com/xmldom/xmldom/issues/453)
+
+Thank you, [@fengxinming](https://github.com/fengxinming), for your contributions
+
+
+## [0.9.0-beta.4](https://github.com/xmldom/xmldom/compare/0.9.0-beta.3...0.9.0-beta.4)
+
+### Fixed
+
+- Security: Prevent inserting DOM nodes when they are not well-formed [`CVE-2022-39353`](https://github.com/xmldom/xmldom/security/advisories/GHSA-crh6-fp67-6883)
+ In case such a DOM would be created, the part that is not well-formed will be transformed into text nodes, in which xml specific characters like `<` and `>` are encoded accordingly.
+ In the upcoming version 0.9.0 those text nodes will no longer be added and an error will be thrown instead.
+ This change can break your code, if you relied on this behavior, e.g. multiple root elements in the past. We consider it more important to align with the specs that we want to be aligned with, considering the potential security issues that might derive from people not being aware of the difference in behavior.
+ Related Spec:
+
+### Chore
+
+- update multiple devDependencies
+- Add eslint-plugin-node for `lib` [`#448`](https://github.com/xmldom/xmldom/pull/448) / [`#190`](https://github.com/xmldom/xmldom/issues/190)
+- style: Apply prettier to all code [`#447`](https://github.com/xmldom/xmldom/pull/447) / [`#29`](https://github.com/xmldom/xmldom/issues/29) / [`#130`](https://github.com/xmldom/xmldom/issues/130)
+
+Thank you, [@XhmikosR](https://github.com/XhmikosR), [@awwright](https://github.com/awwright), [@frumioj](https://github.com/frumioj), [@cjbarth](https://github.com/cjbarth), [@markgollnick](https://github.com/markgollnick) for your contributions
+
+
+## [0.8.4](https://github.com/xmldom/xmldom/compare/0.8.3...0.8.4)
+
+### Fixed
+
+- Security: Prevent inserting DOM nodes when they are not well-formed [`CVE-2022-39353`](https://github.com/xmldom/xmldom/security/advisories/GHSA-crh6-fp67-6883)
+ In case such a DOM would be created, the part that is not well-formed will be transformed into text nodes, in which xml specific characters like `<` and `>` are encoded accordingly.
+ In the upcoming version 0.9.0 those text nodes will no longer be added and an error will be thrown instead.
+ This change can break your code, if you relied on this behavior, e.g. multiple root elements in the past. We consider it more important to align with the specs that we want to be aligned with, considering the potential security issues that might derive from people not being aware of the difference in behavior.
+ Related Spec:
+
+Thank you, [@frumioj](https://github.com/frumioj), [@cjbarth](https://github.com/cjbarth), [@markgollnick](https://github.com/markgollnick) for your contributions
+
+
+## [0.7.7](https://github.com/xmldom/xmldom/compare/0.7.6...0.7.7)
+
+### Fixed
+
+- Security: Prevent inserting DOM nodes when they are not well-formed [`CVE-2022-39353`](https://github.com/xmldom/xmldom/security/advisories/GHSA-crh6-fp67-6883)
+ In case such a DOM would be created, the part that is not well-formed will be transformed into text nodes, in which xml specific characters like `<` and `>` are encoded accordingly.
+ In the upcoming version 0.9.0 those text nodes will no longer be added and an error will be thrown instead.
+ This change can break your code, if you relied on this behavior, e.g. multiple root elements in the past. We consider it more important to align with the specs that we want to be aligned with, considering the potential security issues that might derive from people not being aware of the difference in behavior.
+ Related Spec:
+
+Thank you, [@frumioj](https://github.com/frumioj), [@cjbarth](https://github.com/cjbarth), [@markgollnick](https://github.com/markgollnick) for your contributions
+
+
+## [0.9.0-beta.3](https://github.com/xmldom/xmldom/compare/0.9.0-beta.2...0.9.0-beta.3)
+
+### Fixed
+
+- fix: Stop adding tags after incomplete closing tag [`#445`](https://github.com/xmldom/xmldom/pull/445) / [`#416`](https://github.com/xmldom/xmldom/pull/416)
+ BREAKING CHANGE: It no longer reports an error when parsing HTML containing incomplete closing tags, to align the behavior with the one in the browser.
+ BREAKING CHANGE: If your code relied on not well-formed XML to be parsed and include subsequent tags, this will no longer work.
+- fix: Avoid bidirectional characters in source code [`#440`](https://github.com/xmldom/xmldom/pull/440)
+
+### Other
+
+- ci: Add CodeQL scan [`#444`](https://github.com/xmldom/xmldom/pull/444)
+
+Thank you, [@ACN-kck](https://github.com/ACN-kck), [@mgerlach](https://github.com/mgerlach) for your contributions
+
+
+## [0.7.6](https://github.com/xmldom/xmldom/compare/0.7.5...0.7.6)
+
+### Fixed
+- Avoid iterating over prototype properties [`#441`](https://github.com/xmldom/xmldom/pull/441) / [`#437`](https://github.com/xmldom/xmldom/pull/437) / [`#436`](https://github.com/xmldom/xmldom/issues/436)
+
+Thank you, [@jftanner](https://github.com/jftanner), [@Supraja9726](https://github.com/Supraja9726) for your contributions
+
+
+## [0.8.3](https://github.com/xmldom/xmldom/compare/0.8.3...0.8.2)
+
+### Fixed
+- Avoid iterating over prototype properties [`#437`](https://github.com/xmldom/xmldom/pull/437) / [`#436`](https://github.com/xmldom/xmldom/issues/436)
+
+Thank you, [@Supraja9726](https://github.com/Supraja9726) for your contributions
+
+
+## [0.9.0-beta.2](https://github.com/xmldom/xmldom/compare/0.9.0-beta.1...0.9.0-beta.2)
+
+### Fixed
+- Avoid iterating over prototype properties [`#437`](https://github.com/xmldom/xmldom/pull/437) / [`#436`](https://github.com/xmldom/xmldom/issues/436)
+
+Thank you, [@Supraja9726](https://github.com/Supraja9726) for your contributions
+
+
+## [0.9.0-beta.1](https://github.com/xmldom/xmldom/compare/0.8.2...0.9.0-beta.1)
+
+### Fixed
+
+**Only use HTML rules if mimeType matches** [`#338`](https://github.com/xmldom/xmldom/pull/338), fixes [`#203`](https://github.com/xmldom/xmldom/issues/203)
+
+In the living specs for parsing XML and HTML, that this library is trying to implement,
+there is a distinction between the different types of documents being parsed:
+There are quite some rules that are different for parsing, constructing and serializing XML vs HTML documents.
+
+So far xmldom was always "detecting" whether "the HTML rules should be applied" by looking at the current namespace. So from the first time an the HTML default namespace (`http://www.w3.org/1999/xhtml`) was found, every node was treated as being part of an HTML document. This misconception is the root cause for quite some reported bugs.
+
+BREAKING CHANGE: HTML rules are no longer applied just because of the namespace, but require the `mimeType` argument passed to `DOMParser.parseFromString(source, mimeType)` to match `'text/html'`. Doing so implies all rules for handling casing for tag and attribute names when parsing, creation of nodes and searching nodes.
+
+BREAKING CHANGE: Correct the return type of `DOMParser.parseFromString` to `Document | undefined`. In case of parsing errors it was always possible that "the returned `Document`" has not been created. In case you are using Typescript you now need to handle those cases.
+
+BREAKING CHANGE: The instance property `DOMParser.options` is no longer available, instead use the individual `readonly` property per option (`assign`, `domHandler`, `errorHandler`, `normalizeLineEndings`, `locator`, `xmlns`). Those also provides the default value if the option was not passed. The 'locator' option is now just a boolean (default remains `true`).
+
+BREAKING CHANGE: The following methods no longer allow a (non spec compliant) boolean argument to toggle "HTML rules":
+- `XMLSerializer.serializeToString`
+- `Node.toString`
+- `Document.toString`
+
+The following interfaces have been implemented:
+`DOMImplementation` now implements all methods defined in the DOM spec, but not all of the behavior is implemented (see docstring):
+- `createDocument` creates an "XML Document" (prototype: `Document`, property `type` is `'xml'`)
+- `createHTMLDocument` creates an "HTML Document" (type/prototype: `Document`, property `type` is `'html'`).
+ - when no argument is passed or the first argument is a string, the basic nodes for an HTML structure are created, as specified
+ - when the first argument is `false` no child nodes are created
+
+`Document` now has two new readonly properties as specified in the DOM spec:
+- `contentType` which is the mime-type that was used to create the document
+- `type` which is either the string literal `'xml'` or `'html'`
+
+`MIME_TYPE` (`/lib/conventions.js`):
+- `hasDefaultHTMLNamespace` test if the provided string is one of the miem types that implies the default HTML namespace: `text/html` or `application/xhtml+xml`
+
+Thank you [@weiwu-zhang](https://github.com/weiwu-zhang) for your contributions
+
+### Chore
+
+- update multiple devDependencies
+
+
+## [0.8.2](https://github.com/xmldom/xmldom/compare/0.8.1...0.8.2)
+
+### Fixed
+- fix(dom): Serialize `>` as specified (#395) [`#58`](https://github.com/xmldom/xmldom/issues/58)
+
+### Other
+- docs: Add `nodeType` values to public interface description [`#396`](https://github.com/xmldom/xmldom/pull/396)
+- test: Add executable examples for node and typescript [`#317`](https://github.com/xmldom/xmldom/pull/317)
+- fix(dom): Serialize `>` as specified [`#395`](https://github.com/xmldom/xmldom/pull/395)
+- chore: Add minimal `Object.assign` ponyfill [`#379`](https://github.com/xmldom/xmldom/pull/379)
+- docs: Refine release documentation [`#378`](https://github.com/xmldom/xmldom/pull/378)
+- chore: update various dev dependencies
+
+Thank you [@niklasl](https://github.com/niklasl), [@cburatto](https://github.com/cburatto), [@SheetJSDev](https://github.com/SheetJSDev), [@pyrsmk](https://github.com/pyrsmk) for your contributions
+
+## [0.8.1](https://github.com/xmldom/xmldom/compare/0.8.0...0.8.1)
+
+### Fixes
+- Only use own properties in entityMap [`#374`](https://github.com/xmldom/xmldom/pull/374)
+
+### Docs
+- Add security policy [`#365`](https://github.com/xmldom/xmldom/pull/365)
+- changelog: Correct contributor name and link [`#366`](https://github.com/xmldom/xmldom/pull/366)
+- Describe release/publish steps [`#358`](https://github.com/xmldom/xmldom/pull/358), [`#376`](https://github.com/xmldom/xmldom/pull/376)
+- Add snyk package health badge [`#360`](https://github.com/xmldom/xmldom/pull/360)
+
+
+## [0.8.0](https://github.com/xmldom/xmldom/compare/0.7.5...0.8.0)
+
+### Fixed
+- Normalize all line endings according to XML specs [1.0](https://w3.org/TR/xml/#sec-line-ends) and [1.1](https://www.w3.org/TR/xml11/#sec-line-ends) \
+ BREAKING CHANGE: Certain combination of line break characters are normalized to a single `\n` before parsing takes place and will no longer be preserved.
+ - [`#303`](https://github.com/xmldom/xmldom/issues/303) / [`#307`](https://github.com/xmldom/xmldom/pull/307)
+ - [`#49`](https://github.com/xmldom/xmldom/issues/49), [`#97`](https://github.com/xmldom/xmldom/issues/97), [`#324`](https://github.com/xmldom/xmldom/issues/324) / [`#314`](https://github.com/xmldom/xmldom/pull/314)
+- XMLSerializer: Preserve whitespace character references [`#284`](https://github.com/xmldom/xmldom/issues/284) / [`#310`](https://github.com/xmldom/xmldom/pull/310) \
+ BREAKING CHANGE: If you relied on the not spec compliant preservation of literal `\t`, `\n` or `\r` in **attribute values**.
+ To preserve those you will have to create XML that instead contains the correct numerical (or hexadecimal) equivalent (e.g. ` `, `
`, `
`).
+- Drop deprecated exports `DOMImplementation` and `XMLSerializer` from `lib/dom-parser.js` [#53](https://github.com/xmldom/xmldom/issues/53) / [`#309`](https://github.com/xmldom/xmldom/pull/309)
+ BREAKING CHANGE: Use the one provided by the main package export.
+- dom: Remove all links as part of `removeChild` [`#343`](https://github.com/xmldom/xmldom/issues/343) / [`#355`](https://github.com/xmldom/xmldom/pull/355)
+
+### Chore
+- ci: Restore latest tested node version to 16.x [`#325`](https://github.com/xmldom/xmldom/pull/325)
+- ci: Split test and lint steps into jobs [`#111`](https://github.com/xmldom/xmldom/issues/111) / [`#304`](https://github.com/xmldom/xmldom/pull/304)
+- Pinned and updated devDependencies
+
+Thank you [@marrus-sh](https://github.com/marrus-sh), [@victorandree](https://github.com/victorandree), [@mdierolf](https://github.com/mdierolf), [@tsabbay](https://github.com/tsabbay), [@fatihpense](https://github.com/fatihpense) for your contributions
+
+## [0.7.5](https://github.com/xmldom/xmldom/compare/0.7.4...0.7.5)
+
+### Fixes:
+
+- Preserve default namespace when serializing [`#319`](https://github.com/xmldom/xmldom/issues/319) / [`#321`](https://github.com/xmldom/xmldom/pull/321)
+ Thank you, [@lupestro](https://github.com/lupestro)
+
+## [0.7.4](https://github.com/xmldom/xmldom/compare/0.7.3...0.7.4)
+
+### Fixes:
+
+- Restore ability to parse `__prototype__` attributes [`#315`](https://github.com/xmldom/xmldom/pull/315)
+ Thank you, [@dsimpsonOMF](https://github.com/dsimpsonOMF)
+
+## [0.7.3](https://github.com/xmldom/xmldom/compare/0.7.2...0.7.3)
+
+### Fixes:
+
+- Add doctype when parsing from string [`#277`](https://github.com/xmldom/xmldom/issues/277) / [`#301`](https://github.com/xmldom/xmldom/pull/301)
+- Correct typo in error message [`#294`](https://github.com/xmldom/xmldom/pull/294)
+ Thank you, [@rrthomas](https://github.com/rrthomas)
+
+### Refactor:
+
+- Improve exports & require statements, new main package entry [`#233`](https://github.com/xmldom/xmldom/pull/233)
+
+### Docs:
+
+- Fix Stryker badge [`#298`](https://github.com/xmldom/xmldom/pull/298)
+- Fix link to help-wanted issues [`#299`](https://github.com/xmldom/xmldom/pull/299)
+
+### Chore:
+
+- Execute stryker:dry-run on branches [`#302`](https://github.com/xmldom/xmldom/pull/302)
+- Fix stryker config [`#300`](https://github.com/xmldom/xmldom/pull/300)
+- Split test and lint scripts [`#297`](https://github.com/xmldom/xmldom/pull/297)
+- Switch to stryker dashboard owned by org [`#292`](https://github.com/xmldom/xmldom/pull/292)
+
+## [0.7.2](https://github.com/xmldom/xmldom/compare/0.7.1...0.7.2)
+
+### Fixes:
+
+- Types: Add index.d.ts to packaged files [`#288`](https://github.com/xmldom/xmldom/pull/288)
+ Thank you, [@forty](https://github.com/forty)
+
+## [0.7.1](https://github.com/xmldom/xmldom/compare/0.7.0...0.7.1)
+
+### Fixes:
+
+- Types: Copy types from DefinitelyTyped [`#283`](https://github.com/xmldom/xmldom/pull/283)
+ Thank you, [@kachkaev](https://github.com/kachkaev)
+
+### Chore:
+- package.json: remove author, maintainers, etc. [`#279`](https://github.com/xmldom/xmldom/pull/279)
+
+## [0.7.0](https://github.com/xmldom/xmldom/compare/0.6.0...0.7.0)
+
+Due to [`#271`](https://github.com/xmldom/xmldom/issue/271) this version was published as
+- unscoped `xmldom` package to **github** (git tags [`0.7.0`](https://github.com/xmldom/xmldom/tree/0.7.0) and [`0.7.0+unscoped`](https://github.com/xmldom/xmldom/tree/0.7.0%2Bunscoped))
+- scoped `@xmldom/xmldom` package to npm (git tag `0.7.0+scoped`)
+For more details look at [`#278`](https://github.com/xmldom/xmldom/pull/278#issuecomment-902172483)
+
+### Fixes:
+
+- Security: Misinterpretation of malicious XML input [`CVE-2021-32796`](https://github.com/xmldom/xmldom/security/advisories/GHSA-5fg8-2547-mr8q)
+- Implement `Document.getElementsByClassName` as specified [`#213`](https://github.com/xmldom/xmldom/pull/213), thank you, [@ChALkeR](https://github.com/ChALkeR)
+- Inherit namespace prefix from parent when required [`#268`](https://github.com/xmldom/xmldom/pull/268)
+- Handle whitespace in closing tags [`#267`](https://github.com/xmldom/xmldom/pull/267)
+- Update `DOMImplementation` according to recent specs [`#210`](https://github.com/xmldom/xmldom/pull/210)
+ BREAKING CHANGE: Only if you "passed features to be marked as available as a constructor arguments" and expected it to "magically work".
+- No longer serializes any namespaces with an empty URI [`#244`](https://github.com/xmldom/xmldom/pull/244)
+ (related to [`#168`](https://github.com/xmldom/xmldom/pull/168) released in 0.6.0)
+ BREAKING CHANGE: Only if you rely on ["unsetting" a namespace prefix](https://github.com/xmldom/xmldom/pull/168#issuecomment-886984994) by setting it to an empty string
+- Set `localName` as part of `Document.createElement` [`#229`](https://github.com/xmldom/xmldom/pull/229), thank you, [@rrthomas](https://github.com/rrthomas)
+
+### CI
+
+- We are now additionally running tests against node v16
+- Stryker tests on the master branch now run against node v14
+
+### Docs
+
+- Describe relations with and between specs: [`#211`](https://github.com/xmldom/xmldom/pull/211), [`#247`](https://github.com/xmldom/xmldom/pull/247)
+
+## [0.6.0](https://github.com/xmldom/xmldom/compare/0.5.0...0.6.0)
+
+Published to npm: 2021-04-17 16:41 UTC by @karfau as `xmldom`
+
+### Fixes
+
+- Stop serializing empty namespace values like `xmlns:ds=""` [`#168`](https://github.com/xmldom/xmldom/pull/168)
+ BREAKING CHANGE: If your code expected empty namespaces attributes to be serialized.
+ Thank you, [@pdecat](https://github.com/pdecat) and [@FranckDepoortere](https://github.com/FranckDepoortere)
+- Escape `<` to `<` when serializing attribute values [`#198`](https://github.com/xmldom/xmldom/issues/198) / [`#199`](https://github.com/xmldom/xmldom/pull/199)
+
+## [0.5.0](https://github.com/xmldom/xmldom/compare/0.4.0...0.5.0)
+
+Published to npm: 2021-03-09 03:59 UTC by @brodybits as `xmldom`
+
+### Fixes
+- Avoid misinterpretation of malicious XML input - [`GHSA-h6q6-9hqw-rwfv`](https://github.com/xmldom/xmldom/security/advisories/GHSA-h6q6-9hqw-rwfv) (CVE-2021-21366)
+ - Improve error reporting; throw on duplicate attribute\
+ BREAKING CHANGE: It is currently not clear how to consistently deal with duplicate attributes, so it's also safer for our users to fail when detecting them.
+ It's possible to configure the `DOMParser.errorHandler` before parsing, to handle those errors differently.
+
+ To accomplish this and also be able to verify it in tests I needed to
+ - create a new `Error` type `ParseError` and export it
+ - Throw `ParseError` from `errorHandler.fatalError` and prevent those from being caught in `XMLReader`.
+ - export `DOMHandler` constructor as `__DOMHandler`
+ - Preserve quotes in DOCTYPE declaration
+ Since the only purpose of parsing the DOCTYPE is to be able to restore it when serializing, we decided that it would be best to leave the parsed `publicId` and `systemId` as is, including any quotes.
+ BREAKING CHANGE: If somebody relies on the actual unquoted values of those ids, they will need to take care of either single or double quotes and the right escaping.
+ (Without this change this would not have been possible because the SAX parser already dropped the information about the quotes that have been used in the source.)
+
+ https://www.w3.org/TR/2006/REC-xml11-20060816/#dtd
+ https://www.w3.org/TR/2006/REC-xml11-20060816/#IDAX1KS (External Entity Declaration)
+
+- Fix breaking preprocessors' directives when parsing attributes [`#171`](https://github.com/xmldom/xmldom/pull/171)
+- fix(dom): Escape `]]>` when serializing CharData [`#181`](https://github.com/xmldom/xmldom/pull/181)
+- Switch to (only) MIT license (drop problematic LGPL license option) [`#178`](https://github.com/xmldom/xmldom/pull/178)
+- Export DOMException; remove custom assertions; etc. [`#174`](https://github.com/xmldom/xmldom/pull/174)
+
+### Docs
+- Update MDN links in `readme.md` [`#188`](https://github.com/xmldom/xmldom/pull/188)
+
+## [0.4.0](https://github.com/xmldom/xmldom/compare/0.3.0...0.4.0)
+
+Published to npm: 2020-10-27 00:44 UTC by @brodybits as `xmldom`
+
+### Fixes
+- **BREAKING** Restore ` ` behavior from v0.1.27 [`#67`](https://github.com/xmldom/xmldom/pull/67)
+- **BREAKING** Typecheck source param before parsing [`#113`](https://github.com/xmldom/xmldom/pull/113)
+- Include documents in package files list [`#156`](https://github.com/xmldom/xmldom/pull/156)
+- Preserve doctype with sysid [`#144`](https://github.com/xmldom/xmldom/pull/144)
+- Remove ES6 syntax from getElementsByClassName [`#91`](https://github.com/xmldom/xmldom/pull/91)
+- Revert "Add lowercase of åäö in entityMap" due to duplicate entries [`#84`](https://github.com/xmldom/xmldom/pull/84)
+- fix: Convert all line separators to LF [`#66`](https://github.com/xmldom/xmldom/pull/66)
+
+### Docs
+- Update CHANGELOG.md through version 0.3.0 [`#63`](https://github.com/xmldom/xmldom/pull/63)
+- Update badges [`#78`](https://github.com/xmldom/xmldom/pull/78)
+- Add .editorconfig file [`#104`](https://github.com/xmldom/xmldom/pull/104)
+- Add note about import [`#79`](https://github.com/xmldom/xmldom/pull/79)
+- Modernize & improve the example in readme.md [`#81`](https://github.com/xmldom/xmldom/pull/81)
+
+### CI
+- Add Stryker Mutator [`#70`](https://github.com/xmldom/xmldom/pull/70)
+- Add Stryker action to update dashboard [`#77`](https://github.com/xmldom/xmldom/pull/77)
+- Add Node GitHub action workflow [`#64`](https://github.com/xmldom/xmldom/pull/64)
+- add & enable eslint [`#106`](https://github.com/xmldom/xmldom/pull/106)
+- Use eslint-plugin-es5 to enforce ES5 syntax [`#107`](https://github.com/xmldom/xmldom/pull/107)
+- Recover `vows` tests, drop `proof` tests [`#59`](https://github.com/xmldom/xmldom/pull/59)
+- Add jest tessuite and first tests [`#114`](https://github.com/xmldom/xmldom/pull/114)
+- Add jest testsuite with `xmltest` cases [`#112`](https://github.com/xmldom/xmldom/pull/112)
+- Configure Renovate [`#108`](https://github.com/xmldom/xmldom/pull/108)
+- Test European HTML entities [`#86`](https://github.com/xmldom/xmldom/pull/86)
+- Updated devDependencies
+
+### Other
+- Remove files that are not of any use [`#131`](https://github.com/xmldom/xmldom/pull/131), [`#65`](https://github.com/xmldom/xmldom/pull/65), [`#33`](https://github.com/xmldom/xmldom/pull/33)
+
+## [0.3.0](https://github.com/xmldom/xmldom/compare/0.2.1...0.3.0)
+
+Published to npm: 2020-03-04 16:32 UTC by @kethinov as `xmldom`
+
+- **BREAKING** Node >=10.x is now required.
+- **BREAKING** Remove `component.json` (deprecated package manager https://github.com/componentjs/guide)
+- **BREAKING** Move existing sources into `lib` subdirectory.
+- **POSSIBLY BREAKING** Introduce `files` entry in `package.json` and remove use of `.npmignore`.
+- [Add `Document.getElementsByClassName`](https://github.com/xmldom/xmldom/issues/24).
+- [Add `Node` to the list of exports](https://github.com/xmldom/xmldom/pull/27)
+- [Add lowercase of åäö in `entityMap`](https://github.com/xmldom/xmldom/pull/23).
+- Move CHANGELOG to markdown file.
+- Move LICENSE to markdown file.
+
+## [0.2.1](https://github.com/xmldom/xmldom/compare/0.2.0...0.2.1)
+
+Published to npm: 2019-12-20 00:40 UTC by @brodybits as `xmldom`
+
+- Correct `homepage`, `repository` and `bugs` URLs in `package.json`.
+
+## [0.2.0](https://github.com/xmldom/xmldom/compare/v0.1.27...0.2.0)
+
+Published to npm: 2019-12-20 00:19 UTC by @brodybits as `xmldom`
+
+- Includes all **BREAKING** changes introduced in [`xmldom-alpha@v0.1.28`](#0128) by the original authors.
+- **POSSIBLY BREAKING** [remove the `Object.create` check from the `_extends` method of `dom.js` that added a `__proto__` property](https://github.com/xmldom/xmldom/commit/0be2ae910a8a22c9ec2cac042e04de4c04317d2a#diff-7d1c5d97786fdf9af5446a241d0b6d56L19-L22) ().
+- **POSSIBLY BREAKING** [remove code that added a `__proto__` property](https://github.com/xmldom/xmldom/commit/366159a76a181ce9a0d83f5dc48205686cfaf9cc)
+- formatting/corrections in `package.json`
+
+## [0.1.31](https://github.com/xmldom/xmldom/compare/0.1.30...0.1.31)
+
+Published to npm: 2019-12-19 22:34 UTC by @brodybits as `xmldom`
+
+## [0.1.30](https://github.com/xmldom/xmldom/compare/0.1.29...0.1.30)
+
+Published to npm: 2019-12-19 22:30 UTC by @brodybits as `xmldom`
+
+## [0.1.29](https://github.com/xmldom/xmldom/compare/0.1.27...0.1.29)
+
+Published to npm: 2019-12-19 22:26 UTC by @brodybits as `xmldom`
+
+The patch versions (`0.1.29` - `0.1.31`) that have been released on the [v0.1.x branch](https://github.com/xmldom/xmldom/tree/0.1.x), to reflect the changed maintainers, **are branched off from [`0.1.27`](#0127) so they don't include the breaking changes introduced in [`xmldom-alpha@v0.1.28`](#0128)**:
+
+## Maintainer changes
+
+After the last commit to the original repository on the 9th of May 2017, the first commit to is from the 19th of December 2019. [The fork has been announced in the original repository on the 2nd of March 2020.](https://github.com/jindw/xmldom/issues/259)
+
+The versions listed below have been published to one or both of the following packages:
+-
+-
+
+It is currently not planned to continue publishing the `xmldom-alpha` package.
+
+The new maintainers did not invest time to understand changes that led to the last `xmldom` version [`0.1.27`](#0127) published by the original maintainer, but consider it the basis for their work.
+A timeline of all the changes that happened from that version until `0.3.0` is available in . Any related questions should be asked there.
+
+## [0.1.28](https://github.com/xmldom/xmldom/compare/v0.1.27...xmldom-alpha@v0.1.28)
+
+Published to npm: 2017-05-08 02:51 UTC by @jindw as `xmldom-alpha`
+
+- **BREAKING** includes [regression regarding ` ` (issue #57)](https://github.com/xmldom/xmldom/issues/57)
+- [Fix `license` field in `package.json`](https://github.com/jindw/xmldom/pull/178)
+- [Conditional converting of HTML entities](https://github.com/jindw/xmldom/pull/80)
+- Fix `dom.js` serialization issue for missing document element ([example that failed on `toString()` before this change](https://github.com/xmldom/xmldom/blob/a58dcf7a265522e80ce520fe3be0cddb1b976f6f/test/parse/unclosedcomment.js#L10-L11))
+- Add new module `entities.js`
+
+## [0.1.27](https://github.com/xmldom/xmldom/compare/0.1.26...0.1.27)
+
+Published to npm: 2016-11-28 03:56 UTC by @jindw as `xmldom` and `xmldom-alpha`
+
+Tags `0.1.24`, `0.1.25`, `0.1.26`, and `0.1.27` all point to the same git commit (`b53aa82`). These four versions were published within 24 hours in November 2016 with version bumps applied only to the working directory, not committed to git.
+
+- Various bug fixes.
+
+## [0.1.26](https://github.com/xmldom/xmldom/compare/0.1.25...0.1.26)
+
+Published to npm: 2016-11-28 03:47 UTC by @jindw as `xmldom`
+
+Tags `0.1.24`, `0.1.25`, `0.1.26`, and `0.1.27` all point to the same git commit (`b53aa82`). These four versions were published within 24 hours in November 2016 with version bumps applied only to the working directory, not committed to git.
+
+- Details unknown
+
+## [0.1.25](https://github.com/xmldom/xmldom/compare/0.1.24...0.1.25)
+
+Published to npm: 2016-11-28 03:35 UTC by @jindw as `xmldom`
+
+Tags `0.1.24`, `0.1.25`, `0.1.26`, and `0.1.27` all point to the same git commit (`b53aa82`). These four versions were published within 24 hours in November 2016 with version bumps applied only to the working directory, not committed to git.
+
+- Details unknown
+
+## [0.1.24](https://github.com/xmldom/xmldom/compare/0.1.22...0.1.24)
+
+Published to npm: 2016-11-27 14:00 UTC by @jindw as `xmldom` and `xmldom-alpha`
+
+Tags `0.1.24`, `0.1.25`, `0.1.26`, and `0.1.27` all point to the same git commit (`b53aa82`). These four versions were published within 24 hours in November 2016 with version bumps applied only to the working directory, not committed to git.
+
+- Added node filter.
+
+## [0.1.23](https://github.com/xmldom/xmldom/compare/0.1.22...0.1.23)
+
+Published to npm: 2016-05-20 04:24 UTC by @jindw as `xmldom-alpha`
+
+- Add namespace support for nest node serialize.
+- Various other bug fixes.
+
+## [0.1.22](https://github.com/xmldom/xmldom/compare/0.1.21...0.1.22)
+
+Published to npm: 2016-01-30 11:50 UTC by @jindw as `xmldom`
+
+- Merge XMLNS serialization.
+- Remove \r from source string.
+- Print namespaces for child elements.
+- Switch references to nodeType to use named constants.
+- Add nodelist toString support.
+
+## [0.1.21](https://github.com/xmldom/xmldom/compare/0.1.20...0.1.21)
+
+Published to npm: 2016-01-13 11:41 UTC by @jindw as `xmldom`
+
+- Fix serialize bug.
+
+## [0.1.20](https://github.com/xmldom/xmldom/compare/0.1.19...0.1.20)
+
+Published to npm: 2016-01-10 08:23 UTC by @jindw as `xmldom`
+
+- Optimize invalid XML support.
+- Add toString sorter for attributes output.
+- Add html self closed node button.
+- Add `*` NS support for getElementsByTagNameNS.
+- Convert attribute's value to string in setAttributeNS.
+- Add support for HTML entities for HTML docs only.
+- Fix TypeError when Document is created with DocumentType.
+
+## [0.1.19](https://github.com/xmldom/xmldom/compare/0.1.18...0.1.19)
+
+Published to npm: 2014-01-28 15:15 UTC by @jindw as `xmldom`
+
+- Fix [infinite loop on unclosed comment (jindw/xmldom#68)](https://github.com/jindw/xmldom/issues/68)
+- Add error report for unclosed tag.
+- Various other fixes.
+
+## [0.1.18](https://github.com/xmldom/xmldom/compare/0.1.17...0.1.18)
+
+Published to npm: 2014-01-17 06:59 UTC by @bigeasy as `xmldom`
+
+- Add default `ns` support.
+- parseFromString now renders entirely plain text documents as textNode.
+- Enable option to ignore white space on parsing.
+
+## [0.1.17](https://github.com/xmldom/xmldom/compare/0.1.16...0.1.17)
+
+Published to npm: 2013-12-16 03:07 UTC by @jindw as `xmldom`
+
+No version bump commit for 0.1.17 was found in git history. The tag `0.1.17` points to the commit immediately preceding the 0.1.18 version bump (`87f63e6`, parent of `9ddac14`), which is the last committed state before the next version.
+
+## [0.1.16](https://github.com/xmldom/xmldom/compare/0.1.15...0.1.16)
+
+Published to npm: 2013-05-04 15:00 UTC by @bigeasy as `xmldom`
+
+- Correctly handle multibyte Unicode greater than two byts. #57. #56.
+- Initial unit testing and test coverage. #53. #46. #19.
+- Create Bower `component.json` #52.
+
+## [0.1.15](https://github.com/xmldom/xmldom/compare/0.1.14...0.1.15)
+
+Published to npm: 2013-04-03 02:41 UTC by @bigeasy as `xmldom`
+
+## [0.1.14](https://github.com/xmldom/xmldom/compare/0.1.13...0.1.14)
+
+Published to npm: 2013-03-31 15:31 UTC by @bigeasy as `xmldom`
+
+## [0.1.13](https://github.com/xmldom/xmldom/compare/0.1.12...0.1.13)
+
+Published to npm: 2012-10-02 11:35 UTC by @jindw as `xmldom`
+
+## [0.1.12](https://github.com/xmldom/xmldom/compare/0.1.11...0.1.12)
+
+Published to npm: 2012-09-03 15:02 UTC as `xmldom`
+
+No version bump commit for 0.1.12 was found in git history. The tag `0.1.12` points to the commit immediately preceding the 0.1.13 version bump (`47fa9b8`, parent of `eb17b3a`), which is the last committed state before the next version.
+
+## [0.1.11](https://github.com/xmldom/xmldom/compare/0.1.10...0.1.11)
+
+Published to npm: 2012-06-18 10:45 UTC by @jindw as `xmldom`
+
+## [0.1.10](https://github.com/xmldom/xmldom/compare/0.1.9...0.1.10)
+
+Published to npm: 2012-06-14 02:54 UTC by @jindw as `xmldom`
+
+## [0.1.9](https://github.com/xmldom/xmldom/compare/0.1.8...0.1.9)
+
+Published to npm: 2012-06-08 06:18 UTC by @jindw as `xmldom`
+
+## [0.1.8](https://github.com/xmldom/xmldom/compare/0.1.7...0.1.8)
+
+Published to npm: 2012-05-29 13:30 UTC by @jindw as `xmldom`
+
+- Add: some test case from node-o3-xml(excludes xpath support)
+- Fix: remove existed attribute before setting (bug introduced in v0.1.5)
+- Fix: index direct access for childNodes and any NodeList collection(not w3c standard)
+- Fix: remove last child bug
+
+## [0.1.7](https://github.com/xmldom/xmldom/compare/0.1.6...0.1.7)
+
+Published to npm: 2012-05-29 03:05 UTC by @jindw as `xmldom`
+
+## [0.1.6](https://github.com/xmldom/xmldom/compare/0.1.5...0.1.6)
+
+Published to npm: 2012-05-28 12:49 UTC by @jindw as `xmldom`
+
+## [0.1.5](https://github.com/xmldom/xmldom/compare/0.1.4...0.1.5)
+
+Published to npm: 2012-05-25 17:43 UTC by @jindw as `xmldom`
+
+## [0.1.4](https://github.com/xmldom/xmldom/compare/0.1.3...0.1.4)
+
+Published to npm: 2012-05-22 16:41 UTC by @jindw as `xmldom`
+
+## [0.1.3](https://github.com/xmldom/xmldom/compare/0.1.2...0.1.3)
+
+Published to npm: 2012-05-22 16:39 UTC by @jindw as `xmldom`
+
+## [0.1.2](https://github.com/xmldom/xmldom/compare/0.1.1...0.1.2)
+
+Published to npm: 2012-02-03 10:49 UTC by @jindw as `xmldom`
+
+## [0.1.1](https://github.com/xmldom/xmldom/compare/0.1.0...0.1.1)
+
+Published to npm: 2012-01-10 07:18 UTC by @jindw as `xmldom`
+
+## [0.1.0](https://github.com/xmldom/xmldom/commit/5d770d4)
+
+Published to npm: 2012-01-06 09:49 UTC by @jindw as `xmldom`
diff --git a/node_modules/@xmldom/xmldom/LICENSE b/node_modules/@xmldom/xmldom/LICENSE
new file mode 100644
index 000000000..b95f5698c
--- /dev/null
+++ b/node_modules/@xmldom/xmldom/LICENSE
@@ -0,0 +1,8 @@
+Copyright 2019 - present Christopher J. Brody and other contributors, as listed in: https://github.com/xmldom/xmldom/graphs/contributors
+Copyright 2012 - 2017 @jindw and other contributors, as listed in: https://github.com/jindw/xmldom/graphs/contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/node_modules/@xmldom/xmldom/SECURITY.md b/node_modules/@xmldom/xmldom/SECURITY.md
new file mode 100644
index 000000000..3d58efc7b
--- /dev/null
+++ b/node_modules/@xmldom/xmldom/SECURITY.md
@@ -0,0 +1,50 @@
+# Security Policy
+
+The most up-to-date version of this document can be found at .
+
+## Supported Versions
+
+This repository contains the code for the libraries `xmldom` and `@xmldom/xmldom` on npm.
+
+As long as we didn't publish v1, we aim to maintain the last two minor versions with security fixes. If it is possible we provide security fixes as patch versions.
+If you think there is a good reason to also patch an earlier version, let us know in a GitHub issue or the release discussion once the fix has been provided.
+The maintainers will consider it, and if we agree and have/find the required resources, a patch for that version will be provided.
+
+Please notice that [we are no longer able to publish the (unscoped) `xmldom` package](https://github.com/xmldom/xmldom/issues/271),
+and that all existing versions of `xmldom` are affected by at least one security vulnerability and should be considered deprecated.
+You can still report issues regarding `xmldom` as described below.
+
+If you need help with migrating from `xmldom` to `@xmldom/xmldom`, file a GitHub issue or PR in the affected repository and mention @karfau.
+
+## Reporting vulnerabilities
+
+Please email reports about any security related issues you find to `security@xmldom.org`, which will forward it to the list of maintainers.
+The maintainers will try to respond within 7 calendar days. (If nobody replies after 7 days, please us send a reminder!)
+As part of you communication please make sure to always hit "Reply all", so all maintainers are kept in the loop.
+
+In addition, please include the following information along with your report:
+
+- Your name and affiliation (if any).
+- A description of the technical details of the vulnerabilities. It is very important to let us know how we can reproduce your findings.
+- An explanation who can exploit this vulnerability, and what they gain when doing so -- write an attack scenario. This will help us evaluate your report quickly, especially if the issue is complex.
+- Whether this vulnerability public or known to third parties. If it is, please provide details.
+
+If you believe that an existing (public) issue is security-related, please email `security@xmldom.org`.
+The email should include the issue URL and a short description of why it should be handled according to this security policy.
+
+Once an issue is reported, the maintainers use the following disclosure process:
+
+- When a report is received, we confirm the issue, determine its severity and the affected versions.
+- If we know of specific third-party services or software based on xmldom that require mitigation before publication, those projects will be notified.
+- A [GitHub security advisory](https://docs.github.com/en/code-security/security-advisories/about-github-security-advisories) is [created](https://docs.github.com/en/code-security/security-advisories/creating-a-security-advisory) (but not published) which details the problem and steps for mitigation.
+- If the reporter provides a GitHub account and agrees to it, we [add that GitHub account as a collaborator on the advisory](https://docs.github.com/en/code-security/security-advisories/adding-a-collaborator-to-a-security-advisory).
+- The vulnerability is fixed in a [private fork](https://docs.github.com/en/code-security/security-advisories/collaborating-in-a-temporary-private-fork-to-resolve-a-security-vulnerability) and potential workarounds are identified.
+- The maintainers audit the existing code to find any potential similar problems.
+- The release for the current minor version and the [security advisory are published](https://docs.github.com/en/code-security/security-advisories/publishing-a-security-advisory).
+- The release(s) for previous minor version(s) are published.
+
+We credit reporters for identifying security issues, if they confirm that they want to.
+
+## Known vulnerabilities
+
+See https://github.com/xmldom/xmldom/security/advisories?state=published
diff --git a/node_modules/@xmldom/xmldom/index.d.ts b/node_modules/@xmldom/xmldom/index.d.ts
new file mode 100644
index 000000000..60c0b228f
--- /dev/null
+++ b/node_modules/@xmldom/xmldom/index.d.ts
@@ -0,0 +1,1843 @@
+declare module '@xmldom/xmldom' {
+ // START ./lib/conventions.js
+ /**
+ * Since xmldom can not rely on `Object.assign`,
+ * it uses/provides a simplified version that is sufficient for its needs.
+ *
+ * @throws {TypeError}
+ * If target is not an object.
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
+ * @see https://tc39.es/ecma262/multipage/fundamental-objects.html#sec-object.assign
+ */
+ function assign(target: T, source: S): T & S;
+
+ /**
+ * For both the `text/html` and the `application/xhtml+xml` namespace the spec defines that
+ * the HTML namespace is provided as the default.
+ *
+ * @param {string} mimeType
+ * @returns {boolean}
+ * @see https://dom.spec.whatwg.org/#dom-document-createelement
+ * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocument
+ * @see https://dom.spec.whatwg.org/#dom-domimplementation-createhtmldocument
+ */
+ function hasDefaultHTMLNamespace(
+ mimeType: string
+ ): mimeType is typeof MIME_TYPE.HTML | typeof MIME_TYPE.XML_XHTML_APPLICATION;
+
+ /**
+ * Only returns true if `value` matches MIME_TYPE.HTML, which indicates an HTML document.
+ *
+ * @see https://www.iana.org/assignments/media-types/text/html
+ * @see https://en.wikipedia.org/wiki/HTML
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString
+ * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-domparser-parsefromstring
+ */
+ function isHTMLMimeType(mimeType: string): mimeType is typeof MIME_TYPE.HTML;
+
+ /**
+ * Only returns true if `mimeType` is one of the allowed values for `DOMParser.parseFromString`.
+ */
+ function isValidMimeType(mimeType: string): mimeType is MIME_TYPE;
+
+ /**
+ * All mime types that are allowed as input to `DOMParser.parseFromString`
+ *
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString#Argument02
+ * MDN
+ * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#domparsersupportedtype
+ * WHATWG HTML Spec
+ * @see {@link DOMParser.prototype.parseFromString}
+ */
+ type MIME_TYPE = (typeof MIME_TYPE)[keyof typeof MIME_TYPE];
+ /**
+ * All mime types that are allowed as input to `DOMParser.parseFromString`
+ *
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString#Argument02
+ * MDN
+ * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#domparsersupportedtype
+ * WHATWG HTML Spec
+ * @see {@link DOMParser.prototype.parseFromString}
+ */
+ var MIME_TYPE: {
+ /**
+ * `text/html`, the only mime type that triggers treating an XML document as HTML.
+ *
+ * @see https://www.iana.org/assignments/media-types/text/html IANA MimeType registration
+ * @see https://en.wikipedia.org/wiki/HTML Wikipedia
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString MDN
+ * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-domparser-parsefromstring
+ * WHATWG HTML Spec
+ */
+ readonly HTML: 'text/html';
+ /**
+ * `application/xml`, the standard mime type for XML documents.
+ *
+ * @see https://www.iana.org/assignments/media-types/application/xml IANA MimeType
+ * registration
+ * @see https://tools.ietf.org/html/rfc7303#section-9.1 RFC 7303
+ * @see https://en.wikipedia.org/wiki/XML_and_MIME Wikipedia
+ */
+ readonly XML_APPLICATION: 'application/xml';
+ /**
+ * `text/html`, an alias for `application/xml`.
+ *
+ * @see https://tools.ietf.org/html/rfc7303#section-9.2 RFC 7303
+ * @see https://www.iana.org/assignments/media-types/text/xml IANA MimeType registration
+ * @see https://en.wikipedia.org/wiki/XML_and_MIME Wikipedia
+ */
+ readonly XML_TEXT: 'text/xml';
+ /**
+ * `application/xhtml+xml`, indicates an XML document that has the default HTML namespace,
+ * but is parsed as an XML document.
+ *
+ * @see https://www.iana.org/assignments/media-types/application/xhtml+xml IANA MimeType
+ * registration
+ * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocument WHATWG DOM Spec
+ * @see https://en.wikipedia.org/wiki/XHTML Wikipedia
+ */
+ readonly XML_XHTML_APPLICATION: 'application/xhtml+xml';
+ /**
+ * `image/svg+xml`,
+ *
+ * @see https://www.iana.org/assignments/media-types/image/svg+xml IANA MimeType registration
+ * @see https://www.w3.org/TR/SVG11/ W3C SVG 1.1
+ * @see https://en.wikipedia.org/wiki/Scalable_Vector_Graphics Wikipedia
+ */
+ readonly XML_SVG_IMAGE: 'image/svg+xml';
+ };
+ /**
+ * Namespaces that are used in xmldom.
+ *
+ * @see http://www.w3.org/TR/REC-xml-names
+ */
+ type NAMESPACE = (typeof NAMESPACE)[keyof typeof NAMESPACE];
+ /**
+ * Namespaces that are used in xmldom.
+ *
+ * @see http://www.w3.org/TR/REC-xml-names
+ */
+ var NAMESPACE: {
+ /**
+ * The XHTML namespace.
+ *
+ * @see http://www.w3.org/1999/xhtml
+ */
+ readonly HTML: 'http://www.w3.org/1999/xhtml';
+ /**
+ * The SVG namespace.
+ *
+ * @see http://www.w3.org/2000/svg
+ */
+ readonly SVG: 'http://www.w3.org/2000/svg';
+ /**
+ * The `xml:` namespace.
+ *
+ * @see http://www.w3.org/XML/1998/namespace
+ */
+ readonly XML: 'http://www.w3.org/XML/1998/namespace';
+
+ /**
+ * The `xmlns:` namespace.
+ *
+ * @see https://www.w3.org/2000/xmlns/
+ */
+ readonly XMLNS: 'http://www.w3.org/2000/xmlns/';
+ };
+
+ // END ./lib/conventions.js
+
+ // START ./lib/errors.js
+ type DOMExceptionName =
+ (typeof DOMExceptionName)[keyof typeof DOMExceptionName];
+ var DOMExceptionName: {
+ /**
+ * the default value as defined by the spec
+ */
+ readonly Error: 'Error';
+ /**
+ * @deprecated
+ * Use RangeError instead.
+ */
+ readonly IndexSizeError: 'IndexSizeError';
+ /**
+ * @deprecated
+ * Just to match the related static code, not part of the spec.
+ */
+ readonly DomstringSizeError: 'DomstringSizeError';
+ readonly HierarchyRequestError: 'HierarchyRequestError';
+ readonly WrongDocumentError: 'WrongDocumentError';
+ readonly InvalidCharacterError: 'InvalidCharacterError';
+ /**
+ * @deprecated
+ * Just to match the related static code, not part of the spec.
+ */
+ readonly NoDataAllowedError: 'NoDataAllowedError';
+ readonly NoModificationAllowedError: 'NoModificationAllowedError';
+ readonly NotFoundError: 'NotFoundError';
+ readonly NotSupportedError: 'NotSupportedError';
+ readonly InUseAttributeError: 'InUseAttributeError';
+ readonly InvalidStateError: 'InvalidStateError';
+ readonly SyntaxError: 'SyntaxError';
+ readonly InvalidModificationError: 'InvalidModificationError';
+ readonly NamespaceError: 'NamespaceError';
+ /**
+ * @deprecated
+ * Use TypeError for invalid arguments,
+ * "NotSupportedError" DOMException for unsupported operations,
+ * and "NotAllowedError" DOMException for denied requests instead.
+ */
+ readonly InvalidAccessError: 'InvalidAccessError';
+ /**
+ * @deprecated
+ * Just to match the related static code, not part of the spec.
+ */
+ readonly ValidationError: 'ValidationError';
+ /**
+ * @deprecated
+ * Use TypeError instead.
+ */
+ readonly TypeMismatchError: 'TypeMismatchError';
+ readonly SecurityError: 'SecurityError';
+ readonly NetworkError: 'NetworkError';
+ readonly AbortError: 'AbortError';
+ /**
+ * @deprecated
+ * Just to match the related static code, not part of the spec.
+ */
+ readonly URLMismatchError: 'URLMismatchError';
+ readonly QuotaExceededError: 'QuotaExceededError';
+ readonly TimeoutError: 'TimeoutError';
+ readonly InvalidNodeTypeError: 'InvalidNodeTypeError';
+ readonly DataCloneError: 'DataCloneError';
+ readonly EncodingError: 'EncodingError';
+ readonly NotReadableError: 'NotReadableError';
+ readonly UnknownError: 'UnknownError';
+ readonly ConstraintError: 'ConstraintError';
+ readonly DataError: 'DataError';
+ readonly TransactionInactiveError: 'TransactionInactiveError';
+ readonly ReadOnlyError: 'ReadOnlyError';
+ readonly VersionError: 'VersionError';
+ readonly OperationError: 'OperationError';
+ readonly NotAllowedError: 'NotAllowedError';
+ readonly OptOutError: 'OptOutError';
+ };
+ type ExceptionCode = (typeof ExceptionCode)[keyof typeof ExceptionCode];
+
+ var ExceptionCode: {
+ readonly INDEX_SIZE_ERR: 1;
+ readonly DOMSTRING_SIZE_ERR: 2;
+ readonly HIERARCHY_REQUEST_ERR: 3;
+ readonly WRONG_DOCUMENT_ERR: 4;
+ readonly INVALID_CHARACTER_ERR: 5;
+ readonly NO_DATA_ALLOWED_ERR: 6;
+ readonly NO_MODIFICATION_ALLOWED_ERR: 7;
+ readonly NOT_FOUND_ERR: 8;
+ readonly NOT_SUPPORTED_ERR: 9;
+ readonly INUSE_ATTRIBUTE_ERR: 10;
+ readonly INVALID_STATE_ERR: 11;
+ readonly SYNTAX_ERR: 12;
+ readonly INVALID_MODIFICATION_ERR: 13;
+ readonly NAMESPACE_ERR: 14;
+ readonly INVALID_ACCESS_ERR: 15;
+ readonly VALIDATION_ERR: 16;
+ readonly TYPE_MISMATCH_ERR: 17;
+ readonly SECURITY_ERR: 18;
+ readonly NETWORK_ERR: 19;
+ readonly ABORT_ERR: 20;
+ readonly URL_MISMATCH_ERR: 21;
+ readonly QUOTA_EXCEEDED_ERR: 22;
+ readonly TIMEOUT_ERR: 23;
+ readonly INVALID_NODE_TYPE_ERR: 24;
+ readonly DATA_CLONE_ERR: 25;
+ };
+
+ /**
+ * DOM operations only raise exceptions in "exceptional" circumstances, i.e., when an
+ * operation is impossible to perform (either for logical reasons, because data is lost, or
+ * because the implementation has become unstable). In general, DOM methods return specific
+ * error values in ordinary processing situations, such as out-of-bound errors when using
+ * NodeList.
+ *
+ * Implementations should raise other exceptions under other circumstances. For example,
+ * implementations should raise an implementation-dependent exception if a null argument is
+ * passed when null was not expected.
+ *
+ * This implementation supports the following usages:
+ * 1. according to the living standard (both arguments are optional):
+ * ```
+ * new DOMException("message (can be empty)", DOMExceptionNames.HierarchyRequestError)
+ * ```
+ * 2. according to previous xmldom implementation (only the first argument is required):
+ * ```
+ * new DOMException(DOMException.HIERARCHY_REQUEST_ERR, "optional message")
+ * ```
+ * both result in the proper name being set.
+ *
+ * @see https://webidl.spec.whatwg.org/#idl-DOMException
+ * @see https://webidl.spec.whatwg.org/#dfn-error-names-table
+ * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-17189187
+ * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/ecma-script-binding.html
+ * @see http://www.w3.org/TR/REC-DOM-Level-1/ecma-script-language-binding.html
+ */
+ class DOMException extends Error {
+ constructor(message?: string, name?: DOMExceptionName | string);
+ constructor(code?: ExceptionCode, message?: string);
+
+ readonly name: DOMExceptionName;
+ readonly code: ExceptionCode | 0;
+ static readonly INDEX_SIZE_ERR: 1;
+ static readonly DOMSTRING_SIZE_ERR: 2;
+ static readonly HIERARCHY_REQUEST_ERR: 3;
+ static readonly WRONG_DOCUMENT_ERR: 4;
+ static readonly INVALID_CHARACTER_ERR: 5;
+ static readonly NO_DATA_ALLOWED_ERR: 6;
+ static readonly NO_MODIFICATION_ALLOWED_ERR: 7;
+ static readonly NOT_FOUND_ERR: 8;
+ static readonly NOT_SUPPORTED_ERR: 9;
+ static readonly INUSE_ATTRIBUTE_ERR: 10;
+ static readonly INVALID_STATE_ERR: 11;
+ static readonly SYNTAX_ERR: 12;
+ static readonly INVALID_MODIFICATION_ERR: 13;
+ static readonly NAMESPACE_ERR: 14;
+ static readonly INVALID_ACCESS_ERR: 15;
+ static readonly VALIDATION_ERR: 16;
+ static readonly TYPE_MISMATCH_ERR: 17;
+ static readonly SECURITY_ERR: 18;
+ static readonly NETWORK_ERR: 19;
+ static readonly ABORT_ERR: 20;
+ static readonly URL_MISMATCH_ERR: 21;
+ static readonly QUOTA_EXCEEDED_ERR: 22;
+ static readonly TIMEOUT_ERR: 23;
+ static readonly INVALID_NODE_TYPE_ERR: 24;
+ static readonly DATA_CLONE_ERR: 25;
+ }
+
+ /**
+ * Creates an error that will not be caught by XMLReader aka the SAX parser.
+ */
+ class ParseError extends Error {
+ constructor(message: string, locator?: any, cause?: Error);
+
+ readonly message: string;
+ readonly locator?: any;
+ readonly cause?: Error;
+ }
+
+ // END ./lib/errors.js
+
+ // START ./lib/dom.js
+
+ /**
+ * Exported for `instanceof` checks only — these types cannot be constructed directly.
+ */
+ type InstanceOf = {
+ // instanceof pre ts 5.3
+ (val: unknown): val is T;
+ // instanceof post ts 5.3
+ [Symbol.hasInstance](val: unknown): val is T;
+ };
+
+ type GetRootNodeOptions = {
+ composed?: boolean;
+ };
+
+ /**
+ * The DOM Node interface is an abstract base class upon which many other DOM API objects are
+ * based, thus letting those object types to be used similarly and often interchangeably. As an
+ * abstract class, there is no such thing as a plain Node object. All objects that implement
+ * Node functionality are based on one of its subclasses. Most notable are Document, Element,
+ * and DocumentFragment.
+ *
+ * In addition, every kind of DOM node is represented by an interface based on Node. These
+ * include Attr, CharacterData (which Text, Comment, CDATASection and ProcessingInstruction are
+ * all based on), and DocumentType.
+ *
+ * In some cases, a particular feature of the base Node interface may not apply to one of its
+ * child interfaces; in that case, the inheriting node may return null or throw an exception,
+ * depending on circumstances. For example, attempting to add children to a node type that
+ * cannot have children will throw an exception.
+ *
+ * **This behavior is slightly different from the in the specs**:
+ * - unimplemented interfaces: EventTarget
+ *
+ * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247
+ * @see https://dom.spec.whatwg.org/#node
+ * @prettierignore
+ */
+ interface Node {
+ /**
+ * Returns the children.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/childNodes)
+ */
+ readonly childNodes: NodeList;
+ /**
+ * Returns the first child.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/firstChild)
+ */
+ readonly firstChild: Node | null;
+ /**
+ * Returns the last child.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/lastChild)
+ */
+ readonly lastChild: Node | null;
+ /**
+ * The local part of the qualified name of this node.
+ */
+ localName: string | null;
+ /**
+ * Always returns `about:blank` currently.
+ *
+ * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Node/baseURI)
+ */
+ readonly baseURI: 'about:blank';
+ /**
+ * Returns true if this node is inside of a document or is the document node itself.
+ *
+ * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Node/isConnected)
+ */
+ readonly isConnected: boolean;
+ /**
+ * The namespace URI of this node.
+ */
+ readonly namespaceURI: string | null;
+ /**
+ * Returns the next sibling.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/nextSibling)
+ */
+ readonly nextSibling: Node | null;
+ /**
+ * Returns a string appropriate for the type of node.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/nodeName)
+ */
+ readonly nodeName: string;
+ /**
+ * Returns the type of node.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/nodeType)
+ */
+ readonly nodeType: number;
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/nodeValue) */
+ nodeValue: string | null;
+ /**
+ * Returns the node document. Returns null for documents.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/ownerDocument)
+ */
+ readonly ownerDocument: Document | null;
+ /**
+ * Returns the parent.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/parentNode)
+ */
+ readonly parentNode: Node | null;
+ /**
+ * Returns the parent `Node` if it is of type `Element`, otherwise `null`.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/parentElement)
+ */
+ readonly parentElement: Element | null;
+ /**
+ * The prefix of the namespace for this node.
+ */
+ prefix: string | null;
+ /**
+ * Returns the previous sibling.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/previousSibling)
+ */
+ readonly previousSibling: Node | null;
+ /**
+ * The text content of this node and its descendants.
+ *
+ * For {@link Element} and {@link DocumentFragment} nodes, returns the concatenation of the
+ * `nodeValue` of every descendant text node, excluding processing instruction and comment
+ * nodes. For all other node types, returns `nodeValue`.
+ *
+ * Setting `textContent` on an element or document fragment replaces all child nodes with a
+ * single text node; on other nodes it sets `data`, `value`, and `nodeValue` directly.
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/textContent)
+ *
+ * @see {@link https://dom.spec.whatwg.org/#dom-node-textcontent}
+ */
+ textContent: string | null;
+
+ /**
+ * Zero based line position inside the parsed source,
+ * if the `locator` was not disabled.
+ */
+ lineNumber?: number;
+ /**
+ * One based column position inside the parsed source,
+ * if the `locator` was not disabled.
+ */
+ columnNumber?: number;
+
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/appendChild) */
+ appendChild(node: Node): Node;
+
+ /**
+ * Checks whether `other` is an inclusive descendant of this node.
+ *
+ * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Node/contains)
+ */
+ contains(other: Node | null | undefined): boolean;
+ /**
+ * Searches for the root node of this node.
+ *
+ * **This behavior is slightly different from the one in the specs**:
+ * - ignores `options.composed`, since `ShadowRoot`s are unsupported, therefore always
+ * returning root.
+ *
+ * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Node/getRootNode)
+ *
+ * @see https://dom.spec.whatwg.org/#dom-node-getrootnode
+ * @see https://dom.spec.whatwg.org/#concept-shadow-including-root
+ */
+ getRootNode(options: GetRootNodeOptions): Node;
+
+ /**
+ * Checks whether the given node is equal to this node.
+ *
+ * Two nodes are equal when they have the same type, defining characteristics (for the type),
+ * and the same `childNodes`. The comparison is iterative to avoid stack overflows on deeply
+ * nested trees. `Attribute` nodes of each `Element` pair are also compared iteratively.
+ *
+ * @see {@link https://dom.spec.whatwg.org/#concept-node-equals}
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Node/isEqualNode}
+ */
+ isEqualNode(other: Node): boolean;
+
+ /**
+ * Checks whether the given node is this node.
+ *
+ * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Node/isSameNode)
+ */
+ isSameNode(other: Node): boolean;
+
+ /**
+ * Returns a copy of node. If deep is true, the copy also includes the node's descendants.
+ *
+ * @throws {DOMException}
+ * May throw a DOMException if operations within {@link Element#setAttributeNode} or
+ * {@link Node#appendChild} (which are potentially invoked in this method) do not meet their
+ * specific constraints.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/cloneNode)
+ */
+ cloneNode(deep?: boolean): Node;
+
+ /**
+ * Returns a bitmask indicating the position of other relative to node.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/compareDocumentPosition)
+ */
+ compareDocumentPosition(other: Node): number;
+
+ /**
+ * Returns whether node has children.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/hasChildNodes)
+ */
+ hasChildNodes(): boolean;
+
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/insertBefore) */
+ insertBefore(node: Node, child: Node | null): Node;
+
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/isDefaultNamespace) */
+ isDefaultNamespace(namespace: string | null): boolean;
+
+ /**
+ * Checks whether the DOM implementation implements a specific feature and its version.
+ *
+ * @deprecated
+ * Since `DOMImplementation.hasFeature` is deprecated and always returns true.
+ * @param feature
+ * The package name of the feature to test. This is the same name that can be passed to the
+ * method `hasFeature` on `DOMImplementation`.
+ * @param version
+ * This is the version number of the package name to test.
+ * @since Introduced in DOM Level 2
+ * @see {@link DOMImplementation.hasFeature}
+ */
+ isSupported(feature: string, version: string): true;
+
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/lookupNamespaceURI) */
+ lookupNamespaceURI(prefix: string | null): string | null;
+
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/lookupPrefix) */
+ lookupPrefix(namespace: string | null): string | null;
+
+ /**
+ * Removes empty exclusive Text nodes and concatenates the data of remaining contiguous
+ * exclusive Text nodes into the first of their nodes.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/normalize)
+ */
+ normalize(): void;
+
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/removeChild) */
+ removeChild(child: Node): Node;
+
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/replaceChild) */
+ replaceChild(node: Node, child: Node): Node;
+
+ /** node is an element. */
+ readonly ELEMENT_NODE: 1;
+ readonly ATTRIBUTE_NODE: 2;
+ /** node is a Text node. */
+ readonly TEXT_NODE: 3;
+ /** node is a CDATASection node. */
+ readonly CDATA_SECTION_NODE: 4;
+ readonly ENTITY_REFERENCE_NODE: 5;
+ readonly ENTITY_NODE: 6;
+ /** node is a ProcessingInstruction node. */
+ readonly PROCESSING_INSTRUCTION_NODE: 7;
+ /** node is a Comment node. */
+ readonly COMMENT_NODE: 8;
+ /** node is a document. */
+ readonly DOCUMENT_NODE: 9;
+ /** node is a doctype. */
+ readonly DOCUMENT_TYPE_NODE: 10;
+ /** node is a DocumentFragment node. */
+ readonly DOCUMENT_FRAGMENT_NODE: 11;
+ readonly NOTATION_NODE: 12;
+ /** Set when node and other are not in the same tree. */
+ readonly DOCUMENT_POSITION_DISCONNECTED: 0x01;
+ /** Set when other is preceding node. */
+ readonly DOCUMENT_POSITION_PRECEDING: 0x02;
+ /** Set when other is following node. */
+ readonly DOCUMENT_POSITION_FOLLOWING: 0x04;
+ /** Set when other is an ancestor of node. */
+ readonly DOCUMENT_POSITION_CONTAINS: 0x08;
+ /** Set when other is a descendant of node. */
+ readonly DOCUMENT_POSITION_CONTAINED_BY: 0x10;
+ readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: 0x20;
+ }
+
+ var Node: InstanceOf & {
+ /** node is an element. */
+ readonly ELEMENT_NODE: 1;
+ readonly ATTRIBUTE_NODE: 2;
+ /** node is a Text node. */
+ readonly TEXT_NODE: 3;
+ /** node is a CDATASection node. */
+ readonly CDATA_SECTION_NODE: 4;
+ readonly ENTITY_REFERENCE_NODE: 5;
+ readonly ENTITY_NODE: 6;
+ /** node is a ProcessingInstruction node. */
+ readonly PROCESSING_INSTRUCTION_NODE: 7;
+ /** node is a Comment node. */
+ readonly COMMENT_NODE: 8;
+ /** node is a document. */
+ readonly DOCUMENT_NODE: 9;
+ /** node is a doctype. */
+ readonly DOCUMENT_TYPE_NODE: 10;
+ /** node is a DocumentFragment node. */
+ readonly DOCUMENT_FRAGMENT_NODE: 11;
+ readonly NOTATION_NODE: 12;
+ /** Set when node and other are not in the same tree. */
+ readonly DOCUMENT_POSITION_DISCONNECTED: 0x01;
+ /** Set when other is preceding node. */
+ readonly DOCUMENT_POSITION_PRECEDING: 0x02;
+ /** Set when other is following node. */
+ readonly DOCUMENT_POSITION_FOLLOWING: 0x04;
+ /** Set when other is an ancestor of node. */
+ readonly DOCUMENT_POSITION_CONTAINS: 0x08;
+ /** Set when other is a descendant of node. */
+ readonly DOCUMENT_POSITION_CONTAINED_BY: 0x10;
+ readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: 0x20;
+ };
+
+ /**
+ * A DOM element's attribute as an object. In most DOM methods, you will probably directly
+ * retrieve the attribute as a string (e.g., Element.getAttribute(), but certain functions (e.g.,
+ * Element.getAttributeNode()) or means of iterating give Attr types.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Attr)
+ */
+ interface Attr extends Node {
+ readonly nodeType: typeof Node.ATTRIBUTE_NODE;
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Attr/name) */
+ readonly name: string;
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Attr/namespaceURI) */
+ readonly namespaceURI: string | null;
+ readonly ownerDocument: Document;
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Attr/ownerElement) */
+ readonly ownerElement: Element | null;
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Attr/prefix) */
+ readonly prefix: string | null;
+ /**
+ * @deprecated
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Attr/specified)
+ */
+ readonly specified: true;
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Attr/value) */
+ value: string;
+ }
+ /**
+ * A DOM element's attribute as an object. In most DOM methods, you will probably directly
+ * retrieve the attribute as a string (e.g., Element.getAttribute(), but certain functions (e.g.,
+ * Element.getAttributeNode()) or means of iterating give Attr types.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Attr)
+ */
+ var Attr: InstanceOf;
+
+ /**
+ * Objects implementing the NamedNodeMap interface are used to represent collections of nodes
+ * that can be accessed by name.
+ * Note that NamedNodeMap does not inherit from NodeList;
+ * NamedNodeMaps are not maintained in any particular order.
+ * Objects contained in an object implementing NamedNodeMap may also be accessed by an ordinal
+ * index,
+ * but this is simply to allow convenient enumeration of the contents of a NamedNodeMap,
+ * and does not imply that the DOM specifies an order to these Nodes.
+ * NamedNodeMap objects in the DOM are live.
+ * used for attributes or DocumentType entities
+ *
+ * This implementation only supports property indices, but does not support named properties,
+ * as specified in the living standard.
+ *
+ * @see https://dom.spec.whatwg.org/#interface-namednodemap
+ * @see https://webidl.spec.whatwg.org/#dfn-supported-property-names
+ */
+ class NamedNodeMap implements Iterable {
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/NamedNodeMap/length) */
+ readonly length: number;
+ /**
+ * Get an attribute by name. Note: Name is in lower case in case of HTML namespace and
+ * document.
+ *
+ * @see https://dom.spec.whatwg.org/#concept-element-attributes-get-by-name
+ */
+ getNamedItem(qualifiedName: string): Attr | null;
+ /**
+ * Get an attribute by namespace and local name.
+ *
+ * @see https://dom.spec.whatwg.org/#concept-element-attributes-get-by-namespace
+ */
+ getNamedItemNS(namespace: string | null, localName: string): Attr | null;
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/NamedNodeMap/item) */
+ item(index: number): Attr | null;
+
+ /**
+ * Removes an attribute specified by the local name.
+ *
+ * @throws {DOMException}
+ * With code:
+ * - {@link DOMException.NOT_FOUND_ERR} if no attribute with the given name is found.
+ * @see https://dom.spec.whatwg.org/#dom-namednodemap-removenameditem
+ * @see https://dom.spec.whatwg.org/#concept-element-attributes-remove-by-name
+ */
+ removeNamedItem(qualifiedName: string): Attr;
+ /**
+ * Removes an attribute specified by the namespace and local name.
+ *
+ * @throws {DOMException}
+ * With code:
+ * - {@link DOMException.NOT_FOUND_ERR} if no attribute with the given namespace URI and
+ * local name is found.
+ * @see https://dom.spec.whatwg.org/#dom-namednodemap-removenameditemns
+ * @see https://dom.spec.whatwg.org/#concept-element-attributes-remove-by-namespace
+ */
+ removeNamedItemNS(namespace: string | null, localName: string): Attr;
+ /**
+ * Set an attribute.
+ *
+ * @throws {DOMException}
+ * With code:
+ * - {@link INUSE_ATTRIBUTE_ERR} - If the attribute is already an attribute of another
+ * element.
+ * @see https://dom.spec.whatwg.org/#concept-element-attributes-set
+ */
+ setNamedItem(attr: Attr): Attr | null;
+ /**
+ * Set an attribute, replacing an existing attribute with the same local name and namespace
+ * URI if one exists.
+ *
+ * @throws {DOMException}
+ * Throws a DOMException with the name "InUseAttributeError" if the attribute is already an
+ * attribute of another element.
+ * @see https://dom.spec.whatwg.org/#concept-element-attributes-set
+ */
+ setNamedItemNS(attr: Attr): Attr | null;
+ [index: number]: Attr;
+ [Symbol.iterator](): Iterator;
+ }
+
+ /**
+ * NodeList objects are collections of nodes, usually returned by properties such as
+ * Node.childNodes and methods such as document.querySelectorAll().
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/NodeList)
+ */
+ class NodeList implements Iterable {
+ /**
+ * Returns the number of nodes in the collection.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/NodeList/length)
+ */
+ readonly length: number;
+ /**
+ * Returns the node with index index from the collection. The nodes are sorted in tree order.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/NodeList/item)
+ */
+ item(index: number): T | null;
+ /**
+ * Returns a string representation of the NodeList.
+ * Accepts the same options as `XMLSerializer.prototype.serializeToString`.
+ */
+ toString(
+ options?: XMLSerializerOptions | ((node: T) => T | undefined)
+ ): string;
+ /**
+ * Filters the NodeList based on a predicate.
+ *
+ * @private
+ */
+ filter(predicate: (node: T) => boolean): T[];
+ /**
+ * Returns the first index at which a given node can be found in the NodeList, or -1 if it is
+ * not present.
+ *
+ * @private
+ */
+ indexOf(node: T): number;
+
+ /**
+ * Index based access returns `undefined`, when accessing indexes >= `length`.
+ * But it would break a lot of code (like `Array.from` usages),
+ * if it would be typed as `T | undefined`.
+ */
+ [index: number]: T;
+
+ [Symbol.iterator](): Iterator;
+ }
+
+ /**
+ * Represents a live collection of nodes that is automatically updated when its associated
+ * document changes.
+ */
+ interface LiveNodeList extends NodeList {}
+ /**
+ * Represents a live collection of nodes that is automatically updated when its associated
+ * document changes.
+ */
+ var LiveNodeList: InstanceOf;
+
+ /**
+ * Element is the most general base class from which all objects in a Document inherit. It only
+ * has methods and properties common to all kinds of elements. More specific classes inherit from
+ * Element.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element)
+ */
+ interface Element extends Node {
+ readonly nodeType: typeof Node.ELEMENT_NODE;
+
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/attributes) */
+ readonly attributes: NamedNodeMap;
+ /**
+ * Returns the HTML-uppercased qualified name.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/tagName)
+ */
+ readonly tagName: string;
+
+ /**
+ * Returns a live collection of the direct child elements of this element.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/children)
+ *
+ * @see https://dom.spec.whatwg.org/#dom-parentnode-children
+ */
+ readonly children: LiveNodeList;
+
+ /**
+ * Returns element's first attribute whose qualified name is qualifiedName, and null if there
+ * is no such attribute otherwise.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/getAttribute)
+ */
+ getAttribute(qualifiedName: string): string | null;
+ /**
+ * Returns element's attribute whose namespace is namespace and local name is localName, and
+ * null if there is no such attribute otherwise.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/getAttributeNS)
+ */
+ getAttributeNS(namespace: string | null, localName: string): string | null;
+ /**
+ * Returns the qualified names of all element's attributes. Can contain duplicates.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/getAttributeNames)
+ */
+ getAttributeNames(): string[];
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/getAttributeNode) */
+ getAttributeNode(qualifiedName: string): Attr | null;
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/getAttributeNodeNS) */
+ getAttributeNodeNS(
+ namespace: string | null,
+ localName: string
+ ): Attr | null;
+ /**
+ * Returns a LiveNodeList of all child elements which have **all** of the given class
+ * name(s).
+ *
+ * Returns an empty list if `classNames` is an empty string or only contains HTML white space
+ * characters.
+ *
+ * Warning: This returns a live LiveNodeList.
+ * Changes in the DOM will reflect in the array as the changes occur.
+ * If an element selected by this array no longer qualifies for the selector,
+ * it will automatically be removed. Be aware of this for iteration purposes.
+ *
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/getElementsByClassName
+ * @see https://dom.spec.whatwg.org/#concept-getelementsbyclassname
+ */
+ getElementsByClassName(classNames: string): LiveNodeList;
+
+ /**
+ * Returns a LiveNodeList of elements with the given qualifiedName.
+ * Searching for all descendants can be done by passing `*` as `qualifiedName`.
+ *
+ * All descendants of the specified element are searched, but not the element itself.
+ * The returned list is live, which means it updates itself with the DOM tree automatically.
+ * Therefore, there is no need to call `Element.getElementsByTagName()`
+ * with the same element and arguments repeatedly if the DOM changes in between calls.
+ *
+ * When called on an HTML element in an HTML document,
+ * `getElementsByTagName` lower-cases the argument before searching for it.
+ * This is undesirable when trying to match camel-cased SVG elements (such as
+ * ``) in an HTML document.
+ * Instead, use `Element.getElementsByTagNameNS()`,
+ * which preserves the capitalization of the tag name.
+ *
+ * `Element.getElementsByTagName` is similar to `Document.getElementsByTagName()`,
+ * except that it only searches for elements that are descendants of the specified element.
+ *
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/getElementsByTagName
+ * @see https://dom.spec.whatwg.org/#concept-getelementsbytagname
+ */
+ getElementsByTagName(qualifiedName: string): LiveNodeList;
+
+ /**
+ * Returns a `LiveNodeList` of elements with the given tag name belonging to the given
+ * namespace. It is similar to `Document.getElementsByTagNameNS`, except that its search is
+ * restricted to descendants of the specified element.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/getElementsByTagNameNS)
+ * */
+ getElementsByTagNameNS(
+ namespaceURI: string | null,
+ localName: string
+ ): LiveNodeList;
+
+ getQualifiedName(): string;
+ /**
+ * Returns true if element has an attribute whose qualified name is qualifiedName, and false
+ * otherwise.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/hasAttribute)
+ */
+ hasAttribute(qualifiedName: string): boolean;
+ /**
+ * Returns true if element has an attribute whose namespace is namespace and local name is
+ * localName.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/hasAttributeNS)
+ */
+ hasAttributeNS(namespace: string | null, localName: string): boolean;
+ /**
+ * Returns true if element has attributes, and false otherwise.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/hasAttributes)
+ */
+ hasAttributes(): boolean;
+ /**
+ * Removes element's first attribute whose qualified name is qualifiedName.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/removeAttribute)
+ */
+ removeAttribute(qualifiedName: string): void;
+ /**
+ * Removes element's attribute whose namespace is namespace and local name is localName.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/removeAttributeNS)
+ */
+ removeAttributeNS(namespace: string | null, localName: string): void;
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/removeAttributeNode) */
+ removeAttributeNode(attr: Attr): Attr;
+ /**
+ * Sets the value of element's first attribute whose qualified name is qualifiedName to value.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/setAttribute)
+ */
+ setAttribute(qualifiedName: string, value: string): void;
+ /**
+ * Sets the value of element's attribute whose namespace is namespace and local name is
+ * localName to value.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/setAttributeNS)
+ */
+ setAttributeNS(
+ namespace: string | null,
+ qualifiedName: string,
+ value: string
+ ): void;
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/setAttributeNode) */
+ setAttributeNode(attr: Attr): Attr | null;
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/setAttributeNodeNS) */
+ setAttributeNodeNS(attr: Attr): Attr | null;
+ }
+ /**
+ * Element is the most general base class from which all objects in a Document inherit. It only
+ * has methods and properties common to all kinds of elements. More specific classes inherit from
+ * Element.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element)
+ */
+ var Element: InstanceOf;
+
+ /**
+ * The CharacterData abstract interface represents a Node object that contains characters. This
+ * is an abstract interface, meaning there aren't any object of type CharacterData: it is
+ * implemented by other interfaces, like Text, Comment, or ProcessingInstruction which aren't
+ * abstract.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData)
+ */
+ interface CharacterData extends Node {
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData/data) */
+ data: string;
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData/length) */
+ readonly length: number;
+ readonly ownerDocument: Document;
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData/appendData) */
+ appendData(data: string): void;
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData/deleteData) */
+ deleteData(offset: number, count: number): void;
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData/insertData) */
+ insertData(offset: number, data: string): void;
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData/replaceData) */
+ replaceData(offset: number, count: number, data: string): void;
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData/substringData) */
+ substringData(offset: number, count: number): string;
+ }
+ /**
+ * The CharacterData abstract interface represents a Node object that contains characters. This
+ * is an abstract interface, meaning there aren't any object of type CharacterData: it is
+ * implemented by other interfaces, like Text, Comment, or ProcessingInstruction which aren't
+ * abstract.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData)
+ */
+ var CharacterData: InstanceOf;
+
+ /**
+ * The textual content of Element or Attr. If an element has no markup within its content, it has
+ * a single child implementing Text that contains the element's text. However, if the element
+ * contains markup, it is parsed into information items and Text nodes that form its children.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Text)
+ */
+ interface Text extends CharacterData {
+ nodeName: '#text' | '#cdata-section';
+ nodeType: typeof Node.TEXT_NODE | typeof Node.CDATA_SECTION_NODE;
+ /**
+ * Splits data at the given offset and returns the remainder as Text node.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Text/splitText)
+ */
+ splitText(offset: number): Text;
+ }
+
+ /**
+ * The textual content of Element or Attr. If an element has no markup within its content, it has
+ * a single child implementing Text that contains the element's text. However, if the element
+ * contains markup, it is parsed into information items and Text nodes that form its children.
+ *
+ * __This implementation differs from the specification:__ not constructable,
+ * use `document.createTextNode(data)` instead.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Text)
+ */
+ var Text: InstanceOf;
+
+ /**
+ * The Comment interface represents textual notations within markup; although it is generally not
+ * visually shown, such comments are available to be read in the source view. Comments are
+ * represented in HTML and XML as content between ''. In XML, like inside SVG or
+ * MathML markup, the character sequence '--' cannot be used within a comment.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Comment)
+ */
+ interface Comment extends CharacterData {
+ nodeName: '#comment';
+ nodeType: typeof Node.COMMENT_NODE;
+ }
+ /**
+ * The Comment interface represents textual notations within markup; although it is generally not
+ * visually shown, such comments are available to be read in the source view. Comments are
+ * represented in HTML and XML as content between ''. In XML, like inside SVG or
+ * MathML markup, the character sequence '--' cannot be used within a comment.
+ *
+ * __This implementation differs from the specification:__ not constructable,
+ * use `document.createComment(data)` instead.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Comment)
+ */
+ var Comment: InstanceOf;
+
+ /**
+ * A CDATA section that can be used within XML to include extended portions of unescaped text.
+ * The symbols < and & don’t need escaping as they normally do when inside a CDATA section.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CDATASection)
+ */
+ interface CDATASection extends Text {
+ nodeName: '#cdata-section';
+ nodeType: typeof Node.CDATA_SECTION_NODE;
+ }
+ /**
+ * A CDATA section that can be used within XML to include extended portions of unescaped text.
+ * The symbols < and & don’t need escaping as they normally do when inside a CDATA section.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CDATASection)
+ */
+ var CDATASection: InstanceOf;
+
+ /**
+ * The DocumentFragment interface represents a minimal document object that has no parent.
+ * It is used as a lightweight version of Document that stores a segment of a document structure
+ * comprised of nodes just like a standard document.
+ * The key difference is due to the fact that the document fragment isn't part
+ * of the active document tree structure.
+ * Changes made to the fragment don't affect the document.
+ */
+ interface DocumentFragment extends Node {
+ readonly ownerDocument: Document;
+
+ /**
+ * Returns a live collection of the direct child elements of this document fragment.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DocumentFragment/children)
+ *
+ * @see https://dom.spec.whatwg.org/#dom-parentnode-children
+ */
+ readonly children: LiveNodeList;
+
+ getElementById(elementId: string): Element | null;
+ }
+ /**
+ * __This implementation differs from the specification:__ not constructable,
+ * use `document.createDocumentFragment()` instead.
+ */
+ var DocumentFragment: InstanceOf;
+
+ interface Entity extends Node {
+ nodeType: typeof Node.ENTITY_NODE;
+ }
+ var Entity: InstanceOf;
+
+ /**
+ * Represents an EntityReference node, serialized as `&nodeName;`.
+ *
+ * `nodeName` is the referenced entity's name, stored verbatim. When serialized with
+ * `requireWellFormed: true`, the serializer validates `nodeName` against the XML `Name`
+ * production and throws `InvalidStateError` if it does not match; without that option the name
+ * is emitted verbatim between `&` and `;`.
+ *
+ * xmldom does not expand entities — the parser resolves entity references inline and never
+ * constructs `EntityReference` nodes, so the only producer is `Document.createEntityReference`.
+ */
+ interface EntityReference extends Node {
+ nodeType: typeof Node.ENTITY_REFERENCE_NODE;
+ }
+ var EntityReference: InstanceOf;
+
+ interface Notation extends Node {
+ nodeType: typeof Node.NOTATION_NODE;
+ }
+ var Notation: InstanceOf;
+
+ interface ProcessingInstruction extends CharacterData {
+ nodeType: typeof Node.PROCESSING_INSTRUCTION_NODE;
+ /**
+ * A string representing the textual data contained in this object.
+ * For `ProcessingInstruction`, that means everything that goes after the `target`, excluding
+ * `?>`.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData/data)
+ */
+ data: string;
+ /**
+ * A string containing the name of the application.
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ProcessingInstruction/target) */
+ readonly target: string;
+ }
+ var ProcessingInstruction: InstanceOf;
+
+ interface Document extends Node {
+ /**
+ * The mime type of the document is determined at creation time and can not be modified.
+ *
+ * @see https://dom.spec.whatwg.org/#concept-document-content-type
+ * @see {@link DOMImplementation}
+ * @see {@link MIME_TYPE}
+ */
+ readonly contentType: MIME_TYPE;
+ /**
+ * @see https://dom.spec.whatwg.org/#concept-document-type
+ * @see {@link DOMImplementation}
+ */
+ readonly type: 'html' | 'xml';
+ /**
+ * The implementation that created this document.
+ *
+ * @readonly
+ */
+ readonly implementation: DOMImplementation;
+ readonly ownerDocument: Document;
+ readonly nodeName: '#document';
+ readonly nodeType: typeof Node.DOCUMENT_NODE;
+ readonly doctype: DocumentType | null;
+ /**
+ * Gets a reference to the root node of the document.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/documentElement)
+ */
+ readonly documentElement: Element | null;
+
+ /**
+ * Returns a live collection of the direct child elements of this document.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/children)
+ *
+ * @see https://dom.spec.whatwg.org/#dom-parentnode-children
+ */
+ readonly children: LiveNodeList;
+
+ /**
+ * Creates an attribute object with a specified name.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/createAttribute)
+ */
+ createAttribute(localName: string): Attr;
+
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/createAttributeNS) */
+ createAttributeNS(namespace: string | null, qualifiedName: string): Attr;
+
+ /**
+ * Returns a new CDATASection node whose data is `data`.
+ *
+ * __This implementation differs from the specification:__ - calling this method on an HTML
+ * document does not throw `NotSupportedError`.
+ *
+ * @throws {DOMException}
+ * With code `INVALID_CHARACTER_ERR` if `data` contains `"]]>"`.
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/createCDATASection
+ * @see https://dom.spec.whatwg.org/#dom-document-createcdatasection
+ */
+ createCDATASection(data: string): CDATASection;
+
+ /**
+ * Creates a comment object with the specified data.
+ *
+ * No validation is performed at creation time. When the resulting document is serialized
+ * with `requireWellFormed: true`, the serializer throws `InvalidStateError` if the comment
+ * data contains `--` anywhere, ends with `-`, or contains characters outside the XML Char
+ * production (W3C DOM Parsing §3.2.1.3). Without that option the data is emitted verbatim.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/createComment)
+ */
+ createComment(data: string): Comment;
+
+ /**
+ * Creates a new document.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/createDocumentFragment)
+ */
+ createDocumentFragment(): DocumentFragment;
+
+ createElement(tagName: string): Element;
+
+ /**
+ * Returns an element with namespace namespace. Its namespace prefix will be everything before
+ * ":" (U+003E) in qualifiedName or null. Its local name will be everything after ":" (U+003E)
+ * in qualifiedName or qualifiedName.
+ *
+ * If localName does not match the Name production an "InvalidCharacterError" DOMException will
+ * be thrown.
+ *
+ * If one of the following conditions is true a "NamespaceError" DOMException will be thrown:
+ *
+ * localName does not match the QName production.
+ * Namespace prefix is not null and namespace is the empty string.
+ * Namespace prefix is "xml" and namespace is not the XML namespace.
+ * qualifiedName or namespace prefix is "xmlns" and namespace is not the XMLNS namespace.
+ * namespace is the XMLNS namespace and neither qualifiedName nor namespace prefix is "xmlns".
+ *
+ * When supplied, options's is can be used to create a customized built-in element.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/createElementNS)
+ */
+ createElementNS(namespace: string | null, qualifiedName: string): Element;
+ /**
+ * Creates an EntityReference object.
+ * The current implementation does not fill the `childNodes` with those of the corresponding
+ * `Entity`
+ *
+ * The name of the entity to reference. No namespace well-formedness checks are performed.
+ *
+ * The `name` is validated against the XML `Name` production at creation time; an invalid
+ * name throws `InvalidCharacterError`. When the resulting node is serialized with
+ * `requireWellFormed: true`, the serializer re-validates `nodeName` against the XML `Name`
+ * production and throws `InvalidStateError` if a later `nodeName` mutation made it invalid;
+ * without that option the name is emitted verbatim.
+ *
+ * __This implementation differs from the specification:__ xmldom does not expand entities —
+ * the parser resolves entity references inline and never constructs `EntityReference` nodes,
+ * so this method is the only producer.
+ *
+ * @deprecated
+ * In DOM Level 4.
+ * @returns {EntityReference}
+ * @throws {DOMException}
+ * With code `INVALID_CHARACTER_ERR` when `name` is not a valid XML `Name`.
+ * @throws {DOMException}
+ * with code `NOT_SUPPORTED_ERR` when the document is of type `html`
+ * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-392B75AE
+ */
+ createEntityReference(name: string): EntityReference;
+
+ /**
+ * Returns a ProcessingInstruction node whose target is target and data is data.
+ *
+ * __This behavior is slightly different from the in the specs__:
+ * - it does not do any input validation on the arguments and doesn't throw
+ * "InvalidCharacterError".
+ *
+ * Note: When the resulting document is serialized with `requireWellFormed: true`, the
+ * serializer throws `InvalidStateError` if `.target` is not a valid XML `NCName` (a `Name`
+ * with no colon) or is an ASCII case-insensitive match for `"xml"`, or if `.data` contains
+ * `?>` or characters outside the XML Char production (W3C DOM Parsing §3.2.1.7). Without
+ * that option the target and data are emitted verbatim.
+ *
+ * @see https://developer.mozilla.org/docs/Web/API/Document/createProcessingInstruction
+ * @see https://dom.spec.whatwg.org/#dom-document-createprocessinginstruction
+ * @see https://www.w3.org/TR/DOM-Parsing/#dfn-concept-serialize-xml §3.2.1.7
+ */
+ createProcessingInstruction(
+ target: string,
+ data: string
+ ): ProcessingInstruction;
+
+ /**
+ * Creates a text string from the specified value.
+ *
+ * @param data
+ * String that specifies the nodeValue property of the text node.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/createTextNode)
+ */
+ createTextNode(data: string): Text;
+
+ /**
+ * Returns a reference to the first object with the specified value of the ID attribute.
+ */
+ getElementById(elementId: string): Element | null;
+
+ /**
+ * Returns a LiveNodeList of all child elements which have **all** of the given class
+ * name(s).
+ *
+ * Returns an empty list if `classNames` is an empty string or only contains HTML white space
+ * characters.
+ *
+ * Warning: This returns a live LiveNodeList.
+ * Changes in the DOM will reflect in the array as the changes occur.
+ * If an element selected by this array no longer qualifies for the selector,
+ * it will automatically be removed. Be aware of this for iteration purposes.
+ *
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName
+ * @see https://dom.spec.whatwg.org/#concept-getelementsbyclassname
+ */
+ getElementsByClassName(classNames: string): LiveNodeList;
+
+ /**
+ * Returns a LiveNodeList of elements with the given qualifiedName.
+ * Searching for all descendants can be done by passing `*` as `qualifiedName`.
+ *
+ * The complete document is searched, including the root node.
+ * The returned list is live, which means it updates itself with the DOM tree automatically.
+ * Therefore, there is no need to call `Element.getElementsByTagName()`
+ * with the same element and arguments repeatedly if the DOM changes in between calls.
+ *
+ * When called on an HTML element in an HTML document,
+ * `getElementsByTagName` lower-cases the argument before searching for it.
+ * This is undesirable when trying to match camel-cased SVG elements (such as
+ * ``) in an HTML document.
+ * Instead, use `Element.getElementsByTagNameNS()`,
+ * which preserves the capitalization of the tag name.
+ *
+ * `Element.getElementsByTagName` is similar to `Document.getElementsByTagName()`,
+ * except that it only searches for elements that are descendants of the specified element.
+ *
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/getElementsByTagName
+ * @see https://dom.spec.whatwg.org/#concept-getelementsbytagname
+ */
+ getElementsByTagName(qualifiedName: string): LiveNodeList;
+
+ /**
+ * Returns a `LiveNodeList` of elements with the given tag name belonging to the given
+ * namespace. The complete document is searched, including the root node.
+ *
+ * The returned list is live, which means it updates itself with the DOM tree automatically.
+ * Therefore, there is no need to call `Element.getElementsByTagName()`
+ * with the same element and arguments repeatedly if the DOM changes in between calls.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/getElementsByTagNameNS)
+ * */
+ getElementsByTagNameNS(
+ namespaceURI: string | null,
+ localName: string
+ ): LiveNodeList;
+ /**
+ * Imports a node from another document into this document, creating a new copy owned by this
+ * document. If `deep` is true, the copy also includes the node's descendants.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/importNode)
+ *
+ * @see {@link https://dom.spec.whatwg.org/#dom-document-importnode}
+ */
+ importNode(node: T, deep?: boolean): T;
+ }
+
+ var Document: InstanceOf;
+
+ /**
+ * A Node containing a doctype.
+ *
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DocumentType)
+ */
+ interface DocumentType extends Node {
+ /**
+ * The doctype name, stored verbatim.
+ * Declared `readonly` by the WHATWG DOM spec; xmldom does not enforce this — direct
+ * property writes succeed and the written value is serialized verbatim.
+ * When serialized with `requireWellFormed: true`, throws `InvalidStateError` if the value
+ * is not a valid XML `Name` production (XML 1.0 [5]).
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DocumentType/name)
+ */
+ readonly name: string;
+ /**
+ * The internal subset string (the raw content between `[` and `]`), or an empty string.
+ * Declared `readonly` by the WHATWG DOM spec; xmldom does not enforce this — direct
+ * property writes succeed and the written value is serialized verbatim.
+ * When serialized with `requireWellFormed: true`, throws `InvalidStateError` if the value
+ * contains `"]>"`.
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DocumentType/internalSubset)
+ */
+ readonly internalSubset: string;
+ /**
+ * The external subset public identifier, stored verbatim including surrounding quotes.
+ * Declared `readonly` by the WHATWG DOM spec; xmldom does not enforce this — direct
+ * property writes succeed and the written value is serialized verbatim.
+ * When serialized with `requireWellFormed: true`, throws `InvalidStateError` if the value
+ * is non-empty and does not match the XML `PubidLiteral` production (XML 1.0 [12]).
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DocumentType/publicId)
+ */
+ readonly publicId: string;
+ /**
+ * The external subset system identifier, stored verbatim including surrounding quotes.
+ * Declared `readonly` by the WHATWG DOM spec; xmldom does not enforce this — direct
+ * property writes succeed and the written value is serialized verbatim.
+ * When serialized with `requireWellFormed: true`, throws `InvalidStateError` if the value
+ * is non-empty and does not match the XML `SystemLiteral` production (XML 1.0 [11]).
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DocumentType/systemId)
+ */
+ readonly systemId: string;
+ }
+
+ var DocumentType: InstanceOf;
+
+ class DOMImplementation {
+ /**
+ * The DOMImplementation interface represents an object providing methods which are not
+ * dependent on any particular document.
+ * Such an object is returned by the `Document.implementation` property.
+ *
+ * __The individual methods describe the differences compared to the specs.__.
+ *
+ * @class
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation MDN
+ * @see https://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-102161490 DOM Level 1
+ * Core (Initial)
+ * @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-102161490 DOM Level 2 Core
+ * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-102161490 DOM Level 3 Core
+ * @see https://dom.spec.whatwg.org/#domimplementation DOM Living Standard
+ */
+ constructor();
+
+ /**
+ * Creates an XML Document object of the specified type with its document element.
+ *
+ * __It behaves slightly different from the description in the living standard__:
+ * - There is no interface/class `XMLDocument`, it returns a `Document` instance (with it's
+ * `type` set to `'xml'`).
+ * - `encoding`, `mode`, `origin`, `url` fields are currently not declared.
+ *
+ * @returns {Document}
+ * The XML document.
+ * @see {@link DOMImplementation.createHTMLDocument}
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/createDocument MDN
+ * @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#Level-2-Core-DOM-createDocument DOM
+ * Level 2 Core (initial)
+ * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocument DOM Level 2 Core
+ */
+ createDocument(
+ namespaceURI: NAMESPACE | string | null,
+ qualifiedName: string,
+ doctype?: DocumentType | null
+ ): Document;
+
+ /**
+ * Returns a doctype, with the given `qualifiedName`, `publicId`, and `systemId`.
+ *
+ * __This behavior is slightly different from the in the specs__:
+ * - `encoding`, `mode`, `origin`, `url` fields are currently not declared.
+ *
+ * @returns {DocumentType}
+ * which can either be used with `DOMImplementation.createDocument`
+ * upon document creation or can be put into the document via methods like
+ * `Node.insertBefore()` or `Node.replaceChild()`
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/createDocumentType
+ * MDN
+ * @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#Level-2-Core-DOM-createDocType DOM
+ * Level 2 Core
+ * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype DOM Living
+ * Standard
+ */
+ createDocumentType(
+ qualifiedName: string,
+ /**
+ * External subset public identifier. Stored verbatim including surrounding quotes.
+ * No creation-time validation — deferred to a future breaking release.
+ */
+ publicId?: string,
+ /**
+ * External subset system identifier. Stored verbatim including surrounding quotes.
+ * No creation-time validation — deferred to a future breaking release.
+ */
+ systemId?: string,
+ /**
+ * Internal subset string (content between `[` and `]`). Stored verbatim.
+ * No creation-time validation — deferred to a future breaking release.
+ */
+ internalSubset?: string
+ ): DocumentType;
+
+ /**
+ * Returns an HTML document, that might already have a basic DOM structure.
+ *
+ * __It behaves slightly different from the description in the living standard__:
+ * - If the first argument is `false` no initial nodes are added (steps 3-7 in the specs are
+ * omitted)
+ * - several properties and methods are missing - Nothing related to events is implemented.
+ *
+ * @see {@link DOMImplementation.createDocument}
+ * @see https://dom.spec.whatwg.org/#dom-domimplementation-createhtmldocument
+ * @see https://dom.spec.whatwg.org/#html-document
+ */
+ createHTMLDocument(title?: string | false): Document;
+
+ /**
+ * The DOMImplementation.hasFeature() method returns a Boolean flag indicating if a given
+ * feature is supported. The different implementations fairly diverged in what kind of
+ * features were reported. The latest version of the spec settled to force this method to
+ * always return true, where the functionality was accurate and in use.
+ *
+ * @deprecated
+ * It is deprecated and modern browsers return true in all cases.
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/hasFeature MDN
+ * @see https://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-5CED94D7 DOM Level 1
+ * Core
+ * @see https://dom.spec.whatwg.org/#dom-domimplementation-hasfeature DOM Living Standard
+ */
+ hasFeature(feature: string, version?: string): true;
+ }
+
+ /** Options accepted by `XMLSerializer.prototype.serializeToString` and `node.toString`. */
+ interface XMLSerializerOptions {
+ /**
+ * When `true`, the serializer throws `InvalidStateError` for content that would produce
+ * ill-formed XML: CDATASection data containing `"]]>"`; Text data with characters outside
+ * the XML Char production; a Comment node whose data contains `--` anywhere or ends with
+ * `-`; or a Document with no `documentElement`.
+ *
+ * @default false
+ */
+ requireWellFormed?: boolean;
+ /**
+ * When `true` (the default), `"]]>"` sequences in CDATASection data are split across
+ * concatenated CDATA sections. **Deprecated** — this option and the underlying split
+ * mechanics will be removed in the next breaking release. Callers should migrate to `{
+ * requireWellFormed: true }`, which throws `InvalidStateError` instead of transforming.
+ *
+ * @default true
+ */
+ splitCDATASections?: boolean;
+ /** A filter function applied to each node before serialization. */
+ nodeFilter?: (node: Node) => Node | null | undefined;
+ }
+
+ class XMLSerializer {
+ /**
+ * Returns the result of serializing `node` to XML.
+ *
+ * When `options.requireWellFormed` is `true`, throws `InvalidStateError` for content that
+ * would produce ill-formed XML. When `options.splitCDATASections` is `false`,
+ * CDATASection data is emitted verbatim. Passing a function as `options` is treated as a
+ * legacy `nodeFilter` for backward compatibility.
+ *
+ * __This implementation differs from the specification:__ - CDATASection serialization is
+ * not specified by W3C DOM Parsing or WHATWG DOM Parsing (see
+ * {@link https://github.com/w3c/DOM-Parsing/issues/38 w3c/DOM-Parsing#38}).
+ * When `splitCDATASections` is `true` (the default), `"]]>"` sequences are split across
+ * concatenated CDATA sections — **deprecated**, will be removed in the next breaking
+ * release.
+ * - W3C DOM Parsing §3.2.1.1 requires well-formedness checks on Element `localName`s,
+ * prefixes, and attribute serialization when `requireWellFormed` is `true`. Element and
+ * attribute qualified names (which cover the namespace prefix) are validated against the XML
+ * `QName` production; the remaining §3.2.1.1 checks (duplicate attributes,
+ * namespace-declaration consistency) and creation-time name validation are **not
+ * implemented** in this release — see the tracking issue filed against the next breaking
+ * milestone.
+ *
+ * @throws {DOMException}
+ * `InvalidStateError` when `requireWellFormed` is `true` and any of the following conditions
+ * hold:
+ * - an Element's qualified name (including any namespace prefix) is not a valid XML QName
+ * - an attribute's qualified name (including a synthesized `xmlns:` namespace declaration) is
+ * not a valid XML QName
+ * - CDATASection data contains `"]]>"`
+ * - Text data contains characters outside the XML Char production
+ * - a Comment node's data contains `--` anywhere or ends with `-`
+ * - a ProcessingInstruction's target is not a valid XML `NCName` (a `Name` with no colon) or
+ * is an ASCII case-insensitive match for `"xml"`, or its data contains `?>` or characters
+ * outside the XML Char production
+ * - a DocumentType's `name` is not a valid XML `Name` (XML 1.0 production [5])
+ * - a DocumentType's `publicId` is non-empty and does not match the XML `PubidLiteral`
+ * production (W3C DOM Parsing §3.2.1.3; XML 1.0 production [12])
+ * - a DocumentType's `systemId` is non-empty and does not match the XML `SystemLiteral`
+ * production (W3C DOM Parsing §3.2.1.3; XML 1.0 production [11])
+ * - a DocumentType's `internalSubset` contains `"]>"`
+ * - an EntityReference's `nodeName` is not a valid XML `Name` (XML 1.0 production [5])
+ * - the Document has no `documentElement`
+ * @see https://developer.mozilla.org/docs/Web/API/XMLSerializer/serializeToString
+ * @see https://html.spec.whatwg.org/#dom-xmlserializer-serializetostring
+ * @see https://github.com/w3c/DOM-Parsing/issues/84
+ * @prettierignore
+ */
+ serializeToString(
+ node: Node,
+ options?: XMLSerializerOptions | ((node: Node) => Node | null | undefined)
+ ): string;
+ }
+ // END ./lib/dom.js
+
+ // START ./lib/dom-parser.js
+ /**
+ * The DOMParser interface provides the ability to parse XML or HTML source code from a string
+ * into a DOM `Document`.
+ *
+ * _xmldom is different from the spec in that it allows an `options` parameter,
+ * to control the behavior._.
+ *
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser
+ * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-parsing-and-serialization
+ */
+ class DOMParser {
+ /**
+ * The DOMParser interface provides the ability to parse XML or HTML source code from a
+ * string into a DOM `Document`.
+ *
+ * _xmldom is different from the spec in that it allows an `options` parameter,
+ * to control the behavior._.
+ *
+ * @class
+ * @param {DOMParserOptions} [options]
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser
+ * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-parsing-and-serialization
+ */
+ constructor(options?: DOMParserOptions);
+
+ /**
+ * Parses `source` using the options in the way configured by the `DOMParserOptions` of
+ * `this`
+ * `DOMParser`. If `mimeType` is `text/html` an HTML `Document` is created, otherwise an XML
+ * `Document` is created.
+ *
+ * __It behaves different from the description in the living standard__:
+ * - Uses the `options` passed to the `DOMParser` constructor to modify the behavior.
+ * - Any unexpected input is reported to `onError` with either a `warning`, `error` or
+ * `fatalError` level.
+ * - Any `fatalError` throws a `ParseError` which prevents further processing.
+ * - Any error thrown by `onError` is converted to a `ParseError` which prevents further
+ * processing - If no `Document` was created during parsing it is reported as a `fatalError`.
+ * - A `DOMException` raised while building the DOM (e.g. an unbound namespace prefix) is
+ * reported as a `fatalError` and rethrown as a `ParseError` with the `DOMException` as its
+ * `cause`.
+ *
+ * @returns
+ * The `Document` node.
+ * @throws {ParseError}
+ * for any `fatalError` or anything that is thrown by `onError`
+ * @throws {TypeError}
+ * for any invalid `mimeType`
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString
+ * @see https://html.spec.whatwg.org/#dom-domparser-parsefromstring-dev
+ */
+ parseFromString(source: string, mimeType: MIME_TYPE | string): Document;
+ }
+
+ interface DOMParserOptions {
+ /**
+ * The method to use instead of `Object.assign` (defaults to `conventions.assign`),
+ * which is used to copy values from the options before they are used for parsing.
+ *
+ * @private
+ * @see {@link assign}
+ */
+ readonly assign?: typeof Object.assign;
+ /**
+ * For internal testing: The class for creating an instance for handling events from the SAX
+ * parser.
+ * *****Warning: By configuring a faulty implementation,
+ * the specified behavior can completely be broken*****.
+ *
+ * @private
+ */
+ readonly domHandler?: unknown;
+
+ /**
+ * DEPRECATED: Use `onError` instead!
+ *
+ * For backwards compatibility:
+ * If it is a function, it will be used as a value for `onError`,
+ * but it receives different argument types than before 0.9.0.
+ *
+ * @deprecated
+ * @throws {TypeError}
+ * If it is an object.
+ */
+ readonly errorHandler?: ErrorHandlerFunction;
+
+ /**
+ * Configures if the nodes created during parsing
+ * will have a `lineNumber` and a `columnNumber` attribute
+ * describing their location in the XML string.
+ * Default is true.
+ */
+ readonly locator?: boolean;
+
+ /**
+ * used to replace line endings before parsing, defaults to exported `normalizeLineEndings`,
+ * which normalizes line endings according to ,
+ * including some Unicode "newline" characters.
+ *
+ * @see {@link normalizeLineEndings}
+ */
+ readonly normalizeLineEndings?: (source: string) => string;
+ /**
+ * A function invoked for every error that occurs during parsing.
+ *
+ * If it is not provided, all errors are reported to `console.error`
+ * and only `fatalError`s are thrown as a `ParseError`,
+ * which prevents any further processing.
+ * If the provided method throws, a `ParserError` is thrown,
+ * which prevents any further processing.
+ *
+ * Be aware that many `warning`s are considered an error that prevents further processing in
+ * most implementations.
+ *
+ * @param level
+ * The error level as reported by the SAXParser.
+ * @param message
+ * The error message.
+ * @param context
+ * The DOMHandler instance used for parsing.
+ * @see {@link onErrorStopParsing}
+ * @see {@link onWarningStopParsing}
+ */
+ readonly onError?: ErrorHandlerFunction;
+
+ /**
+ * The XML namespaces that should be assumed when parsing.
+ * The default namespace can be provided by the key that is the empty string.
+ * When the `mimeType` for HTML, XHTML or SVG are passed to `parseFromString`,
+ * the default namespace that will be used,
+ * will be overridden according to the specification.
+ */
+ readonly xmlns?: Readonly>;
+ }
+
+ interface ErrorHandlerFunction {
+ (
+ level: 'warning' | 'error' | 'fatalError',
+ msg: string,
+ context: any
+ ): void;
+ }
+
+ /**
+ * Normalizes line ending according to ,
+ * including some Unicode "newline" characters:
+ *
+ * > XML parsed entities are often stored in computer files which,
+ * > for editing convenience, are organized into lines.
+ * > These lines are typically separated by some combination
+ * > of the characters CARRIAGE RETURN (#xD) and LINE FEED (#xA).
+ * >
+ * > To simplify the tasks of applications, the XML processor must behave
+ * > as if it normalized all line breaks in external parsed entities (including the document entity)
+ * > on input, before parsing, by translating the following to a single #xA character:
+ * >
+ * > 1. the two-character sequence #xD #xA,
+ * > 2. the two-character sequence #xD #x85,
+ * > 3. the single character #x85,
+ * > 4. the single character #x2028,
+ * > 5. the single character #x2029,
+ * > 6. any #xD character that is not immediately followed by #xA or #x85.
+ *
+ * @prettierignore
+ */
+ function normalizeLineEndings(input: string): string;
+ /**
+ * A method that prevents any further parsing when an `error`
+ * with level `error` is reported during parsing.
+ *
+ * @see {@link DOMParserOptions.onError}
+ * @see {@link onWarningStopParsing}
+ */
+ function onErrorStopParsing(): void | never;
+
+ /**
+ * A method that prevents any further parsing when an `error`
+ * with any level is reported during parsing.
+ *
+ * @see {@link DOMParserOptions.onError}
+ * @see {@link onErrorStopParsing}
+ */
+ function onWarningStopParsing(): never;
+
+ // END ./lib/dom-parser.js
+}
diff --git a/node_modules/@xmldom/xmldom/lib/.eslintrc.yml b/node_modules/@xmldom/xmldom/lib/.eslintrc.yml
new file mode 100644
index 000000000..a7314af01
--- /dev/null
+++ b/node_modules/@xmldom/xmldom/lib/.eslintrc.yml
@@ -0,0 +1,3 @@
+extends:
+ - 'plugin:es5/no-es2015'
+ - 'plugin:n/recommended'
diff --git a/node_modules/@xmldom/xmldom/lib/conventions.js b/node_modules/@xmldom/xmldom/lib/conventions.js
new file mode 100644
index 000000000..c0642011d
--- /dev/null
+++ b/node_modules/@xmldom/xmldom/lib/conventions.js
@@ -0,0 +1,429 @@
+'use strict';
+
+/**
+ * Ponyfill for `Array.prototype.find` which is only available in ES6 runtimes.
+ *
+ * Works with anything that has a `length` property and index access properties,
+ * including NodeList.
+ *
+ * @param {T[] | { length: number; [number]: T }} list
+ * @param {function (item: T, index: number, list:T[]):boolean} predicate
+ * @param {Partial>?} ac
+ * Allows injecting a custom implementation in tests (`Array.prototype` by default).
+ * @returns {T | undefined}
+ * @template {unknown} T
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find
+ * @see https://tc39.es/ecma262/multipage/indexed-collections.html#sec-array.prototype.find
+ */
+function find(list, predicate, ac) {
+ if (ac === undefined) {
+ ac = Array.prototype;
+ }
+ if (list && typeof ac.find === 'function') {
+ return ac.find.call(list, predicate);
+ }
+ for (var i = 0; i < list.length; i++) {
+ if (hasOwn(list, i)) {
+ var item = list[i];
+ if (predicate.call(undefined, item, i, list)) {
+ return item;
+ }
+ }
+ }
+}
+
+/**
+ * "Shallow freezes" an object to render it immutable.
+ * Uses `Object.freeze` if available,
+ * otherwise the immutability is only in the type.
+ *
+ * Is used to create "enum like" objects.
+ *
+ * If `Object.getOwnPropertyDescriptors` is available,
+ * a new object with all properties of object but without any prototype is created and returned
+ * after freezing it.
+ *
+ * @param {T} object
+ * The object to freeze.
+ * @param {Pick} [oc=Object]
+ * `Object` by default,
+ * allows to inject custom object constructor for tests.
+ * @returns {Readonly}
+ * @template {Object} T
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze
+ * @prettierignore
+ */
+function freeze(object, oc) {
+ if (oc === undefined) {
+ oc = Object;
+ }
+ if (oc && typeof oc.getOwnPropertyDescriptors === 'function') {
+ object = oc.create(null, oc.getOwnPropertyDescriptors(object));
+ }
+ return oc && typeof oc.freeze === 'function' ? oc.freeze(object) : object;
+}
+
+/**
+ * Implementation for `Object.hasOwn` but ES5 compatible.
+ *
+ * @param {any} object
+ * @param {string | number} key
+ * @returns {boolean}
+ */
+function hasOwn(object, key) {
+ return Object.prototype.hasOwnProperty.call(object, key);
+}
+
+/**
+ * Since xmldom can not rely on `Object.assign`,
+ * it uses/provides a simplified version that is sufficient for its needs.
+ *
+ * @param {Object} target
+ * @param {Object | null | undefined} source
+ * @returns {Object}
+ * The target with the merged/overridden properties.
+ * @throws {TypeError}
+ * If target is not an object.
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
+ * @see https://tc39.es/ecma262/multipage/fundamental-objects.html#sec-object.assign
+ */
+function assign(target, source) {
+ if (target === null || typeof target !== 'object') {
+ throw new TypeError('target is not an object');
+ }
+ for (var key in source) {
+ if (hasOwn(source, key)) {
+ target[key] = source[key];
+ }
+ }
+ return target;
+}
+
+/**
+ * A number of attributes are boolean attributes.
+ * The presence of a boolean attribute on an element represents the `true` value,
+ * and the absence of the attribute represents the `false` value.
+ *
+ * If the attribute is present, its value must either be the empty string, or a value that is
+ * an ASCII case-insensitive match for the attribute's canonical name,
+ * with no leading or trailing whitespace.
+ *
+ * Note: The values `"true"` and `"false"` are not allowed on boolean attributes.
+ * To represent a `false` value, the attribute has to be omitted altogether.
+ *
+ * @see https://html.spec.whatwg.org/#boolean-attributes
+ * @see https://html.spec.whatwg.org/#attributes-3
+ */
+var HTML_BOOLEAN_ATTRIBUTES = freeze({
+ allowfullscreen: true,
+ async: true,
+ autofocus: true,
+ autoplay: true,
+ checked: true,
+ controls: true,
+ default: true,
+ defer: true,
+ disabled: true,
+ formnovalidate: true,
+ hidden: true,
+ ismap: true,
+ itemscope: true,
+ loop: true,
+ multiple: true,
+ muted: true,
+ nomodule: true,
+ novalidate: true,
+ open: true,
+ playsinline: true,
+ readonly: true,
+ required: true,
+ reversed: true,
+ selected: true,
+});
+
+/**
+ * Check if `name` is matching one of the HTML boolean attribute names.
+ * This method doesn't check if such attributes are allowed in the context of the current
+ * document/parsing.
+ *
+ * @param {string} name
+ * @returns {boolean}
+ * @see {@link HTML_BOOLEAN_ATTRIBUTES}
+ * @see https://html.spec.whatwg.org/#boolean-attributes
+ * @see https://html.spec.whatwg.org/#attributes-3
+ */
+function isHTMLBooleanAttribute(name) {
+ return hasOwn(HTML_BOOLEAN_ATTRIBUTES, name.toLowerCase());
+}
+
+/**
+ * Void elements only have a start tag; end tags must not be specified for void elements.
+ * These elements should be written as self-closing like this: ``.
+ * This should not be confused with optional tags that HTML allows to omit the end tag for
+ * (like `li`, `tr` and others), which can have content after them,
+ * so they can not be written as self-closing.
+ * xmldom does not have any logic for optional end tags cases,
+ * and will report them as a warning.
+ * Content that would go into the unopened element,
+ * will instead be added as a sibling text node.
+ *
+ * @type {Readonly<{
+ * area: boolean;
+ * col: boolean;
+ * img: boolean;
+ * wbr: boolean;
+ * link: boolean;
+ * hr: boolean;
+ * source: boolean;
+ * br: boolean;
+ * input: boolean;
+ * param: boolean;
+ * meta: boolean;
+ * embed: boolean;
+ * track: boolean;
+ * base: boolean;
+ * }>}
+ * @see https://html.spec.whatwg.org/#void-elements
+ * @see https://html.spec.whatwg.org/#optional-tags
+ */
+var HTML_VOID_ELEMENTS = freeze({
+ area: true,
+ base: true,
+ br: true,
+ col: true,
+ embed: true,
+ hr: true,
+ img: true,
+ input: true,
+ link: true,
+ meta: true,
+ param: true,
+ source: true,
+ track: true,
+ wbr: true,
+});
+
+/**
+ * Check if `tagName` is matching one of the HTML void element names.
+ * This method doesn't check if such tags are allowed in the context of the current
+ * document/parsing.
+ *
+ * @param {string} tagName
+ * @returns {boolean}
+ * @see {@link HTML_VOID_ELEMENTS}
+ * @see https://html.spec.whatwg.org/#void-elements
+ */
+function isHTMLVoidElement(tagName) {
+ return hasOwn(HTML_VOID_ELEMENTS, tagName.toLowerCase());
+}
+
+/**
+ * Tag names that are raw text elements according to HTML spec.
+ * The value denotes whether they are escapable or not.
+ *
+ * @see {@link isHTMLEscapableRawTextElement}
+ * @see {@link isHTMLRawTextElement}
+ * @see https://html.spec.whatwg.org/#raw-text-elements
+ * @see https://html.spec.whatwg.org/#escapable-raw-text-elements
+ */
+var HTML_RAW_TEXT_ELEMENTS = freeze({
+ script: false,
+ style: false,
+ textarea: true,
+ title: true,
+});
+
+/**
+ * Check if `tagName` is matching one of the HTML raw text element names.
+ * This method doesn't check if such tags are allowed in the context of the current
+ * document/parsing.
+ *
+ * @param {string} tagName
+ * @returns {boolean}
+ * @see {@link isHTMLEscapableRawTextElement}
+ * @see {@link HTML_RAW_TEXT_ELEMENTS}
+ * @see https://html.spec.whatwg.org/#raw-text-elements
+ * @see https://html.spec.whatwg.org/#escapable-raw-text-elements
+ */
+function isHTMLRawTextElement(tagName) {
+ var key = tagName.toLowerCase();
+ return hasOwn(HTML_RAW_TEXT_ELEMENTS, key) && !HTML_RAW_TEXT_ELEMENTS[key];
+}
+/**
+ * Check if `tagName` is matching one of the HTML escapable raw text element names.
+ * This method doesn't check if such tags are allowed in the context of the current
+ * document/parsing.
+ *
+ * @param {string} tagName
+ * @returns {boolean}
+ * @see {@link isHTMLRawTextElement}
+ * @see {@link HTML_RAW_TEXT_ELEMENTS}
+ * @see https://html.spec.whatwg.org/#raw-text-elements
+ * @see https://html.spec.whatwg.org/#escapable-raw-text-elements
+ */
+function isHTMLEscapableRawTextElement(tagName) {
+ var key = tagName.toLowerCase();
+ return hasOwn(HTML_RAW_TEXT_ELEMENTS, key) && HTML_RAW_TEXT_ELEMENTS[key];
+}
+/**
+ * Only returns true if `value` matches MIME_TYPE.HTML, which indicates an HTML document.
+ *
+ * @param {string} mimeType
+ * @returns {mimeType is 'text/html'}
+ * @see https://www.iana.org/assignments/media-types/text/html
+ * @see https://en.wikipedia.org/wiki/HTML
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString
+ * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-domparser-parsefromstring
+ */
+function isHTMLMimeType(mimeType) {
+ return mimeType === MIME_TYPE.HTML;
+}
+/**
+ * For both the `text/html` and the `application/xhtml+xml` namespace the spec defines that the
+ * HTML namespace is provided as the default.
+ *
+ * @param {string} mimeType
+ * @returns {boolean}
+ * @see https://dom.spec.whatwg.org/#dom-document-createelement
+ * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocument
+ * @see https://dom.spec.whatwg.org/#dom-domimplementation-createhtmldocument
+ */
+function hasDefaultHTMLNamespace(mimeType) {
+ return isHTMLMimeType(mimeType) || mimeType === MIME_TYPE.XML_XHTML_APPLICATION;
+}
+
+/**
+ * All mime types that are allowed as input to `DOMParser.parseFromString`
+ *
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString#Argument02
+ * MDN
+ * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#domparsersupportedtype
+ * WHATWG HTML Spec
+ * @see {@link DOMParser.prototype.parseFromString}
+ */
+var MIME_TYPE = freeze({
+ /**
+ * `text/html`, the only mime type that triggers treating an XML document as HTML.
+ *
+ * @see https://www.iana.org/assignments/media-types/text/html IANA MimeType registration
+ * @see https://en.wikipedia.org/wiki/HTML Wikipedia
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString MDN
+ * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-domparser-parsefromstring
+ * WHATWG HTML Spec
+ */
+ HTML: 'text/html',
+
+ /**
+ * `application/xml`, the standard mime type for XML documents.
+ *
+ * @see https://www.iana.org/assignments/media-types/application/xml IANA MimeType
+ * registration
+ * @see https://tools.ietf.org/html/rfc7303#section-9.1 RFC 7303
+ * @see https://en.wikipedia.org/wiki/XML_and_MIME Wikipedia
+ */
+ XML_APPLICATION: 'application/xml',
+
+ /**
+ * `text/xml`, an alias for `application/xml`.
+ *
+ * @see https://tools.ietf.org/html/rfc7303#section-9.2 RFC 7303
+ * @see https://www.iana.org/assignments/media-types/text/xml IANA MimeType registration
+ * @see https://en.wikipedia.org/wiki/XML_and_MIME Wikipedia
+ */
+ XML_TEXT: 'text/xml',
+
+ /**
+ * `application/xhtml+xml`, indicates an XML document that has the default HTML namespace,
+ * but is parsed as an XML document.
+ *
+ * @see https://www.iana.org/assignments/media-types/application/xhtml+xml IANA MimeType
+ * registration
+ * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocument WHATWG DOM Spec
+ * @see https://en.wikipedia.org/wiki/XHTML Wikipedia
+ */
+ XML_XHTML_APPLICATION: 'application/xhtml+xml',
+
+ /**
+ * `image/svg+xml`,
+ *
+ * @see https://www.iana.org/assignments/media-types/image/svg+xml IANA MimeType registration
+ * @see https://www.w3.org/TR/SVG11/ W3C SVG 1.1
+ * @see https://en.wikipedia.org/wiki/Scalable_Vector_Graphics Wikipedia
+ */
+ XML_SVG_IMAGE: 'image/svg+xml',
+});
+/**
+ * @typedef {'application/xhtml+xml' | 'application/xml' | 'image/svg+xml' | 'text/html' | 'text/xml'}
+ * MimeType
+ */
+/**
+ * @type {MimeType[]}
+ * @private
+ * Basically `Object.values`, which is not available in ES5.
+ */
+var _MIME_TYPES = Object.keys(MIME_TYPE).map(function (key) {
+ return MIME_TYPE[key];
+});
+
+/**
+ * Only returns true if `mimeType` is one of the allowed values for
+ * `DOMParser.parseFromString`.
+ *
+ * @param {string} mimeType
+ * @returns {mimeType is 'application/xhtml+xml' | 'application/xml' | 'image/svg+xml' | 'text/html' | 'text/xml'}
+ *
+ */
+function isValidMimeType(mimeType) {
+ return _MIME_TYPES.indexOf(mimeType) > -1;
+}
+/**
+ * Namespaces that are used in this code base.
+ *
+ * @see http://www.w3.org/TR/REC-xml-names
+ */
+var NAMESPACE = freeze({
+ /**
+ * The XHTML namespace.
+ *
+ * @see http://www.w3.org/1999/xhtml
+ */
+ HTML: 'http://www.w3.org/1999/xhtml',
+
+ /**
+ * The SVG namespace.
+ *
+ * @see http://www.w3.org/2000/svg
+ */
+ SVG: 'http://www.w3.org/2000/svg',
+
+ /**
+ * The `xml:` namespace.
+ *
+ * @see http://www.w3.org/XML/1998/namespace
+ */
+ XML: 'http://www.w3.org/XML/1998/namespace',
+
+ /**
+ * The `xmlns:` namespace.
+ *
+ * @see https://www.w3.org/2000/xmlns/
+ */
+ XMLNS: 'http://www.w3.org/2000/xmlns/',
+});
+
+exports.assign = assign;
+exports.find = find;
+exports.freeze = freeze;
+exports.HTML_BOOLEAN_ATTRIBUTES = HTML_BOOLEAN_ATTRIBUTES;
+exports.HTML_RAW_TEXT_ELEMENTS = HTML_RAW_TEXT_ELEMENTS;
+exports.HTML_VOID_ELEMENTS = HTML_VOID_ELEMENTS;
+exports.hasDefaultHTMLNamespace = hasDefaultHTMLNamespace;
+exports.hasOwn = hasOwn;
+exports.isHTMLBooleanAttribute = isHTMLBooleanAttribute;
+exports.isHTMLRawTextElement = isHTMLRawTextElement;
+exports.isHTMLEscapableRawTextElement = isHTMLEscapableRawTextElement;
+exports.isHTMLMimeType = isHTMLMimeType;
+exports.isHTMLVoidElement = isHTMLVoidElement;
+exports.isValidMimeType = isValidMimeType;
+exports.MIME_TYPE = MIME_TYPE;
+exports.NAMESPACE = NAMESPACE;
diff --git a/node_modules/@xmldom/xmldom/lib/dom-parser.js b/node_modules/@xmldom/xmldom/lib/dom-parser.js
new file mode 100644
index 000000000..d74ba8dcb
--- /dev/null
+++ b/node_modules/@xmldom/xmldom/lib/dom-parser.js
@@ -0,0 +1,591 @@
+'use strict';
+
+var conventions = require('./conventions');
+var dom = require('./dom');
+var errors = require('./errors');
+var entities = require('./entities');
+var sax = require('./sax');
+
+var DOMImplementation = dom.DOMImplementation;
+
+var hasDefaultHTMLNamespace = conventions.hasDefaultHTMLNamespace;
+var isHTMLMimeType = conventions.isHTMLMimeType;
+var isValidMimeType = conventions.isValidMimeType;
+var MIME_TYPE = conventions.MIME_TYPE;
+var NAMESPACE = conventions.NAMESPACE;
+var ParseError = errors.ParseError;
+
+var XMLReader = sax.XMLReader;
+
+/**
+ * Normalizes line ending according to ,
+ * including some Unicode "newline" characters:
+ *
+ * > XML parsed entities are often stored in computer files which,
+ * > for editing convenience, are organized into lines.
+ * > These lines are typically separated by some combination
+ * > of the characters CARRIAGE RETURN (#xD) and LINE FEED (#xA).
+ * >
+ * > To simplify the tasks of applications, the XML processor must behave
+ * > as if it normalized all line breaks in external parsed entities (including the document entity)
+ * > on input, before parsing, by translating the following to a single #xA character:
+ * >
+ * > 1. the two-character sequence #xD #xA,
+ * > 2. the two-character sequence #xD #x85,
+ * > 3. the single character #x85,
+ * > 4. the single character #x2028,
+ * > 5. the single character #x2029,
+ * > 6. any #xD character that is not immediately followed by #xA or #x85.
+ *
+ * @param {string} input
+ * @returns {string}
+ * @prettierignore
+ */
+function normalizeLineEndings(input) {
+ return input.replace(/\r[\n\u0085]/g, '\n').replace(/[\r\u0085\u2028\u2029]/g, '\n');
+}
+
+/**
+ * @typedef Locator
+ * @property {number} [columnNumber]
+ * @property {number} [lineNumber]
+ */
+
+/**
+ * @typedef DOMParserOptions
+ * @property {typeof assign} [assign]
+ * The method to use instead of `conventions.assign`, which is used to copy values from
+ * `options` before they are used for parsing.
+ * @property {typeof DOMHandler} [domHandler]
+ * For internal testing: The class for creating an instance for handling events from the SAX
+ * parser.
+ * *****Warning: By configuring a faulty implementation, the specified behavior can completely
+ * be broken.*****.
+ * @property {Function} [errorHandler]
+ * DEPRECATED! use `onError` instead.
+ * @property {function(level:ErrorLevel, message:string, context: DOMHandler):void}
+ * [onError]
+ * A function invoked for every error that occurs during parsing.
+ *
+ * If it is not provided, all errors are reported to `console.error`
+ * and only `fatalError`s are thrown as a `ParseError`,
+ * which prevents any further processing.
+ * If the provided method throws, a `ParserError` is thrown,
+ * which prevents any further processing.
+ *
+ * Be aware that many `warning`s are considered an error that prevents further processing in
+ * most implementations.
+ * @property {boolean} [locator=true]
+ * Configures if the nodes created during parsing will have a `lineNumber` and a `columnNumber`
+ * attribute describing their location in the XML string.
+ * Default is true.
+ * @property {(string) => string} [normalizeLineEndings]
+ * used to replace line endings before parsing, defaults to exported `normalizeLineEndings`,
+ * which normalizes line endings according to ,
+ * including some Unicode "newline" characters.
+ * @property {Object} [xmlns]
+ * The XML namespaces that should be assumed when parsing.
+ * The default namespace can be provided by the key that is the empty string.
+ * When the `mimeType` for HTML, XHTML or SVG are passed to `parseFromString`,
+ * the default namespace that will be used,
+ * will be overridden according to the specification.
+ * @see {@link normalizeLineEndings}
+ */
+
+/**
+ * The DOMParser interface provides the ability to parse XML or HTML source code from a string
+ * into a DOM `Document`.
+ *
+ * ***xmldom is different from the spec in that it allows an `options` parameter,
+ * to control the behavior***.
+ *
+ * @class
+ * @param {DOMParserOptions} [options]
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser
+ * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-parsing-and-serialization
+ */
+function DOMParser(options) {
+ options = options || {};
+ if (options.locator === undefined) {
+ options.locator = true;
+ }
+
+ /**
+ * The method to use instead of `conventions.assign`, which is used to copy values from
+ * `options`
+ * before they are used for parsing.
+ *
+ * @type {conventions.assign}
+ * @private
+ * @see {@link conventions.assign}
+ * @readonly
+ */
+ this.assign = options.assign || conventions.assign;
+
+ /**
+ * For internal testing: The class for creating an instance for handling events from the SAX
+ * parser.
+ * *****Warning: By configuring a faulty implementation, the specified behavior can completely
+ * be broken*****.
+ *
+ * @type {typeof DOMHandler}
+ * @private
+ * @readonly
+ */
+ this.domHandler = options.domHandler || DOMHandler;
+
+ /**
+ * A function that is invoked for every error that occurs during parsing.
+ *
+ * If it is not provided, all errors are reported to `console.error`
+ * and only `fatalError`s are thrown as a `ParseError`,
+ * which prevents any further processing.
+ * If the provided method throws, a `ParserError` is thrown,
+ * which prevents any further processing.
+ *
+ * Be aware that many `warning`s are considered an error that prevents further processing in
+ * most implementations.
+ *
+ * @type {function(level:ErrorLevel, message:string, context: DOMHandler):void}
+ * @see {@link onErrorStopParsing}
+ * @see {@link onWarningStopParsing}
+ */
+ this.onError = options.onError || options.errorHandler;
+ if (options.errorHandler && typeof options.errorHandler !== 'function') {
+ throw new TypeError('errorHandler object is no longer supported, switch to onError!');
+ } else if (options.errorHandler) {
+ options.errorHandler('warning', 'The `errorHandler` option has been deprecated, use `onError` instead!', this);
+ }
+
+ /**
+ * used to replace line endings before parsing, defaults to `normalizeLineEndings`
+ *
+ * @type {(string) => string}
+ * @readonly
+ */
+ this.normalizeLineEndings = options.normalizeLineEndings || normalizeLineEndings;
+
+ /**
+ * Configures if the nodes created during parsing will have a `lineNumber` and a
+ * `columnNumber`
+ * attribute describing their location in the XML string.
+ * Default is true.
+ *
+ * @type {boolean}
+ * @readonly
+ */
+ this.locator = !!options.locator;
+
+ /**
+ * The default namespace can be provided by the key that is the empty string.
+ * When the `mimeType` for HTML, XHTML or SVG are passed to `parseFromString`,
+ * the default namespace that will be used,
+ * will be overridden according to the specification.
+ *
+ * @type {Readonly}
+ * @readonly
+ */
+ this.xmlns = this.assign(Object.create(null), options.xmlns);
+}
+
+/**
+ * Parses `source` using the options in the way configured by the `DOMParserOptions` of `this`
+ * `DOMParser`. If `mimeType` is `text/html` an HTML `Document` is created,
+ * otherwise an XML `Document` is created.
+ *
+ * __It behaves different from the description in the living standard__:
+ * - Uses the `options` passed to the `DOMParser` constructor to modify the behavior.
+ * - Any unexpected input is reported to `onError` with either a `warning`,
+ * `error` or `fatalError` level.
+ * - Any `fatalError` throws a `ParseError` which prevents further processing.
+ * - Any error thrown by `onError` is converted to a `ParseError` which prevents further
+ * processing - If no `Document` was created during parsing it is reported as a `fatalError`.
+ * - A `DOMException` raised while building the DOM (e.g. an unbound namespace prefix) is
+ * reported as a `fatalError` and rethrown as a `ParseError` with the `DOMException` as its
+ * `cause`.
+ * *****Warning: By configuring a faulty DOMHandler implementation,
+ * the specified behavior can completely be broken*****.
+ *
+ * @param {string} source
+ * The XML mime type only allows string input!
+ * @param {string} [mimeType='application/xml']
+ * the mimeType or contentType of the document to be created determines the `type` of document
+ * created (XML or HTML)
+ * @returns {Document}
+ * The `Document` node.
+ * @throws {ParseError}
+ * for any `fatalError` or anything that is thrown by `onError`
+ * @throws {TypeError}
+ * for any invalid `mimeType`
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString
+ * @see https://html.spec.whatwg.org/#dom-domparser-parsefromstring-dev
+ */
+DOMParser.prototype.parseFromString = function (source, mimeType) {
+ if (!isValidMimeType(mimeType)) {
+ throw new TypeError('DOMParser.parseFromString: the provided mimeType "' + mimeType + '" is not valid.');
+ }
+ var defaultNSMap = this.assign(Object.create(null), this.xmlns);
+ var entityMap = entities.XML_ENTITIES;
+ var defaultNamespace = defaultNSMap[''] || null;
+ if (hasDefaultHTMLNamespace(mimeType)) {
+ entityMap = entities.HTML_ENTITIES;
+ defaultNamespace = NAMESPACE.HTML;
+ } else if (mimeType === MIME_TYPE.XML_SVG_IMAGE) {
+ defaultNamespace = NAMESPACE.SVG;
+ }
+ defaultNSMap[''] = defaultNamespace;
+ defaultNSMap.xml = defaultNSMap.xml || NAMESPACE.XML;
+
+ var domBuilder = new this.domHandler({
+ mimeType: mimeType,
+ defaultNamespace: defaultNamespace,
+ onError: this.onError,
+ });
+ var locator = this.locator ? {} : undefined;
+ if (this.locator) {
+ domBuilder.setDocumentLocator(locator);
+ }
+
+ var sax = new XMLReader();
+ sax.errorHandler = domBuilder;
+ sax.domBuilder = domBuilder;
+ var isXml = !conventions.isHTMLMimeType(mimeType);
+ if (isXml && typeof source !== 'string') {
+ sax.errorHandler.fatalError('source is not a string');
+ }
+ sax.parse(this.normalizeLineEndings(String(source)), defaultNSMap, entityMap);
+ if (!domBuilder.doc.documentElement) {
+ sax.errorHandler.fatalError('missing root element');
+ }
+ return domBuilder.doc;
+};
+
+/**
+ * @typedef DOMHandlerOptions
+ * @property {string} [mimeType=MIME_TYPE.XML_APPLICATION]
+ * @property {string | null} [defaultNamespace=null]
+ */
+/**
+ * The class that is used to handle events from the SAX parser to create the related DOM
+ * elements.
+ *
+ * Some methods are only implemented as an empty function,
+ * since they are (at least currently) not relevant for xmldom.
+ *
+ * @class
+ * @param {DOMHandlerOptions} [options]
+ * @see http://www.saxproject.org/apidoc/org/xml/sax/ext/DefaultHandler2.html
+ */
+function DOMHandler(options) {
+ var opt = options || {};
+ /**
+ * The mime type is used to determine if the DOM handler will create an XML or HTML document.
+ * Only if it is set to `text/html` it will create an HTML document.
+ * It defaults to MIME_TYPE.XML_APPLICATION.
+ *
+ * @type {string}
+ * @see {@link MIME_TYPE}
+ * @readonly
+ */
+ this.mimeType = opt.mimeType || MIME_TYPE.XML_APPLICATION;
+
+ /**
+ * The namespace to use to create an XML document.
+ * For the following reasons this is required:
+ * - The SAX API for `startDocument` doesn't offer any way to pass a namespace,
+ * since at that point there is no way for the parser to know what the default namespace from
+ * the document will be.
+ * - When creating using `DOMImplementation.createDocument` it is required to pass a
+ * namespace,
+ * to determine the correct `Document.contentType`, which should match `this.mimeType`.
+ * - When parsing an XML document with the `application/xhtml+xml` mimeType,
+ * the HTML namespace needs to be the default namespace.
+ *
+ * @type {string | null}
+ * @private
+ * @readonly
+ */
+ this.defaultNamespace = opt.defaultNamespace || null;
+
+ /**
+ * @type {boolean}
+ * @private
+ */
+ this.cdata = false;
+
+ /**
+ * The last `Element` that was created by `startElement`.
+ * `endElement` sets it to the `currentElement.parentNode`.
+ *
+ * Note: The sax parser currently sets it to white space text nodes between tags.
+ *
+ * @type {Element | Node | undefined}
+ * @private
+ */
+ this.currentElement = undefined;
+
+ /**
+ * The Document that is created as part of `startDocument`,
+ * and returned by `DOMParser.parseFromString`.
+ *
+ * @type {Document | undefined}
+ * @readonly
+ */
+ this.doc = undefined;
+
+ /**
+ * The locator is stored as part of setDocumentLocator.
+ * It is controlled and mutated by the SAX parser to store the current parsing position.
+ * It is used by DOMHandler to set `columnNumber` and `lineNumber`
+ * on the DOM nodes.
+ *
+ * @type {Readonly | undefined}
+ * @private
+ * @readonly (the
+ * sax parser currently sometimes set's it)
+ */
+ this.locator = undefined;
+ /**
+ * @type {function (level:ErrorLevel ,message:string, context:DOMHandler):void}
+ * @readonly
+ */
+ this.onError = opt.onError;
+}
+
+function position(locator, node) {
+ node.lineNumber = locator.lineNumber;
+ node.columnNumber = locator.columnNumber;
+}
+
+DOMHandler.prototype = {
+ /**
+ * Either creates an XML or an HTML document and stores it under `this.doc`.
+ * If it is an XML document, `this.defaultNamespace` is used to create it,
+ * and it will not contain any `childNodes`.
+ * If it is an HTML document, it will be created without any `childNodes`.
+ *
+ * @see http://www.saxproject.org/apidoc/org/xml/sax/ContentHandler.html
+ */
+ startDocument: function () {
+ var impl = new DOMImplementation();
+ this.doc = isHTMLMimeType(this.mimeType) ? impl.createHTMLDocument(false) : impl.createDocument(this.defaultNamespace, '');
+ },
+ startElement: function (namespaceURI, localName, qName, attrs) {
+ var doc = this.doc;
+ var el = doc.createElementNS(namespaceURI, qName || localName);
+ var len = attrs.length;
+ appendElement(this, el);
+ this.currentElement = el;
+
+ this.locator && position(this.locator, el);
+ for (var i = 0; i < len; i++) {
+ var namespaceURI = attrs.getURI(i);
+ var value = attrs.getValue(i);
+ var qName = attrs.getQName(i);
+ var attr = doc.createAttributeNS(namespaceURI, qName);
+ this.locator && position(attrs.getLocator(i), attr);
+ attr.value = attr.nodeValue = value;
+ el.setAttributeNode(attr);
+ }
+ },
+ endElement: function (namespaceURI, localName, qName) {
+ this.currentElement = this.currentElement.parentNode;
+ },
+ startPrefixMapping: function (prefix, uri) {},
+ endPrefixMapping: function (prefix) {},
+ processingInstruction: function (target, data) {
+ var ins = this.doc.createProcessingInstruction(target, data);
+ this.locator && position(this.locator, ins);
+ appendElement(this, ins);
+ },
+ ignorableWhitespace: function (ch, start, length) {},
+ characters: function (chars, start, length) {
+ chars = _toString.apply(this, arguments);
+ //console.log(chars)
+ if (chars) {
+ if (this.cdata) {
+ var charNode = this.doc.createCDATASection(chars);
+ } else {
+ var charNode = this.doc.createTextNode(chars);
+ }
+ if (this.currentElement) {
+ this.currentElement.appendChild(charNode);
+ } else if (/^\s*$/.test(chars)) {
+ this.doc.appendChild(charNode);
+ //process xml
+ }
+ this.locator && position(this.locator, charNode);
+ }
+ },
+ skippedEntity: function (name) {},
+ endDocument: function () {
+ this.doc.normalize();
+ },
+ /**
+ * Stores the locator to be able to set the `columnNumber` and `lineNumber`
+ * on the created DOM nodes.
+ *
+ * @param {Locator} locator
+ */
+ setDocumentLocator: function (locator) {
+ if (locator) {
+ locator.lineNumber = 0;
+ }
+ this.locator = locator;
+ },
+ //LexicalHandler
+ comment: function (chars, start, length) {
+ chars = _toString.apply(this, arguments);
+ var comm = this.doc.createComment(chars);
+ this.locator && position(this.locator, comm);
+ appendElement(this, comm);
+ },
+
+ startCDATA: function () {
+ //used in characters() methods
+ this.cdata = true;
+ },
+ endCDATA: function () {
+ this.cdata = false;
+ },
+
+ startDTD: function (name, publicId, systemId, internalSubset) {
+ var impl = this.doc.implementation;
+ if (impl && impl.createDocumentType) {
+ var dt = impl.createDocumentType(name, publicId, systemId, internalSubset);
+ this.locator && position(this.locator, dt);
+ appendElement(this, dt);
+ this.doc.doctype = dt;
+ }
+ },
+ reportError: function (level, message) {
+ if (typeof this.onError === 'function') {
+ try {
+ this.onError(level, message, this);
+ } catch (e) {
+ throw new ParseError('Reporting ' + level + ' "' + message + '" caused ' + e, this.locator);
+ }
+ } else {
+ console.error('[xmldom ' + level + ']\t' + message, _locator(this.locator));
+ }
+ },
+ /**
+ * @see http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html
+ */
+ warning: function (message) {
+ this.reportError('warning', message);
+ },
+ error: function (message) {
+ this.reportError('error', message);
+ },
+ /**
+ * This function reports a fatal error and throws a ParseError.
+ *
+ * @param {string} message
+ * - The message to be used for reporting and throwing the error.
+ * @param {Error} [cause]
+ * The error that caused this fatal error, preserved as the thrown `ParseError`'s `cause`.
+ * @returns {never}
+ * This function always throws an error and never returns a value.
+ * @throws {ParseError}
+ * Always throws a ParseError with the provided message.
+ */
+ fatalError: function (message, cause) {
+ this.reportError('fatalError', message);
+ throw new ParseError(message, this.locator, cause);
+ },
+};
+
+function _locator(l) {
+ if (l) {
+ return '\n@#[line:' + l.lineNumber + ',col:' + l.columnNumber + ']';
+ }
+}
+
+function _toString(chars, start, length) {
+ if (typeof chars == 'string') {
+ return chars.substr(start, length);
+ } else {
+ //java sax connect width xmldom on rhino(what about: "? && !(chars instanceof String)")
+ if (chars.length >= start + length || start) {
+ return new java.lang.String(chars, start, length) + '';
+ }
+ return chars;
+ }
+}
+
+/*
+ * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/LexicalHandler.html
+ * used method of org.xml.sax.ext.LexicalHandler:
+ * #comment(chars, start, length)
+ * #startCDATA()
+ * #endCDATA()
+ * #startDTD(name, publicId, systemId)
+ *
+ *
+ * IGNORED method of org.xml.sax.ext.LexicalHandler:
+ * #endDTD()
+ * #startEntity(name)
+ * #endEntity(name)
+ *
+ *
+ * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/DeclHandler.html
+ * IGNORED method of org.xml.sax.ext.DeclHandler
+ * #attributeDecl(eName, aName, type, mode, value)
+ * #elementDecl(name, model)
+ * #externalEntityDecl(name, publicId, systemId)
+ * #internalEntityDecl(name, value)
+ * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/EntityResolver2.html
+ * IGNORED method of org.xml.sax.EntityResolver2
+ * #resolveEntity(String name,String publicId,String baseURI,String systemId)
+ * #resolveEntity(publicId, systemId)
+ * #getExternalSubset(name, baseURI)
+ * @link http://www.saxproject.org/apidoc/org/xml/sax/DTDHandler.html
+ * IGNORED method of org.xml.sax.DTDHandler
+ * #notationDecl(name, publicId, systemId) {};
+ * #unparsedEntityDecl(name, publicId, systemId, notationName) {};
+ */
+'endDTD,startEntity,endEntity,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,resolveEntity,getExternalSubset,notationDecl,unparsedEntityDecl'.replace(
+ /\w+/g,
+ function (key) {
+ DOMHandler.prototype[key] = function () {
+ return null;
+ };
+ }
+);
+
+/* Private static helpers treated below as private instance methods, so don't need to add these to the public API; we might use a Relator to also get rid of non-standard public properties */
+function appendElement(handler, node) {
+ if (!handler.currentElement) {
+ handler.doc.appendChild(node);
+ } else {
+ handler.currentElement.appendChild(node);
+ }
+}
+
+/**
+ * A method that prevents any further parsing when an `error`
+ * with level `error` is reported during parsing.
+ *
+ * @see {@link DOMParserOptions.onError}
+ * @see {@link onWarningStopParsing}
+ */
+function onErrorStopParsing(level) {
+ if (level === 'error') throw 'onErrorStopParsing';
+}
+
+/**
+ * A method that prevents any further parsing when any `error` is reported during parsing.
+ *
+ * @see {@link DOMParserOptions.onError}
+ * @see {@link onErrorStopParsing}
+ */
+function onWarningStopParsing() {
+ throw 'onWarningStopParsing';
+}
+
+exports.__DOMHandler = DOMHandler;
+exports.DOMParser = DOMParser;
+exports.normalizeLineEndings = normalizeLineEndings;
+exports.onErrorStopParsing = onErrorStopParsing;
+exports.onWarningStopParsing = onWarningStopParsing;
diff --git a/node_modules/@xmldom/xmldom/lib/dom.js b/node_modules/@xmldom/xmldom/lib/dom.js
new file mode 100644
index 000000000..5731bed13
--- /dev/null
+++ b/node_modules/@xmldom/xmldom/lib/dom.js
@@ -0,0 +1,3759 @@
+'use strict';
+
+var conventions = require('./conventions');
+var find = conventions.find;
+var hasDefaultHTMLNamespace = conventions.hasDefaultHTMLNamespace;
+var hasOwn = conventions.hasOwn;
+var isHTMLMimeType = conventions.isHTMLMimeType;
+var isHTMLRawTextElement = conventions.isHTMLRawTextElement;
+var isHTMLVoidElement = conventions.isHTMLVoidElement;
+var MIME_TYPE = conventions.MIME_TYPE;
+var NAMESPACE = conventions.NAMESPACE;
+
+/**
+ * Private DOM Constructor symbol
+ *
+ * Internal symbol used for construction of all classes whose constructors should be private.
+ * Currently used for checks in `Node`, `Document`, `Element`, `Attr`, `CharacterData`, `Text`, `Comment`,
+ * `CDATASection`, `DocumentType`, `Notation`, `Entity`, `EntityReference`, `DocumentFragment`, `ProcessingInstruction`
+ * so the constructor can't be used from outside the module.
+ */
+var PDC = Symbol();
+
+var errors = require('./errors');
+var DOMException = errors.DOMException;
+var DOMExceptionName = errors.DOMExceptionName;
+
+var g = require('./grammar');
+
+/**
+ * Checks if the given symbol equals the Private DOM Constructor symbol (PDC)
+ * and throws an Illegal constructor exception when the symbols don't match.
+ * This ensures that the constructor remains private and can't be used outside this module.
+ */
+function checkSymbol(symbol) {
+ if (symbol !== PDC) {
+ throw new TypeError('Illegal constructor');
+ }
+}
+
+/**
+ * A prerequisite for `[].filter`, to drop elements that are empty.
+ *
+ * @param {string} input
+ * The string to be checked.
+ * @returns {boolean}
+ * Returns `true` if the input string is not empty, `false` otherwise.
+ */
+function notEmptyString(input) {
+ return input !== '';
+}
+/**
+ * Splits a string on ASCII whitespace characters (U+0009 TAB, U+000A LF, U+000C FF, U+000D CR,
+ * U+0020 SPACE).
+ * It follows the definition from the infra specification from WHATWG.
+ *
+ * @param {string} input
+ * The string to be split.
+ * @returns {string[]}
+ * An array of the split strings. The array can be empty if the input string is empty or only
+ * contains whitespace characters.
+ * @see {@link https://infra.spec.whatwg.org/#split-on-ascii-whitespace}
+ * @see {@link https://infra.spec.whatwg.org/#ascii-whitespace}
+ */
+function splitOnASCIIWhitespace(input) {
+ // U+0009 TAB, U+000A LF, U+000C FF, U+000D CR, U+0020 SPACE
+ return input ? input.split(/[\t\n\f\r ]+/).filter(notEmptyString) : [];
+}
+
+/**
+ * Adds element as a key to current if it is not already present.
+ *
+ * @param {Record} current
+ * The current record object to which the element will be added as a key.
+ * The object's keys are string types and values are either boolean or undefined.
+ * @param {string} element
+ * The string to be added as a key to the current record.
+ * @returns {Record}
+ * The updated record object after the addition of the new element.
+ */
+function orderedSetReducer(current, element) {
+ if (!hasOwn(current, element)) {
+ current[element] = true;
+ }
+ return current;
+}
+
+/**
+ * Converts a string into an ordered set by splitting the input on ASCII whitespace and
+ * ensuring uniqueness of elements.
+ * This follows the definition of an ordered set from the infra specification by WHATWG.
+ *
+ * @param {string} input
+ * The input string to be transformed into an ordered set.
+ * @returns {string[]}
+ * An array of unique strings obtained from the input, preserving the original order.
+ * The array can be empty if the input string is empty or only contains whitespace characters.
+ * @see {@link https://infra.spec.whatwg.org/#ordered-set}
+ */
+function toOrderedSet(input) {
+ if (!input) return [];
+ var list = splitOnASCIIWhitespace(input);
+ return Object.keys(list.reduce(orderedSetReducer, {}));
+}
+
+/**
+ * Uses `list.indexOf` to implement a function that behaves like `Array.prototype.includes`.
+ * This function is used in environments where `Array.prototype.includes` may not be available.
+ *
+ * @param {any[]} list
+ * The array in which to search for the element.
+ * @returns {function(any): boolean}
+ * A function that accepts an element and returns a boolean indicating whether the element is
+ * included in the provided list.
+ */
+function arrayIncludes(list) {
+ return function (element) {
+ return list && list.indexOf(element) !== -1;
+ };
+}
+
+/**
+ * Validates a qualified name based on the criteria provided in the DOM specification by
+ * WHATWG.
+ *
+ * @param {string} qualifiedName
+ * The qualified name to be validated.
+ * @throws {DOMException}
+ * With code {@link DOMException.INVALID_CHARACTER_ERR} if the qualified name contains an
+ * invalid character.
+ * @see {@link https://dom.spec.whatwg.org/#validate}
+ */
+function validateQualifiedName(qualifiedName) {
+ if (!g.QName_exact.test(qualifiedName)) {
+ throw new DOMException(DOMException.INVALID_CHARACTER_ERR, 'invalid character in qualified name "' + qualifiedName + '"');
+ }
+}
+
+/**
+ * Validates a qualified name and the namespace associated with it,
+ * based on the criteria provided in the DOM specification by WHATWG.
+ *
+ * @param {string | null} namespace
+ * The namespace to be validated. It can be a string or null.
+ * @param {string} qualifiedName
+ * The qualified name to be validated.
+ * @returns {[namespace: string | null, prefix: string | null, localName: string]}
+ * Returns a tuple with the namespace,
+ * prefix and local name of the qualified name.
+ * @throws {DOMException}
+ * Throws a DOMException if the qualified name or the namespace is not valid.
+ * @see {@link https://dom.spec.whatwg.org/#validate-and-extract}
+ */
+function validateAndExtract(namespace, qualifiedName) {
+ validateQualifiedName(qualifiedName);
+ namespace = namespace || null;
+ /**
+ * @type {string | null}
+ */
+ var prefix = null;
+ var localName = qualifiedName;
+ if (qualifiedName.indexOf(':') >= 0) {
+ var splitResult = qualifiedName.split(':');
+ prefix = splitResult[0];
+ localName = splitResult[1];
+ }
+ if (prefix !== null && namespace === null) {
+ throw new DOMException(DOMException.NAMESPACE_ERR, 'prefix is non-null and namespace is null');
+ }
+ if (prefix === 'xml' && namespace !== conventions.NAMESPACE.XML) {
+ throw new DOMException(DOMException.NAMESPACE_ERR, 'prefix is "xml" and namespace is not the XML namespace');
+ }
+ if ((prefix === 'xmlns' || qualifiedName === 'xmlns') && namespace !== conventions.NAMESPACE.XMLNS) {
+ throw new DOMException(
+ DOMException.NAMESPACE_ERR,
+ 'either qualifiedName or prefix is "xmlns" and namespace is not the XMLNS namespace'
+ );
+ }
+ if (namespace === conventions.NAMESPACE.XMLNS && prefix !== 'xmlns' && qualifiedName !== 'xmlns') {
+ throw new DOMException(
+ DOMException.NAMESPACE_ERR,
+ 'namespace is the XMLNS namespace and neither qualifiedName nor prefix is "xmlns"'
+ );
+ }
+ return [namespace, prefix, localName];
+}
+
+/**
+ * Copies properties from one object to another.
+ * It only copies the object's own (not inherited) properties.
+ *
+ * @param {Object} src
+ * The source object from which properties are copied.
+ * @param {Object} dest
+ * The destination object to which properties are copied.
+ */
+function copy(src, dest) {
+ for (var p in src) {
+ if (hasOwn(src, p)) {
+ dest[p] = src[p];
+ }
+ }
+}
+
+/**
+ * Extends a class with the properties and methods of a super class.
+ * It uses a form of prototypal inheritance, and establishes the `constructor` property
+ * correctly(?).
+ *
+ * It is not clear to the current maintainers if this implementation is making sense,
+ * since it creates an intermediate prototype function,
+ * which all properties of `Super` are copied onto using `_copy`.
+ *
+ * @param {Object} Class
+ * The class that is to be extended.
+ * @param {Object} Super
+ * The super class from which properties and methods are inherited.
+ * @private
+ */
+function _extends(Class, Super) {
+ var pt = Class.prototype;
+ if (!(pt instanceof Super)) {
+ function t() {}
+ t.prototype = Super.prototype;
+ t = new t();
+ copy(pt, t);
+ Class.prototype = pt = t;
+ }
+ if (pt.constructor != Class) {
+ if (typeof Class != 'function') {
+ console.error('unknown Class:' + Class);
+ }
+ pt.constructor = Class;
+ }
+}
+
+var NodeType = {};
+var ELEMENT_NODE = (NodeType.ELEMENT_NODE = 1);
+var ATTRIBUTE_NODE = (NodeType.ATTRIBUTE_NODE = 2);
+var TEXT_NODE = (NodeType.TEXT_NODE = 3);
+var CDATA_SECTION_NODE = (NodeType.CDATA_SECTION_NODE = 4);
+var ENTITY_REFERENCE_NODE = (NodeType.ENTITY_REFERENCE_NODE = 5);
+var ENTITY_NODE = (NodeType.ENTITY_NODE = 6);
+var PROCESSING_INSTRUCTION_NODE = (NodeType.PROCESSING_INSTRUCTION_NODE = 7);
+var COMMENT_NODE = (NodeType.COMMENT_NODE = 8);
+var DOCUMENT_NODE = (NodeType.DOCUMENT_NODE = 9);
+var DOCUMENT_TYPE_NODE = (NodeType.DOCUMENT_TYPE_NODE = 10);
+var DOCUMENT_FRAGMENT_NODE = (NodeType.DOCUMENT_FRAGMENT_NODE = 11);
+var NOTATION_NODE = (NodeType.NOTATION_NODE = 12);
+
+var DocumentPosition = conventions.freeze({
+ DOCUMENT_POSITION_DISCONNECTED: 1,
+ DOCUMENT_POSITION_PRECEDING: 2,
+ DOCUMENT_POSITION_FOLLOWING: 4,
+ DOCUMENT_POSITION_CONTAINS: 8,
+ DOCUMENT_POSITION_CONTAINED_BY: 16,
+ DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: 32,
+});
+
+//helper functions for compareDocumentPosition
+/**
+ * Finds the common ancestor in two parent chains.
+ *
+ * @param {Node[]} a
+ * The first parent chain.
+ * @param {Node[]} b
+ * The second parent chain.
+ * @returns {Node}
+ * The common ancestor node if it exists. If there is no common ancestor, the function will
+ * return `null`.
+ */
+function commonAncestor(a, b) {
+ if (b.length < a.length) return commonAncestor(b, a);
+ var c = null;
+ for (var n in a) {
+ if (a[n] !== b[n]) return c;
+ c = a[n];
+ }
+ return c;
+}
+
+/**
+ * Assigns a unique identifier to a document to ensure consistency while comparing unrelated
+ * nodes.
+ *
+ * @param {Document} doc
+ * The document to which a unique identifier is to be assigned.
+ * @returns {string}
+ * The unique identifier of the document. If the document already had a unique identifier, the
+ * function will return the existing one.
+ */
+function docGUID(doc) {
+ if (!doc.guid) doc.guid = Math.random();
+ return doc.guid;
+}
+//-- end of helper functions
+
+/**
+ * The NodeList interface provides the abstraction of an ordered collection of nodes,
+ * without defining or constraining how this collection is implemented.
+ * NodeList objects in the DOM are live.
+ * The items in the NodeList are accessible via an integral index, starting from 0.
+ * You can also access the items of the NodeList with a `for...of` loop.
+ *
+ * @class NodeList
+ * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-536297177
+ * @constructs NodeList
+ */
+function NodeList() {}
+NodeList.prototype = {
+ /**
+ * The number of nodes in the list. The range of valid child node indices is 0 to length-1
+ * inclusive.
+ *
+ * @type {number}
+ */
+ length: 0,
+ /**
+ * Returns the item at `index`. If index is greater than or equal to the number of nodes in
+ * the list, this returns null.
+ *
+ * @param index
+ * Unsigned long Index into the collection.
+ * @returns {Node | null}
+ * The node at position `index` in the NodeList,
+ * or null if that is not a valid index.
+ */
+ item: function (index) {
+ return index >= 0 && index < this.length ? this[index] : null;
+ },
+ /**
+ * Returns a string representation of the NodeList.
+ *
+ * Accepts the same `options` object as `XMLSerializer.prototype.serializeToString`
+ * (`requireWellFormed`, `splitCDATASections`, `nodeFilter`). Passing a function is treated as
+ * a legacy `nodeFilter` for backward compatibility.
+ *
+ * @param {Object | function} [options]
+ * @param {boolean} [options.requireWellFormed=false]
+ * @param {boolean} [options.splitCDATASections=true]
+ * @param {function} [options.nodeFilter]
+ * @returns {string}
+ */
+ toString: function (options) {
+ var opts;
+ if (typeof options === 'function') {
+ opts = { requireWellFormed: false, splitCDATASections: true, nodeFilter: options };
+ } else if (!!options) {
+ opts = {
+ requireWellFormed: !!options.requireWellFormed,
+ splitCDATASections: options.splitCDATASections !== false,
+ nodeFilter: options.nodeFilter || null,
+ };
+ } else {
+ opts = { requireWellFormed: false, splitCDATASections: true, nodeFilter: null };
+ }
+ for (var buf = [], i = 0; i < this.length; i++) {
+ serializeToString(this[i], buf, null, opts);
+ }
+ return buf.join('');
+ },
+ /**
+ * Filters the NodeList based on a predicate.
+ *
+ * @param {function(Node): boolean} predicate
+ * - A predicate function to filter the NodeList.
+ * @returns {Node[]}
+ * An array of nodes that satisfy the predicate.
+ * @private
+ */
+ filter: function (predicate) {
+ return Array.prototype.filter.call(this, predicate);
+ },
+ /**
+ * Returns the first index at which a given node can be found in the NodeList, or -1 if it is
+ * not present.
+ *
+ * @param {Node} item
+ * - The Node item to locate in the NodeList.
+ * @returns {number}
+ * The first index of the node in the NodeList; -1 if not found.
+ * @private
+ */
+ indexOf: function (item) {
+ return Array.prototype.indexOf.call(this, item);
+ },
+};
+NodeList.prototype[Symbol.iterator] = function () {
+ var me = this;
+ var index = 0;
+
+ return {
+ next: function () {
+ if (index < me.length) {
+ return {
+ value: me[index++],
+ done: false,
+ };
+ } else {
+ return {
+ done: true,
+ };
+ }
+ },
+ return: function () {
+ return {
+ done: true,
+ };
+ },
+ };
+};
+
+/**
+ * Represents a live collection of nodes that is automatically updated when its associated
+ * document changes.
+ *
+ * @class LiveNodeList
+ * @param {Node} node
+ * The associated node.
+ * @param {function} refresh
+ * The function to refresh the live node list.
+ * @augments NodeList
+ * @constructs LiveNodeList
+ */
+function LiveNodeList(node, refresh) {
+ this._node = node;
+ this._refresh = refresh;
+ _updateLiveList(this);
+}
+/**
+ * Updates the live node list.
+ *
+ * @param {LiveNodeList} list
+ * The live node list to update.
+ * @private
+ */
+function _updateLiveList(list) {
+ var inc = list._node._inc || list._node.ownerDocument._inc;
+ if (list._inc !== inc) {
+ var ls = list._refresh(list._node);
+ __set__(list, 'length', ls.length);
+ if (!list.$$length || ls.length < list.$$length) {
+ for (var i = ls.length; i in list; i++) {
+ if (hasOwn(list, i)) {
+ delete list[i];
+ }
+ }
+ }
+ copy(ls, list);
+ list._inc = inc;
+ }
+}
+/**
+ * Returns the node at position `index` in the LiveNodeList, or null if that is not a valid
+ * index.
+ *
+ * @param {number} i
+ * Index into the collection.
+ * @returns {Node | null}
+ * The node at position `index` in the LiveNodeList, or null if that is not a valid index.
+ */
+LiveNodeList.prototype.item = function (i) {
+ _updateLiveList(this);
+ return this[i] || null;
+};
+
+_extends(LiveNodeList, NodeList);
+
+/**
+ * Objects implementing the NamedNodeMap interface are used to represent collections of nodes
+ * that can be accessed by name.
+ * Note that NamedNodeMap does not inherit from NodeList;
+ * NamedNodeMaps are not maintained in any particular order.
+ * Objects contained in an object implementing NamedNodeMap may also be accessed by an ordinal
+ * index,
+ * but this is simply to allow convenient enumeration of the contents of a NamedNodeMap,
+ * and does not imply that the DOM specifies an order to these Nodes.
+ * NamedNodeMap objects in the DOM are live.
+ * used for attributes or DocumentType entities
+ *
+ * This implementation only supports property indices, but does not support named properties,
+ * as specified in the living standard.
+ *
+ * @class NamedNodeMap
+ * @see https://dom.spec.whatwg.org/#interface-namednodemap
+ * @see https://webidl.spec.whatwg.org/#dfn-supported-property-names
+ * @constructs NamedNodeMap
+ */
+/**
+ * A live collection of an element's attributes, keyed by name.
+ *
+ * The numbered entries and `length` are the sole authority for attribute order.
+ * A separate two-level null-prototype membership index (`namespaceURI` ->
+ * `localName` -> `Attr`, with the null/empty namespace held in its own bucket)
+ * lets the parse-time de-duplication in `setNamedItem` resolve an existing
+ * attribute in O(1) instead of scanning the list, so building an element with M
+ * attributes costs O(M) rather than O(M^2). The index never reorders attributes.
+ */
+function NamedNodeMap() {
+ // namespaceURI (non-empty string) -> (localName -> Attr)
+ this._nsIndex = Object.create(null);
+ // localName -> Attr, for the null / empty-string namespace
+ this._noNsIndex = Object.create(null);
+}
+/**
+ * Returns the index of a node within the list.
+ *
+ * @param {Array} list
+ * The list of nodes.
+ * @param {Node} node
+ * The node to find.
+ * @returns {number}
+ * The index of the node within the list, or -1 if not found.
+ * @private
+ */
+function _findNodeIndex(list, node) {
+ var i = 0;
+ while (i < list.length) {
+ if (list[i] === node) {
+ return i;
+ }
+ i++;
+ }
+}
+/**
+ * Returns the second-level index bucket (`localName` -> `Attr`) for a namespace,
+ * replicating `getNamedItemNS`'s falsy-namespace normalization: `null`,
+ * `undefined` and `''` all resolve to the dedicated null-namespace bucket, kept separate from
+ * any real URI (so a namespace URI equal to the string `"null"`
+ * cannot collide with the null namespace). Both levels are null-prototype objects, so an
+ * attribute named `__proto__` or `constructor` is an ordinary key.
+ *
+ * @param {NamedNodeMap} map
+ * @param {string | null | undefined} namespaceURI
+ * @param {boolean} create
+ * Create the bucket if it does not exist yet.
+ * @returns {Object | undefined}
+ * @private
+ */
+function _nnmBucket(map, namespaceURI, create) {
+ if (!namespaceURI) {
+ return map._noNsIndex;
+ }
+ var bucket = map._nsIndex[namespaceURI];
+ if (!bucket && create) {
+ bucket = map._nsIndex[namespaceURI] = Object.create(null);
+ }
+ return bucket;
+}
+/**
+ * Looks up an attribute by namespace and local name through the membership index.
+ *
+ * @param {NamedNodeMap} map
+ * @param {string | null | undefined} namespaceURI
+ * @param {string} localName
+ * @returns {Attr | null}
+ * The matching attribute, or `null` when absent.
+ * @private
+ */
+function _nnmIndexFind(map, namespaceURI, localName) {
+ var bucket = _nnmBucket(map, namespaceURI, false);
+ var found = bucket && bucket[localName];
+ return found ? found : null;
+}
+/**
+ * Records `attr` in the membership index under its namespace and local name,
+ * replacing any previous attribute with the same key.
+ *
+ * @param {NamedNodeMap} map
+ * @param {Attr} attr
+ * @private
+ */
+function _nnmIndexAdd(map, attr) {
+ _nnmBucket(map, attr.namespaceURI, true)[attr.localName] = attr;
+}
+/**
+ * Removes `attr` from the membership index.
+ *
+ * @param {NamedNodeMap} map
+ * @param {Attr} attr
+ * @private
+ */
+function _nnmIndexRemove(map, attr) {
+ var bucket = _nnmBucket(map, attr.namespaceURI, false);
+ if (bucket) {
+ delete bucket[attr.localName];
+ }
+}
+/**
+ * Adds a new attribute to the list and updates the owner element of the attribute.
+ *
+ * @param {Element} el
+ * The element which will become the owner of the new attribute.
+ * @param {NamedNodeMap} list
+ * The list to which the new attribute will be added.
+ * @param {Attr} newAttr
+ * The new attribute to be added.
+ * @param {Attr} oldAttr
+ * The old attribute to be replaced, or null if no attribute is to be replaced.
+ * @returns {void}
+ * @private
+ */
+function _addNamedNode(el, list, newAttr, oldAttr) {
+ if (oldAttr) {
+ list[_findNodeIndex(list, oldAttr)] = newAttr;
+ } else {
+ list[list.length] = newAttr;
+ list.length++;
+ }
+ // Keep the membership index in sync with the ordered list. On replacement
+ // `oldAttr` shares `newAttr`'s (namespace, localName) key, so this overwrites
+ // its entry; on append it adds a new one.
+ _nnmIndexAdd(list, newAttr);
+ if (el) {
+ newAttr.ownerElement = el;
+ var doc = el.ownerDocument;
+ if (doc) {
+ oldAttr && _onRemoveAttribute(doc, el, oldAttr);
+ _onAddAttribute(doc, el, newAttr);
+ }
+ }
+}
+/**
+ * Removes an attribute from the list and updates the owner element of the attribute.
+ *
+ * @param {Element} el
+ * The element which is the current owner of the attribute.
+ * @param {NamedNodeMap} list
+ * The list from which the attribute will be removed.
+ * @param {Attr} attr
+ * The attribute to be removed.
+ * @returns {void}
+ * @private
+ */
+function _removeNamedNode(el, list, attr) {
+ //console.log('remove attr:'+attr)
+ var i = _findNodeIndex(list, attr);
+ if (i >= 0) {
+ var lastIndex = list.length - 1;
+ while (i <= lastIndex) {
+ list[i] = list[++i];
+ }
+ list.length = lastIndex;
+ _nnmIndexRemove(list, attr);
+ if (el) {
+ var doc = el.ownerDocument;
+ if (doc) {
+ _onRemoveAttribute(doc, el, attr);
+ }
+ attr.ownerElement = null;
+ }
+ }
+}
+NamedNodeMap.prototype = {
+ length: 0,
+ item: NodeList.prototype.item,
+
+ /**
+ * Get an attribute by name. Note: Name is in lower case in case of HTML namespace and
+ * document.
+ *
+ * @param {string} localName
+ * The local name of the attribute.
+ * @returns {Attr | null}
+ * The attribute with the given local name, or null if no such attribute exists.
+ * @see https://dom.spec.whatwg.org/#concept-element-attributes-get-by-name
+ */
+ getNamedItem: function (localName) {
+ if (this._ownerElement && this._ownerElement._isInHTMLDocumentAndNamespace()) {
+ localName = localName.toLowerCase();
+ }
+ var i = 0;
+ while (i < this.length) {
+ var attr = this[i];
+ if (attr.nodeName === localName) {
+ return attr;
+ }
+ i++;
+ }
+ return null;
+ },
+
+ /**
+ * Set an attribute.
+ *
+ * @param {Attr} attr
+ * The attribute to set.
+ * @returns {Attr | null}
+ * The old attribute with the same local name and namespace URI as the new one, or null if no
+ * such attribute exists.
+ * @throws {DOMException}
+ * With code:
+ * - {@link INUSE_ATTRIBUTE_ERR} - If the attribute is already an attribute of another
+ * element.
+ * @see https://dom.spec.whatwg.org/#concept-element-attributes-set
+ */
+ setNamedItem: function (attr) {
+ var el = attr.ownerElement;
+ if (el && el !== this._ownerElement) {
+ throw new DOMException(DOMException.INUSE_ATTRIBUTE_ERR);
+ }
+ // Resolve any existing attribute with the same (namespace, localName)
+ // through the O(1) membership index rather than an O(M) scan — this is the
+ // parse-dedup hot path (`setAttributeNode` per attribute during parse).
+ var oldAttr = _nnmIndexFind(this, attr.namespaceURI, attr.localName);
+ if (oldAttr === attr) {
+ return attr;
+ }
+ _addNamedNode(this._ownerElement, this, attr, oldAttr);
+ return oldAttr;
+ },
+
+ /**
+ * Set an attribute, replacing an existing attribute with the same local name and namespace
+ * URI if one exists.
+ *
+ * @param {Attr} attr
+ * The attribute to set.
+ * @returns {Attr | null}
+ * The old attribute with the same local name and namespace URI as the new one, or null if no
+ * such attribute exists.
+ * @throws {DOMException}
+ * Throws a DOMException with the name "InUseAttributeError" if the attribute is already an
+ * attribute of another element.
+ * @see https://dom.spec.whatwg.org/#concept-element-attributes-set
+ */
+ setNamedItemNS: function (attr) {
+ return this.setNamedItem(attr);
+ },
+
+ /**
+ * Removes an attribute specified by the local name.
+ *
+ * @param {string} localName
+ * The local name of the attribute to be removed.
+ * @returns {Attr}
+ * The attribute node that was removed.
+ * @throws {DOMException}
+ * With code:
+ * - {@link DOMException.NOT_FOUND_ERR} if no attribute with the given name is found.
+ * @see https://dom.spec.whatwg.org/#dom-namednodemap-removenameditem
+ * @see https://dom.spec.whatwg.org/#concept-element-attributes-remove-by-name
+ */
+ removeNamedItem: function (localName) {
+ var attr = this.getNamedItem(localName);
+ if (!attr) {
+ throw new DOMException(DOMException.NOT_FOUND_ERR, localName);
+ }
+ _removeNamedNode(this._ownerElement, this, attr);
+ return attr;
+ },
+
+ /**
+ * Removes an attribute specified by the namespace and local name.
+ *
+ * @param {string | null} namespaceURI
+ * The namespace URI of the attribute to be removed.
+ * @param {string} localName
+ * The local name of the attribute to be removed.
+ * @returns {Attr}
+ * The attribute node that was removed.
+ * @throws {DOMException}
+ * With code:
+ * - {@link DOMException.NOT_FOUND_ERR} if no attribute with the given namespace URI and local
+ * name is found.
+ * @see https://dom.spec.whatwg.org/#dom-namednodemap-removenameditemns
+ * @see https://dom.spec.whatwg.org/#concept-element-attributes-remove-by-namespace
+ */
+ removeNamedItemNS: function (namespaceURI, localName) {
+ var attr = this.getNamedItemNS(namespaceURI, localName);
+ if (!attr) {
+ throw new DOMException(DOMException.NOT_FOUND_ERR, namespaceURI ? namespaceURI + ' : ' + localName : localName);
+ }
+ _removeNamedNode(this._ownerElement, this, attr);
+ return attr;
+ },
+
+ /**
+ * Get an attribute by namespace and local name.
+ *
+ * @param {string | null} namespaceURI
+ * The namespace URI of the attribute.
+ * @param {string} localName
+ * The local name of the attribute.
+ * @returns {Attr | null}
+ * The attribute with the given namespace URI and local name, or null if no such attribute
+ * exists.
+ * @see https://dom.spec.whatwg.org/#concept-element-attributes-get-by-namespace
+ */
+ getNamedItemNS: function (namespaceURI, localName) {
+ if (!namespaceURI) {
+ namespaceURI = null;
+ }
+ var i = 0;
+ while (i < this.length) {
+ var node = this[i];
+ if (node.localName === localName && node.namespaceURI === namespaceURI) {
+ return node;
+ }
+ i++;
+ }
+ return null;
+ },
+};
+NamedNodeMap.prototype[Symbol.iterator] = function () {
+ var me = this;
+ var index = 0;
+
+ return {
+ next: function () {
+ if (index < me.length) {
+ return {
+ value: me[index++],
+ done: false,
+ };
+ } else {
+ return {
+ done: true,
+ };
+ }
+ },
+ return: function () {
+ return {
+ done: true,
+ };
+ },
+ };
+};
+
+/**
+ * The DOMImplementation interface provides a number of methods for performing operations that
+ * are independent of any particular instance of the document object model.
+ *
+ * The DOMImplementation interface represents an object providing methods which are not
+ * dependent on any particular document.
+ * Such an object is returned by the `Document.implementation` property.
+ *
+ * **The individual methods describe the differences compared to the specs**.
+ *
+ * @class DOMImplementation
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation MDN
+ * @see https://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-102161490 DOM Level 1 Core
+ * (Initial)
+ * @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-102161490 DOM Level 2 Core
+ * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-102161490 DOM Level 3 Core
+ * @see https://dom.spec.whatwg.org/#domimplementation DOM Living Standard
+ * @constructs DOMImplementation
+ */
+function DOMImplementation() {}
+
+DOMImplementation.prototype = {
+ /**
+ * Test if the DOM implementation implements a specific feature and version, as specified in
+ * {@link https://www.w3.org/TR/DOM-Level-3-Core/core.html#DOMFeatures DOM Features}.
+ *
+ * The DOMImplementation.hasFeature() method returns a Boolean flag indicating if a given
+ * feature is supported. The different implementations fairly diverged in what kind of
+ * features were reported. The latest version of the spec settled to force this method to
+ * always return true, where the functionality was accurate and in use.
+ *
+ * @deprecated
+ * It is deprecated and modern browsers return true in all cases.
+ * @function DOMImplementation#hasFeature
+ * @param {string} feature
+ * The name of the feature to test.
+ * @param {string} [version]
+ * This is the version number of the feature to test.
+ * @returns {boolean}
+ * Always returns true.
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/hasFeature MDN
+ * @see https://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-5CED94D7 DOM Level 1 Core
+ * @see https://dom.spec.whatwg.org/#dom-domimplementation-hasfeature DOM Living Standard
+ * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-5CED94D7 DOM Level 3 Core
+ */
+ hasFeature: function (feature, version) {
+ return true;
+ },
+ /**
+ * Creates a DOM Document object of the specified type with its document element. Note that
+ * based on the {@link DocumentType}
+ * given to create the document, the implementation may instantiate specialized
+ * {@link Document} objects that support additional features than the "Core", such as "HTML"
+ * {@link https://www.w3.org/TR/DOM-Level-3-Core/references.html#DOM2HTML DOM Level 2 HTML}.
+ * On the other hand, setting the {@link DocumentType} after the document was created makes
+ * this very unlikely to happen. Alternatively, specialized {@link Document} creation methods,
+ * such as createHTMLDocument
+ * {@link https://www.w3.org/TR/DOM-Level-3-Core/references.html#DOM2HTML DOM Level 2 HTML},
+ * can be used to obtain specific types of {@link Document} objects.
+ *
+ * __It behaves slightly different from the description in the living standard__:
+ * - There is no interface/class `XMLDocument`, it returns a `Document`
+ * instance (with it's `type` set to `'xml'`).
+ * - `encoding`, `mode`, `origin`, `url` fields are currently not declared.
+ *
+ * @function DOMImplementation.createDocument
+ * @param {string | null} namespaceURI
+ * The
+ * {@link https://www.w3.org/TR/DOM-Level-3-Core/glossary.html#dt-namespaceURI namespace URI}
+ * of the document element to create or null.
+ * @param {string | null} qualifiedName
+ * The
+ * {@link https://www.w3.org/TR/DOM-Level-3-Core/glossary.html#dt-qualifiedname qualified name}
+ * of the document element to be created or null.
+ * @param {DocumentType | null} [doctype=null]
+ * The type of document to be created or null. When doctype is not null, its
+ * {@link Node#ownerDocument} attribute is set to the document being created. Default is
+ * `null`
+ * @returns {Document}
+ * A new {@link Document} object with its document element. If the NamespaceURI,
+ * qualifiedName, and doctype are null, the returned {@link Document} is empty with no
+ * document element.
+ * @throws {DOMException}
+ * With code:
+ *
+ * - `INVALID_CHARACTER_ERR`: Raised if the specified qualified name is not an XML name
+ * according to {@link https://www.w3.org/TR/DOM-Level-3-Core/references.html#XML XML 1.0}.
+ * - `NAMESPACE_ERR`: Raised if the qualifiedName is malformed, if the qualifiedName has a
+ * prefix and the namespaceURI is null, or if the qualifiedName is null and the namespaceURI
+ * is different from null, or if the qualifiedName has a prefix that is "xml" and the
+ * namespaceURI is different from "{@link http://www.w3.org/XML/1998/namespace}"
+ * {@link https://www.w3.org/TR/DOM-Level-3-Core/references.html#Namespaces XML Namespaces},
+ * or if the DOM implementation does not support the "XML" feature but a non-null namespace
+ * URI was provided, since namespaces were defined by XML.
+ * - `WRONG_DOCUMENT_ERR`: Raised if doctype has already been used with a different document
+ * or was created from a different implementation.
+ * - `NOT_SUPPORTED_ERR`: May be raised if the implementation does not support the feature
+ * "XML" and the language exposed through the Document does not support XML Namespaces (such
+ * as {@link https://www.w3.org/TR/DOM-Level-3-Core/references.html#HTML40 HTML 4.01}).
+ * @since DOM Level 2.
+ * @see {@link #createHTMLDocument}
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/createDocument MDN
+ * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocument DOM Living Standard
+ * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#Level-2-Core-DOM-createDocument DOM
+ * Level 3 Core
+ * @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#Level-2-Core-DOM-createDocument DOM
+ * Level 2 Core (initial)
+ */
+ createDocument: function (namespaceURI, qualifiedName, doctype) {
+ var contentType = MIME_TYPE.XML_APPLICATION;
+ if (namespaceURI === NAMESPACE.HTML) {
+ contentType = MIME_TYPE.XML_XHTML_APPLICATION;
+ } else if (namespaceURI === NAMESPACE.SVG) {
+ contentType = MIME_TYPE.XML_SVG_IMAGE;
+ }
+ var doc = new Document(PDC, { contentType: contentType });
+ doc.implementation = this;
+ doc.childNodes = new NodeList();
+ doc.doctype = doctype || null;
+ if (doctype) {
+ doc.appendChild(doctype);
+ }
+ if (qualifiedName) {
+ var root = doc.createElementNS(namespaceURI, qualifiedName);
+ doc.appendChild(root);
+ }
+ return doc;
+ },
+ /**
+ * Creates an empty DocumentType node. Entity declarations and notations are not made
+ * available. Entity reference expansions and default attribute additions do not occur.
+ *
+ * **This behavior is slightly different from the one in the specs**:
+ * - `encoding`, `mode`, `origin`, `url` fields are currently not declared.
+ * - `publicId` and `systemId` contain the raw data including any possible quotes,
+ * so they can always be serialized back to the original value
+ * - `internalSubset` contains the raw string between `[` and `]` if present,
+ * but is not parsed or validated in any form.
+ *
+ * @function DOMImplementation#createDocumentType
+ * @param {string} qualifiedName
+ * The {@link https://www.w3.org/TR/DOM-Level-3-Core/glossary.html#dt-qualifiedname qualified
+ * name} of the document type to be created.
+ * @param {string} [publicId]
+ * The external subset public identifier. Stored verbatim including surrounding quotes.
+ * When serialized with `requireWellFormed: true`, the serializer throws `InvalidStateError`
+ * if the value is non-empty and does not match the XML `PubidLiteral` production
+ * (W3C DOM Parsing §3.2.1.3; XML 1.0 production [12]). Creation-time validation is not
+ * enforced — deferred to a future breaking release.
+ * @param {string} [systemId]
+ * The external subset system identifier. Stored verbatim including surrounding quotes.
+ * When serialized with `requireWellFormed: true`, the serializer throws `InvalidStateError`
+ * if the value is non-empty and does not match the XML `SystemLiteral` production
+ * (W3C DOM Parsing §3.2.1.3; XML 1.0 production [11]). Creation-time validation is not
+ * enforced — deferred to a future breaking release.
+ * @param {string} [internalSubset]
+ * The internal subset or an empty string if it is not present. Stored verbatim.
+ * When serialized with `requireWellFormed: true`, the serializer throws `InvalidStateError`
+ * if the value contains `"]>"`. Creation-time validation is not enforced.
+ * @returns {DocumentType}
+ * A new {@link DocumentType} node with {@link Node#ownerDocument} set to null.
+ * @throws {DOMException}
+ * With code:
+ *
+ * - `INVALID_CHARACTER_ERR`: Raised if the specified qualified name is not an XML name
+ * according to {@link https://www.w3.org/TR/DOM-Level-3-Core/references.html#XML XML 1.0}.
+ * - `NAMESPACE_ERR`: Raised if the qualifiedName is malformed.
+ * - `NOT_SUPPORTED_ERR`: May be raised if the implementation does not support the feature
+ * "XML" and the language exposed through the Document does not support XML Namespaces (such
+ * as {@link https://www.w3.org/TR/DOM-Level-3-Core/references.html#HTML40 HTML 4.01}).
+ * @since DOM Level 2.
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/createDocumentType
+ * MDN
+ * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype DOM Living
+ * Standard
+ * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#Level-3-Core-DOM-createDocType DOM
+ * Level 3 Core
+ * @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#Level-2-Core-DOM-createDocType DOM
+ * Level 2 Core
+ * @see https://github.com/xmldom/xmldom/blob/master/CHANGELOG.md#050
+ * @see https://www.w3.org/TR/DOM-Level-2-Core/#core-ID-Core-DocType-internalSubset
+ * @prettierignore
+ */
+ createDocumentType: function (qualifiedName, publicId, systemId, internalSubset) {
+ validateQualifiedName(qualifiedName);
+ var node = new DocumentType(PDC);
+ node.name = qualifiedName;
+ node.nodeName = qualifiedName;
+ node.publicId = publicId || '';
+ node.systemId = systemId || '';
+ node.internalSubset = internalSubset || '';
+ node.childNodes = new NodeList();
+
+ return node;
+ },
+ /**
+ * Returns an HTML document, that might already have a basic DOM structure.
+ *
+ * __It behaves slightly different from the description in the living standard__:
+ * - If the first argument is `false` no initial nodes are added (steps 3-7 in the specs are
+ * omitted)
+ * - `encoding`, `mode`, `origin`, `url` fields are currently not declared.
+ *
+ * @param {string | false} [title]
+ * A string containing the title to give the new HTML document.
+ * @returns {Document}
+ * The HTML document.
+ * @since WHATWG Living Standard.
+ * @see {@link #createDocument}
+ * @see https://dom.spec.whatwg.org/#dom-domimplementation-createhtmldocument
+ * @see https://dom.spec.whatwg.org/#html-document
+ */
+ createHTMLDocument: function (title) {
+ var doc = new Document(PDC, { contentType: MIME_TYPE.HTML });
+ doc.implementation = this;
+ doc.childNodes = new NodeList();
+ if (title !== false) {
+ doc.doctype = this.createDocumentType('html');
+ doc.doctype.ownerDocument = doc;
+ doc.appendChild(doc.doctype);
+ var htmlNode = doc.createElement('html');
+ doc.appendChild(htmlNode);
+ var headNode = doc.createElement('head');
+ htmlNode.appendChild(headNode);
+ if (typeof title === 'string') {
+ var titleNode = doc.createElement('title');
+ titleNode.appendChild(doc.createTextNode(title));
+ headNode.appendChild(titleNode);
+ }
+ htmlNode.appendChild(doc.createElement('body'));
+ }
+ return doc;
+ },
+};
+
+/**
+ * The DOM Node interface is an abstract base class upon which many other DOM API objects are
+ * based, thus letting those object types to be used similarly and often interchangeably. As an
+ * abstract class, there is no such thing as a plain Node object. All objects that implement
+ * Node functionality are based on one of its subclasses. Most notable are Document, Element,
+ * and DocumentFragment.
+ *
+ * In addition, every kind of DOM node is represented by an interface based on Node. These
+ * include Attr, CharacterData (which Text, Comment, CDATASection and ProcessingInstruction are
+ * all based on), and DocumentType.
+ *
+ * In some cases, a particular feature of the base Node interface may not apply to one of its
+ * child interfaces; in that case, the inheriting node may return null or throw an exception,
+ * depending on circumstances. For example, attempting to add children to a node type that
+ * cannot have children will throw an exception.
+ *
+ * **This behavior is slightly different from the in the specs**:
+ * - unimplemented interfaces: `EventTarget`
+ *
+ * @class
+ * @abstract
+ * @param {Symbol} symbol
+ * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247
+ * @see https://dom.spec.whatwg.org/#node
+ * @prettierignore
+ */
+function Node(symbol) {
+ checkSymbol(symbol);
+}
+
+Node.prototype = {
+ /**
+ * The first child of this node.
+ *
+ * @type {Node | null}
+ */
+ firstChild: null,
+ /**
+ * The last child of this node.
+ *
+ * @type {Node | null}
+ */
+ lastChild: null,
+ /**
+ * The previous sibling of this node.
+ *
+ * @type {Node | null}
+ */
+ previousSibling: null,
+ /**
+ * The next sibling of this node.
+ *
+ * @type {Node | null}
+ */
+ nextSibling: null,
+ /**
+ * The parent node of this node.
+ *
+ * @type {Node | null}
+ */
+ parentNode: null,
+ /**
+ * The parent element of this node.
+ *
+ * @type {Element | null}
+ */
+ get parentElement() {
+ return this.parentNode && this.parentNode.nodeType === this.ELEMENT_NODE ? this.parentNode : null;
+ },
+ /**
+ * The child nodes of this node.
+ *
+ * @type {NodeList}
+ */
+ childNodes: null,
+ /**
+ * The document object associated with this node.
+ *
+ * @type {Document | null}
+ */
+ ownerDocument: null,
+ /**
+ * The value of this node.
+ *
+ * @type {string | null}
+ */
+ nodeValue: null,
+ /**
+ * The namespace URI of this node.
+ *
+ * @type {string | null}
+ */
+ namespaceURI: null,
+ /**
+ * The prefix of the namespace for this node.
+ *
+ * @type {string | null}
+ */
+ prefix: null,
+ /**
+ * The local part of the qualified name of this node.
+ *
+ * @type {string | null}
+ */
+ localName: null,
+ /**
+ * The baseURI is currently always `about:blank`,
+ * since that's what happens when you create a document from scratch.
+ *
+ * @type {'about:blank'}
+ */
+ baseURI: 'about:blank',
+ /**
+ * Is true if this node is part of a document.
+ *
+ * @type {boolean}
+ */
+ get isConnected() {
+ var rootNode = this.getRootNode();
+ return rootNode && rootNode.nodeType === rootNode.DOCUMENT_NODE;
+ },
+ /**
+ * Checks whether `other` is an inclusive descendant of this node.
+ *
+ * @param {Node | null | undefined} other
+ * The node to check.
+ * @returns {boolean}
+ * True if `other` is an inclusive descendant of this node; false otherwise.
+ * @see https://dom.spec.whatwg.org/#dom-node-contains
+ */
+ contains: function (other) {
+ if (!other) return false;
+ var parent = other;
+ do {
+ if (this === parent) return true;
+ parent = parent.parentNode;
+ } while (parent);
+ return false;
+ },
+ /**
+ * @typedef GetRootNodeOptions
+ * @property {boolean} [composed=false]
+ */
+ /**
+ * Searches for the root node of this node.
+ *
+ * **This behavior is slightly different from the in the specs**:
+ * - ignores `options.composed`, since `ShadowRoot`s are unsupported, always returns root.
+ *
+ * @param {GetRootNodeOptions} [options]
+ * @returns {Node}
+ * Root node.
+ * @see https://dom.spec.whatwg.org/#dom-node-getrootnode
+ * @see https://dom.spec.whatwg.org/#concept-shadow-including-root
+ */
+ getRootNode: function (options) {
+ var parent = this;
+ do {
+ if (!parent.parentNode) {
+ return parent;
+ }
+ parent = parent.parentNode;
+ } while (parent);
+ },
+ /**
+ * Checks whether the given node is equal to this node.
+ *
+ * Two nodes are equal when they have the same type, defining characteristics (for the type),
+ * and the same childNodes. The comparison is iterative to avoid stack overflows on
+ * deeply-nested trees. Attribute nodes of each Element pair are also pushed onto the stack
+ * and compared the same way.
+ *
+ * @param {Node} [otherNode]
+ * @returns {boolean}
+ * @see https://dom.spec.whatwg.org/#concept-node-equals
+ * @see ../docs/walk-dom.md.
+ */
+ isEqualNode: function (otherNode) {
+ if (!otherNode) return false;
+
+ // Use an explicit {node, other} pair stack to avoid call-stack overflow on deep trees.
+ // walkDOM cannot be used here — parallel two-tree traversal requires pairing
+ // corresponding nodes at each step across both trees simultaneously.
+ var stack = [{ node: this, other: otherNode }];
+ while (stack.length > 0) {
+ var pair = stack.pop();
+ var node = pair.node;
+ var other = pair.other;
+
+ if (node.nodeType !== other.nodeType) return false;
+
+ switch (node.nodeType) {
+ case node.DOCUMENT_TYPE_NODE:
+ if (node.name !== other.name) return false;
+ if (node.publicId !== other.publicId) return false;
+ if (node.systemId !== other.systemId) return false;
+ break;
+ case node.ELEMENT_NODE:
+ if (node.namespaceURI !== other.namespaceURI) return false;
+ if (node.prefix !== other.prefix) return false;
+ if (node.localName !== other.localName) return false;
+ if (node.attributes.length !== other.attributes.length) return false;
+ for (var i = 0; i < node.attributes.length; i++) {
+ var attr = node.attributes.item(i);
+ var otherAttr = other.getAttributeNodeNS(attr.namespaceURI, attr.localName);
+ if (!otherAttr) return false;
+ stack.push({ node: attr, other: otherAttr });
+ }
+ break;
+ case node.ATTRIBUTE_NODE:
+ if (node.namespaceURI !== other.namespaceURI) return false;
+ if (node.localName !== other.localName) return false;
+ if (node.value !== other.value) return false;
+ break;
+ case node.PROCESSING_INSTRUCTION_NODE:
+ if (node.target !== other.target || node.data !== other.data) return false;
+ break;
+ case node.TEXT_NODE:
+ case node.CDATA_SECTION_NODE:
+ case node.COMMENT_NODE:
+ if (node.data !== other.data) return false;
+ break;
+ }
+
+ if (node.childNodes.length !== other.childNodes.length) return false;
+
+ // Push children in reverse order so index 0 is processed first (LIFO).
+ for (var i = node.childNodes.length - 1; i >= 0; i--) {
+ stack.push({ node: node.childNodes[i], other: other.childNodes[i] });
+ }
+ }
+
+ return true;
+ },
+ /**
+ * Checks whether or not the given node is this node.
+ *
+ * @param {Node} [otherNode]
+ */
+ isSameNode: function (otherNode) {
+ return this === otherNode;
+ },
+ /**
+ * Inserts a node before a reference node as a child of this node.
+ *
+ * @param {Node} newChild
+ * The new child node to be inserted.
+ * @param {Node | null} refChild
+ * The reference node before which newChild will be inserted.
+ * @returns {Node}
+ * The new child node successfully inserted.
+ * @throws {DOMException}
+ * Throws a DOMException if inserting the node would result in a DOM tree that is not
+ * well-formed, or if `child` is provided but is not a child of `parent`.
+ * See {@link _insertBefore} for more details.
+ * @since Modified in DOM L2
+ */
+ insertBefore: function (newChild, refChild) {
+ return _insertBefore(this, newChild, refChild);
+ },
+ /**
+ * Replaces an old child node with a new child node within this node.
+ *
+ * @param {Node} newChild
+ * The new node that is to replace the old node.
+ * If it already exists in the DOM, it is removed from its original position.
+ * @param {Node} oldChild
+ * The existing child node to be replaced.
+ * @returns {Node}
+ * Returns the replaced child node.
+ * @throws {DOMException}
+ * Throws a DOMException if replacing the node would result in a DOM tree that is not
+ * well-formed, or if `oldChild` is not a child of `this`.
+ * This can also occur if the pre-replacement validity assertion fails.
+ * See {@link _insertBefore}, {@link Node.removeChild}, and
+ * {@link assertPreReplacementValidityInDocument} for more details.
+ * @see https://dom.spec.whatwg.org/#concept-node-replace
+ */
+ replaceChild: function (newChild, oldChild) {
+ _insertBefore(this, newChild, oldChild, assertPreReplacementValidityInDocument);
+ if (oldChild) {
+ this.removeChild(oldChild);
+ }
+ },
+ /**
+ * Removes an existing child node from this node.
+ *
+ * @param {Node} oldChild
+ * The child node to be removed.
+ * @returns {Node}
+ * Returns the removed child node.
+ * @throws {DOMException}
+ * Throws a DOMException if `oldChild` is not a child of `this`.
+ * See {@link _removeChild} for more details.
+ */
+ removeChild: function (oldChild) {
+ return _removeChild(this, oldChild);
+ },
+ /**
+ * Appends a child node to this node.
+ *
+ * @param {Node} newChild
+ * The child node to be appended to this node.
+ * If it already exists in the DOM, it is removed from its original position.
+ * @returns {Node}
+ * Returns the appended child node.
+ * @throws {DOMException}
+ * Throws a DOMException if appending the node would result in a DOM tree that is not
+ * well-formed, or if `newChild` is not a valid Node.
+ * See {@link insertBefore} for more details.
+ */
+ appendChild: function (newChild) {
+ return this.insertBefore(newChild, null);
+ },
+ /**
+ * Determines whether this node has any child nodes.
+ *
+ * @returns {boolean}
+ * Returns true if this node has any child nodes, and false otherwise.
+ */
+ hasChildNodes: function () {
+ return this.firstChild != null;
+ },
+ /**
+ * Creates a copy of the calling node.
+ *
+ * @param {boolean} deep
+ * If true, the contents of the node are recursively copied.
+ * If false, only the node itself (and its attributes, if it is an element) are copied.
+ * @returns {Node}
+ * Returns the newly created copy of the node.
+ * @throws {DOMException}
+ * May throw a DOMException if operations within {@link Element#setAttributeNode} or
+ * {@link Node#appendChild} (which are potentially invoked in this method) do not meet their
+ * specific constraints.
+ * @see {@link cloneNode}
+ */
+ cloneNode: function (deep) {
+ return cloneNode(this.ownerDocument || this, this, deep);
+ },
+ /**
+ * Puts the specified node and all of its subtree into a "normalized" form. In a normalized
+ * subtree, no text nodes in the subtree are empty and there are no adjacent text nodes.
+ *
+ * Specifically, this method merges any adjacent text nodes (i.e., nodes for which `nodeType`
+ * is `TEXT_NODE`) into a single node with the combined data. It also removes any empty text
+ * nodes.
+ *
+ * This method iterativly traverses all child nodes to normalize all descendent nodes within
+ * the subtree.
+ *
+ * @throws {DOMException}
+ * May throw a DOMException if operations within removeChild or appendData (which are
+ * potentially invoked in this method) do not meet their specific constraints.
+ * @since Modified in DOM Level 2
+ * @see {@link Node.removeChild}
+ * @see {@link CharacterData.appendData}
+ * @see ../docs/walk-dom.md.
+ */
+ normalize: function () {
+ walkDOM(this, null, {
+ enter: function (node) {
+ // Merge adjacent text children of node before walkDOM schedules them.
+ // walkDOM reads lastChild/previousSibling after enter returns, so the
+ // surviving post-merge children are what it descends into.
+ var child = node.firstChild;
+ while (child) {
+ var next = child.nextSibling;
+ if (next !== null && next.nodeType === TEXT_NODE && child.nodeType === TEXT_NODE) {
+ // Merge the whole run of adjacent text nodes at once: gather the
+ // following text siblings' data, unlink them in a single pass, and
+ // re-index the child list a single time. Per-sibling `removeChild`
+ // (each an O(K) re-index) plus per-sibling `appendData` (each an O(K)
+ // string rebuild) is O(K^2) over a long run of single-character text
+ // nodes; this keeps it O(K). The first text node of the run survives
+ // and carries the concatenated data, preserving node identity and
+ // locator semantics.
+ var tail = [];
+ var sibling = next;
+ while (sibling !== null && sibling.nodeType === TEXT_NODE) {
+ tail.push(sibling.data);
+ sibling = sibling.nextSibling;
+ }
+ // `sibling` is now the first non-text node after the run, or null.
+ var removed = child.nextSibling;
+ while (removed !== sibling) {
+ var following = removed.nextSibling;
+ removed.parentNode = null;
+ removed.previousSibling = null;
+ removed.nextSibling = null;
+ removed = following;
+ }
+ child.nextSibling = sibling;
+ if (sibling !== null) {
+ sibling.previousSibling = child;
+ } else {
+ node.lastChild = child;
+ }
+ child.appendData(tail.join('')); // single O(K) string rebuild
+ _onUpdateChild(node.ownerDocument, node); // single O(K) re-index
+ child = sibling;
+ } else {
+ child = next;
+ }
+ }
+ return true; // descend into surviving children
+ },
+ });
+ },
+ /**
+ * Checks whether the DOM implementation implements a specific feature and its version.
+ *
+ * @deprecated
+ * Since `DOMImplementation.hasFeature` is deprecated and always returns true.
+ * @param {string} feature
+ * The package name of the feature to test. This is the same name that can be passed to the
+ * method `hasFeature` on `DOMImplementation`.
+ * @param {string} version
+ * This is the version number of the package name to test.
+ * @returns {boolean}
+ * Returns true in all cases in the current implementation.
+ * @since Introduced in DOM Level 2
+ * @see {@link DOMImplementation.hasFeature}
+ */
+ isSupported: function (feature, version) {
+ return this.ownerDocument.implementation.hasFeature(feature, version);
+ },
+ /**
+ * Look up the prefix associated to the given namespace URI, starting from this node.
+ * **The default namespace declarations are ignored by this method.**
+ * See Namespace Prefix Lookup for details on the algorithm used by this method.
+ *
+ * **This behavior is different from the in the specs**:
+ * - no node type specific handling
+ * - uses the internal attribute _nsMap for resolving namespaces that is updated when changing attributes
+ *
+ * @param {string | null} namespaceURI
+ * The namespace URI for which to find the associated prefix.
+ * @returns {string | null}
+ * The associated prefix, if found; otherwise, null.
+ * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespacePrefix
+ * @see https://www.w3.org/TR/DOM-Level-3-Core/namespaces-algorithms.html#lookupNamespacePrefixAlgo
+ * @see https://dom.spec.whatwg.org/#dom-node-lookupprefix
+ * @see https://github.com/xmldom/xmldom/issues/322
+ * @prettierignore
+ */
+ lookupPrefix: function (namespaceURI) {
+ var el = this;
+ while (el) {
+ var map = el._nsMap;
+ //console.dir(map)
+ if (map) {
+ for (var n in map) {
+ if (hasOwn(map, n) && map[n] === namespaceURI) {
+ return n;
+ }
+ }
+ }
+ el = el.nodeType == ATTRIBUTE_NODE ? el.ownerDocument : el.parentNode;
+ }
+ return null;
+ },
+ /**
+ * This function is used to look up the namespace URI associated with the given prefix,
+ * starting from this node.
+ *
+ * **This behavior is different from the in the specs**:
+ * - no node type specific handling
+ * - uses the internal attribute _nsMap for resolving namespaces that is updated when changing attributes
+ *
+ * @param {string | null} prefix
+ * The prefix for which to find the associated namespace URI.
+ * @returns {string | null}
+ * The associated namespace URI, if found; otherwise, null.
+ * @since DOM Level 3
+ * @see https://dom.spec.whatwg.org/#dom-node-lookupnamespaceuri
+ * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespaceURI
+ * @prettierignore
+ */
+ lookupNamespaceURI: function (prefix) {
+ var el = this;
+ while (el) {
+ var map = el._nsMap;
+ //console.dir(map)
+ if (map) {
+ if (hasOwn(map, prefix)) {
+ return map[prefix];
+ }
+ }
+ el = el.nodeType == ATTRIBUTE_NODE ? el.ownerDocument : el.parentNode;
+ }
+ return null;
+ },
+ /**
+ * Determines whether the given namespace URI is the default namespace.
+ *
+ * The function works by looking up the prefix associated with the given namespace URI. If no
+ * prefix is found (i.e., the namespace URI is not registered in the namespace map of this
+ * node or any of its ancestors), it returns `true`, implying the namespace URI is considered
+ * the default.
+ *
+ * **This behavior is different from the in the specs**:
+ * - no node type specific handling
+ * - uses the internal attribute _nsMap for resolving namespaces that is updated when changing attributes
+ *
+ * @param {string | null} namespaceURI
+ * The namespace URI to be checked.
+ * @returns {boolean}
+ * Returns true if the given namespace URI is the default namespace, false otherwise.
+ * @since DOM Level 3
+ * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-isDefaultNamespace
+ * @see https://dom.spec.whatwg.org/#dom-node-isdefaultnamespace
+ * @prettierignore
+ */
+ isDefaultNamespace: function (namespaceURI) {
+ var prefix = this.lookupPrefix(namespaceURI);
+ return prefix == null;
+ },
+ /**
+ * Compares the reference node with a node with regard to their position in the document and
+ * according to the document order.
+ *
+ * @param {Node} other
+ * The node to compare the reference node to.
+ * @returns {number}
+ * Returns how the node is positioned relatively to the reference node according to the
+ * bitmask. 0 if reference node and given node are the same.
+ * @since DOM Level 3
+ * @see https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#Node3-compare
+ * @see https://dom.spec.whatwg.org/#dom-node-comparedocumentposition
+ */
+ compareDocumentPosition: function (other) {
+ if (this === other) return 0;
+ var node1 = other;
+ var node2 = this;
+ var attr1 = null;
+ var attr2 = null;
+ if (node1 instanceof Attr) {
+ attr1 = node1;
+ node1 = attr1.ownerElement;
+ }
+ if (node2 instanceof Attr) {
+ attr2 = node2;
+ node2 = attr2.ownerElement;
+ if (attr1 && node1 && node2 === node1) {
+ for (var i = 0, attr; (attr = node2.attributes[i]); i++) {
+ if (attr === attr1)
+ return DocumentPosition.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC + DocumentPosition.DOCUMENT_POSITION_PRECEDING;
+ if (attr === attr2)
+ return DocumentPosition.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC + DocumentPosition.DOCUMENT_POSITION_FOLLOWING;
+ }
+ }
+ }
+ if (!node1 || !node2 || node2.ownerDocument !== node1.ownerDocument) {
+ return (
+ DocumentPosition.DOCUMENT_POSITION_DISCONNECTED +
+ DocumentPosition.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC +
+ (docGUID(node2.ownerDocument) > docGUID(node1.ownerDocument)
+ ? DocumentPosition.DOCUMENT_POSITION_FOLLOWING
+ : DocumentPosition.DOCUMENT_POSITION_PRECEDING)
+ );
+ }
+ if (attr2 && node1 === node2) {
+ return DocumentPosition.DOCUMENT_POSITION_CONTAINS + DocumentPosition.DOCUMENT_POSITION_PRECEDING;
+ }
+ if (attr1 && node1 === node2) {
+ return DocumentPosition.DOCUMENT_POSITION_CONTAINED_BY + DocumentPosition.DOCUMENT_POSITION_FOLLOWING;
+ }
+
+ var chain1 = [];
+ var ancestor1 = node1.parentNode;
+ while (ancestor1) {
+ if (!attr2 && ancestor1 === node2) {
+ return DocumentPosition.DOCUMENT_POSITION_CONTAINED_BY + DocumentPosition.DOCUMENT_POSITION_FOLLOWING;
+ }
+ chain1.push(ancestor1);
+ ancestor1 = ancestor1.parentNode;
+ }
+ chain1.reverse();
+
+ var chain2 = [];
+ var ancestor2 = node2.parentNode;
+ while (ancestor2) {
+ if (!attr1 && ancestor2 === node1) {
+ return DocumentPosition.DOCUMENT_POSITION_CONTAINS + DocumentPosition.DOCUMENT_POSITION_PRECEDING;
+ }
+ chain2.push(ancestor2);
+ ancestor2 = ancestor2.parentNode;
+ }
+ chain2.reverse();
+
+ var ca = commonAncestor(chain1, chain2);
+ for (var n in ca.childNodes) {
+ var child = ca.childNodes[n];
+ if (child === node2) return DocumentPosition.DOCUMENT_POSITION_FOLLOWING;
+ if (child === node1) return DocumentPosition.DOCUMENT_POSITION_PRECEDING;
+ if (chain2.indexOf(child) >= 0) return DocumentPosition.DOCUMENT_POSITION_FOLLOWING;
+ if (chain1.indexOf(child) >= 0) return DocumentPosition.DOCUMENT_POSITION_PRECEDING;
+ }
+ return 0;
+ },
+};
+
+/**
+ * Encodes special XML characters to their corresponding entities.
+ *
+ * @param {string} c
+ * The character to be encoded.
+ * @returns {string}
+ * The encoded character.
+ * @private
+ */
+function _xmlEncoder(c) {
+ return (
+ (c == '<' && '<') || (c == '>' && '>') || (c == '&' && '&') || (c == '"' && '"') || '' + c.charCodeAt() + ';'
+ );
+}
+
+copy(NodeType, Node);
+copy(NodeType, Node.prototype);
+copy(DocumentPosition, Node);
+copy(DocumentPosition, Node.prototype);
+
+/**
+ * Visits every node in the subtree rooted at `node` in depth-first pre-order.
+ *
+ * Delegates to {@link walkDOM} for traversal. The `callback` is called on each node;
+ * if it returns a truthy value, traversal stops immediately.
+ *
+ * @param {Node} node
+ * Root of the subtree to visit.
+ * @param {function(Node): *} callback
+ * Called for each node. A truthy return value stops traversal early.
+ */
+function _visitNode(node, callback) {
+ walkDOM(node, null, {
+ enter: function (n) {
+ return callback(n) ? walkDOM.STOP : true;
+ },
+ });
+}
+
+/**
+ * Depth-first pre/post-order DOM tree walker.
+ *
+ * Visits every node in the subtree rooted at `node`. For each node:
+ *
+ * 1. Calls `callbacks.enter(node, context)` before descending into the node's children. The
+ * return value becomes the `context` passed to each child's `enter` call and to the matching
+ * `exit` call.
+ * 2. If `enter` returns `null` or `undefined`, the node's children are skipped;
+ * sibling traversal continues normally.
+ * 3. If `enter` returns `walkDOM.STOP`, the entire traversal is aborted immediately — no
+ * further `enter` or `exit` calls are made.
+ * 4. `lastChild` and `previousSibling` are read **after** `enter` returns, so `enter` may
+ * safely modify the node's own child list before the walker descends. Modifying siblings of
+ * the current node or any other part of the tree produces unpredictable results: nodes already
+ * queued on the stack are visited regardless of DOM changes, and newly inserted nodes outside
+ * the current child list are never visited.
+ * 5. Calls `callbacks.exit(node, context)` (if provided) after all of a node's children have
+ * been visited, passing the same `context` that `enter`
+ * returned for that node.
+ *
+ * This implementation uses an explicit stack and does not recurse — it is safe on arbitrarily
+ * deep trees.
+ *
+ * @param {Node} node
+ * Root of the subtree to walk.
+ * @param {*} context
+ * Initial context value passed to the root node's `enter`.
+ * @param {{ enter: function(Node, *): *, exit?: function(Node, *): void }} callbacks
+ * @returns {void | walkDOM.STOP}
+ * @see ../docs/walk-dom.md.
+ */
+function walkDOM(node, context, callbacks) {
+ // Each stack frame is {node, context, phase}:
+ // walkDOM.ENTER — call enter, then push children
+ // walkDOM.EXIT — call exit
+ var stack = [{ node: node, context: context, phase: walkDOM.ENTER }];
+ while (stack.length > 0) {
+ var frame = stack.pop();
+ if (frame.phase === walkDOM.ENTER) {
+ var childContext = callbacks.enter(frame.node, frame.context);
+ if (childContext === walkDOM.STOP) {
+ return walkDOM.STOP;
+ }
+ // Push exit frame before children so it fires after all children are processed (Last In First Out)
+ stack.push({ node: frame.node, context: childContext, phase: walkDOM.EXIT });
+ if (childContext === null || childContext === undefined) {
+ continue; // skip children
+ }
+ // lastChild is read after enter returns, so enter may modify the child list.
+ var child = frame.node.lastChild;
+ // Traverse from lastChild backwards so that pushing onto the stack
+ // naturally yields firstChild on top (processed first).
+ while (child) {
+ stack.push({ node: child, context: childContext, phase: walkDOM.ENTER });
+ child = child.previousSibling;
+ }
+ } else {
+ // frame.phase === walkDOM.EXIT
+ if (callbacks.exit) {
+ callbacks.exit(frame.node, frame.context);
+ }
+ }
+ }
+}
+
+/**
+ * Sentinel value returned from a `walkDOM` `enter` callback to abort the entire traversal
+ * immediately.
+ *
+ * @type {symbol}
+ */
+walkDOM.STOP = Symbol('walkDOM.STOP');
+/**
+ * Phase constant for a stack frame that has not yet been visited.
+ * The `enter` callback is called and children are scheduled.
+ *
+ * @type {number}
+ */
+walkDOM.ENTER = 0;
+/**
+ * Phase constant for a stack frame whose subtree has been fully visited.
+ * The `exit` callback is called.
+ *
+ * @type {number}
+ */
+walkDOM.EXIT = 1;
+
+/**
+ * @typedef DocumentOptions
+ * @property {string} [contentType=MIME_TYPE.XML_APPLICATION]
+ */
+/**
+ * The Document interface describes the common properties and methods for any kind of document.
+ *
+ * It should usually be created using `new DOMImplementation().createDocument(...)`
+ * or `new DOMImplementation().createHTMLDocument(...)`.
+ *
+ * The constructor is considered a private API and offers to initially set the `contentType`
+ * property via it's options parameter.
+ *
+ * @class
+ * @param {Symbol} symbol
+ * @param {DocumentOptions} [options]
+ * @augments Node
+ * @private
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Document
+ * @see https://dom.spec.whatwg.org/#interface-document
+ */
+function Document(symbol, options) {
+ checkSymbol(symbol);
+
+ var opt = options || {};
+ this.ownerDocument = this;
+ /**
+ * The mime type of the document is determined at creation time and can not be modified.
+ *
+ * @type {string}
+ * @see https://dom.spec.whatwg.org/#concept-document-content-type
+ * @see {@link DOMImplementation}
+ * @see {@link MIME_TYPE}
+ * @readonly
+ */
+ this.contentType = opt.contentType || MIME_TYPE.XML_APPLICATION;
+ /**
+ * @type {'html' | 'xml'}
+ * @see https://dom.spec.whatwg.org/#concept-document-type
+ * @see {@link DOMImplementation}
+ * @readonly
+ */
+ this.type = isHTMLMimeType(this.contentType) ? 'html' : 'xml';
+}
+
+/**
+ * Updates the namespace mapping of an element when a new attribute is added.
+ *
+ * @param {Document} doc
+ * The document that the element belongs to.
+ * @param {Element} el
+ * The element to which the attribute is being added.
+ * @param {Attr} newAttr
+ * The new attribute being added.
+ * @private
+ */
+function _onAddAttribute(doc, el, newAttr) {
+ doc && doc._inc++;
+ var ns = newAttr.namespaceURI;
+ if (ns === NAMESPACE.XMLNS) {
+ //update namespace
+ el._nsMap[newAttr.prefix ? newAttr.localName : ''] = newAttr.value;
+ }
+}
+
+/**
+ * Updates the namespace mapping of an element when an attribute is removed.
+ *
+ * @param {Document} doc
+ * The document that the element belongs to.
+ * @param {Element} el
+ * The element from which the attribute is being removed.
+ * @param {Attr} newAttr
+ * The attribute being removed.
+ * @param {boolean} remove
+ * Indicates whether the attribute is to be removed.
+ * @private
+ */
+function _onRemoveAttribute(doc, el, newAttr, remove) {
+ doc && doc._inc++;
+ var ns = newAttr.namespaceURI;
+ if (ns === NAMESPACE.XMLNS) {
+ //update namespace
+ delete el._nsMap[newAttr.prefix ? newAttr.localName : ''];
+ }
+}
+
+/**
+ * Updates `parent.childNodes`, adjusting the indexed items and its `length`.
+ * If `newChild` is provided and has no nextSibling, it will be appended.
+ * Otherwise, it's assumed that an item has been removed or inserted,
+ * and `parent.firstNode` and its `.nextSibling` to re-indexing all child nodes of `parent`.
+ *
+ * @param {Document} doc
+ * The parent document of `el`.
+ * @param {Node} parent
+ * The parent node whose childNodes list needs to be updated.
+ * @param {Node} [newChild]
+ * The new child node to be appended. If not provided, the function assumes a node has been
+ * removed.
+ * @private
+ */
+function _onUpdateChild(doc, parent, newChild) {
+ if (doc && doc._inc) {
+ doc._inc++;
+ var childNodes = parent.childNodes;
+ // assumes nextSibling and previousSibling were already configured upfront
+ if (newChild && !newChild.nextSibling) {
+ // if an item has been appended, we only need to update the last index and the length
+ childNodes[childNodes.length++] = newChild;
+ } else {
+ // otherwise we need to reindex all items,
+ // which can take a while when processing nodes with a lot of children
+ var child = parent.firstChild;
+ var i = 0;
+ while (child) {
+ childNodes[i++] = child;
+ child = child.nextSibling;
+ }
+ childNodes.length = i;
+ delete childNodes[childNodes.length];
+ }
+ }
+}
+
+/**
+ * Removes the connections between `parentNode` and `child`
+ * and any existing `child.previousSibling` or `child.nextSibling`.
+ *
+ * @param {Node} parentNode
+ * The parent node from which the child node is to be removed.
+ * @param {Node} child
+ * The child node to be removed from the parentNode.
+ * @returns {Node}
+ * Returns the child node that was removed.
+ * @throws {DOMException}
+ * With code:
+ * - {@link DOMException.NOT_FOUND_ERR} If the parentNode is not the parent of the child node.
+ * @private
+ * @see https://github.com/xmldom/xmldom/issues/135
+ * @see https://github.com/xmldom/xmldom/issues/145
+ */
+function _removeChild(parentNode, child) {
+ if (parentNode !== child.parentNode) {
+ throw new DOMException(DOMException.NOT_FOUND_ERR, "child's parent is not parent");
+ }
+ var oldPreviousSibling = child.previousSibling;
+ var oldNextSibling = child.nextSibling;
+ if (oldPreviousSibling) {
+ oldPreviousSibling.nextSibling = oldNextSibling;
+ } else {
+ parentNode.firstChild = oldNextSibling;
+ }
+ if (oldNextSibling) {
+ oldNextSibling.previousSibling = oldPreviousSibling;
+ } else {
+ parentNode.lastChild = oldPreviousSibling;
+ }
+ _onUpdateChild(parentNode.ownerDocument, parentNode);
+ child.parentNode = null;
+ child.previousSibling = null;
+ child.nextSibling = null;
+ return child;
+}
+
+/**
+ * Returns `true` if `node` can be a parent for insertion.
+ *
+ * @param {Node} node
+ * @returns {boolean}
+ */
+function hasValidParentNodeType(node) {
+ return (
+ node &&
+ (node.nodeType === Node.DOCUMENT_NODE || node.nodeType === Node.DOCUMENT_FRAGMENT_NODE || node.nodeType === Node.ELEMENT_NODE)
+ );
+}
+
+/**
+ * Returns `true` if `node` can be inserted according to it's `nodeType`.
+ *
+ * @param {Node} node
+ * @returns {boolean}
+ */
+function hasInsertableNodeType(node) {
+ return (
+ node &&
+ (node.nodeType === Node.CDATA_SECTION_NODE ||
+ node.nodeType === Node.COMMENT_NODE ||
+ node.nodeType === Node.DOCUMENT_FRAGMENT_NODE ||
+ node.nodeType === Node.DOCUMENT_TYPE_NODE ||
+ node.nodeType === Node.ELEMENT_NODE ||
+ node.nodeType === Node.PROCESSING_INSTRUCTION_NODE ||
+ node.nodeType === Node.TEXT_NODE)
+ );
+}
+
+/**
+ * Returns true if `node` is a DOCTYPE node.
+ *
+ * @param {Node} node
+ * @returns {boolean}
+ */
+function isDocTypeNode(node) {
+ return node && node.nodeType === Node.DOCUMENT_TYPE_NODE;
+}
+
+/**
+ * Returns true if the node is an element.
+ *
+ * @param {Node} node
+ * @returns {boolean}
+ */
+function isElementNode(node) {
+ return node && node.nodeType === Node.ELEMENT_NODE;
+}
+/**
+ * Returns true if `node` is a text node.
+ *
+ * @param {Node} node
+ * @returns {boolean}
+ */
+function isTextNode(node) {
+ return node && node.nodeType === Node.TEXT_NODE;
+}
+
+/**
+ * Check if en element node can be inserted before `child`, or at the end if child is falsy,
+ * according to the presence and position of a doctype node on the same level.
+ *
+ * @param {Document} doc
+ * The document node.
+ * @param {Node} child
+ * The node that would become the nextSibling if the element would be inserted.
+ * @returns {boolean}
+ * `true` if an element can be inserted before child.
+ * @private
+ */
+function isElementInsertionPossible(doc, child) {
+ var parentChildNodes = doc.childNodes || [];
+ if (find(parentChildNodes, isElementNode) || isDocTypeNode(child)) {
+ return false;
+ }
+ var docTypeNode = find(parentChildNodes, isDocTypeNode);
+ return !(child && docTypeNode && parentChildNodes.indexOf(docTypeNode) > parentChildNodes.indexOf(child));
+}
+
+/**
+ * Check if en element node can be inserted before `child`, or at the end if child is falsy,
+ * according to the presence and position of a doctype node on the same level.
+ *
+ * @param {Node} doc
+ * The document node.
+ * @param {Node} child
+ * The node that would become the nextSibling if the element would be inserted.
+ * @returns {boolean}
+ * `true` if an element can be inserted before child.
+ * @private
+ */
+function isElementReplacementPossible(doc, child) {
+ var parentChildNodes = doc.childNodes || [];
+
+ function hasElementChildThatIsNotChild(node) {
+ return isElementNode(node) && node !== child;
+ }
+
+ if (find(parentChildNodes, hasElementChildThatIsNotChild)) {
+ return false;
+ }
+ var docTypeNode = find(parentChildNodes, isDocTypeNode);
+ return !(child && docTypeNode && parentChildNodes.indexOf(docTypeNode) > parentChildNodes.indexOf(child));
+}
+
+/**
+ * Asserts pre-insertion validity of a node into a parent before a child.
+ * Throws errors for invalid node combinations that would result in an ill-formed DOM.
+ *
+ * @param {Node} parent
+ * The parent node to insert `node` into.
+ * @param {Node} node
+ * The node to insert.
+ * @param {Node | null} child
+ * The node that should become the `nextSibling` of `node`. If null, no sibling is considered.
+ * @throws {DOMException}
+ * With code:
+ * - {@link DOMException.HIERARCHY_REQUEST_ERR} If `parent` is not a Document,
+ * DocumentFragment, or Element node.
+ * - {@link DOMException.HIERARCHY_REQUEST_ERR} If `node` is a host-including inclusive
+ * ancestor of `parent`. (Currently not implemented)
+ * - {@link DOMException.NOT_FOUND_ERR} If `child` is non-null and its `parent` is not
+ * `parent`.
+ * - {@link DOMException.HIERARCHY_REQUEST_ERR} If `node` is not a DocumentFragment,
+ * DocumentType, Element, or CharacterData node.
+ * - {@link DOMException.HIERARCHY_REQUEST_ERR} If either `node` is a Text node and `parent` is
+ * a document, or if `node` is a doctype and `parent` is not a document.
+ * @private
+ * @see https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity
+ * @see https://dom.spec.whatwg.org/#concept-node-replace
+ */
+function assertPreInsertionValidity1to5(parent, node, child) {
+ // 1. If `parent` is not a Document, DocumentFragment, or Element node, then throw a "HierarchyRequestError" DOMException.
+ if (!hasValidParentNodeType(parent)) {
+ throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, 'Unexpected parent node type ' + parent.nodeType);
+ }
+ // 2. If `node` is a host-including inclusive ancestor of `parent`, then throw a "HierarchyRequestError" DOMException.
+ // not implemented!
+ // 3. If `child` is non-null and its parent is not `parent`, then throw a "NotFoundError" DOMException.
+ if (child && child.parentNode !== parent) {
+ throw new DOMException(DOMException.NOT_FOUND_ERR, 'child not in parent');
+ }
+ if (
+ // 4. If `node` is not a DocumentFragment, DocumentType, Element, or CharacterData node, then throw a "HierarchyRequestError" DOMException.
+ !hasInsertableNodeType(node) ||
+ // 5. If either `node` is a Text node and `parent` is a document,
+ // the sax parser currently adds top level text nodes, this will be fixed in 0.9.0
+ // || (node.nodeType === Node.TEXT_NODE && parent.nodeType === Node.DOCUMENT_NODE)
+ // or `node` is a doctype and `parent` is not a document, then throw a "HierarchyRequestError" DOMException.
+ (isDocTypeNode(node) && parent.nodeType !== Node.DOCUMENT_NODE)
+ ) {
+ throw new DOMException(
+ DOMException.HIERARCHY_REQUEST_ERR,
+ 'Unexpected node type ' + node.nodeType + ' for parent node type ' + parent.nodeType
+ );
+ }
+}
+
+/**
+ * Asserts pre-insertion validity of a node into a document before a child.
+ * Throws errors for invalid node combinations that would result in an ill-formed DOM.
+ *
+ * @param {Document} parent
+ * The parent node to insert `node` into.
+ * @param {Node} node
+ * The node to insert.
+ * @param {Node | undefined} child
+ * The node that should become the `nextSibling` of `node`. If undefined, no sibling is
+ * considered.
+ * @returns {Node}
+ * @throws {DOMException}
+ * With code:
+ * - {@link DOMException.HIERARCHY_REQUEST_ERR} If `node` is a DocumentFragment with more than
+ * one element child or has a Text node child.
+ * - {@link DOMException.HIERARCHY_REQUEST_ERR} If `node` is a DocumentFragment with one
+ * element child and either `parent` has an element child, `child` is a doctype, or `child` is
+ * non-null and a doctype is following `child`.
+ * - {@link DOMException.HIERARCHY_REQUEST_ERR} If `node` is an Element and `parent` has an
+ * element child, `child` is a doctype, or `child` is non-null and a doctype is following
+ * `child`.
+ * - {@link DOMException.HIERARCHY_REQUEST_ERR} If `node` is a DocumentType and `parent` has a
+ * doctype child, `child` is non-null and an element is preceding `child`, or `child` is null
+ * and `parent` has an element child.
+ * @private
+ * @see https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity
+ * @see https://dom.spec.whatwg.org/#concept-node-replace
+ */
+function assertPreInsertionValidityInDocument(parent, node, child) {
+ var parentChildNodes = parent.childNodes || [];
+ var nodeChildNodes = node.childNodes || [];
+
+ // DocumentFragment
+ if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
+ var nodeChildElements = nodeChildNodes.filter(isElementNode);
+ // If node has more than one element child or has a Text node child.
+ if (nodeChildElements.length > 1 || find(nodeChildNodes, isTextNode)) {
+ throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, 'More than one element or text in fragment');
+ }
+ // Otherwise, if `node` has one element child and either `parent` has an element child,
+ // `child` is a doctype, or `child` is non-null and a doctype is following `child`.
+ if (nodeChildElements.length === 1 && !isElementInsertionPossible(parent, child)) {
+ throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, 'Element in fragment can not be inserted before doctype');
+ }
+ }
+ // Element
+ if (isElementNode(node)) {
+ // `parent` has an element child, `child` is a doctype,
+ // or `child` is non-null and a doctype is following `child`.
+ if (!isElementInsertionPossible(parent, child)) {
+ throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, 'Only one element can be added and only after doctype');
+ }
+ }
+ // DocumentType
+ if (isDocTypeNode(node)) {
+ // `parent` has a doctype child,
+ if (find(parentChildNodes, isDocTypeNode)) {
+ throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, 'Only one doctype is allowed');
+ }
+ var parentElementChild = find(parentChildNodes, isElementNode);
+ // `child` is non-null and an element is preceding `child`,
+ if (child && parentChildNodes.indexOf(parentElementChild) < parentChildNodes.indexOf(child)) {
+ throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, 'Doctype can only be inserted before an element');
+ }
+ // or `child` is null and `parent` has an element child.
+ if (!child && parentElementChild) {
+ throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, 'Doctype can not be appended since element is present');
+ }
+ }
+}
+
+/**
+ * @param {Document} parent
+ * The parent node to insert `node` into.
+ * @param {Node} node
+ * The node to insert.
+ * @param {Node | undefined} child
+ * the node that should become the `nextSibling` of `node`
+ * @returns {Node}
+ * @throws {DOMException}
+ * For several node combinations that would create a DOM that is not well-formed.
+ * @throws {DOMException}
+ * If `child` is provided but is not a child of `parent`.
+ * @private
+ * @see https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity
+ * @see https://dom.spec.whatwg.org/#concept-node-replace
+ */
+function assertPreReplacementValidityInDocument(parent, node, child) {
+ var parentChildNodes = parent.childNodes || [];
+ var nodeChildNodes = node.childNodes || [];
+
+ // DocumentFragment
+ if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
+ var nodeChildElements = nodeChildNodes.filter(isElementNode);
+ // If `node` has more than one element child or has a Text node child.
+ if (nodeChildElements.length > 1 || find(nodeChildNodes, isTextNode)) {
+ throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, 'More than one element or text in fragment');
+ }
+ // Otherwise, if `node` has one element child and either `parent` has an element child that is not `child` or a doctype is following `child`.
+ if (nodeChildElements.length === 1 && !isElementReplacementPossible(parent, child)) {
+ throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, 'Element in fragment can not be inserted before doctype');
+ }
+ }
+ // Element
+ if (isElementNode(node)) {
+ // `parent` has an element child that is not `child` or a doctype is following `child`.
+ if (!isElementReplacementPossible(parent, child)) {
+ throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, 'Only one element can be added and only after doctype');
+ }
+ }
+ // DocumentType
+ if (isDocTypeNode(node)) {
+ function hasDoctypeChildThatIsNotChild(node) {
+ return isDocTypeNode(node) && node !== child;
+ }
+
+ // `parent` has a doctype child that is not `child`,
+ if (find(parentChildNodes, hasDoctypeChildThatIsNotChild)) {
+ throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, 'Only one doctype is allowed');
+ }
+ var parentElementChild = find(parentChildNodes, isElementNode);
+ // or an element is preceding `child`.
+ if (child && parentChildNodes.indexOf(parentElementChild) < parentChildNodes.indexOf(child)) {
+ throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, 'Doctype can only be inserted before an element');
+ }
+ }
+}
+
+/**
+ * Inserts a node into a parent node before a child node.
+ *
+ * @param {Node} parent
+ * The parent node to insert the node into.
+ * @param {Node} node
+ * The node to insert into the parent.
+ * @param {Node | null} child
+ * The node that should become the next sibling of the node.
+ * If null, the function inserts the node at the end of the children of the parent node.
+ * @param {Function} [_inDocumentAssertion]
+ * An optional function to check pre-insertion validity if parent is a document node.
+ * Defaults to {@link assertPreInsertionValidityInDocument}
+ * @returns {Node}
+ * Returns the inserted node.
+ * @throws {DOMException}
+ * Throws a DOMException if inserting the node would result in a DOM tree that is not
+ * well-formed. See {@link assertPreInsertionValidity1to5},
+ * {@link assertPreInsertionValidityInDocument}.
+ * @throws {DOMException}
+ * Throws a DOMException if child is provided but is not a child of the parent. See
+ * {@link Node.removeChild}
+ * @private
+ * @see https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity
+ */
+function _insertBefore(parent, node, child, _inDocumentAssertion) {
+ // To ensure pre-insertion validity of a node into a parent before a child, run these steps:
+ assertPreInsertionValidity1to5(parent, node, child);
+
+ // If parent is a document, and any of the statements below, switched on the interface node implements,
+ // are true, then throw a "HierarchyRequestError" DOMException.
+ if (parent.nodeType === Node.DOCUMENT_NODE) {
+ (_inDocumentAssertion || assertPreInsertionValidityInDocument)(parent, node, child);
+ }
+
+ var cp = node.parentNode;
+ if (cp) {
+ cp.removeChild(node); //remove and update
+ }
+ if (node.nodeType === DOCUMENT_FRAGMENT_NODE) {
+ var newFirst = node.firstChild;
+ if (newFirst == null) {
+ return node;
+ }
+ var newLast = node.lastChild;
+ } else {
+ newFirst = newLast = node;
+ }
+ var pre = child ? child.previousSibling : parent.lastChild;
+
+ newFirst.previousSibling = pre;
+ newLast.nextSibling = child;
+
+ if (pre) {
+ pre.nextSibling = newFirst;
+ } else {
+ parent.firstChild = newFirst;
+ }
+ if (child == null) {
+ parent.lastChild = newLast;
+ } else {
+ child.previousSibling = newLast;
+ }
+ do {
+ newFirst.parentNode = parent;
+ } while (newFirst !== newLast && (newFirst = newFirst.nextSibling));
+ _onUpdateChild(parent.ownerDocument || parent, parent, node);
+ if (node.nodeType == DOCUMENT_FRAGMENT_NODE) {
+ node.firstChild = node.lastChild = null;
+ }
+
+ return node;
+}
+
+Document.prototype = {
+ /**
+ * The implementation that created this document.
+ *
+ * @type DOMImplementation
+ * @readonly
+ */
+ implementation: null,
+ nodeName: '#document',
+ nodeType: DOCUMENT_NODE,
+ /**
+ * The DocumentType node of the document.
+ *
+ * @type DocumentType
+ * @readonly
+ */
+ doctype: null,
+ documentElement: null,
+ _inc: 1,
+
+ insertBefore: function (newChild, refChild) {
+ //raises
+ if (newChild.nodeType === DOCUMENT_FRAGMENT_NODE) {
+ var child = newChild.firstChild;
+ while (child) {
+ var next = child.nextSibling;
+ this.insertBefore(child, refChild);
+ child = next;
+ }
+ return newChild;
+ }
+ _insertBefore(this, newChild, refChild);
+ newChild.ownerDocument = this;
+ if (this.documentElement === null && newChild.nodeType === ELEMENT_NODE) {
+ this.documentElement = newChild;
+ }
+
+ return newChild;
+ },
+ removeChild: function (oldChild) {
+ var removed = _removeChild(this, oldChild);
+ if (removed === this.documentElement) {
+ this.documentElement = null;
+ }
+ return removed;
+ },
+ replaceChild: function (newChild, oldChild) {
+ //raises
+ _insertBefore(this, newChild, oldChild, assertPreReplacementValidityInDocument);
+ newChild.ownerDocument = this;
+ if (oldChild) {
+ this.removeChild(oldChild);
+ }
+ if (isElementNode(newChild)) {
+ this.documentElement = newChild;
+ }
+ },
+ /**
+ * Imports a node from another document into this document, creating a new copy owned by this
+ * document. The source node and its subtree are not modified.
+ *
+ * @param {Node} importedNode
+ * The node to import.
+ * @param {boolean} deep
+ * If true, the contents of the node are recursively imported.
+ * If false, only the node itself (and its attributes, if it is an element) are imported.
+ * @returns {Node}
+ * Returns the newly created import of the node.
+ * @see {@link importNode}
+ * @see {@link https://dom.spec.whatwg.org/#dom-document-importnode}
+ */
+ importNode: function (importedNode, deep) {
+ return importNode(this, importedNode, deep);
+ },
+ // Introduced in DOM Level 2:
+ getElementById: function (id) {
+ var rtv = null;
+ _visitNode(this.documentElement, function (node) {
+ if (node.nodeType == ELEMENT_NODE) {
+ if (node.getAttribute('id') == id) {
+ rtv = node;
+ return true;
+ }
+ }
+ });
+ return rtv;
+ },
+
+ /**
+ * Creates a new `Element` that is owned by this `Document`.
+ * In HTML Documents `localName` is the lower cased `tagName`,
+ * otherwise no transformation is being applied.
+ * When `contentType` implies the HTML namespace, it will be set as `namespaceURI`.
+ *
+ * __This implementation differs from the specification:__ - The provided name is not checked
+ * against the `Name` production,
+ * so no related error will be thrown.
+ * - There is no interface `HTMLElement`, it is always an `Element`.
+ * - There is no support for a second argument to indicate using custom elements.
+ *
+ * @param {string} tagName
+ * @returns {Element}
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement
+ * @see https://dom.spec.whatwg.org/#dom-document-createelement
+ * @see https://dom.spec.whatwg.org/#concept-create-element
+ */
+ createElement: function (tagName) {
+ var node = new Element(PDC);
+ node.ownerDocument = this;
+ if (this.type === 'html') {
+ tagName = tagName.toLowerCase();
+ }
+ if (hasDefaultHTMLNamespace(this.contentType)) {
+ node.namespaceURI = NAMESPACE.HTML;
+ }
+ node.nodeName = tagName;
+ node.tagName = tagName;
+ node.localName = tagName;
+ node.childNodes = new NodeList();
+ var attrs = (node.attributes = new NamedNodeMap());
+ attrs._ownerElement = node;
+ return node;
+ },
+ /**
+ * @returns {DocumentFragment}
+ */
+ createDocumentFragment: function () {
+ var node = new DocumentFragment(PDC);
+ node.ownerDocument = this;
+ node.childNodes = new NodeList();
+ return node;
+ },
+ /**
+ * @param {string} data
+ * @returns {Text}
+ */
+ createTextNode: function (data) {
+ var node = new Text(PDC);
+ node.ownerDocument = this;
+ node.childNodes = new NodeList();
+ node.appendData(data);
+ return node;
+ },
+ /**
+ * @param {string} data
+ * @returns {Comment}
+ * @see https://dom.spec.whatwg.org/#dom-document-createcomment
+ * @see https://www.w3.org/TR/xml/#NT-Comment XML 1.0 production [15]
+ * @see https://www.w3.org/TR/DOM-Parsing/#dfn-concept-serialize-xml §3.2.1.3
+ *
+ * Note: no validation is performed at creation time. When the resulting document is
+ * serialized with `requireWellFormed: true`, the serializer throws `InvalidStateError`
+ * if the comment data contains `--` anywhere, ends with `-`, or contains characters
+ * outside the XML Char production (W3C DOM Parsing §3.2.1.3). Without that option the
+ * data is emitted verbatim.
+ */
+ createComment: function (data) {
+ var node = new Comment(PDC);
+ node.ownerDocument = this;
+ node.childNodes = new NodeList();
+ node.appendData(data);
+ return node;
+ },
+ /**
+ * Returns a new CDATASection node whose data is `data`.
+ *
+ * __This implementation differs from the specification:__ - calling this method on an HTML
+ * document does not throw `NotSupportedError`.
+ *
+ * @param {string} data
+ * @returns {CDATASection}
+ * @throws {DOMException}
+ * With code `INVALID_CHARACTER_ERR` if `data` contains `"]]>"`.
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/createCDATASection
+ * @see https://dom.spec.whatwg.org/#dom-document-createcdatasection
+ */
+ createCDATASection: function (data) {
+ if (data.indexOf(']]>') !== -1) {
+ throw new DOMException(DOMException.INVALID_CHARACTER_ERR, 'data contains "]]>"');
+ }
+ var node = new CDATASection(PDC);
+ node.ownerDocument = this;
+ node.childNodes = new NodeList();
+ node.appendData(data);
+ return node;
+ },
+ /**
+ * Returns a ProcessingInstruction node whose target is target and data is data.
+ *
+ * __This behavior is slightly different from the in the specs__:
+ * - it does not do any input validation on the arguments and doesn't throw
+ * "InvalidCharacterError".
+ *
+ * Note: When the resulting document is serialized with `requireWellFormed: true`, the
+ * serializer throws `InvalidStateError` if `.target` is not a valid XML `NCName` (a `Name`
+ * with no colon) or is an ASCII case-insensitive match for `"xml"`, or if `.data` contains
+ * `?>` or characters outside the XML Char production (W3C DOM Parsing §3.2.1.7). Without that
+ * option the target and data are emitted verbatim.
+ *
+ * @param {string} target
+ * @param {string} data
+ * @returns {ProcessingInstruction}
+ * @see https://developer.mozilla.org/docs/Web/API/Document/createProcessingInstruction
+ * @see https://dom.spec.whatwg.org/#dom-document-createprocessinginstruction
+ * @see https://www.w3.org/TR/DOM-Parsing/#dfn-concept-serialize-xml §3.2.1.7
+ */
+ createProcessingInstruction: function (target, data) {
+ var node = new ProcessingInstruction(PDC);
+ node.ownerDocument = this;
+ node.childNodes = new NodeList();
+ node.nodeName = node.target = target;
+ node.nodeValue = node.data = data;
+ return node;
+ },
+ /**
+ * Creates an `Attr` node that is owned by this document.
+ * In HTML Documents `localName` is the lower cased `name`,
+ * otherwise no transformation is being applied.
+ *
+ * __This implementation differs from the specification:__ - The provided name is not checked
+ * against the `Name` production,
+ * so no related error will be thrown.
+ *
+ * @param {string} name
+ * @returns {Attr}
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/createAttribute
+ * @see https://dom.spec.whatwg.org/#dom-document-createattribute
+ */
+ createAttribute: function (name) {
+ if (!g.QName_exact.test(name)) {
+ throw new DOMException(DOMException.INVALID_CHARACTER_ERR, 'invalid character in name "' + name + '"');
+ }
+ if (this.type === 'html') {
+ name = name.toLowerCase();
+ }
+ return this._createAttribute(name);
+ },
+ _createAttribute: function (name) {
+ var node = new Attr(PDC);
+ node.ownerDocument = this;
+ node.childNodes = new NodeList();
+ node.name = name;
+ node.nodeName = name;
+ node.localName = name;
+ node.specified = true;
+ return node;
+ },
+ /**
+ * Creates an EntityReference object.
+ * The current implementation does not fill the `childNodes` with those of the corresponding
+ * `Entity`
+ *
+ * The `name` is validated against the XML `Name` production at creation time; an invalid name
+ * throws `InvalidCharacterError`. When the resulting node is serialized with
+ * `requireWellFormed: true`, the serializer re-validates `nodeName` against the XML `Name`
+ * production and throws `InvalidStateError` if a later `nodeName` mutation made it invalid;
+ * without that option the name is emitted verbatim.
+ *
+ * __This implementation differs from the specification:__ xmldom does not expand entities —
+ * the parser resolves entity references inline and never constructs `EntityReference` nodes,
+ * so this method is the only producer.
+ *
+ * @deprecated
+ * In DOM Level 4.
+ * @param {string} name
+ * The name of the entity to reference. No namespace well-formedness checks are performed.
+ * @returns {EntityReference}
+ * @throws {DOMException}
+ * With code `INVALID_CHARACTER_ERR` when `name` is not a valid XML `Name`.
+ * @throws {DOMException}
+ * with code `NOT_SUPPORTED_ERR` when the document is of type `html`
+ * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-392B75AE
+ */
+ createEntityReference: function (name) {
+ if (!g.Name_exact.test(name)) {
+ throw new DOMException(DOMException.INVALID_CHARACTER_ERR, 'not a valid xml name "' + name + '"');
+ }
+ if (this.type === 'html') {
+ throw new DOMException('document is an html document', DOMExceptionName.NotSupportedError);
+ }
+
+ var node = new EntityReference(PDC);
+ node.ownerDocument = this;
+ node.childNodes = new NodeList();
+ node.nodeName = name;
+ return node;
+ },
+ // Introduced in DOM Level 2:
+ /**
+ * @param {string} namespaceURI
+ * @param {string} qualifiedName
+ * @returns {Element}
+ */
+ createElementNS: function (namespaceURI, qualifiedName) {
+ var validated = validateAndExtract(namespaceURI, qualifiedName);
+ var node = new Element(PDC);
+ var attrs = (node.attributes = new NamedNodeMap());
+ node.childNodes = new NodeList();
+ node.ownerDocument = this;
+ node.nodeName = qualifiedName;
+ node.tagName = qualifiedName;
+ node.namespaceURI = validated[0];
+ node.prefix = validated[1];
+ node.localName = validated[2];
+ attrs._ownerElement = node;
+ return node;
+ },
+ // Introduced in DOM Level 2:
+ /**
+ * @param {string} namespaceURI
+ * @param {string} qualifiedName
+ * @returns {Attr}
+ */
+ createAttributeNS: function (namespaceURI, qualifiedName) {
+ var validated = validateAndExtract(namespaceURI, qualifiedName);
+ var node = new Attr(PDC);
+ node.ownerDocument = this;
+ node.childNodes = new NodeList();
+ node.nodeName = qualifiedName;
+ node.name = qualifiedName;
+ node.specified = true;
+ node.namespaceURI = validated[0];
+ node.prefix = validated[1];
+ node.localName = validated[2];
+ return node;
+ },
+};
+_extends(Document, Node);
+
+function Element(symbol) {
+ checkSymbol(symbol);
+
+ this._nsMap = Object.create(null);
+}
+Element.prototype = {
+ nodeType: ELEMENT_NODE,
+ /**
+ * The attributes of this element.
+ *
+ * @type {NamedNodeMap | null}
+ */
+ attributes: null,
+ getQualifiedName: function () {
+ return this.prefix ? this.prefix + ':' + this.localName : this.localName;
+ },
+ _isInHTMLDocumentAndNamespace: function () {
+ return this.ownerDocument.type === 'html' && this.namespaceURI === NAMESPACE.HTML;
+ },
+ /**
+ * Implementaton of Level2 Core function hasAttributes.
+ *
+ * @returns {boolean}
+ * True if attribute list is not empty.
+ * @see https://www.w3.org/TR/DOM-Level-2-Core/#core-ID-NodeHasAttrs
+ */
+ hasAttributes: function () {
+ return !!(this.attributes && this.attributes.length);
+ },
+ hasAttribute: function (name) {
+ return !!this.getAttributeNode(name);
+ },
+ /**
+ * Returns element’s first attribute whose qualified name is `name`, and `null`
+ * if there is no such attribute.
+ *
+ * @param {string} name
+ * @returns {string | null}
+ */
+ getAttribute: function (name) {
+ var attr = this.getAttributeNode(name);
+ return attr ? attr.value : null;
+ },
+ getAttributeNode: function (name) {
+ if (this._isInHTMLDocumentAndNamespace()) {
+ name = name.toLowerCase();
+ }
+ return this.attributes.getNamedItem(name);
+ },
+ /**
+ * Sets the value of element’s first attribute whose qualified name is qualifiedName to value.
+ *
+ * @param {string} name
+ * @param {string} value
+ */
+ setAttribute: function (name, value) {
+ if (this._isInHTMLDocumentAndNamespace()) {
+ name = name.toLowerCase();
+ }
+ var attr = this.getAttributeNode(name);
+ if (attr) {
+ attr.value = attr.nodeValue = '' + value;
+ } else {
+ attr = this.ownerDocument._createAttribute(name);
+ attr.value = attr.nodeValue = '' + value;
+ this.setAttributeNode(attr);
+ }
+ },
+ removeAttribute: function (name) {
+ var attr = this.getAttributeNode(name);
+ attr && this.removeAttributeNode(attr);
+ },
+ setAttributeNode: function (newAttr) {
+ return this.attributes.setNamedItem(newAttr);
+ },
+ setAttributeNodeNS: function (newAttr) {
+ return this.attributes.setNamedItemNS(newAttr);
+ },
+ removeAttributeNode: function (oldAttr) {
+ //console.log(this == oldAttr.ownerElement)
+ return this.attributes.removeNamedItem(oldAttr.nodeName);
+ },
+ //get real attribute name,and remove it by removeAttributeNode
+ removeAttributeNS: function (namespaceURI, localName) {
+ var old = this.getAttributeNodeNS(namespaceURI, localName);
+ old && this.removeAttributeNode(old);
+ },
+
+ hasAttributeNS: function (namespaceURI, localName) {
+ return this.getAttributeNodeNS(namespaceURI, localName) != null;
+ },
+ /**
+ * Returns element’s attribute whose namespace is `namespaceURI` and local name is
+ * `localName`,
+ * or `null` if there is no such attribute.
+ *
+ * @param {string} namespaceURI
+ * @param {string} localName
+ * @returns {string | null}
+ */
+ getAttributeNS: function (namespaceURI, localName) {
+ var attr = this.getAttributeNodeNS(namespaceURI, localName);
+ return attr ? attr.value : null;
+ },
+ /**
+ * Sets the value of element’s attribute whose namespace is `namespaceURI` and local name is
+ * `localName` to value.
+ *
+ * @param {string} namespaceURI
+ * @param {string} qualifiedName
+ * @param {string} value
+ * @see https://dom.spec.whatwg.org/#dom-element-setattributens
+ */
+ setAttributeNS: function (namespaceURI, qualifiedName, value) {
+ var validated = validateAndExtract(namespaceURI, qualifiedName);
+ var localName = validated[2];
+ var attr = this.getAttributeNodeNS(namespaceURI, localName);
+ if (attr) {
+ attr.value = attr.nodeValue = '' + value;
+ } else {
+ attr = this.ownerDocument.createAttributeNS(namespaceURI, qualifiedName);
+ attr.value = attr.nodeValue = '' + value;
+ this.setAttributeNode(attr);
+ }
+ },
+ getAttributeNodeNS: function (namespaceURI, localName) {
+ return this.attributes.getNamedItemNS(namespaceURI, localName);
+ },
+
+ /**
+ * Returns a LiveNodeList of all child elements which have **all** of the given class name(s).
+ *
+ * Returns an empty list if `classNames` is an empty string or only contains HTML white space
+ * characters.
+ *
+ * Warning: This returns a live LiveNodeList.
+ * Changes in the DOM will reflect in the array as the changes occur.
+ * If an element selected by this array no longer qualifies for the selector,
+ * it will automatically be removed. Be aware of this for iteration purposes.
+ *
+ * @param {string} classNames
+ * Is a string representing the class name(s) to match; multiple class names are separated by
+ * (ASCII-)whitespace.
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/getElementsByClassName
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName
+ * @see https://dom.spec.whatwg.org/#concept-getelementsbyclassname
+ */
+ getElementsByClassName: function (classNames) {
+ var classNamesSet = toOrderedSet(classNames);
+ return new LiveNodeList(this, function (base) {
+ var ls = [];
+ if (classNamesSet.length > 0) {
+ _visitNode(base, function (node) {
+ if (node !== base && node.nodeType === ELEMENT_NODE) {
+ var nodeClassNames = node.getAttribute('class');
+ // can be null if the attribute does not exist
+ if (nodeClassNames) {
+ // before splitting and iterating just compare them for the most common case
+ var matches = classNames === nodeClassNames;
+ if (!matches) {
+ var nodeClassNamesSet = toOrderedSet(nodeClassNames);
+ matches = classNamesSet.every(arrayIncludes(nodeClassNamesSet));
+ }
+ if (matches) {
+ ls.push(node);
+ }
+ }
+ }
+ });
+ }
+ return ls;
+ });
+ },
+
+ /**
+ * Returns a LiveNodeList of elements with the given qualifiedName.
+ * Searching for all descendants can be done by passing `*` as `qualifiedName`.
+ *
+ * All descendants of the specified element are searched, but not the element itself.
+ * The returned list is live, which means it updates itself with the DOM tree automatically.
+ * Therefore, there is no need to call `Element.getElementsByTagName()`
+ * with the same element and arguments repeatedly if the DOM changes in between calls.
+ *
+ * When called on an HTML element in an HTML document,
+ * `getElementsByTagName` lower-cases the argument before searching for it.
+ * This is undesirable when trying to match camel-cased SVG elements (such as
+ * ``) in an HTML document.
+ * Instead, use `Element.getElementsByTagNameNS()`,
+ * which preserves the capitalization of the tag name.
+ *
+ * `Element.getElementsByTagName` is similar to `Document.getElementsByTagName()`,
+ * except that it only searches for elements that are descendants of the specified element.
+ *
+ * @param {string} qualifiedName
+ * @returns {LiveNodeList}
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/getElementsByTagName
+ * @see https://dom.spec.whatwg.org/#concept-getelementsbytagname
+ */
+ getElementsByTagName: function (qualifiedName) {
+ var isHTMLDocument = (this.nodeType === DOCUMENT_NODE ? this : this.ownerDocument).type === 'html';
+ var lowerQualifiedName = qualifiedName.toLowerCase();
+ return new LiveNodeList(this, function (base) {
+ var ls = [];
+ _visitNode(base, function (node) {
+ if (node === base || node.nodeType !== ELEMENT_NODE) {
+ return;
+ }
+ if (qualifiedName === '*') {
+ ls.push(node);
+ } else {
+ var nodeQualifiedName = node.getQualifiedName();
+ var matchingQName = isHTMLDocument && node.namespaceURI === NAMESPACE.HTML ? lowerQualifiedName : qualifiedName;
+ if (nodeQualifiedName === matchingQName) {
+ ls.push(node);
+ }
+ }
+ });
+ return ls;
+ });
+ },
+ getElementsByTagNameNS: function (namespaceURI, localName) {
+ return new LiveNodeList(this, function (base) {
+ var ls = [];
+ _visitNode(base, function (node) {
+ if (
+ node !== base &&
+ node.nodeType === ELEMENT_NODE &&
+ (namespaceURI === '*' || node.namespaceURI === namespaceURI) &&
+ (localName === '*' || node.localName == localName)
+ ) {
+ ls.push(node);
+ }
+ });
+ return ls;
+ });
+ },
+};
+Document.prototype.getElementsByClassName = Element.prototype.getElementsByClassName;
+Document.prototype.getElementsByTagName = Element.prototype.getElementsByTagName;
+Document.prototype.getElementsByTagNameNS = Element.prototype.getElementsByTagNameNS;
+
+_extends(Element, Node);
+function Attr(symbol) {
+ checkSymbol(symbol);
+
+ this.namespaceURI = null;
+ this.prefix = null;
+ this.ownerElement = null;
+}
+Attr.prototype.nodeType = ATTRIBUTE_NODE;
+_extends(Attr, Node);
+
+function CharacterData(symbol) {
+ checkSymbol(symbol);
+}
+CharacterData.prototype = {
+ data: '',
+ substringData: function (offset, count) {
+ return this.data.substring(offset, offset + count);
+ },
+ appendData: function (text) {
+ text = this.data + text;
+ this.nodeValue = this.data = text;
+ this.length = text.length;
+ },
+ insertData: function (offset, text) {
+ this.replaceData(offset, 0, text);
+ },
+ deleteData: function (offset, count) {
+ this.replaceData(offset, count, '');
+ },
+ replaceData: function (offset, count, text) {
+ var start = this.data.substring(0, offset);
+ var end = this.data.substring(offset + count);
+ text = start + text + end;
+ this.nodeValue = this.data = text;
+ this.length = text.length;
+ },
+};
+_extends(CharacterData, Node);
+function Text(symbol) {
+ checkSymbol(symbol);
+}
+Text.prototype = {
+ nodeName: '#text',
+ nodeType: TEXT_NODE,
+ splitText: function (offset) {
+ var text = this.data;
+ var newText = text.substring(offset);
+ text = text.substring(0, offset);
+ this.data = this.nodeValue = text;
+ this.length = text.length;
+ var newNode = this.ownerDocument.createTextNode(newText);
+ if (this.parentNode) {
+ this.parentNode.insertBefore(newNode, this.nextSibling);
+ }
+ return newNode;
+ },
+};
+_extends(Text, CharacterData);
+function Comment(symbol) {
+ checkSymbol(symbol);
+}
+Comment.prototype = {
+ nodeName: '#comment',
+ nodeType: COMMENT_NODE,
+};
+_extends(Comment, CharacterData);
+
+function CDATASection(symbol) {
+ checkSymbol(symbol);
+}
+CDATASection.prototype = {
+ nodeName: '#cdata-section',
+ nodeType: CDATA_SECTION_NODE,
+};
+_extends(CDATASection, Text);
+
+/**
+ * @class DocumentType
+ * @augments Node
+ * @property {string} name
+ * The doctype name, stored verbatim. Declared `readonly` by the WHATWG DOM spec; xmldom does
+ * not enforce this constraint — direct property writes succeed and the written value is
+ * serialized verbatim. When serialized with `requireWellFormed: true`, the serializer
+ * validates the value against the XML `Name` production and throws `InvalidStateError` if it
+ * does not match.
+ * @property {string} publicId
+ * The external subset public identifier, stored verbatim (including surrounding quotes).
+ * Declared `readonly` by the WHATWG DOM spec; xmldom does not enforce this constraint —
+ * direct property writes succeed and the written value is serialized verbatim.
+ * When serialized with `requireWellFormed: true`, the serializer validates the value against
+ * the XML `PubidLiteral` production and throws `InvalidStateError` if it does not match.
+ * @property {string} systemId
+ * The external subset system identifier, stored verbatim (including surrounding quotes).
+ * Declared `readonly` by the WHATWG DOM spec; xmldom does not enforce this constraint —
+ * direct property writes succeed and the written value is serialized verbatim.
+ * When serialized with `requireWellFormed: true`, the serializer validates the value against
+ * the XML `SystemLiteral` production and throws `InvalidStateError` if it does not match.
+ * @property {string} internalSubset
+ * The internal subset string (the raw content between `[` and `]`), or an empty string.
+ * Declared `readonly` by the WHATWG DOM spec; xmldom does not enforce this constraint —
+ * direct property writes succeed and the written value is serialized verbatim.
+ * When serialized with `requireWellFormed: true`, the serializer throws `InvalidStateError`
+ * if the value contains `"]>"`.
+ * @see https://developer.mozilla.org/docs/Web/API/DocumentType MDN
+ * @see https://dom.spec.whatwg.org/#interface-documenttype WHATWG DOM
+ * @prettierignore
+ */
+function DocumentType(symbol) {
+ checkSymbol(symbol);
+}
+DocumentType.prototype.nodeType = DOCUMENT_TYPE_NODE;
+_extends(DocumentType, Node);
+
+function Notation(symbol) {
+ checkSymbol(symbol);
+}
+Notation.prototype.nodeType = NOTATION_NODE;
+_extends(Notation, Node);
+
+function Entity(symbol) {
+ checkSymbol(symbol);
+}
+Entity.prototype.nodeType = ENTITY_NODE;
+_extends(Entity, Node);
+
+/**
+ * Represents an EntityReference node, serialized as `&nodeName;`.
+ *
+ * `nodeName` is the referenced entity's name, stored verbatim. When serialized with
+ * `requireWellFormed: true`, the serializer validates `nodeName` against the XML `Name`
+ * production and throws `InvalidStateError` if it does not match; without that option the name
+ * is emitted verbatim between `&` and `;`.
+ *
+ * __This implementation differs from the specification:__ xmldom does not expand entities —
+ * the parser resolves entity references inline and never constructs `EntityReference` nodes,
+ * so the only producer is {@link Document#createEntityReference}.
+ *
+ * @class
+ * @see https://www.w3.org/TR/xml/#NT-Name
+ */
+function EntityReference(symbol) {
+ checkSymbol(symbol);
+}
+EntityReference.prototype.nodeType = ENTITY_REFERENCE_NODE;
+_extends(EntityReference, Node);
+
+function DocumentFragment(symbol) {
+ checkSymbol(symbol);
+}
+DocumentFragment.prototype.nodeName = '#document-fragment';
+DocumentFragment.prototype.nodeType = DOCUMENT_FRAGMENT_NODE;
+_extends(DocumentFragment, Node);
+
+function ProcessingInstruction(symbol) {
+ checkSymbol(symbol);
+}
+ProcessingInstruction.prototype.nodeType = PROCESSING_INSTRUCTION_NODE;
+_extends(ProcessingInstruction, CharacterData);
+function XMLSerializer() {}
+/**
+ * Returns the result of serializing `node` to XML.
+ *
+ * When `options.requireWellFormed` is `true`, the serializer throws `InvalidStateError` for
+ * content that would produce ill-formed XML (e.g. CDATASection data containing `"]]>"`, Text
+ * data containing characters outside the XML Char production, or a Document with no
+ * `documentElement`).
+ *
+ * When `options.splitCDATASections` is `false`, CDATASection data is emitted verbatim even
+ * when it contains `"]]>"`. When `true` (the default), `"]]>"` sequences are split across
+ * concatenated CDATA sections — this behavior is **deprecated** and will be removed in the
+ * next breaking release. Callers should migrate to `{ requireWellFormed: true }`, which throws
+ * `InvalidStateError` instead of transforming.
+ *
+ * __This implementation differs from the specification:__ - CDATASection serialization is not
+ * specified by W3C DOM Parsing or WHATWG DOM Parsing (see
+ * {@link https://github.com/w3c/DOM-Parsing/issues/38 w3c/DOM-Parsing#38}).
+ * When `splitCDATASections` is `true` (the default), `"]]>"` sequences in CDATASection data
+ * are split across concatenated CDATA sections — this mechanism is derived from DOM Level 3
+ * Core and is **deprecated**. The split mechanics will be removed in the next breaking
+ * release. Callers that rely on this behavior should migrate to `{ requireWellFormed: true }`.
+ * - W3C DOM Parsing §3.2.1.1 requires well-formedness checks on Element `localName`s,
+ * prefixes,
+ * and attribute serialization (duplicate attributes, namespace declarations, attribute value
+ * characters) when `requireWellFormed` is `true`. Element and attribute qualified names (which
+ * cover the namespace prefix) are validated against the XML `QName` production; the remaining
+ * §3.2.1.1 checks (duplicate attributes, namespace-declaration consistency) and creation-time
+ * name validation are **not implemented** in this release — see the tracking issue filed
+ * against the next breaking milestone.
+ *
+ * @param {Node} node
+ * @param {Object | function} [options]
+ * Options object, or a legacy nodeFilter function (backward compatible).
+ * @param {boolean} [options.requireWellFormed=false]
+ * When `true`, throws `InvalidStateError` for content that would produce ill-formed XML.
+ * @param {boolean} [options.splitCDATASections=true]
+ * When `true` (default), splits `"]]>"` sequences in CDATASection data across concatenated
+ * CDATA sections. **Deprecated** — will be removed in the next breaking release.
+ * @param {function} [options.nodeFilter]
+ * A filter function applied to each node before serialization.
+ * @returns {string}
+ * @throws {DOMException}
+ * With name `InvalidStateError` when `requireWellFormed` is `true` and any of the following
+ * conditions hold:
+ * - an Element's qualified name (including any namespace prefix) is not a valid XML QName
+ * - an attribute's qualified name (including a synthesized `xmlns:` namespace declaration) is
+ * not a valid XML QName
+ * - CDATASection data contains `"]]>"`
+ * - Text data contains characters outside the XML Char production
+ * - a Comment node's data contains `--` anywhere or ends with `-`
+ * - a ProcessingInstruction's target is not a valid XML `NCName` (a `Name` with no colon) or is
+ * an ASCII case-insensitive match for `"xml"`, or its data contains `?>` or characters outside
+ * the XML Char production
+ * - a DocumentType's `name` is not a valid XML `Name` (XML 1.0 production [5])
+ * - a DocumentType's `publicId` is non-empty and does not match the XML `PubidLiteral`
+ * production (W3C DOM Parsing §3.2.1.3; XML 1.0 production [12])
+ * - a DocumentType's `systemId` is non-empty and does not match the XML `SystemLiteral`
+ * production (W3C DOM Parsing §3.2.1.3; XML 1.0 production [11])
+ * - a DocumentType's `internalSubset` contains `"]>"`
+ * - an EntityReference's `nodeName` is not a valid XML `Name` (XML 1.0 production [5])
+ * - the Document has no `documentElement`
+ * @see https://developer.mozilla.org/docs/Web/API/XMLSerializer/serializeToString
+ * @see https://html.spec.whatwg.org/#dom-xmlserializer-serializetostring
+ * @see https://github.com/w3c/DOM-Parsing/issues/84
+ * @prettierignore
+ */
+XMLSerializer.prototype.serializeToString = function (node, options) {
+ return nodeSerializeToString.call(node, options);
+};
+Node.prototype.toString = nodeSerializeToString;
+function nodeSerializeToString(options) {
+ // Normalize the user-supplied options into a single internal opts object so that the
+ // internal serializer always works with a consistent shape rather than positional flags.
+ var opts;
+ if (typeof options === 'function') {
+ opts = { requireWellFormed: false, splitCDATASections: true, nodeFilter: options };
+ } else if (options != null) {
+ opts = {
+ requireWellFormed: !!options.requireWellFormed,
+ splitCDATASections: options.splitCDATASections !== false,
+ nodeFilter: options.nodeFilter || null,
+ };
+ } else {
+ opts = { requireWellFormed: false, splitCDATASections: true, nodeFilter: null };
+ }
+ var buf = [];
+ var refNode = (this.nodeType === DOCUMENT_NODE && this.documentElement) || this;
+ var prefix = refNode.prefix;
+ var uri = refNode.namespaceURI;
+
+ if (uri && prefix == null) {
+ var prefix = refNode.lookupPrefix(uri);
+ if (prefix == null) {
+ var visibleNamespaces = [
+ { namespace: uri, prefix: null },
+ //{namespace:uri,prefix:''}
+ ];
+ }
+ }
+ serializeToString(this, buf, visibleNamespaces, opts);
+ return buf.join('');
+}
+
+function needNamespaceDefine(node, isHTML, visibleNamespaces) {
+ var prefix = node.prefix || '';
+ var uri = node.namespaceURI;
+ // According to [Namespaces in XML 1.0](https://www.w3.org/TR/REC-xml-names/#ns-using) ,
+ // and more specifically https://www.w3.org/TR/REC-xml-names/#nsc-NoPrefixUndecl :
+ // > In a namespace declaration for a prefix [...], the attribute value MUST NOT be empty.
+ // in a similar manner [Namespaces in XML 1.1](https://www.w3.org/TR/xml-names11/#ns-using)
+ // and more specifically https://www.w3.org/TR/xml-names11/#nsc-NSDeclared :
+ // > [...] Furthermore, the attribute value [...] must not be an empty string.
+ // so serializing empty namespace value like xmlns:ds="" would produce an invalid XML document.
+ if (!uri) {
+ return false;
+ }
+ if ((prefix === 'xml' && uri === NAMESPACE.XML) || uri === NAMESPACE.XMLNS) {
+ return false;
+ }
+
+ var i = visibleNamespaces.length;
+ while (i--) {
+ var ns = visibleNamespaces[i];
+ // get namespace prefix
+ if (ns.prefix === prefix) {
+ return ns.namespace !== uri;
+ }
+ }
+ return true;
+}
+/**
+ * Literal whitespace other than space that appear in attribute values are serialized as
+ * their entity references, so they will be preserved.
+ * (In contrast to whitespace literals in the input which are normalized to spaces).
+ *
+ * Well-formed constraint: No < in Attribute Values:
+ * > The replacement text of any entity referred to directly or indirectly
+ * > in an attribute value must not contain a <.
+ *
+ * @see https://www.w3.org/TR/xml11/#CleanAttrVals
+ * @see https://www.w3.org/TR/xml11/#NT-AttValue
+ * @see https://www.w3.org/TR/xml11/#AVNormalize
+ * @see https://w3c.github.io/DOM-Parsing/#serializing-an-element-s-attributes
+ * @prettierignore
+ */
+function addSerializedAttribute(buf, qualifiedName, value, requireWellFormed) {
+ if (requireWellFormed && !g.QName_exact.test(qualifiedName)) {
+ throw new DOMException(
+ 'The attribute name "' + qualifiedName + '" is not a valid XML QName',
+ DOMExceptionName.InvalidStateError
+ );
+ }
+ buf.push(' ', qualifiedName, '="', value.replace(/[<>&"\t\n\r]/g, _xmlEncoder), '"');
+}
+
+function serializeToString(node, buf, visibleNamespaces, opts) {
+ if (!visibleNamespaces) {
+ visibleNamespaces = [];
+ }
+ var nodeFilter = opts.nodeFilter;
+ var requireWellFormed = opts.requireWellFormed;
+ var splitCDATASections = opts.splitCDATASections;
+ var doc = node.nodeType === DOCUMENT_NODE ? node : node.ownerDocument;
+ var isHTML = doc.type === 'html';
+
+ walkDOM(
+ node,
+ { ns: visibleNamespaces },
+ {
+ enter: function (n, ctx) {
+ var namespaces = ctx.ns;
+
+ if (nodeFilter) {
+ n = nodeFilter(n);
+ if (n) {
+ if (typeof n == 'string') {
+ buf.push(n);
+ return null;
+ }
+ } else {
+ return null;
+ }
+ }
+
+ switch (n.nodeType) {
+ case ELEMENT_NODE:
+ var attrs = n.attributes;
+ var len = attrs.length;
+ var nodeName = n.tagName;
+
+ var prefixedNodeName = nodeName;
+ if (!isHTML && !n.prefix && n.namespaceURI) {
+ var defaultNS;
+ // lookup current default ns from `xmlns` attribute
+ for (var ai = 0; ai < attrs.length; ai++) {
+ if (attrs.item(ai).name === 'xmlns') {
+ defaultNS = attrs.item(ai).value;
+ break;
+ }
+ }
+ if (!defaultNS) {
+ // lookup current default ns in visibleNamespaces
+ for (var nsi = namespaces.length - 1; nsi >= 0; nsi--) {
+ var nsEntry = namespaces[nsi];
+ if (nsEntry.prefix === '' && nsEntry.namespace === n.namespaceURI) {
+ defaultNS = nsEntry.namespace;
+ break;
+ }
+ }
+ }
+ if (defaultNS !== n.namespaceURI) {
+ for (var nsi = namespaces.length - 1; nsi >= 0; nsi--) {
+ var nsEntry = namespaces[nsi];
+ if (nsEntry.namespace === n.namespaceURI) {
+ if (nsEntry.prefix) {
+ prefixedNodeName = nsEntry.prefix + ':' + nodeName;
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ if (requireWellFormed && !g.QName_exact.test(prefixedNodeName)) {
+ throw new DOMException(
+ 'The element name "' + prefixedNodeName + '" is not a valid XML QName',
+ DOMExceptionName.InvalidStateError
+ );
+ }
+
+ buf.push('<', prefixedNodeName);
+
+ // Build a fresh namespace snapshot for this element's children.
+ // The slice prevents sibling elements from inheriting each other's declarations.
+ var childNamespaces = namespaces.slice();
+
+ for (var i = 0; i < len; i++) {
+ // add namespaces for attributes
+ var attr = attrs.item(i);
+ if (attr.prefix == 'xmlns') {
+ childNamespaces.push({
+ prefix: attr.localName,
+ namespace: attr.value,
+ });
+ } else if (attr.nodeName == 'xmlns') {
+ childNamespaces.push({ prefix: '', namespace: attr.value });
+ }
+ }
+
+ for (var i = 0; i < len; i++) {
+ var attr = attrs.item(i);
+ if (needNamespaceDefine(attr, isHTML, childNamespaces)) {
+ var attrPrefix = attr.prefix || '';
+ var uri = attr.namespaceURI;
+ addSerializedAttribute(buf, attrPrefix ? 'xmlns:' + attrPrefix : 'xmlns', uri, requireWellFormed);
+ childNamespaces.push({ prefix: attrPrefix, namespace: uri });
+ }
+ // Apply nodeFilter and serialize the attribute.
+ var filteredAttr = nodeFilter ? nodeFilter(attr) : attr;
+ if (filteredAttr) {
+ if (typeof filteredAttr === 'string') {
+ buf.push(filteredAttr);
+ } else {
+ addSerializedAttribute(buf, filteredAttr.name, filteredAttr.value, requireWellFormed);
+ }
+ }
+ }
+
+ // add namespace for current node
+ if (nodeName === prefixedNodeName && needNamespaceDefine(n, isHTML, childNamespaces)) {
+ var nodePrefix = n.prefix || '';
+ var uri = n.namespaceURI;
+ addSerializedAttribute(buf, nodePrefix ? 'xmlns:' + nodePrefix : 'xmlns', uri, requireWellFormed);
+ childNamespaces.push({ prefix: nodePrefix, namespace: uri });
+ }
+
+ // in XML elements can be closed when they have no children
+ var canCloseTag = !n.firstChild;
+ if (canCloseTag && (isHTML || n.namespaceURI === NAMESPACE.HTML)) {
+ // in HTML (doc or ns) only void elements can be closed right away
+ canCloseTag = isHTMLVoidElement(nodeName);
+ }
+ if (canCloseTag) {
+ buf.push('/>');
+ // Self-closing: no children and no closing tag needed from exit.
+ return null;
+ }
+
+ buf.push('>');
+
+ // HTML raw text elements: serialize children as raw data without further descent.
+ if (isHTML && isHTMLRawTextElement(nodeName)) {
+ var child = n.firstChild;
+ while (child) {
+ if (child.data) {
+ buf.push(child.data);
+ } else {
+ serializeToString(child, buf, childNamespaces.slice(), opts);
+ }
+ child = child.nextSibling;
+ }
+ buf.push('', prefixedNodeName, '>');
+ // Children handled manually above; prevent walkDOM from also traversing them.
+ return null;
+ }
+
+ // Return child context so walkDOM descends; exit will emit the closing tag.
+ return { ns: childNamespaces, tag: prefixedNodeName };
+ case DOCUMENT_NODE:
+ case DOCUMENT_FRAGMENT_NODE:
+ if (requireWellFormed && n.nodeType === DOCUMENT_NODE && n.documentElement == null) {
+ throw new DOMException('The Document has no documentElement', DOMExceptionName.InvalidStateError);
+ }
+ // Pass namespaces through; each child element will slice independently.
+ return { ns: namespaces };
+ case ATTRIBUTE_NODE:
+ addSerializedAttribute(buf, n.name, n.value, requireWellFormed);
+ return null;
+ case TEXT_NODE:
+ /*
+ * The ampersand character (&) and the left angle bracket (<) must not appear in their literal form,
+ * except when used as markup delimiters, or within a comment, a processing instruction,
+ * or a CDATA section.
+ * If they are needed elsewhere, they must be escaped using either numeric character
+ * references or the strings `&` and `<` respectively.
+ * The right angle bracket (>) may be represented using the string " > ",
+ * and must, for compatibility, be escaped using either `>`,
+ * or a character reference when it appears in the string `]]>` in content,
+ * when that string is not marking the end of a CDATA section.
+ *
+ * In the content of elements, character data is any string of characters which does not
+ * contain the start-delimiter of any markup and does not include the CDATA-section-close
+ * delimiter, `]]>`.
+ *
+ * @see https://www.w3.org/TR/xml/#NT-CharData
+ * @see https://w3c.github.io/DOM-Parsing/#xml-serializing-a-text-node
+ */
+ if (requireWellFormed && g.InvalidChar.test(n.data)) {
+ throw new DOMException(
+ 'The Text node data contains characters outside the XML Char production',
+ DOMExceptionName.InvalidStateError
+ );
+ }
+ buf.push(n.data.replace(/[<&>]/g, _xmlEncoder));
+ return null;
+ case CDATA_SECTION_NODE:
+ if (requireWellFormed && n.data.indexOf(']]>') !== -1) {
+ throw new DOMException('The CDATASection data contains "]]>"', DOMExceptionName.InvalidStateError);
+ }
+ if (splitCDATASections) {
+ buf.push(g.CDATA_START, n.data.replace(/]]>/g, ']]]]>'), g.CDATA_END);
+ } else {
+ buf.push(g.CDATA_START, n.data, g.CDATA_END);
+ }
+ return null;
+ case COMMENT_NODE:
+ if (requireWellFormed) {
+ if (g.InvalidChar.test(n.data)) {
+ throw new DOMException(
+ 'The comment node data contains characters outside the XML Char production',
+ DOMExceptionName.InvalidStateError
+ );
+ }
+ if (n.data.indexOf('--') !== -1 || n.data[n.data.length - 1] === '-') {
+ throw new DOMException(
+ 'The comment node data contains "--" or ends with "-"',
+ DOMExceptionName.InvalidStateError
+ );
+ }
+ }
+ buf.push(g.COMMENT_START, n.data, g.COMMENT_END);
+ return null;
+ case DOCUMENT_TYPE_NODE:
+ var pubid = n.publicId;
+ var sysid = n.systemId;
+ if (requireWellFormed) {
+ if (!g.Name_exact.test(n.name)) {
+ throw new DOMException(
+ 'The doctype name "' + n.name + '" is not a valid XML Name',
+ DOMExceptionName.InvalidStateError
+ );
+ }
+ if (pubid && !g.PubidLiteral_match.test(pubid)) {
+ throw new DOMException('DocumentType publicId is not a valid PubidLiteral', DOMExceptionName.InvalidStateError);
+ }
+ if (sysid && sysid !== '.' && !g.SystemLiteral_match.test(sysid)) {
+ throw new DOMException('DocumentType systemId is not a valid SystemLiteral', DOMExceptionName.InvalidStateError);
+ }
+ if (n.internalSubset && n.internalSubset.indexOf(']>') !== -1) {
+ throw new DOMException('DocumentType internalSubset contains "]>"', DOMExceptionName.InvalidStateError);
+ }
+ }
+ buf.push(g.DOCTYPE_DECL_START, ' ', n.name);
+ if (pubid) {
+ buf.push(' ', g.PUBLIC, ' ', pubid);
+ if (sysid && sysid !== '.') {
+ buf.push(' ', sysid);
+ }
+ } else if (sysid && sysid !== '.') {
+ buf.push(' ', g.SYSTEM, ' ', sysid);
+ }
+ if (n.internalSubset) {
+ buf.push(' [', n.internalSubset, ']');
+ }
+ buf.push('>');
+ return null;
+ case PROCESSING_INSTRUCTION_NODE:
+ if (requireWellFormed) {
+ if (!g.NCName_exact.test(n.target) || n.target.toLowerCase() === 'xml') {
+ throw new DOMException(
+ 'The processing instruction target "' + n.target + '" is not a valid XML NCName or is reserved',
+ DOMExceptionName.InvalidStateError
+ );
+ }
+ if (g.InvalidChar.test(n.data)) {
+ throw new DOMException(
+ 'The ProcessingInstruction data contains characters outside the XML Char production',
+ DOMExceptionName.InvalidStateError
+ );
+ }
+ if (n.data.indexOf('?>') !== -1) {
+ throw new DOMException('The ProcessingInstruction data contains "?>"', DOMExceptionName.InvalidStateError);
+ }
+ }
+ buf.push('', n.target, ' ', n.data, '?>');
+ return null;
+ case ENTITY_REFERENCE_NODE:
+ if (requireWellFormed && !g.Name_exact.test(n.nodeName)) {
+ throw new DOMException(
+ 'The entity reference name "' + n.nodeName + '" is not a valid XML Name',
+ DOMExceptionName.InvalidStateError
+ );
+ }
+ buf.push('&', n.nodeName, ';');
+ return null;
+ //case ENTITY_NODE:
+ //case NOTATION_NODE:
+ default:
+ buf.push('??', n.nodeName);
+ return null;
+ }
+ },
+ exit: function (n, childCtx) {
+ // Emit the closing tag for elements that were opened (not self-closed, not raw text).
+ if (childCtx && childCtx.tag) {
+ buf.push('', childCtx.tag, '>');
+ }
+ },
+ }
+ );
+}
+/**
+ * Imports a node from a different document into `doc`, creating a new copy.
+ * Delegates to {@link walkDOM} for traversal. Each node in the subtree is shallow-cloned,
+ * stamped with `doc` as its `ownerDocument`, and detached (`parentNode` set to `null`).
+ * Children are imported recursively when `deep` is `true`; for {@link Attr} nodes `deep` is
+ * always forced to `true`
+ * because an attribute's value lives in a child text node.
+ *
+ * @param {Document} doc
+ * The document that will own the imported node.
+ * @param {Node} node
+ * The node to import.
+ * @param {boolean} deep
+ * If `true`, descendants are imported recursively.
+ * @returns {Node}
+ * The newly imported node, now owned by `doc`.
+ */
+function importNode(doc, node, deep) {
+ var destRoot;
+ walkDOM(node, null, {
+ enter: function (srcNode, destParent) {
+ // Shallow-clone the node and stamp it into the target document.
+ var destNode = srcNode.cloneNode(false);
+ destNode.ownerDocument = doc;
+ destNode.parentNode = null;
+ // capture as the root of the imported subtree or attach to parent.
+ if (destParent === null) {
+ destRoot = destNode;
+ } else {
+ destParent.appendChild(destNode);
+ }
+ // ATTRIBUTE_NODE must always be imported deeply: its value lives in a child text node.
+ var shouldDeep = srcNode.nodeType === ATTRIBUTE_NODE || deep;
+ return shouldDeep ? destNode : null;
+ },
+ });
+ return destRoot;
+}
+
+/**
+ * Creates a copy of a node from an existing one.
+ *
+ * @param {Document} doc
+ * The Document object representing the document that the new node will belong to.
+ * @param {Node} node
+ * The node to clone.
+ * @param {boolean} deep
+ * If true, the contents of the node are recursively copied.
+ * If false, only the node itself (and its attributes, if it is an element) are copied.
+ * @returns {Node}
+ * Returns the newly created copy of the node.
+ * @throws {DOMException}
+ * May throw a DOMException if operations within setAttributeNode or appendChild (which are
+ * potentially invoked in this function) do not meet their specific constraints.
+ */
+function cloneNode(doc, node, deep) {
+ var destRoot;
+ walkDOM(node, null, {
+ enter: function (srcNode, destParent) {
+ // 1. Create a blank node of the same type and copy all scalar own properties.
+ var destNode = new srcNode.constructor(PDC);
+ for (var n in srcNode) {
+ if (hasOwn(srcNode, n)) {
+ var v = srcNode[n];
+ if (typeof v != 'object') {
+ if (v != destNode[n]) {
+ destNode[n] = v;
+ }
+ }
+ }
+ }
+ if (srcNode.childNodes) {
+ destNode.childNodes = new NodeList();
+ }
+ destNode.ownerDocument = doc;
+ // 2. Handle node-type-specific setup.
+ // Attributes are not DOM children, so they are cloned inline here
+ // rather than by walkDOM descent.
+ // ATTRIBUTE_NODE forces deep=true so its own children are walked.
+ var shouldDeep = deep;
+ switch (destNode.nodeType) {
+ case ELEMENT_NODE:
+ var attrs = srcNode.attributes;
+ var attrs2 = (destNode.attributes = new NamedNodeMap());
+ var len = attrs.length;
+ attrs2._ownerElement = destNode;
+ for (var i = 0; i < len; i++) {
+ destNode.setAttributeNode(cloneNode(doc, attrs.item(i), true));
+ }
+ break;
+ case ATTRIBUTE_NODE:
+ shouldDeep = true;
+ }
+ // 3. Attach to parent, or capture as the root of the cloned subtree.
+ if (destParent !== null) {
+ destParent.appendChild(destNode);
+ } else {
+ destRoot = destNode;
+ }
+ // 4. Return destNode as the context for children (causes walkDOM to descend),
+ // or null to skip children (shallow clone).
+ return shouldDeep ? destNode : null;
+ },
+ });
+ return destRoot;
+}
+
+function __set__(object, key, value) {
+ object[key] = value;
+}
+
+// Returns a new array of direct Element children.
+// Passed to LiveNodeList to implement ParentNode.children.
+// https://dom.spec.whatwg.org/#dom-parentnode-children
+function childrenRefresh(node) {
+ var ls = [];
+ var child = node.firstChild;
+ while (child) {
+ if (child.nodeType === ELEMENT_NODE) {
+ ls.push(child);
+ }
+ child = child.nextSibling;
+ }
+ return ls;
+}
+
+//do dynamic
+try {
+ if (Object.defineProperty) {
+ Object.defineProperty(LiveNodeList.prototype, 'length', {
+ get: function () {
+ _updateLiveList(this);
+ return this.$$length;
+ },
+ });
+
+ /**
+ * The text content of this node and its descendants.
+ *
+ * For {@link Element} and {@link DocumentFragment} nodes, returns the concatenation of the
+ * `nodeValue` of every descendant text node, excluding processing instruction and comment
+ * nodes. For all other node types, returns `nodeValue`.
+ *
+ * Setting `textContent` on an element or document fragment replaces all child nodes with a
+ * single text node; on other nodes it sets `data`, `value`, and `nodeValue` directly.
+ *
+ * @type {string | null}
+ * @see {@link https://dom.spec.whatwg.org/#dom-node-textcontent}
+ */
+ Object.defineProperty(Node.prototype, 'textContent', {
+ get: function () {
+ if (this.nodeType === ELEMENT_NODE || this.nodeType === DOCUMENT_FRAGMENT_NODE) {
+ var buf = [];
+ walkDOM(this, null, {
+ enter: function (n) {
+ if (n.nodeType === ELEMENT_NODE || n.nodeType === DOCUMENT_FRAGMENT_NODE) {
+ return true; // enter children
+ }
+ if (n.nodeType === PROCESSING_INSTRUCTION_NODE || n.nodeType === COMMENT_NODE) {
+ return null; // excluded from text content
+ }
+ buf.push(n.nodeValue);
+ },
+ });
+ return buf.join('');
+ }
+ return this.nodeValue;
+ },
+
+ set: function (data) {
+ switch (this.nodeType) {
+ case ELEMENT_NODE:
+ case DOCUMENT_FRAGMENT_NODE:
+ while (this.firstChild) {
+ this.removeChild(this.firstChild);
+ }
+ if (data || String(data)) {
+ this.appendChild(this.ownerDocument.createTextNode(data));
+ }
+ break;
+
+ default:
+ this.data = data;
+ this.value = data;
+ this.nodeValue = data;
+ }
+ },
+ });
+
+ Object.defineProperty(CharacterData.prototype, 'data', {
+ get: function () {
+ return this._data != null ? this._data : '';
+ },
+ set: function (v) {
+ this._data = v;
+ this.length = typeof v === 'string' ? v.length : 0;
+ },
+ });
+
+ Object.defineProperty(CharacterData.prototype, 'nodeValue', {
+ get: function () {
+ return this.data;
+ },
+ set: function (v) {
+ this.data = v;
+ },
+ enumerable: true,
+ configurable: true,
+ });
+
+ Object.defineProperty(Element.prototype, 'children', {
+ get: function () {
+ return new LiveNodeList(this, childrenRefresh);
+ },
+ });
+ Object.defineProperty(Document.prototype, 'children', {
+ get: function () {
+ return new LiveNodeList(this, childrenRefresh);
+ },
+ });
+ Object.defineProperty(DocumentFragment.prototype, 'children', {
+ get: function () {
+ return new LiveNodeList(this, childrenRefresh);
+ },
+ });
+
+ __set__ = function (object, key, value) {
+ //console.log(value)
+ object['$$' + key] = value;
+ };
+ }
+} catch (e) {
+ //ie8
+}
+
+exports._updateLiveList = _updateLiveList;
+exports.Attr = Attr;
+exports.CDATASection = CDATASection;
+exports.CharacterData = CharacterData;
+exports.Comment = Comment;
+exports.Document = Document;
+exports.DocumentFragment = DocumentFragment;
+exports.DocumentType = DocumentType;
+exports.DOMImplementation = DOMImplementation;
+exports.Element = Element;
+exports.Entity = Entity;
+exports.EntityReference = EntityReference;
+exports.LiveNodeList = LiveNodeList;
+exports.NamedNodeMap = NamedNodeMap;
+exports.Node = Node;
+exports.NodeList = NodeList;
+exports.Notation = Notation;
+exports.Text = Text;
+exports.ProcessingInstruction = ProcessingInstruction;
+exports.walkDOM = walkDOM;
+exports.XMLSerializer = XMLSerializer;
diff --git a/node_modules/@xmldom/xmldom/lib/entities.js b/node_modules/@xmldom/xmldom/lib/entities.js
new file mode 100644
index 000000000..5684a92c4
--- /dev/null
+++ b/node_modules/@xmldom/xmldom/lib/entities.js
@@ -0,0 +1,2171 @@
+'use strict';
+
+var freeze = require('./conventions').freeze;
+
+/**
+ * The entities that are predefined in every XML document.
+ *
+ * @see https://www.w3.org/TR/2006/REC-xml11-20060816/#sec-predefined-ent W3C XML 1.1
+ * @see https://www.w3.org/TR/2008/REC-xml-20081126/#sec-predefined-ent W3C XML 1.0
+ * @see https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Predefined_entities_in_XML
+ * Wikipedia
+ */
+exports.XML_ENTITIES = freeze({
+ amp: '&',
+ apos: "'",
+ gt: '>',
+ lt: '<',
+ quot: '"',
+});
+
+/**
+ * A map of all entities that are detected in an HTML document.
+ * They contain all entries from `XML_ENTITIES`.
+ *
+ * @see {@link XML_ENTITIES}
+ * @see {@link DOMParser.parseFromString}
+ * @see {@link DOMImplementation.prototype.createHTMLDocument}
+ * @see https://html.spec.whatwg.org/#named-character-references WHATWG HTML(5)
+ * Spec
+ * @see https://html.spec.whatwg.org/entities.json JSON
+ * @see https://www.w3.org/TR/xml-entity-names/ W3C XML Entity Names
+ * @see https://www.w3.org/TR/html4/sgml/entities.html W3C HTML4/SGML
+ * @see https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Character_entity_references_in_HTML
+ * Wikipedia (HTML)
+ * @see https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Entities_representing_special_characters_in_XHTML
+ * Wikpedia (XHTML)
+ */
+exports.HTML_ENTITIES = freeze({
+ Aacute: '\u00C1',
+ aacute: '\u00E1',
+ Abreve: '\u0102',
+ abreve: '\u0103',
+ ac: '\u223E',
+ acd: '\u223F',
+ acE: '\u223E\u0333',
+ Acirc: '\u00C2',
+ acirc: '\u00E2',
+ acute: '\u00B4',
+ Acy: '\u0410',
+ acy: '\u0430',
+ AElig: '\u00C6',
+ aelig: '\u00E6',
+ af: '\u2061',
+ Afr: '\uD835\uDD04',
+ afr: '\uD835\uDD1E',
+ Agrave: '\u00C0',
+ agrave: '\u00E0',
+ alefsym: '\u2135',
+ aleph: '\u2135',
+ Alpha: '\u0391',
+ alpha: '\u03B1',
+ Amacr: '\u0100',
+ amacr: '\u0101',
+ amalg: '\u2A3F',
+ AMP: '\u0026',
+ amp: '\u0026',
+ And: '\u2A53',
+ and: '\u2227',
+ andand: '\u2A55',
+ andd: '\u2A5C',
+ andslope: '\u2A58',
+ andv: '\u2A5A',
+ ang: '\u2220',
+ ange: '\u29A4',
+ angle: '\u2220',
+ angmsd: '\u2221',
+ angmsdaa: '\u29A8',
+ angmsdab: '\u29A9',
+ angmsdac: '\u29AA',
+ angmsdad: '\u29AB',
+ angmsdae: '\u29AC',
+ angmsdaf: '\u29AD',
+ angmsdag: '\u29AE',
+ angmsdah: '\u29AF',
+ angrt: '\u221F',
+ angrtvb: '\u22BE',
+ angrtvbd: '\u299D',
+ angsph: '\u2222',
+ angst: '\u00C5',
+ angzarr: '\u237C',
+ Aogon: '\u0104',
+ aogon: '\u0105',
+ Aopf: '\uD835\uDD38',
+ aopf: '\uD835\uDD52',
+ ap: '\u2248',
+ apacir: '\u2A6F',
+ apE: '\u2A70',
+ ape: '\u224A',
+ apid: '\u224B',
+ apos: '\u0027',
+ ApplyFunction: '\u2061',
+ approx: '\u2248',
+ approxeq: '\u224A',
+ Aring: '\u00C5',
+ aring: '\u00E5',
+ Ascr: '\uD835\uDC9C',
+ ascr: '\uD835\uDCB6',
+ Assign: '\u2254',
+ ast: '\u002A',
+ asymp: '\u2248',
+ asympeq: '\u224D',
+ Atilde: '\u00C3',
+ atilde: '\u00E3',
+ Auml: '\u00C4',
+ auml: '\u00E4',
+ awconint: '\u2233',
+ awint: '\u2A11',
+ backcong: '\u224C',
+ backepsilon: '\u03F6',
+ backprime: '\u2035',
+ backsim: '\u223D',
+ backsimeq: '\u22CD',
+ Backslash: '\u2216',
+ Barv: '\u2AE7',
+ barvee: '\u22BD',
+ Barwed: '\u2306',
+ barwed: '\u2305',
+ barwedge: '\u2305',
+ bbrk: '\u23B5',
+ bbrktbrk: '\u23B6',
+ bcong: '\u224C',
+ Bcy: '\u0411',
+ bcy: '\u0431',
+ bdquo: '\u201E',
+ becaus: '\u2235',
+ Because: '\u2235',
+ because: '\u2235',
+ bemptyv: '\u29B0',
+ bepsi: '\u03F6',
+ bernou: '\u212C',
+ Bernoullis: '\u212C',
+ Beta: '\u0392',
+ beta: '\u03B2',
+ beth: '\u2136',
+ between: '\u226C',
+ Bfr: '\uD835\uDD05',
+ bfr: '\uD835\uDD1F',
+ bigcap: '\u22C2',
+ bigcirc: '\u25EF',
+ bigcup: '\u22C3',
+ bigodot: '\u2A00',
+ bigoplus: '\u2A01',
+ bigotimes: '\u2A02',
+ bigsqcup: '\u2A06',
+ bigstar: '\u2605',
+ bigtriangledown: '\u25BD',
+ bigtriangleup: '\u25B3',
+ biguplus: '\u2A04',
+ bigvee: '\u22C1',
+ bigwedge: '\u22C0',
+ bkarow: '\u290D',
+ blacklozenge: '\u29EB',
+ blacksquare: '\u25AA',
+ blacktriangle: '\u25B4',
+ blacktriangledown: '\u25BE',
+ blacktriangleleft: '\u25C2',
+ blacktriangleright: '\u25B8',
+ blank: '\u2423',
+ blk12: '\u2592',
+ blk14: '\u2591',
+ blk34: '\u2593',
+ block: '\u2588',
+ bne: '\u003D\u20E5',
+ bnequiv: '\u2261\u20E5',
+ bNot: '\u2AED',
+ bnot: '\u2310',
+ Bopf: '\uD835\uDD39',
+ bopf: '\uD835\uDD53',
+ bot: '\u22A5',
+ bottom: '\u22A5',
+ bowtie: '\u22C8',
+ boxbox: '\u29C9',
+ boxDL: '\u2557',
+ boxDl: '\u2556',
+ boxdL: '\u2555',
+ boxdl: '\u2510',
+ boxDR: '\u2554',
+ boxDr: '\u2553',
+ boxdR: '\u2552',
+ boxdr: '\u250C',
+ boxH: '\u2550',
+ boxh: '\u2500',
+ boxHD: '\u2566',
+ boxHd: '\u2564',
+ boxhD: '\u2565',
+ boxhd: '\u252C',
+ boxHU: '\u2569',
+ boxHu: '\u2567',
+ boxhU: '\u2568',
+ boxhu: '\u2534',
+ boxminus: '\u229F',
+ boxplus: '\u229E',
+ boxtimes: '\u22A0',
+ boxUL: '\u255D',
+ boxUl: '\u255C',
+ boxuL: '\u255B',
+ boxul: '\u2518',
+ boxUR: '\u255A',
+ boxUr: '\u2559',
+ boxuR: '\u2558',
+ boxur: '\u2514',
+ boxV: '\u2551',
+ boxv: '\u2502',
+ boxVH: '\u256C',
+ boxVh: '\u256B',
+ boxvH: '\u256A',
+ boxvh: '\u253C',
+ boxVL: '\u2563',
+ boxVl: '\u2562',
+ boxvL: '\u2561',
+ boxvl: '\u2524',
+ boxVR: '\u2560',
+ boxVr: '\u255F',
+ boxvR: '\u255E',
+ boxvr: '\u251C',
+ bprime: '\u2035',
+ Breve: '\u02D8',
+ breve: '\u02D8',
+ brvbar: '\u00A6',
+ Bscr: '\u212C',
+ bscr: '\uD835\uDCB7',
+ bsemi: '\u204F',
+ bsim: '\u223D',
+ bsime: '\u22CD',
+ bsol: '\u005C',
+ bsolb: '\u29C5',
+ bsolhsub: '\u27C8',
+ bull: '\u2022',
+ bullet: '\u2022',
+ bump: '\u224E',
+ bumpE: '\u2AAE',
+ bumpe: '\u224F',
+ Bumpeq: '\u224E',
+ bumpeq: '\u224F',
+ Cacute: '\u0106',
+ cacute: '\u0107',
+ Cap: '\u22D2',
+ cap: '\u2229',
+ capand: '\u2A44',
+ capbrcup: '\u2A49',
+ capcap: '\u2A4B',
+ capcup: '\u2A47',
+ capdot: '\u2A40',
+ CapitalDifferentialD: '\u2145',
+ caps: '\u2229\uFE00',
+ caret: '\u2041',
+ caron: '\u02C7',
+ Cayleys: '\u212D',
+ ccaps: '\u2A4D',
+ Ccaron: '\u010C',
+ ccaron: '\u010D',
+ Ccedil: '\u00C7',
+ ccedil: '\u00E7',
+ Ccirc: '\u0108',
+ ccirc: '\u0109',
+ Cconint: '\u2230',
+ ccups: '\u2A4C',
+ ccupssm: '\u2A50',
+ Cdot: '\u010A',
+ cdot: '\u010B',
+ cedil: '\u00B8',
+ Cedilla: '\u00B8',
+ cemptyv: '\u29B2',
+ cent: '\u00A2',
+ CenterDot: '\u00B7',
+ centerdot: '\u00B7',
+ Cfr: '\u212D',
+ cfr: '\uD835\uDD20',
+ CHcy: '\u0427',
+ chcy: '\u0447',
+ check: '\u2713',
+ checkmark: '\u2713',
+ Chi: '\u03A7',
+ chi: '\u03C7',
+ cir: '\u25CB',
+ circ: '\u02C6',
+ circeq: '\u2257',
+ circlearrowleft: '\u21BA',
+ circlearrowright: '\u21BB',
+ circledast: '\u229B',
+ circledcirc: '\u229A',
+ circleddash: '\u229D',
+ CircleDot: '\u2299',
+ circledR: '\u00AE',
+ circledS: '\u24C8',
+ CircleMinus: '\u2296',
+ CirclePlus: '\u2295',
+ CircleTimes: '\u2297',
+ cirE: '\u29C3',
+ cire: '\u2257',
+ cirfnint: '\u2A10',
+ cirmid: '\u2AEF',
+ cirscir: '\u29C2',
+ ClockwiseContourIntegral: '\u2232',
+ CloseCurlyDoubleQuote: '\u201D',
+ CloseCurlyQuote: '\u2019',
+ clubs: '\u2663',
+ clubsuit: '\u2663',
+ Colon: '\u2237',
+ colon: '\u003A',
+ Colone: '\u2A74',
+ colone: '\u2254',
+ coloneq: '\u2254',
+ comma: '\u002C',
+ commat: '\u0040',
+ comp: '\u2201',
+ compfn: '\u2218',
+ complement: '\u2201',
+ complexes: '\u2102',
+ cong: '\u2245',
+ congdot: '\u2A6D',
+ Congruent: '\u2261',
+ Conint: '\u222F',
+ conint: '\u222E',
+ ContourIntegral: '\u222E',
+ Copf: '\u2102',
+ copf: '\uD835\uDD54',
+ coprod: '\u2210',
+ Coproduct: '\u2210',
+ COPY: '\u00A9',
+ copy: '\u00A9',
+ copysr: '\u2117',
+ CounterClockwiseContourIntegral: '\u2233',
+ crarr: '\u21B5',
+ Cross: '\u2A2F',
+ cross: '\u2717',
+ Cscr: '\uD835\uDC9E',
+ cscr: '\uD835\uDCB8',
+ csub: '\u2ACF',
+ csube: '\u2AD1',
+ csup: '\u2AD0',
+ csupe: '\u2AD2',
+ ctdot: '\u22EF',
+ cudarrl: '\u2938',
+ cudarrr: '\u2935',
+ cuepr: '\u22DE',
+ cuesc: '\u22DF',
+ cularr: '\u21B6',
+ cularrp: '\u293D',
+ Cup: '\u22D3',
+ cup: '\u222A',
+ cupbrcap: '\u2A48',
+ CupCap: '\u224D',
+ cupcap: '\u2A46',
+ cupcup: '\u2A4A',
+ cupdot: '\u228D',
+ cupor: '\u2A45',
+ cups: '\u222A\uFE00',
+ curarr: '\u21B7',
+ curarrm: '\u293C',
+ curlyeqprec: '\u22DE',
+ curlyeqsucc: '\u22DF',
+ curlyvee: '\u22CE',
+ curlywedge: '\u22CF',
+ curren: '\u00A4',
+ curvearrowleft: '\u21B6',
+ curvearrowright: '\u21B7',
+ cuvee: '\u22CE',
+ cuwed: '\u22CF',
+ cwconint: '\u2232',
+ cwint: '\u2231',
+ cylcty: '\u232D',
+ Dagger: '\u2021',
+ dagger: '\u2020',
+ daleth: '\u2138',
+ Darr: '\u21A1',
+ dArr: '\u21D3',
+ darr: '\u2193',
+ dash: '\u2010',
+ Dashv: '\u2AE4',
+ dashv: '\u22A3',
+ dbkarow: '\u290F',
+ dblac: '\u02DD',
+ Dcaron: '\u010E',
+ dcaron: '\u010F',
+ Dcy: '\u0414',
+ dcy: '\u0434',
+ DD: '\u2145',
+ dd: '\u2146',
+ ddagger: '\u2021',
+ ddarr: '\u21CA',
+ DDotrahd: '\u2911',
+ ddotseq: '\u2A77',
+ deg: '\u00B0',
+ Del: '\u2207',
+ Delta: '\u0394',
+ delta: '\u03B4',
+ demptyv: '\u29B1',
+ dfisht: '\u297F',
+ Dfr: '\uD835\uDD07',
+ dfr: '\uD835\uDD21',
+ dHar: '\u2965',
+ dharl: '\u21C3',
+ dharr: '\u21C2',
+ DiacriticalAcute: '\u00B4',
+ DiacriticalDot: '\u02D9',
+ DiacriticalDoubleAcute: '\u02DD',
+ DiacriticalGrave: '\u0060',
+ DiacriticalTilde: '\u02DC',
+ diam: '\u22C4',
+ Diamond: '\u22C4',
+ diamond: '\u22C4',
+ diamondsuit: '\u2666',
+ diams: '\u2666',
+ die: '\u00A8',
+ DifferentialD: '\u2146',
+ digamma: '\u03DD',
+ disin: '\u22F2',
+ div: '\u00F7',
+ divide: '\u00F7',
+ divideontimes: '\u22C7',
+ divonx: '\u22C7',
+ DJcy: '\u0402',
+ djcy: '\u0452',
+ dlcorn: '\u231E',
+ dlcrop: '\u230D',
+ dollar: '\u0024',
+ Dopf: '\uD835\uDD3B',
+ dopf: '\uD835\uDD55',
+ Dot: '\u00A8',
+ dot: '\u02D9',
+ DotDot: '\u20DC',
+ doteq: '\u2250',
+ doteqdot: '\u2251',
+ DotEqual: '\u2250',
+ dotminus: '\u2238',
+ dotplus: '\u2214',
+ dotsquare: '\u22A1',
+ doublebarwedge: '\u2306',
+ DoubleContourIntegral: '\u222F',
+ DoubleDot: '\u00A8',
+ DoubleDownArrow: '\u21D3',
+ DoubleLeftArrow: '\u21D0',
+ DoubleLeftRightArrow: '\u21D4',
+ DoubleLeftTee: '\u2AE4',
+ DoubleLongLeftArrow: '\u27F8',
+ DoubleLongLeftRightArrow: '\u27FA',
+ DoubleLongRightArrow: '\u27F9',
+ DoubleRightArrow: '\u21D2',
+ DoubleRightTee: '\u22A8',
+ DoubleUpArrow: '\u21D1',
+ DoubleUpDownArrow: '\u21D5',
+ DoubleVerticalBar: '\u2225',
+ DownArrow: '\u2193',
+ Downarrow: '\u21D3',
+ downarrow: '\u2193',
+ DownArrowBar: '\u2913',
+ DownArrowUpArrow: '\u21F5',
+ DownBreve: '\u0311',
+ downdownarrows: '\u21CA',
+ downharpoonleft: '\u21C3',
+ downharpoonright: '\u21C2',
+ DownLeftRightVector: '\u2950',
+ DownLeftTeeVector: '\u295E',
+ DownLeftVector: '\u21BD',
+ DownLeftVectorBar: '\u2956',
+ DownRightTeeVector: '\u295F',
+ DownRightVector: '\u21C1',
+ DownRightVectorBar: '\u2957',
+ DownTee: '\u22A4',
+ DownTeeArrow: '\u21A7',
+ drbkarow: '\u2910',
+ drcorn: '\u231F',
+ drcrop: '\u230C',
+ Dscr: '\uD835\uDC9F',
+ dscr: '\uD835\uDCB9',
+ DScy: '\u0405',
+ dscy: '\u0455',
+ dsol: '\u29F6',
+ Dstrok: '\u0110',
+ dstrok: '\u0111',
+ dtdot: '\u22F1',
+ dtri: '\u25BF',
+ dtrif: '\u25BE',
+ duarr: '\u21F5',
+ duhar: '\u296F',
+ dwangle: '\u29A6',
+ DZcy: '\u040F',
+ dzcy: '\u045F',
+ dzigrarr: '\u27FF',
+ Eacute: '\u00C9',
+ eacute: '\u00E9',
+ easter: '\u2A6E',
+ Ecaron: '\u011A',
+ ecaron: '\u011B',
+ ecir: '\u2256',
+ Ecirc: '\u00CA',
+ ecirc: '\u00EA',
+ ecolon: '\u2255',
+ Ecy: '\u042D',
+ ecy: '\u044D',
+ eDDot: '\u2A77',
+ Edot: '\u0116',
+ eDot: '\u2251',
+ edot: '\u0117',
+ ee: '\u2147',
+ efDot: '\u2252',
+ Efr: '\uD835\uDD08',
+ efr: '\uD835\uDD22',
+ eg: '\u2A9A',
+ Egrave: '\u00C8',
+ egrave: '\u00E8',
+ egs: '\u2A96',
+ egsdot: '\u2A98',
+ el: '\u2A99',
+ Element: '\u2208',
+ elinters: '\u23E7',
+ ell: '\u2113',
+ els: '\u2A95',
+ elsdot: '\u2A97',
+ Emacr: '\u0112',
+ emacr: '\u0113',
+ empty: '\u2205',
+ emptyset: '\u2205',
+ EmptySmallSquare: '\u25FB',
+ emptyv: '\u2205',
+ EmptyVerySmallSquare: '\u25AB',
+ emsp: '\u2003',
+ emsp13: '\u2004',
+ emsp14: '\u2005',
+ ENG: '\u014A',
+ eng: '\u014B',
+ ensp: '\u2002',
+ Eogon: '\u0118',
+ eogon: '\u0119',
+ Eopf: '\uD835\uDD3C',
+ eopf: '\uD835\uDD56',
+ epar: '\u22D5',
+ eparsl: '\u29E3',
+ eplus: '\u2A71',
+ epsi: '\u03B5',
+ Epsilon: '\u0395',
+ epsilon: '\u03B5',
+ epsiv: '\u03F5',
+ eqcirc: '\u2256',
+ eqcolon: '\u2255',
+ eqsim: '\u2242',
+ eqslantgtr: '\u2A96',
+ eqslantless: '\u2A95',
+ Equal: '\u2A75',
+ equals: '\u003D',
+ EqualTilde: '\u2242',
+ equest: '\u225F',
+ Equilibrium: '\u21CC',
+ equiv: '\u2261',
+ equivDD: '\u2A78',
+ eqvparsl: '\u29E5',
+ erarr: '\u2971',
+ erDot: '\u2253',
+ Escr: '\u2130',
+ escr: '\u212F',
+ esdot: '\u2250',
+ Esim: '\u2A73',
+ esim: '\u2242',
+ Eta: '\u0397',
+ eta: '\u03B7',
+ ETH: '\u00D0',
+ eth: '\u00F0',
+ Euml: '\u00CB',
+ euml: '\u00EB',
+ euro: '\u20AC',
+ excl: '\u0021',
+ exist: '\u2203',
+ Exists: '\u2203',
+ expectation: '\u2130',
+ ExponentialE: '\u2147',
+ exponentiale: '\u2147',
+ fallingdotseq: '\u2252',
+ Fcy: '\u0424',
+ fcy: '\u0444',
+ female: '\u2640',
+ ffilig: '\uFB03',
+ fflig: '\uFB00',
+ ffllig: '\uFB04',
+ Ffr: '\uD835\uDD09',
+ ffr: '\uD835\uDD23',
+ filig: '\uFB01',
+ FilledSmallSquare: '\u25FC',
+ FilledVerySmallSquare: '\u25AA',
+ fjlig: '\u0066\u006A',
+ flat: '\u266D',
+ fllig: '\uFB02',
+ fltns: '\u25B1',
+ fnof: '\u0192',
+ Fopf: '\uD835\uDD3D',
+ fopf: '\uD835\uDD57',
+ ForAll: '\u2200',
+ forall: '\u2200',
+ fork: '\u22D4',
+ forkv: '\u2AD9',
+ Fouriertrf: '\u2131',
+ fpartint: '\u2A0D',
+ frac12: '\u00BD',
+ frac13: '\u2153',
+ frac14: '\u00BC',
+ frac15: '\u2155',
+ frac16: '\u2159',
+ frac18: '\u215B',
+ frac23: '\u2154',
+ frac25: '\u2156',
+ frac34: '\u00BE',
+ frac35: '\u2157',
+ frac38: '\u215C',
+ frac45: '\u2158',
+ frac56: '\u215A',
+ frac58: '\u215D',
+ frac78: '\u215E',
+ frasl: '\u2044',
+ frown: '\u2322',
+ Fscr: '\u2131',
+ fscr: '\uD835\uDCBB',
+ gacute: '\u01F5',
+ Gamma: '\u0393',
+ gamma: '\u03B3',
+ Gammad: '\u03DC',
+ gammad: '\u03DD',
+ gap: '\u2A86',
+ Gbreve: '\u011E',
+ gbreve: '\u011F',
+ Gcedil: '\u0122',
+ Gcirc: '\u011C',
+ gcirc: '\u011D',
+ Gcy: '\u0413',
+ gcy: '\u0433',
+ Gdot: '\u0120',
+ gdot: '\u0121',
+ gE: '\u2267',
+ ge: '\u2265',
+ gEl: '\u2A8C',
+ gel: '\u22DB',
+ geq: '\u2265',
+ geqq: '\u2267',
+ geqslant: '\u2A7E',
+ ges: '\u2A7E',
+ gescc: '\u2AA9',
+ gesdot: '\u2A80',
+ gesdoto: '\u2A82',
+ gesdotol: '\u2A84',
+ gesl: '\u22DB\uFE00',
+ gesles: '\u2A94',
+ Gfr: '\uD835\uDD0A',
+ gfr: '\uD835\uDD24',
+ Gg: '\u22D9',
+ gg: '\u226B',
+ ggg: '\u22D9',
+ gimel: '\u2137',
+ GJcy: '\u0403',
+ gjcy: '\u0453',
+ gl: '\u2277',
+ gla: '\u2AA5',
+ glE: '\u2A92',
+ glj: '\u2AA4',
+ gnap: '\u2A8A',
+ gnapprox: '\u2A8A',
+ gnE: '\u2269',
+ gne: '\u2A88',
+ gneq: '\u2A88',
+ gneqq: '\u2269',
+ gnsim: '\u22E7',
+ Gopf: '\uD835\uDD3E',
+ gopf: '\uD835\uDD58',
+ grave: '\u0060',
+ GreaterEqual: '\u2265',
+ GreaterEqualLess: '\u22DB',
+ GreaterFullEqual: '\u2267',
+ GreaterGreater: '\u2AA2',
+ GreaterLess: '\u2277',
+ GreaterSlantEqual: '\u2A7E',
+ GreaterTilde: '\u2273',
+ Gscr: '\uD835\uDCA2',
+ gscr: '\u210A',
+ gsim: '\u2273',
+ gsime: '\u2A8E',
+ gsiml: '\u2A90',
+ Gt: '\u226B',
+ GT: '\u003E',
+ gt: '\u003E',
+ gtcc: '\u2AA7',
+ gtcir: '\u2A7A',
+ gtdot: '\u22D7',
+ gtlPar: '\u2995',
+ gtquest: '\u2A7C',
+ gtrapprox: '\u2A86',
+ gtrarr: '\u2978',
+ gtrdot: '\u22D7',
+ gtreqless: '\u22DB',
+ gtreqqless: '\u2A8C',
+ gtrless: '\u2277',
+ gtrsim: '\u2273',
+ gvertneqq: '\u2269\uFE00',
+ gvnE: '\u2269\uFE00',
+ Hacek: '\u02C7',
+ hairsp: '\u200A',
+ half: '\u00BD',
+ hamilt: '\u210B',
+ HARDcy: '\u042A',
+ hardcy: '\u044A',
+ hArr: '\u21D4',
+ harr: '\u2194',
+ harrcir: '\u2948',
+ harrw: '\u21AD',
+ Hat: '\u005E',
+ hbar: '\u210F',
+ Hcirc: '\u0124',
+ hcirc: '\u0125',
+ hearts: '\u2665',
+ heartsuit: '\u2665',
+ hellip: '\u2026',
+ hercon: '\u22B9',
+ Hfr: '\u210C',
+ hfr: '\uD835\uDD25',
+ HilbertSpace: '\u210B',
+ hksearow: '\u2925',
+ hkswarow: '\u2926',
+ hoarr: '\u21FF',
+ homtht: '\u223B',
+ hookleftarrow: '\u21A9',
+ hookrightarrow: '\u21AA',
+ Hopf: '\u210D',
+ hopf: '\uD835\uDD59',
+ horbar: '\u2015',
+ HorizontalLine: '\u2500',
+ Hscr: '\u210B',
+ hscr: '\uD835\uDCBD',
+ hslash: '\u210F',
+ Hstrok: '\u0126',
+ hstrok: '\u0127',
+ HumpDownHump: '\u224E',
+ HumpEqual: '\u224F',
+ hybull: '\u2043',
+ hyphen: '\u2010',
+ Iacute: '\u00CD',
+ iacute: '\u00ED',
+ ic: '\u2063',
+ Icirc: '\u00CE',
+ icirc: '\u00EE',
+ Icy: '\u0418',
+ icy: '\u0438',
+ Idot: '\u0130',
+ IEcy: '\u0415',
+ iecy: '\u0435',
+ iexcl: '\u00A1',
+ iff: '\u21D4',
+ Ifr: '\u2111',
+ ifr: '\uD835\uDD26',
+ Igrave: '\u00CC',
+ igrave: '\u00EC',
+ ii: '\u2148',
+ iiiint: '\u2A0C',
+ iiint: '\u222D',
+ iinfin: '\u29DC',
+ iiota: '\u2129',
+ IJlig: '\u0132',
+ ijlig: '\u0133',
+ Im: '\u2111',
+ Imacr: '\u012A',
+ imacr: '\u012B',
+ image: '\u2111',
+ ImaginaryI: '\u2148',
+ imagline: '\u2110',
+ imagpart: '\u2111',
+ imath: '\u0131',
+ imof: '\u22B7',
+ imped: '\u01B5',
+ Implies: '\u21D2',
+ in: '\u2208',
+ incare: '\u2105',
+ infin: '\u221E',
+ infintie: '\u29DD',
+ inodot: '\u0131',
+ Int: '\u222C',
+ int: '\u222B',
+ intcal: '\u22BA',
+ integers: '\u2124',
+ Integral: '\u222B',
+ intercal: '\u22BA',
+ Intersection: '\u22C2',
+ intlarhk: '\u2A17',
+ intprod: '\u2A3C',
+ InvisibleComma: '\u2063',
+ InvisibleTimes: '\u2062',
+ IOcy: '\u0401',
+ iocy: '\u0451',
+ Iogon: '\u012E',
+ iogon: '\u012F',
+ Iopf: '\uD835\uDD40',
+ iopf: '\uD835\uDD5A',
+ Iota: '\u0399',
+ iota: '\u03B9',
+ iprod: '\u2A3C',
+ iquest: '\u00BF',
+ Iscr: '\u2110',
+ iscr: '\uD835\uDCBE',
+ isin: '\u2208',
+ isindot: '\u22F5',
+ isinE: '\u22F9',
+ isins: '\u22F4',
+ isinsv: '\u22F3',
+ isinv: '\u2208',
+ it: '\u2062',
+ Itilde: '\u0128',
+ itilde: '\u0129',
+ Iukcy: '\u0406',
+ iukcy: '\u0456',
+ Iuml: '\u00CF',
+ iuml: '\u00EF',
+ Jcirc: '\u0134',
+ jcirc: '\u0135',
+ Jcy: '\u0419',
+ jcy: '\u0439',
+ Jfr: '\uD835\uDD0D',
+ jfr: '\uD835\uDD27',
+ jmath: '\u0237',
+ Jopf: '\uD835\uDD41',
+ jopf: '\uD835\uDD5B',
+ Jscr: '\uD835\uDCA5',
+ jscr: '\uD835\uDCBF',
+ Jsercy: '\u0408',
+ jsercy: '\u0458',
+ Jukcy: '\u0404',
+ jukcy: '\u0454',
+ Kappa: '\u039A',
+ kappa: '\u03BA',
+ kappav: '\u03F0',
+ Kcedil: '\u0136',
+ kcedil: '\u0137',
+ Kcy: '\u041A',
+ kcy: '\u043A',
+ Kfr: '\uD835\uDD0E',
+ kfr: '\uD835\uDD28',
+ kgreen: '\u0138',
+ KHcy: '\u0425',
+ khcy: '\u0445',
+ KJcy: '\u040C',
+ kjcy: '\u045C',
+ Kopf: '\uD835\uDD42',
+ kopf: '\uD835\uDD5C',
+ Kscr: '\uD835\uDCA6',
+ kscr: '\uD835\uDCC0',
+ lAarr: '\u21DA',
+ Lacute: '\u0139',
+ lacute: '\u013A',
+ laemptyv: '\u29B4',
+ lagran: '\u2112',
+ Lambda: '\u039B',
+ lambda: '\u03BB',
+ Lang: '\u27EA',
+ lang: '\u27E8',
+ langd: '\u2991',
+ langle: '\u27E8',
+ lap: '\u2A85',
+ Laplacetrf: '\u2112',
+ laquo: '\u00AB',
+ Larr: '\u219E',
+ lArr: '\u21D0',
+ larr: '\u2190',
+ larrb: '\u21E4',
+ larrbfs: '\u291F',
+ larrfs: '\u291D',
+ larrhk: '\u21A9',
+ larrlp: '\u21AB',
+ larrpl: '\u2939',
+ larrsim: '\u2973',
+ larrtl: '\u21A2',
+ lat: '\u2AAB',
+ lAtail: '\u291B',
+ latail: '\u2919',
+ late: '\u2AAD',
+ lates: '\u2AAD\uFE00',
+ lBarr: '\u290E',
+ lbarr: '\u290C',
+ lbbrk: '\u2772',
+ lbrace: '\u007B',
+ lbrack: '\u005B',
+ lbrke: '\u298B',
+ lbrksld: '\u298F',
+ lbrkslu: '\u298D',
+ Lcaron: '\u013D',
+ lcaron: '\u013E',
+ Lcedil: '\u013B',
+ lcedil: '\u013C',
+ lceil: '\u2308',
+ lcub: '\u007B',
+ Lcy: '\u041B',
+ lcy: '\u043B',
+ ldca: '\u2936',
+ ldquo: '\u201C',
+ ldquor: '\u201E',
+ ldrdhar: '\u2967',
+ ldrushar: '\u294B',
+ ldsh: '\u21B2',
+ lE: '\u2266',
+ le: '\u2264',
+ LeftAngleBracket: '\u27E8',
+ LeftArrow: '\u2190',
+ Leftarrow: '\u21D0',
+ leftarrow: '\u2190',
+ LeftArrowBar: '\u21E4',
+ LeftArrowRightArrow: '\u21C6',
+ leftarrowtail: '\u21A2',
+ LeftCeiling: '\u2308',
+ LeftDoubleBracket: '\u27E6',
+ LeftDownTeeVector: '\u2961',
+ LeftDownVector: '\u21C3',
+ LeftDownVectorBar: '\u2959',
+ LeftFloor: '\u230A',
+ leftharpoondown: '\u21BD',
+ leftharpoonup: '\u21BC',
+ leftleftarrows: '\u21C7',
+ LeftRightArrow: '\u2194',
+ Leftrightarrow: '\u21D4',
+ leftrightarrow: '\u2194',
+ leftrightarrows: '\u21C6',
+ leftrightharpoons: '\u21CB',
+ leftrightsquigarrow: '\u21AD',
+ LeftRightVector: '\u294E',
+ LeftTee: '\u22A3',
+ LeftTeeArrow: '\u21A4',
+ LeftTeeVector: '\u295A',
+ leftthreetimes: '\u22CB',
+ LeftTriangle: '\u22B2',
+ LeftTriangleBar: '\u29CF',
+ LeftTriangleEqual: '\u22B4',
+ LeftUpDownVector: '\u2951',
+ LeftUpTeeVector: '\u2960',
+ LeftUpVector: '\u21BF',
+ LeftUpVectorBar: '\u2958',
+ LeftVector: '\u21BC',
+ LeftVectorBar: '\u2952',
+ lEg: '\u2A8B',
+ leg: '\u22DA',
+ leq: '\u2264',
+ leqq: '\u2266',
+ leqslant: '\u2A7D',
+ les: '\u2A7D',
+ lescc: '\u2AA8',
+ lesdot: '\u2A7F',
+ lesdoto: '\u2A81',
+ lesdotor: '\u2A83',
+ lesg: '\u22DA\uFE00',
+ lesges: '\u2A93',
+ lessapprox: '\u2A85',
+ lessdot: '\u22D6',
+ lesseqgtr: '\u22DA',
+ lesseqqgtr: '\u2A8B',
+ LessEqualGreater: '\u22DA',
+ LessFullEqual: '\u2266',
+ LessGreater: '\u2276',
+ lessgtr: '\u2276',
+ LessLess: '\u2AA1',
+ lesssim: '\u2272',
+ LessSlantEqual: '\u2A7D',
+ LessTilde: '\u2272',
+ lfisht: '\u297C',
+ lfloor: '\u230A',
+ Lfr: '\uD835\uDD0F',
+ lfr: '\uD835\uDD29',
+ lg: '\u2276',
+ lgE: '\u2A91',
+ lHar: '\u2962',
+ lhard: '\u21BD',
+ lharu: '\u21BC',
+ lharul: '\u296A',
+ lhblk: '\u2584',
+ LJcy: '\u0409',
+ ljcy: '\u0459',
+ Ll: '\u22D8',
+ ll: '\u226A',
+ llarr: '\u21C7',
+ llcorner: '\u231E',
+ Lleftarrow: '\u21DA',
+ llhard: '\u296B',
+ lltri: '\u25FA',
+ Lmidot: '\u013F',
+ lmidot: '\u0140',
+ lmoust: '\u23B0',
+ lmoustache: '\u23B0',
+ lnap: '\u2A89',
+ lnapprox: '\u2A89',
+ lnE: '\u2268',
+ lne: '\u2A87',
+ lneq: '\u2A87',
+ lneqq: '\u2268',
+ lnsim: '\u22E6',
+ loang: '\u27EC',
+ loarr: '\u21FD',
+ lobrk: '\u27E6',
+ LongLeftArrow: '\u27F5',
+ Longleftarrow: '\u27F8',
+ longleftarrow: '\u27F5',
+ LongLeftRightArrow: '\u27F7',
+ Longleftrightarrow: '\u27FA',
+ longleftrightarrow: '\u27F7',
+ longmapsto: '\u27FC',
+ LongRightArrow: '\u27F6',
+ Longrightarrow: '\u27F9',
+ longrightarrow: '\u27F6',
+ looparrowleft: '\u21AB',
+ looparrowright: '\u21AC',
+ lopar: '\u2985',
+ Lopf: '\uD835\uDD43',
+ lopf: '\uD835\uDD5D',
+ loplus: '\u2A2D',
+ lotimes: '\u2A34',
+ lowast: '\u2217',
+ lowbar: '\u005F',
+ LowerLeftArrow: '\u2199',
+ LowerRightArrow: '\u2198',
+ loz: '\u25CA',
+ lozenge: '\u25CA',
+ lozf: '\u29EB',
+ lpar: '\u0028',
+ lparlt: '\u2993',
+ lrarr: '\u21C6',
+ lrcorner: '\u231F',
+ lrhar: '\u21CB',
+ lrhard: '\u296D',
+ lrm: '\u200E',
+ lrtri: '\u22BF',
+ lsaquo: '\u2039',
+ Lscr: '\u2112',
+ lscr: '\uD835\uDCC1',
+ Lsh: '\u21B0',
+ lsh: '\u21B0',
+ lsim: '\u2272',
+ lsime: '\u2A8D',
+ lsimg: '\u2A8F',
+ lsqb: '\u005B',
+ lsquo: '\u2018',
+ lsquor: '\u201A',
+ Lstrok: '\u0141',
+ lstrok: '\u0142',
+ Lt: '\u226A',
+ LT: '\u003C',
+ lt: '\u003C',
+ ltcc: '\u2AA6',
+ ltcir: '\u2A79',
+ ltdot: '\u22D6',
+ lthree: '\u22CB',
+ ltimes: '\u22C9',
+ ltlarr: '\u2976',
+ ltquest: '\u2A7B',
+ ltri: '\u25C3',
+ ltrie: '\u22B4',
+ ltrif: '\u25C2',
+ ltrPar: '\u2996',
+ lurdshar: '\u294A',
+ luruhar: '\u2966',
+ lvertneqq: '\u2268\uFE00',
+ lvnE: '\u2268\uFE00',
+ macr: '\u00AF',
+ male: '\u2642',
+ malt: '\u2720',
+ maltese: '\u2720',
+ Map: '\u2905',
+ map: '\u21A6',
+ mapsto: '\u21A6',
+ mapstodown: '\u21A7',
+ mapstoleft: '\u21A4',
+ mapstoup: '\u21A5',
+ marker: '\u25AE',
+ mcomma: '\u2A29',
+ Mcy: '\u041C',
+ mcy: '\u043C',
+ mdash: '\u2014',
+ mDDot: '\u223A',
+ measuredangle: '\u2221',
+ MediumSpace: '\u205F',
+ Mellintrf: '\u2133',
+ Mfr: '\uD835\uDD10',
+ mfr: '\uD835\uDD2A',
+ mho: '\u2127',
+ micro: '\u00B5',
+ mid: '\u2223',
+ midast: '\u002A',
+ midcir: '\u2AF0',
+ middot: '\u00B7',
+ minus: '\u2212',
+ minusb: '\u229F',
+ minusd: '\u2238',
+ minusdu: '\u2A2A',
+ MinusPlus: '\u2213',
+ mlcp: '\u2ADB',
+ mldr: '\u2026',
+ mnplus: '\u2213',
+ models: '\u22A7',
+ Mopf: '\uD835\uDD44',
+ mopf: '\uD835\uDD5E',
+ mp: '\u2213',
+ Mscr: '\u2133',
+ mscr: '\uD835\uDCC2',
+ mstpos: '\u223E',
+ Mu: '\u039C',
+ mu: '\u03BC',
+ multimap: '\u22B8',
+ mumap: '\u22B8',
+ nabla: '\u2207',
+ Nacute: '\u0143',
+ nacute: '\u0144',
+ nang: '\u2220\u20D2',
+ nap: '\u2249',
+ napE: '\u2A70\u0338',
+ napid: '\u224B\u0338',
+ napos: '\u0149',
+ napprox: '\u2249',
+ natur: '\u266E',
+ natural: '\u266E',
+ naturals: '\u2115',
+ nbsp: '\u00A0',
+ nbump: '\u224E\u0338',
+ nbumpe: '\u224F\u0338',
+ ncap: '\u2A43',
+ Ncaron: '\u0147',
+ ncaron: '\u0148',
+ Ncedil: '\u0145',
+ ncedil: '\u0146',
+ ncong: '\u2247',
+ ncongdot: '\u2A6D\u0338',
+ ncup: '\u2A42',
+ Ncy: '\u041D',
+ ncy: '\u043D',
+ ndash: '\u2013',
+ ne: '\u2260',
+ nearhk: '\u2924',
+ neArr: '\u21D7',
+ nearr: '\u2197',
+ nearrow: '\u2197',
+ nedot: '\u2250\u0338',
+ NegativeMediumSpace: '\u200B',
+ NegativeThickSpace: '\u200B',
+ NegativeThinSpace: '\u200B',
+ NegativeVeryThinSpace: '\u200B',
+ nequiv: '\u2262',
+ nesear: '\u2928',
+ nesim: '\u2242\u0338',
+ NestedGreaterGreater: '\u226B',
+ NestedLessLess: '\u226A',
+ NewLine: '\u000A',
+ nexist: '\u2204',
+ nexists: '\u2204',
+ Nfr: '\uD835\uDD11',
+ nfr: '\uD835\uDD2B',
+ ngE: '\u2267\u0338',
+ nge: '\u2271',
+ ngeq: '\u2271',
+ ngeqq: '\u2267\u0338',
+ ngeqslant: '\u2A7E\u0338',
+ nges: '\u2A7E\u0338',
+ nGg: '\u22D9\u0338',
+ ngsim: '\u2275',
+ nGt: '\u226B\u20D2',
+ ngt: '\u226F',
+ ngtr: '\u226F',
+ nGtv: '\u226B\u0338',
+ nhArr: '\u21CE',
+ nharr: '\u21AE',
+ nhpar: '\u2AF2',
+ ni: '\u220B',
+ nis: '\u22FC',
+ nisd: '\u22FA',
+ niv: '\u220B',
+ NJcy: '\u040A',
+ njcy: '\u045A',
+ nlArr: '\u21CD',
+ nlarr: '\u219A',
+ nldr: '\u2025',
+ nlE: '\u2266\u0338',
+ nle: '\u2270',
+ nLeftarrow: '\u21CD',
+ nleftarrow: '\u219A',
+ nLeftrightarrow: '\u21CE',
+ nleftrightarrow: '\u21AE',
+ nleq: '\u2270',
+ nleqq: '\u2266\u0338',
+ nleqslant: '\u2A7D\u0338',
+ nles: '\u2A7D\u0338',
+ nless: '\u226E',
+ nLl: '\u22D8\u0338',
+ nlsim: '\u2274',
+ nLt: '\u226A\u20D2',
+ nlt: '\u226E',
+ nltri: '\u22EA',
+ nltrie: '\u22EC',
+ nLtv: '\u226A\u0338',
+ nmid: '\u2224',
+ NoBreak: '\u2060',
+ NonBreakingSpace: '\u00A0',
+ Nopf: '\u2115',
+ nopf: '\uD835\uDD5F',
+ Not: '\u2AEC',
+ not: '\u00AC',
+ NotCongruent: '\u2262',
+ NotCupCap: '\u226D',
+ NotDoubleVerticalBar: '\u2226',
+ NotElement: '\u2209',
+ NotEqual: '\u2260',
+ NotEqualTilde: '\u2242\u0338',
+ NotExists: '\u2204',
+ NotGreater: '\u226F',
+ NotGreaterEqual: '\u2271',
+ NotGreaterFullEqual: '\u2267\u0338',
+ NotGreaterGreater: '\u226B\u0338',
+ NotGreaterLess: '\u2279',
+ NotGreaterSlantEqual: '\u2A7E\u0338',
+ NotGreaterTilde: '\u2275',
+ NotHumpDownHump: '\u224E\u0338',
+ NotHumpEqual: '\u224F\u0338',
+ notin: '\u2209',
+ notindot: '\u22F5\u0338',
+ notinE: '\u22F9\u0338',
+ notinva: '\u2209',
+ notinvb: '\u22F7',
+ notinvc: '\u22F6',
+ NotLeftTriangle: '\u22EA',
+ NotLeftTriangleBar: '\u29CF\u0338',
+ NotLeftTriangleEqual: '\u22EC',
+ NotLess: '\u226E',
+ NotLessEqual: '\u2270',
+ NotLessGreater: '\u2278',
+ NotLessLess: '\u226A\u0338',
+ NotLessSlantEqual: '\u2A7D\u0338',
+ NotLessTilde: '\u2274',
+ NotNestedGreaterGreater: '\u2AA2\u0338',
+ NotNestedLessLess: '\u2AA1\u0338',
+ notni: '\u220C',
+ notniva: '\u220C',
+ notnivb: '\u22FE',
+ notnivc: '\u22FD',
+ NotPrecedes: '\u2280',
+ NotPrecedesEqual: '\u2AAF\u0338',
+ NotPrecedesSlantEqual: '\u22E0',
+ NotReverseElement: '\u220C',
+ NotRightTriangle: '\u22EB',
+ NotRightTriangleBar: '\u29D0\u0338',
+ NotRightTriangleEqual: '\u22ED',
+ NotSquareSubset: '\u228F\u0338',
+ NotSquareSubsetEqual: '\u22E2',
+ NotSquareSuperset: '\u2290\u0338',
+ NotSquareSupersetEqual: '\u22E3',
+ NotSubset: '\u2282\u20D2',
+ NotSubsetEqual: '\u2288',
+ NotSucceeds: '\u2281',
+ NotSucceedsEqual: '\u2AB0\u0338',
+ NotSucceedsSlantEqual: '\u22E1',
+ NotSucceedsTilde: '\u227F\u0338',
+ NotSuperset: '\u2283\u20D2',
+ NotSupersetEqual: '\u2289',
+ NotTilde: '\u2241',
+ NotTildeEqual: '\u2244',
+ NotTildeFullEqual: '\u2247',
+ NotTildeTilde: '\u2249',
+ NotVerticalBar: '\u2224',
+ npar: '\u2226',
+ nparallel: '\u2226',
+ nparsl: '\u2AFD\u20E5',
+ npart: '\u2202\u0338',
+ npolint: '\u2A14',
+ npr: '\u2280',
+ nprcue: '\u22E0',
+ npre: '\u2AAF\u0338',
+ nprec: '\u2280',
+ npreceq: '\u2AAF\u0338',
+ nrArr: '\u21CF',
+ nrarr: '\u219B',
+ nrarrc: '\u2933\u0338',
+ nrarrw: '\u219D\u0338',
+ nRightarrow: '\u21CF',
+ nrightarrow: '\u219B',
+ nrtri: '\u22EB',
+ nrtrie: '\u22ED',
+ nsc: '\u2281',
+ nsccue: '\u22E1',
+ nsce: '\u2AB0\u0338',
+ Nscr: '\uD835\uDCA9',
+ nscr: '\uD835\uDCC3',
+ nshortmid: '\u2224',
+ nshortparallel: '\u2226',
+ nsim: '\u2241',
+ nsime: '\u2244',
+ nsimeq: '\u2244',
+ nsmid: '\u2224',
+ nspar: '\u2226',
+ nsqsube: '\u22E2',
+ nsqsupe: '\u22E3',
+ nsub: '\u2284',
+ nsubE: '\u2AC5\u0338',
+ nsube: '\u2288',
+ nsubset: '\u2282\u20D2',
+ nsubseteq: '\u2288',
+ nsubseteqq: '\u2AC5\u0338',
+ nsucc: '\u2281',
+ nsucceq: '\u2AB0\u0338',
+ nsup: '\u2285',
+ nsupE: '\u2AC6\u0338',
+ nsupe: '\u2289',
+ nsupset: '\u2283\u20D2',
+ nsupseteq: '\u2289',
+ nsupseteqq: '\u2AC6\u0338',
+ ntgl: '\u2279',
+ Ntilde: '\u00D1',
+ ntilde: '\u00F1',
+ ntlg: '\u2278',
+ ntriangleleft: '\u22EA',
+ ntrianglelefteq: '\u22EC',
+ ntriangleright: '\u22EB',
+ ntrianglerighteq: '\u22ED',
+ Nu: '\u039D',
+ nu: '\u03BD',
+ num: '\u0023',
+ numero: '\u2116',
+ numsp: '\u2007',
+ nvap: '\u224D\u20D2',
+ nVDash: '\u22AF',
+ nVdash: '\u22AE',
+ nvDash: '\u22AD',
+ nvdash: '\u22AC',
+ nvge: '\u2265\u20D2',
+ nvgt: '\u003E\u20D2',
+ nvHarr: '\u2904',
+ nvinfin: '\u29DE',
+ nvlArr: '\u2902',
+ nvle: '\u2264\u20D2',
+ nvlt: '\u003C\u20D2',
+ nvltrie: '\u22B4\u20D2',
+ nvrArr: '\u2903',
+ nvrtrie: '\u22B5\u20D2',
+ nvsim: '\u223C\u20D2',
+ nwarhk: '\u2923',
+ nwArr: '\u21D6',
+ nwarr: '\u2196',
+ nwarrow: '\u2196',
+ nwnear: '\u2927',
+ Oacute: '\u00D3',
+ oacute: '\u00F3',
+ oast: '\u229B',
+ ocir: '\u229A',
+ Ocirc: '\u00D4',
+ ocirc: '\u00F4',
+ Ocy: '\u041E',
+ ocy: '\u043E',
+ odash: '\u229D',
+ Odblac: '\u0150',
+ odblac: '\u0151',
+ odiv: '\u2A38',
+ odot: '\u2299',
+ odsold: '\u29BC',
+ OElig: '\u0152',
+ oelig: '\u0153',
+ ofcir: '\u29BF',
+ Ofr: '\uD835\uDD12',
+ ofr: '\uD835\uDD2C',
+ ogon: '\u02DB',
+ Ograve: '\u00D2',
+ ograve: '\u00F2',
+ ogt: '\u29C1',
+ ohbar: '\u29B5',
+ ohm: '\u03A9',
+ oint: '\u222E',
+ olarr: '\u21BA',
+ olcir: '\u29BE',
+ olcross: '\u29BB',
+ oline: '\u203E',
+ olt: '\u29C0',
+ Omacr: '\u014C',
+ omacr: '\u014D',
+ Omega: '\u03A9',
+ omega: '\u03C9',
+ Omicron: '\u039F',
+ omicron: '\u03BF',
+ omid: '\u29B6',
+ ominus: '\u2296',
+ Oopf: '\uD835\uDD46',
+ oopf: '\uD835\uDD60',
+ opar: '\u29B7',
+ OpenCurlyDoubleQuote: '\u201C',
+ OpenCurlyQuote: '\u2018',
+ operp: '\u29B9',
+ oplus: '\u2295',
+ Or: '\u2A54',
+ or: '\u2228',
+ orarr: '\u21BB',
+ ord: '\u2A5D',
+ order: '\u2134',
+ orderof: '\u2134',
+ ordf: '\u00AA',
+ ordm: '\u00BA',
+ origof: '\u22B6',
+ oror: '\u2A56',
+ orslope: '\u2A57',
+ orv: '\u2A5B',
+ oS: '\u24C8',
+ Oscr: '\uD835\uDCAA',
+ oscr: '\u2134',
+ Oslash: '\u00D8',
+ oslash: '\u00F8',
+ osol: '\u2298',
+ Otilde: '\u00D5',
+ otilde: '\u00F5',
+ Otimes: '\u2A37',
+ otimes: '\u2297',
+ otimesas: '\u2A36',
+ Ouml: '\u00D6',
+ ouml: '\u00F6',
+ ovbar: '\u233D',
+ OverBar: '\u203E',
+ OverBrace: '\u23DE',
+ OverBracket: '\u23B4',
+ OverParenthesis: '\u23DC',
+ par: '\u2225',
+ para: '\u00B6',
+ parallel: '\u2225',
+ parsim: '\u2AF3',
+ parsl: '\u2AFD',
+ part: '\u2202',
+ PartialD: '\u2202',
+ Pcy: '\u041F',
+ pcy: '\u043F',
+ percnt: '\u0025',
+ period: '\u002E',
+ permil: '\u2030',
+ perp: '\u22A5',
+ pertenk: '\u2031',
+ Pfr: '\uD835\uDD13',
+ pfr: '\uD835\uDD2D',
+ Phi: '\u03A6',
+ phi: '\u03C6',
+ phiv: '\u03D5',
+ phmmat: '\u2133',
+ phone: '\u260E',
+ Pi: '\u03A0',
+ pi: '\u03C0',
+ pitchfork: '\u22D4',
+ piv: '\u03D6',
+ planck: '\u210F',
+ planckh: '\u210E',
+ plankv: '\u210F',
+ plus: '\u002B',
+ plusacir: '\u2A23',
+ plusb: '\u229E',
+ pluscir: '\u2A22',
+ plusdo: '\u2214',
+ plusdu: '\u2A25',
+ pluse: '\u2A72',
+ PlusMinus: '\u00B1',
+ plusmn: '\u00B1',
+ plussim: '\u2A26',
+ plustwo: '\u2A27',
+ pm: '\u00B1',
+ Poincareplane: '\u210C',
+ pointint: '\u2A15',
+ Popf: '\u2119',
+ popf: '\uD835\uDD61',
+ pound: '\u00A3',
+ Pr: '\u2ABB',
+ pr: '\u227A',
+ prap: '\u2AB7',
+ prcue: '\u227C',
+ prE: '\u2AB3',
+ pre: '\u2AAF',
+ prec: '\u227A',
+ precapprox: '\u2AB7',
+ preccurlyeq: '\u227C',
+ Precedes: '\u227A',
+ PrecedesEqual: '\u2AAF',
+ PrecedesSlantEqual: '\u227C',
+ PrecedesTilde: '\u227E',
+ preceq: '\u2AAF',
+ precnapprox: '\u2AB9',
+ precneqq: '\u2AB5',
+ precnsim: '\u22E8',
+ precsim: '\u227E',
+ Prime: '\u2033',
+ prime: '\u2032',
+ primes: '\u2119',
+ prnap: '\u2AB9',
+ prnE: '\u2AB5',
+ prnsim: '\u22E8',
+ prod: '\u220F',
+ Product: '\u220F',
+ profalar: '\u232E',
+ profline: '\u2312',
+ profsurf: '\u2313',
+ prop: '\u221D',
+ Proportion: '\u2237',
+ Proportional: '\u221D',
+ propto: '\u221D',
+ prsim: '\u227E',
+ prurel: '\u22B0',
+ Pscr: '\uD835\uDCAB',
+ pscr: '\uD835\uDCC5',
+ Psi: '\u03A8',
+ psi: '\u03C8',
+ puncsp: '\u2008',
+ Qfr: '\uD835\uDD14',
+ qfr: '\uD835\uDD2E',
+ qint: '\u2A0C',
+ Qopf: '\u211A',
+ qopf: '\uD835\uDD62',
+ qprime: '\u2057',
+ Qscr: '\uD835\uDCAC',
+ qscr: '\uD835\uDCC6',
+ quaternions: '\u210D',
+ quatint: '\u2A16',
+ quest: '\u003F',
+ questeq: '\u225F',
+ QUOT: '\u0022',
+ quot: '\u0022',
+ rAarr: '\u21DB',
+ race: '\u223D\u0331',
+ Racute: '\u0154',
+ racute: '\u0155',
+ radic: '\u221A',
+ raemptyv: '\u29B3',
+ Rang: '\u27EB',
+ rang: '\u27E9',
+ rangd: '\u2992',
+ range: '\u29A5',
+ rangle: '\u27E9',
+ raquo: '\u00BB',
+ Rarr: '\u21A0',
+ rArr: '\u21D2',
+ rarr: '\u2192',
+ rarrap: '\u2975',
+ rarrb: '\u21E5',
+ rarrbfs: '\u2920',
+ rarrc: '\u2933',
+ rarrfs: '\u291E',
+ rarrhk: '\u21AA',
+ rarrlp: '\u21AC',
+ rarrpl: '\u2945',
+ rarrsim: '\u2974',
+ Rarrtl: '\u2916',
+ rarrtl: '\u21A3',
+ rarrw: '\u219D',
+ rAtail: '\u291C',
+ ratail: '\u291A',
+ ratio: '\u2236',
+ rationals: '\u211A',
+ RBarr: '\u2910',
+ rBarr: '\u290F',
+ rbarr: '\u290D',
+ rbbrk: '\u2773',
+ rbrace: '\u007D',
+ rbrack: '\u005D',
+ rbrke: '\u298C',
+ rbrksld: '\u298E',
+ rbrkslu: '\u2990',
+ Rcaron: '\u0158',
+ rcaron: '\u0159',
+ Rcedil: '\u0156',
+ rcedil: '\u0157',
+ rceil: '\u2309',
+ rcub: '\u007D',
+ Rcy: '\u0420',
+ rcy: '\u0440',
+ rdca: '\u2937',
+ rdldhar: '\u2969',
+ rdquo: '\u201D',
+ rdquor: '\u201D',
+ rdsh: '\u21B3',
+ Re: '\u211C',
+ real: '\u211C',
+ realine: '\u211B',
+ realpart: '\u211C',
+ reals: '\u211D',
+ rect: '\u25AD',
+ REG: '\u00AE',
+ reg: '\u00AE',
+ ReverseElement: '\u220B',
+ ReverseEquilibrium: '\u21CB',
+ ReverseUpEquilibrium: '\u296F',
+ rfisht: '\u297D',
+ rfloor: '\u230B',
+ Rfr: '\u211C',
+ rfr: '\uD835\uDD2F',
+ rHar: '\u2964',
+ rhard: '\u21C1',
+ rharu: '\u21C0',
+ rharul: '\u296C',
+ Rho: '\u03A1',
+ rho: '\u03C1',
+ rhov: '\u03F1',
+ RightAngleBracket: '\u27E9',
+ RightArrow: '\u2192',
+ Rightarrow: '\u21D2',
+ rightarrow: '\u2192',
+ RightArrowBar: '\u21E5',
+ RightArrowLeftArrow: '\u21C4',
+ rightarrowtail: '\u21A3',
+ RightCeiling: '\u2309',
+ RightDoubleBracket: '\u27E7',
+ RightDownTeeVector: '\u295D',
+ RightDownVector: '\u21C2',
+ RightDownVectorBar: '\u2955',
+ RightFloor: '\u230B',
+ rightharpoondown: '\u21C1',
+ rightharpoonup: '\u21C0',
+ rightleftarrows: '\u21C4',
+ rightleftharpoons: '\u21CC',
+ rightrightarrows: '\u21C9',
+ rightsquigarrow: '\u219D',
+ RightTee: '\u22A2',
+ RightTeeArrow: '\u21A6',
+ RightTeeVector: '\u295B',
+ rightthreetimes: '\u22CC',
+ RightTriangle: '\u22B3',
+ RightTriangleBar: '\u29D0',
+ RightTriangleEqual: '\u22B5',
+ RightUpDownVector: '\u294F',
+ RightUpTeeVector: '\u295C',
+ RightUpVector: '\u21BE',
+ RightUpVectorBar: '\u2954',
+ RightVector: '\u21C0',
+ RightVectorBar: '\u2953',
+ ring: '\u02DA',
+ risingdotseq: '\u2253',
+ rlarr: '\u21C4',
+ rlhar: '\u21CC',
+ rlm: '\u200F',
+ rmoust: '\u23B1',
+ rmoustache: '\u23B1',
+ rnmid: '\u2AEE',
+ roang: '\u27ED',
+ roarr: '\u21FE',
+ robrk: '\u27E7',
+ ropar: '\u2986',
+ Ropf: '\u211D',
+ ropf: '\uD835\uDD63',
+ roplus: '\u2A2E',
+ rotimes: '\u2A35',
+ RoundImplies: '\u2970',
+ rpar: '\u0029',
+ rpargt: '\u2994',
+ rppolint: '\u2A12',
+ rrarr: '\u21C9',
+ Rrightarrow: '\u21DB',
+ rsaquo: '\u203A',
+ Rscr: '\u211B',
+ rscr: '\uD835\uDCC7',
+ Rsh: '\u21B1',
+ rsh: '\u21B1',
+ rsqb: '\u005D',
+ rsquo: '\u2019',
+ rsquor: '\u2019',
+ rthree: '\u22CC',
+ rtimes: '\u22CA',
+ rtri: '\u25B9',
+ rtrie: '\u22B5',
+ rtrif: '\u25B8',
+ rtriltri: '\u29CE',
+ RuleDelayed: '\u29F4',
+ ruluhar: '\u2968',
+ rx: '\u211E',
+ Sacute: '\u015A',
+ sacute: '\u015B',
+ sbquo: '\u201A',
+ Sc: '\u2ABC',
+ sc: '\u227B',
+ scap: '\u2AB8',
+ Scaron: '\u0160',
+ scaron: '\u0161',
+ sccue: '\u227D',
+ scE: '\u2AB4',
+ sce: '\u2AB0',
+ Scedil: '\u015E',
+ scedil: '\u015F',
+ Scirc: '\u015C',
+ scirc: '\u015D',
+ scnap: '\u2ABA',
+ scnE: '\u2AB6',
+ scnsim: '\u22E9',
+ scpolint: '\u2A13',
+ scsim: '\u227F',
+ Scy: '\u0421',
+ scy: '\u0441',
+ sdot: '\u22C5',
+ sdotb: '\u22A1',
+ sdote: '\u2A66',
+ searhk: '\u2925',
+ seArr: '\u21D8',
+ searr: '\u2198',
+ searrow: '\u2198',
+ sect: '\u00A7',
+ semi: '\u003B',
+ seswar: '\u2929',
+ setminus: '\u2216',
+ setmn: '\u2216',
+ sext: '\u2736',
+ Sfr: '\uD835\uDD16',
+ sfr: '\uD835\uDD30',
+ sfrown: '\u2322',
+ sharp: '\u266F',
+ SHCHcy: '\u0429',
+ shchcy: '\u0449',
+ SHcy: '\u0428',
+ shcy: '\u0448',
+ ShortDownArrow: '\u2193',
+ ShortLeftArrow: '\u2190',
+ shortmid: '\u2223',
+ shortparallel: '\u2225',
+ ShortRightArrow: '\u2192',
+ ShortUpArrow: '\u2191',
+ shy: '\u00AD',
+ Sigma: '\u03A3',
+ sigma: '\u03C3',
+ sigmaf: '\u03C2',
+ sigmav: '\u03C2',
+ sim: '\u223C',
+ simdot: '\u2A6A',
+ sime: '\u2243',
+ simeq: '\u2243',
+ simg: '\u2A9E',
+ simgE: '\u2AA0',
+ siml: '\u2A9D',
+ simlE: '\u2A9F',
+ simne: '\u2246',
+ simplus: '\u2A24',
+ simrarr: '\u2972',
+ slarr: '\u2190',
+ SmallCircle: '\u2218',
+ smallsetminus: '\u2216',
+ smashp: '\u2A33',
+ smeparsl: '\u29E4',
+ smid: '\u2223',
+ smile: '\u2323',
+ smt: '\u2AAA',
+ smte: '\u2AAC',
+ smtes: '\u2AAC\uFE00',
+ SOFTcy: '\u042C',
+ softcy: '\u044C',
+ sol: '\u002F',
+ solb: '\u29C4',
+ solbar: '\u233F',
+ Sopf: '\uD835\uDD4A',
+ sopf: '\uD835\uDD64',
+ spades: '\u2660',
+ spadesuit: '\u2660',
+ spar: '\u2225',
+ sqcap: '\u2293',
+ sqcaps: '\u2293\uFE00',
+ sqcup: '\u2294',
+ sqcups: '\u2294\uFE00',
+ Sqrt: '\u221A',
+ sqsub: '\u228F',
+ sqsube: '\u2291',
+ sqsubset: '\u228F',
+ sqsubseteq: '\u2291',
+ sqsup: '\u2290',
+ sqsupe: '\u2292',
+ sqsupset: '\u2290',
+ sqsupseteq: '\u2292',
+ squ: '\u25A1',
+ Square: '\u25A1',
+ square: '\u25A1',
+ SquareIntersection: '\u2293',
+ SquareSubset: '\u228F',
+ SquareSubsetEqual: '\u2291',
+ SquareSuperset: '\u2290',
+ SquareSupersetEqual: '\u2292',
+ SquareUnion: '\u2294',
+ squarf: '\u25AA',
+ squf: '\u25AA',
+ srarr: '\u2192',
+ Sscr: '\uD835\uDCAE',
+ sscr: '\uD835\uDCC8',
+ ssetmn: '\u2216',
+ ssmile: '\u2323',
+ sstarf: '\u22C6',
+ Star: '\u22C6',
+ star: '\u2606',
+ starf: '\u2605',
+ straightepsilon: '\u03F5',
+ straightphi: '\u03D5',
+ strns: '\u00AF',
+ Sub: '\u22D0',
+ sub: '\u2282',
+ subdot: '\u2ABD',
+ subE: '\u2AC5',
+ sube: '\u2286',
+ subedot: '\u2AC3',
+ submult: '\u2AC1',
+ subnE: '\u2ACB',
+ subne: '\u228A',
+ subplus: '\u2ABF',
+ subrarr: '\u2979',
+ Subset: '\u22D0',
+ subset: '\u2282',
+ subseteq: '\u2286',
+ subseteqq: '\u2AC5',
+ SubsetEqual: '\u2286',
+ subsetneq: '\u228A',
+ subsetneqq: '\u2ACB',
+ subsim: '\u2AC7',
+ subsub: '\u2AD5',
+ subsup: '\u2AD3',
+ succ: '\u227B',
+ succapprox: '\u2AB8',
+ succcurlyeq: '\u227D',
+ Succeeds: '\u227B',
+ SucceedsEqual: '\u2AB0',
+ SucceedsSlantEqual: '\u227D',
+ SucceedsTilde: '\u227F',
+ succeq: '\u2AB0',
+ succnapprox: '\u2ABA',
+ succneqq: '\u2AB6',
+ succnsim: '\u22E9',
+ succsim: '\u227F',
+ SuchThat: '\u220B',
+ Sum: '\u2211',
+ sum: '\u2211',
+ sung: '\u266A',
+ Sup: '\u22D1',
+ sup: '\u2283',
+ sup1: '\u00B9',
+ sup2: '\u00B2',
+ sup3: '\u00B3',
+ supdot: '\u2ABE',
+ supdsub: '\u2AD8',
+ supE: '\u2AC6',
+ supe: '\u2287',
+ supedot: '\u2AC4',
+ Superset: '\u2283',
+ SupersetEqual: '\u2287',
+ suphsol: '\u27C9',
+ suphsub: '\u2AD7',
+ suplarr: '\u297B',
+ supmult: '\u2AC2',
+ supnE: '\u2ACC',
+ supne: '\u228B',
+ supplus: '\u2AC0',
+ Supset: '\u22D1',
+ supset: '\u2283',
+ supseteq: '\u2287',
+ supseteqq: '\u2AC6',
+ supsetneq: '\u228B',
+ supsetneqq: '\u2ACC',
+ supsim: '\u2AC8',
+ supsub: '\u2AD4',
+ supsup: '\u2AD6',
+ swarhk: '\u2926',
+ swArr: '\u21D9',
+ swarr: '\u2199',
+ swarrow: '\u2199',
+ swnwar: '\u292A',
+ szlig: '\u00DF',
+ Tab: '\u0009',
+ target: '\u2316',
+ Tau: '\u03A4',
+ tau: '\u03C4',
+ tbrk: '\u23B4',
+ Tcaron: '\u0164',
+ tcaron: '\u0165',
+ Tcedil: '\u0162',
+ tcedil: '\u0163',
+ Tcy: '\u0422',
+ tcy: '\u0442',
+ tdot: '\u20DB',
+ telrec: '\u2315',
+ Tfr: '\uD835\uDD17',
+ tfr: '\uD835\uDD31',
+ there4: '\u2234',
+ Therefore: '\u2234',
+ therefore: '\u2234',
+ Theta: '\u0398',
+ theta: '\u03B8',
+ thetasym: '\u03D1',
+ thetav: '\u03D1',
+ thickapprox: '\u2248',
+ thicksim: '\u223C',
+ ThickSpace: '\u205F\u200A',
+ thinsp: '\u2009',
+ ThinSpace: '\u2009',
+ thkap: '\u2248',
+ thksim: '\u223C',
+ THORN: '\u00DE',
+ thorn: '\u00FE',
+ Tilde: '\u223C',
+ tilde: '\u02DC',
+ TildeEqual: '\u2243',
+ TildeFullEqual: '\u2245',
+ TildeTilde: '\u2248',
+ times: '\u00D7',
+ timesb: '\u22A0',
+ timesbar: '\u2A31',
+ timesd: '\u2A30',
+ tint: '\u222D',
+ toea: '\u2928',
+ top: '\u22A4',
+ topbot: '\u2336',
+ topcir: '\u2AF1',
+ Topf: '\uD835\uDD4B',
+ topf: '\uD835\uDD65',
+ topfork: '\u2ADA',
+ tosa: '\u2929',
+ tprime: '\u2034',
+ TRADE: '\u2122',
+ trade: '\u2122',
+ triangle: '\u25B5',
+ triangledown: '\u25BF',
+ triangleleft: '\u25C3',
+ trianglelefteq: '\u22B4',
+ triangleq: '\u225C',
+ triangleright: '\u25B9',
+ trianglerighteq: '\u22B5',
+ tridot: '\u25EC',
+ trie: '\u225C',
+ triminus: '\u2A3A',
+ TripleDot: '\u20DB',
+ triplus: '\u2A39',
+ trisb: '\u29CD',
+ tritime: '\u2A3B',
+ trpezium: '\u23E2',
+ Tscr: '\uD835\uDCAF',
+ tscr: '\uD835\uDCC9',
+ TScy: '\u0426',
+ tscy: '\u0446',
+ TSHcy: '\u040B',
+ tshcy: '\u045B',
+ Tstrok: '\u0166',
+ tstrok: '\u0167',
+ twixt: '\u226C',
+ twoheadleftarrow: '\u219E',
+ twoheadrightarrow: '\u21A0',
+ Uacute: '\u00DA',
+ uacute: '\u00FA',
+ Uarr: '\u219F',
+ uArr: '\u21D1',
+ uarr: '\u2191',
+ Uarrocir: '\u2949',
+ Ubrcy: '\u040E',
+ ubrcy: '\u045E',
+ Ubreve: '\u016C',
+ ubreve: '\u016D',
+ Ucirc: '\u00DB',
+ ucirc: '\u00FB',
+ Ucy: '\u0423',
+ ucy: '\u0443',
+ udarr: '\u21C5',
+ Udblac: '\u0170',
+ udblac: '\u0171',
+ udhar: '\u296E',
+ ufisht: '\u297E',
+ Ufr: '\uD835\uDD18',
+ ufr: '\uD835\uDD32',
+ Ugrave: '\u00D9',
+ ugrave: '\u00F9',
+ uHar: '\u2963',
+ uharl: '\u21BF',
+ uharr: '\u21BE',
+ uhblk: '\u2580',
+ ulcorn: '\u231C',
+ ulcorner: '\u231C',
+ ulcrop: '\u230F',
+ ultri: '\u25F8',
+ Umacr: '\u016A',
+ umacr: '\u016B',
+ uml: '\u00A8',
+ UnderBar: '\u005F',
+ UnderBrace: '\u23DF',
+ UnderBracket: '\u23B5',
+ UnderParenthesis: '\u23DD',
+ Union: '\u22C3',
+ UnionPlus: '\u228E',
+ Uogon: '\u0172',
+ uogon: '\u0173',
+ Uopf: '\uD835\uDD4C',
+ uopf: '\uD835\uDD66',
+ UpArrow: '\u2191',
+ Uparrow: '\u21D1',
+ uparrow: '\u2191',
+ UpArrowBar: '\u2912',
+ UpArrowDownArrow: '\u21C5',
+ UpDownArrow: '\u2195',
+ Updownarrow: '\u21D5',
+ updownarrow: '\u2195',
+ UpEquilibrium: '\u296E',
+ upharpoonleft: '\u21BF',
+ upharpoonright: '\u21BE',
+ uplus: '\u228E',
+ UpperLeftArrow: '\u2196',
+ UpperRightArrow: '\u2197',
+ Upsi: '\u03D2',
+ upsi: '\u03C5',
+ upsih: '\u03D2',
+ Upsilon: '\u03A5',
+ upsilon: '\u03C5',
+ UpTee: '\u22A5',
+ UpTeeArrow: '\u21A5',
+ upuparrows: '\u21C8',
+ urcorn: '\u231D',
+ urcorner: '\u231D',
+ urcrop: '\u230E',
+ Uring: '\u016E',
+ uring: '\u016F',
+ urtri: '\u25F9',
+ Uscr: '\uD835\uDCB0',
+ uscr: '\uD835\uDCCA',
+ utdot: '\u22F0',
+ Utilde: '\u0168',
+ utilde: '\u0169',
+ utri: '\u25B5',
+ utrif: '\u25B4',
+ uuarr: '\u21C8',
+ Uuml: '\u00DC',
+ uuml: '\u00FC',
+ uwangle: '\u29A7',
+ vangrt: '\u299C',
+ varepsilon: '\u03F5',
+ varkappa: '\u03F0',
+ varnothing: '\u2205',
+ varphi: '\u03D5',
+ varpi: '\u03D6',
+ varpropto: '\u221D',
+ vArr: '\u21D5',
+ varr: '\u2195',
+ varrho: '\u03F1',
+ varsigma: '\u03C2',
+ varsubsetneq: '\u228A\uFE00',
+ varsubsetneqq: '\u2ACB\uFE00',
+ varsupsetneq: '\u228B\uFE00',
+ varsupsetneqq: '\u2ACC\uFE00',
+ vartheta: '\u03D1',
+ vartriangleleft: '\u22B2',
+ vartriangleright: '\u22B3',
+ Vbar: '\u2AEB',
+ vBar: '\u2AE8',
+ vBarv: '\u2AE9',
+ Vcy: '\u0412',
+ vcy: '\u0432',
+ VDash: '\u22AB',
+ Vdash: '\u22A9',
+ vDash: '\u22A8',
+ vdash: '\u22A2',
+ Vdashl: '\u2AE6',
+ Vee: '\u22C1',
+ vee: '\u2228',
+ veebar: '\u22BB',
+ veeeq: '\u225A',
+ vellip: '\u22EE',
+ Verbar: '\u2016',
+ verbar: '\u007C',
+ Vert: '\u2016',
+ vert: '\u007C',
+ VerticalBar: '\u2223',
+ VerticalLine: '\u007C',
+ VerticalSeparator: '\u2758',
+ VerticalTilde: '\u2240',
+ VeryThinSpace: '\u200A',
+ Vfr: '\uD835\uDD19',
+ vfr: '\uD835\uDD33',
+ vltri: '\u22B2',
+ vnsub: '\u2282\u20D2',
+ vnsup: '\u2283\u20D2',
+ Vopf: '\uD835\uDD4D',
+ vopf: '\uD835\uDD67',
+ vprop: '\u221D',
+ vrtri: '\u22B3',
+ Vscr: '\uD835\uDCB1',
+ vscr: '\uD835\uDCCB',
+ vsubnE: '\u2ACB\uFE00',
+ vsubne: '\u228A\uFE00',
+ vsupnE: '\u2ACC\uFE00',
+ vsupne: '\u228B\uFE00',
+ Vvdash: '\u22AA',
+ vzigzag: '\u299A',
+ Wcirc: '\u0174',
+ wcirc: '\u0175',
+ wedbar: '\u2A5F',
+ Wedge: '\u22C0',
+ wedge: '\u2227',
+ wedgeq: '\u2259',
+ weierp: '\u2118',
+ Wfr: '\uD835\uDD1A',
+ wfr: '\uD835\uDD34',
+ Wopf: '\uD835\uDD4E',
+ wopf: '\uD835\uDD68',
+ wp: '\u2118',
+ wr: '\u2240',
+ wreath: '\u2240',
+ Wscr: '\uD835\uDCB2',
+ wscr: '\uD835\uDCCC',
+ xcap: '\u22C2',
+ xcirc: '\u25EF',
+ xcup: '\u22C3',
+ xdtri: '\u25BD',
+ Xfr: '\uD835\uDD1B',
+ xfr: '\uD835\uDD35',
+ xhArr: '\u27FA',
+ xharr: '\u27F7',
+ Xi: '\u039E',
+ xi: '\u03BE',
+ xlArr: '\u27F8',
+ xlarr: '\u27F5',
+ xmap: '\u27FC',
+ xnis: '\u22FB',
+ xodot: '\u2A00',
+ Xopf: '\uD835\uDD4F',
+ xopf: '\uD835\uDD69',
+ xoplus: '\u2A01',
+ xotime: '\u2A02',
+ xrArr: '\u27F9',
+ xrarr: '\u27F6',
+ Xscr: '\uD835\uDCB3',
+ xscr: '\uD835\uDCCD',
+ xsqcup: '\u2A06',
+ xuplus: '\u2A04',
+ xutri: '\u25B3',
+ xvee: '\u22C1',
+ xwedge: '\u22C0',
+ Yacute: '\u00DD',
+ yacute: '\u00FD',
+ YAcy: '\u042F',
+ yacy: '\u044F',
+ Ycirc: '\u0176',
+ ycirc: '\u0177',
+ Ycy: '\u042B',
+ ycy: '\u044B',
+ yen: '\u00A5',
+ Yfr: '\uD835\uDD1C',
+ yfr: '\uD835\uDD36',
+ YIcy: '\u0407',
+ yicy: '\u0457',
+ Yopf: '\uD835\uDD50',
+ yopf: '\uD835\uDD6A',
+ Yscr: '\uD835\uDCB4',
+ yscr: '\uD835\uDCCE',
+ YUcy: '\u042E',
+ yucy: '\u044E',
+ Yuml: '\u0178',
+ yuml: '\u00FF',
+ Zacute: '\u0179',
+ zacute: '\u017A',
+ Zcaron: '\u017D',
+ zcaron: '\u017E',
+ Zcy: '\u0417',
+ zcy: '\u0437',
+ Zdot: '\u017B',
+ zdot: '\u017C',
+ zeetrf: '\u2128',
+ ZeroWidthSpace: '\u200B',
+ Zeta: '\u0396',
+ zeta: '\u03B6',
+ Zfr: '\u2128',
+ zfr: '\uD835\uDD37',
+ ZHcy: '\u0416',
+ zhcy: '\u0436',
+ zigrarr: '\u21DD',
+ Zopf: '\u2124',
+ zopf: '\uD835\uDD6B',
+ Zscr: '\uD835\uDCB5',
+ zscr: '\uD835\uDCCF',
+ zwj: '\u200D',
+ zwnj: '\u200C',
+});
+
+/**
+ * @deprecated
+ * Use `HTML_ENTITIES` instead.
+ * @see {@link HTML_ENTITIES}
+ */
+exports.entityMap = exports.HTML_ENTITIES;
diff --git a/node_modules/@xmldom/xmldom/lib/errors.js b/node_modules/@xmldom/xmldom/lib/errors.js
new file mode 100644
index 000000000..996cd3665
--- /dev/null
+++ b/node_modules/@xmldom/xmldom/lib/errors.js
@@ -0,0 +1,205 @@
+'use strict';
+
+var conventions = require('./conventions');
+
+function extendError(constructor, writableName) {
+ constructor.prototype = Object.create(Error.prototype, {
+ constructor: { value: constructor },
+ name: { value: constructor.name, enumerable: true, writable: writableName },
+ });
+}
+
+var DOMExceptionName = conventions.freeze({
+ /**
+ * the default value as defined by the spec
+ */
+ Error: 'Error',
+ /**
+ * @deprecated
+ * Use RangeError instead.
+ */
+ IndexSizeError: 'IndexSizeError',
+ /**
+ * @deprecated
+ * Just to match the related static code, not part of the spec.
+ */
+ DomstringSizeError: 'DomstringSizeError',
+ HierarchyRequestError: 'HierarchyRequestError',
+ WrongDocumentError: 'WrongDocumentError',
+ InvalidCharacterError: 'InvalidCharacterError',
+ /**
+ * @deprecated
+ * Just to match the related static code, not part of the spec.
+ */
+ NoDataAllowedError: 'NoDataAllowedError',
+ NoModificationAllowedError: 'NoModificationAllowedError',
+ NotFoundError: 'NotFoundError',
+ NotSupportedError: 'NotSupportedError',
+ InUseAttributeError: 'InUseAttributeError',
+ InvalidStateError: 'InvalidStateError',
+ SyntaxError: 'SyntaxError',
+ InvalidModificationError: 'InvalidModificationError',
+ NamespaceError: 'NamespaceError',
+ /**
+ * @deprecated
+ * Use TypeError for invalid arguments,
+ * "NotSupportedError" DOMException for unsupported operations,
+ * and "NotAllowedError" DOMException for denied requests instead.
+ */
+ InvalidAccessError: 'InvalidAccessError',
+ /**
+ * @deprecated
+ * Just to match the related static code, not part of the spec.
+ */
+ ValidationError: 'ValidationError',
+ /**
+ * @deprecated
+ * Use TypeError instead.
+ */
+ TypeMismatchError: 'TypeMismatchError',
+ SecurityError: 'SecurityError',
+ NetworkError: 'NetworkError',
+ AbortError: 'AbortError',
+ /**
+ * @deprecated
+ * Just to match the related static code, not part of the spec.
+ */
+ URLMismatchError: 'URLMismatchError',
+ QuotaExceededError: 'QuotaExceededError',
+ TimeoutError: 'TimeoutError',
+ InvalidNodeTypeError: 'InvalidNodeTypeError',
+ DataCloneError: 'DataCloneError',
+ EncodingError: 'EncodingError',
+ NotReadableError: 'NotReadableError',
+ UnknownError: 'UnknownError',
+ ConstraintError: 'ConstraintError',
+ DataError: 'DataError',
+ TransactionInactiveError: 'TransactionInactiveError',
+ ReadOnlyError: 'ReadOnlyError',
+ VersionError: 'VersionError',
+ OperationError: 'OperationError',
+ NotAllowedError: 'NotAllowedError',
+ OptOutError: 'OptOutError',
+});
+var DOMExceptionNames = Object.keys(DOMExceptionName);
+
+function isValidDomExceptionCode(value) {
+ return typeof value === 'number' && value >= 1 && value <= 25;
+}
+function endsWithError(value) {
+ return typeof value === 'string' && value.substring(value.length - DOMExceptionName.Error.length) === DOMExceptionName.Error;
+}
+/**
+ * DOM operations only raise exceptions in "exceptional" circumstances, i.e., when an operation
+ * is impossible to perform (either for logical reasons, because data is lost, or because the
+ * implementation has become unstable). In general, DOM methods return specific error values in
+ * ordinary processing situations, such as out-of-bound errors when using NodeList.
+ *
+ * Implementations should raise other exceptions under other circumstances. For example,
+ * implementations should raise an implementation-dependent exception if a null argument is
+ * passed when null was not expected.
+ *
+ * This implementation supports the following usages:
+ * 1. according to the living standard (both arguments are optional):
+ * ```
+ * new DOMException("message (can be empty)", DOMExceptionNames.HierarchyRequestError)
+ * ```
+ * 2. according to previous xmldom implementation (only the first argument is required):
+ * ```
+ * new DOMException(DOMException.HIERARCHY_REQUEST_ERR, "optional message")
+ * ```
+ * both result in the proper name being set.
+ *
+ * @class DOMException
+ * @param {number | string} messageOrCode
+ * The reason why an operation is not acceptable.
+ * If it is a number, it is used to determine the `name`, see
+ * {@link https://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-258A00AF ExceptionCode}
+ * @param {string | keyof typeof DOMExceptionName | Error} [nameOrMessage]
+ * The `name` to use for the error.
+ * If `messageOrCode` is a number, this arguments is used as the `message` instead.
+ * @augments Error
+ * @see https://webidl.spec.whatwg.org/#idl-DOMException
+ * @see https://webidl.spec.whatwg.org/#dfn-error-names-table
+ * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-17189187
+ * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/ecma-script-binding.html
+ * @see http://www.w3.org/TR/REC-DOM-Level-1/ecma-script-language-binding.html
+ */
+function DOMException(messageOrCode, nameOrMessage) {
+ // support old way of passing arguments: first argument is a valid number
+ if (isValidDomExceptionCode(messageOrCode)) {
+ this.name = DOMExceptionNames[messageOrCode];
+ this.message = nameOrMessage || '';
+ } else {
+ this.message = messageOrCode;
+ this.name = endsWithError(nameOrMessage) ? nameOrMessage : DOMExceptionName.Error;
+ }
+ if (Error.captureStackTrace) Error.captureStackTrace(this, DOMException);
+}
+extendError(DOMException, true);
+Object.defineProperties(DOMException.prototype, {
+ code: {
+ enumerable: true,
+ get: function () {
+ var code = DOMExceptionNames.indexOf(this.name);
+ if (isValidDomExceptionCode(code)) return code;
+ return 0;
+ },
+ },
+});
+
+var ExceptionCode = {
+ INDEX_SIZE_ERR: 1,
+ DOMSTRING_SIZE_ERR: 2,
+ HIERARCHY_REQUEST_ERR: 3,
+ WRONG_DOCUMENT_ERR: 4,
+ INVALID_CHARACTER_ERR: 5,
+ NO_DATA_ALLOWED_ERR: 6,
+ NO_MODIFICATION_ALLOWED_ERR: 7,
+ NOT_FOUND_ERR: 8,
+ NOT_SUPPORTED_ERR: 9,
+ INUSE_ATTRIBUTE_ERR: 10,
+ INVALID_STATE_ERR: 11,
+ SYNTAX_ERR: 12,
+ INVALID_MODIFICATION_ERR: 13,
+ NAMESPACE_ERR: 14,
+ INVALID_ACCESS_ERR: 15,
+ VALIDATION_ERR: 16,
+ TYPE_MISMATCH_ERR: 17,
+ SECURITY_ERR: 18,
+ NETWORK_ERR: 19,
+ ABORT_ERR: 20,
+ URL_MISMATCH_ERR: 21,
+ QUOTA_EXCEEDED_ERR: 22,
+ TIMEOUT_ERR: 23,
+ INVALID_NODE_TYPE_ERR: 24,
+ DATA_CLONE_ERR: 25,
+};
+
+var entries = Object.entries(ExceptionCode);
+for (var i = 0; i < entries.length; i++) {
+ var key = entries[i][0];
+ DOMException[key] = entries[i][1];
+}
+
+/**
+ * Creates an error that will not be caught by XMLReader aka the SAX parser.
+ *
+ * @class
+ * @param {string} message
+ * @param {any} [locator]
+ * @param {Error} [cause]
+ * The error that caused this one, e.g. a `DOMException` thrown while building the DOM.
+ */
+function ParseError(message, locator, cause) {
+ this.message = message;
+ this.locator = locator;
+ this.cause = cause;
+ if (Error.captureStackTrace) Error.captureStackTrace(this, ParseError);
+}
+extendError(ParseError);
+
+exports.DOMException = DOMException;
+exports.DOMExceptionName = DOMExceptionName;
+exports.ExceptionCode = ExceptionCode;
+exports.ParseError = ParseError;
diff --git a/node_modules/@xmldom/xmldom/lib/grammar.js b/node_modules/@xmldom/xmldom/lib/grammar.js
new file mode 100644
index 000000000..01bf0a34d
--- /dev/null
+++ b/node_modules/@xmldom/xmldom/lib/grammar.js
@@ -0,0 +1,559 @@
+'use strict';
+
+/**
+ * Detects relevant unicode support for regular expressions in the runtime.
+ * Should the runtime not accepts the flag `u` or unicode ranges,
+ * character classes without unicode handling will be used.
+ *
+ * @param {typeof RegExp} [RegExpImpl=RegExp]
+ * For testing: the RegExp class.
+ * @returns {boolean}
+ * @see https://node.green/#ES2015-syntax-RegExp--y--and--u--flags
+ */
+function detectUnicodeSupport(RegExpImpl) {
+ try {
+ if (typeof RegExpImpl !== 'function') {
+ RegExpImpl = RegExp;
+ }
+ // eslint-disable-next-line es5/no-unicode-regex,es5/no-unicode-code-point-escape
+ var match = new RegExpImpl('\u{1d306}', 'u').exec('𝌆');
+ return !!match && match[0].length === 2;
+ } catch (error) {}
+ return false;
+}
+var UNICODE_SUPPORT = detectUnicodeSupport();
+
+/**
+ * Removes `[`, `]` and any trailing quantifiers from the source of a RegExp.
+ *
+ * @param {RegExp} regexp
+ */
+function chars(regexp) {
+ if (regexp.source[0] !== '[') {
+ throw new Error(regexp + ' can not be used with chars');
+ }
+ return regexp.source.slice(1, regexp.source.lastIndexOf(']'));
+}
+
+/**
+ * Creates a new character list regular expression,
+ * by removing `search` from the source of `regexp`.
+ *
+ * @param {RegExp} regexp
+ * @param {string} search
+ * The character(s) to remove.
+ * @returns {RegExp}
+ */
+function chars_without(regexp, search) {
+ if (regexp.source[0] !== '[') {
+ throw new Error('/' + regexp.source + '/ can not be used with chars_without');
+ }
+ if (!search || typeof search !== 'string') {
+ throw new Error(JSON.stringify(search) + ' is not a valid search');
+ }
+ if (regexp.source.indexOf(search) === -1) {
+ throw new Error('"' + search + '" is not is /' + regexp.source + '/');
+ }
+ if (search === '-' && regexp.source.indexOf(search) !== 1) {
+ throw new Error('"' + search + '" is not at the first postion of /' + regexp.source + '/');
+ }
+ return new RegExp(regexp.source.replace(search, ''), UNICODE_SUPPORT ? 'u' : '');
+}
+
+/**
+ * Combines and Regular expressions correctly by using `RegExp.source`.
+ *
+ * @param {...(RegExp | string)[]} args
+ * @returns {RegExp}
+ */
+function reg(args) {
+ var self = this;
+ return new RegExp(
+ Array.prototype.slice
+ .call(arguments)
+ .map(function (part) {
+ var isStr = typeof part === 'string';
+ if (isStr && self === undefined && part === '|') {
+ throw new Error('use regg instead of reg to wrap expressions with `|`!');
+ }
+ return isStr ? part : part.source;
+ })
+ .join(''),
+ UNICODE_SUPPORT ? 'u' : ''
+ );
+}
+
+/**
+ * Like `reg` but wraps the expression in `(?:`,`)` to create a non tracking group.
+ *
+ * @param {...(RegExp | string)[]} args
+ * @returns {RegExp}
+ */
+function regg(args) {
+ if (arguments.length === 0) {
+ throw new Error('no parameters provided');
+ }
+ return reg.apply(regg, ['(?:'].concat(Array.prototype.slice.call(arguments), [')']));
+}
+
+// /**
+// * Append ^ to the beginning of the expression.
+// * @param {...(RegExp | string)[]} args
+// * @returns {RegExp}
+// */
+// function reg_start(args) {
+// if (arguments.length === 0) {
+// throw new Error('no parameters provided');
+// }
+// return reg.apply(reg_start, ['^'].concat(Array.prototype.slice.call(arguments)));
+// }
+
+// https://www.w3.org/TR/xml/#document
+// `[1] document ::= prolog element Misc*`
+// https://www.w3.org/TR/xml11/#NT-document
+// `[1] document ::= ( prolog element Misc* ) - ( Char* RestrictedChar Char* )`
+
+/**
+ * A character usually appearing in wrongly converted strings.
+ *
+ * @type {string}
+ * @see https://en.wikipedia.org/wiki/Specials_(Unicode_block)#Replacement_character
+ * @see https://nodejs.dev/en/api/v18/buffer/#buffers-and-character-encodings
+ * @see https://www.unicode.org/faq/utf_bom.html#BOM
+ * @readonly
+ */
+var UNICODE_REPLACEMENT_CHARACTER = '\uFFFD';
+// https://www.w3.org/TR/xml/#NT-Char
+// any Unicode character, excluding the surrogate blocks, FFFE, and FFFF.
+// `[2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]`
+// https://www.w3.org/TR/xml11/#NT-Char
+// `[2] Char ::= [#x1-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]`
+// https://www.w3.org/TR/xml11/#NT-RestrictedChar
+// `[2a] RestrictedChar ::= [#x1-#x8] | [#xB-#xC] | [#xE-#x1F] | [#x7F-#x84] | [#x86-#x9F]`
+// https://www.w3.org/TR/xml11/#charsets
+var Char = /[-\x09\x0A\x0D\x20-\x2C\x2E-\uD7FF\uE000-\uFFFD]/; // without \u10000-\uEFFFF
+if (UNICODE_SUPPORT) {
+ // eslint-disable-next-line es5/no-unicode-code-point-escape
+ Char = reg('[', chars(Char), '\\u{10000}-\\u{10FFFF}', ']');
+}
+// Negation of Char: matches any character that is NOT a valid XML 1.0 Char.
+// Derived directly from the Char character class above (after the unicode-support extension).
+// XML 1.0 Char production [2]: #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
+// @see https://www.w3.org/TR/xml/#NT-Char
+var InvalidChar = new RegExp('[^' + chars(Char) + ']', UNICODE_SUPPORT ? 'u' : '');
+
+var _SChar = /[\x20\x09\x0D\x0A]/;
+var SChar_s = chars(_SChar);
+// https://www.w3.org/TR/xml11/#NT-S
+// `[3] S ::= (#x20 | #x9 | #xD | #xA)+`
+var S = reg(_SChar, '+');
+// optional whitespace described as `S?` in the grammar,
+// simplified to 0-n occurrences of the character class
+// instead of 0-1 occurrences of a non-capturing group around S
+var S_OPT = reg(_SChar, '*');
+
+// https://www.w3.org/TR/xml11/#NT-NameStartChar
+// `[4] NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]`
+var NameStartChar =
+ /[:_a-zA-Z\xC0-\xD6\xD8-\xF6\xF8-\u02FF\u0370-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/; // without \u10000-\uEFFFF
+if (UNICODE_SUPPORT) {
+ // eslint-disable-next-line es5/no-unicode-code-point-escape
+ NameStartChar = reg('[', chars(NameStartChar), '\\u{10000}-\\u{10FFFF}', ']');
+}
+var NameStartChar_s = chars(NameStartChar);
+
+// https://www.w3.org/TR/xml11/#NT-NameChar
+// `[4a] NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]`
+var NameChar = reg('[', NameStartChar_s, chars(/[-.0-9\xB7]/), chars(/[\u0300-\u036F\u203F-\u2040]/), ']');
+// https://www.w3.org/TR/xml11/#NT-Name
+// `[5] Name ::= NameStartChar (NameChar)*`
+var Name = reg(NameStartChar, NameChar, '*');
+// Full-string anchored matcher for requireWellFormed serializer checks
+// https://w3c.github.io/DOM-Parsing/#xml-serializing-a-document-node
+var Name_exact = reg('^', Name, '$');
+/*
+https://www.w3.org/TR/xml11/#NT-Names
+`[6] Names ::= Name (#x20 Name)*`
+*/
+
+// https://www.w3.org/TR/xml11/#NT-Nmtoken
+// `[7] Nmtoken ::= (NameChar)+`
+var Nmtoken = reg(NameChar, '+');
+/*
+https://www.w3.org/TR/xml11/#NT-Nmtokens
+`[8] Nmtokens ::= Nmtoken (#x20 Nmtoken)*`
+var Nmtokens = reg(Nmtoken, regg(/\x20/, Nmtoken), '*');
+*/
+
+// https://www.w3.org/TR/xml11/#NT-EntityRef
+// `[68] EntityRef ::= '&' Name ';'` [WFC: Entity Declared] [VC: Entity Declared] [WFC: Parsed Entity] [WFC: No Recursion]
+var EntityRef = reg('&', Name, ';');
+// https://www.w3.org/TR/xml11/#NT-CharRef
+// `[66] CharRef ::= '' [0-9]+ ';' | '' [0-9a-fA-F]+ ';'` [WFC: Legal Character]
+var CharRef = regg(/[0-9]+;|[0-9a-fA-F]+;/);
+
+/*
+https://www.w3.org/TR/xml11/#NT-Reference
+- `[67] Reference ::= EntityRef | CharRef`
+- `[66] CharRef ::= '' [0-9]+ ';' | '' [0-9a-fA-F]+ ';'` [WFC: Legal Character]
+- `[68] EntityRef ::= '&' Name ';'` [WFC: Entity Declared] [VC: Entity Declared] [WFC: Parsed Entity] [WFC: No Recursion]
+*/
+var Reference = regg(EntityRef, '|', CharRef);
+
+// https://www.w3.org/TR/xml11/#NT-PEReference
+// `[69] PEReference ::= '%' Name ';'`
+// [VC: Entity Declared] [WFC: No Recursion] [WFC: In DTD]
+var PEReference = reg('%', Name, ';');
+
+// https://www.w3.org/TR/xml11/#NT-EntityValue
+// `[9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"' | "'" ([^%&'] | PEReference | Reference)* "'"`
+var EntityValue = regg(
+ reg('"', regg(/[^%&"]/, '|', PEReference, '|', Reference), '*', '"'),
+ '|',
+ reg("'", regg(/[^%&']/, '|', PEReference, '|', Reference), '*', "'")
+);
+
+// https://www.w3.org/TR/xml11/#NT-AttValue
+// `[10] AttValue ::= '"' ([^<&"] | Reference)* '"' | "'" ([^<&'] | Reference)* "'"`
+var AttValue = regg('"', regg(/[^<&"]/, '|', Reference), '*', '"', '|', "'", regg(/[^<&']/, '|', Reference), '*', "'");
+
+// https://www.w3.org/TR/xml-names/#ns-decl
+// https://www.w3.org/TR/xml-names/#ns-qualnames
+// NameStartChar without ":"
+var NCNameStartChar = chars_without(NameStartChar, ':');
+// https://www.w3.org/TR/xml-names/#orphans
+// `[5] NCNameChar ::= NameChar - ':'`
+// An XML NameChar, minus the ":"
+var NCNameChar = chars_without(NameChar, ':');
+// https://www.w3.org/TR/xml-names/#NT-NCName
+// `[4] NCName ::= Name - (Char* ':' Char*)`
+// An XML Name, minus the ":"
+var NCName = reg(NCNameStartChar, NCNameChar, '*');
+// Full-string anchored matcher for requireWellFormed serializer checks
+// https://w3c.github.io/DOM-Parsing/#xml-serializing-a-document-node
+var NCName_exact = reg('^', NCName, '$');
+
+/**
+https://www.w3.org/TR/xml-names/#ns-qualnames
+
+```
+[7] QName ::= PrefixedName | UnprefixedName
+ === (NCName ':' NCName) | NCName
+ === NCName (':' NCName)?
+[8] PrefixedName ::= Prefix ':' LocalPart
+ === NCName ':' NCName
+[9] UnprefixedName ::= LocalPart
+ === NCName
+[10] Prefix ::= NCName
+[11] LocalPart ::= NCName
+```
+*/
+var QName = reg(NCName, regg(':', NCName), '?');
+var QName_exact = reg('^', QName, '$');
+var QName_group = reg('(', QName, ')');
+
+// https://www.w3.org/TR/xml11/#NT-SystemLiteral
+// `[11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")`
+var SystemLiteral = regg(/"[^"]*"|'[^']*'/);
+
+/*
+ https://www.w3.org/TR/xml11/#NT-PI
+ ```
+ [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
+ [16] PI ::= '' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
+ ```
+ target /xml/i is not excluded!
+*/
+// The `(?!S)` after the leading `S+` asserts the data starts with a non-whitespace
+// character (greedy `S+` already consumes all separating whitespace), pruning the
+// `S+`/`Char*?` whitespace overlap that otherwise makes an unterminated PI (no `?>`)
+// backtrack quadratically. The lookahead is non-capturing, so the data stays group 2.
+var PI = reg(/^<\?/, '(', Name, ')', regg(S, '(?!', _SChar, ')(', Char, '*?)'), '?', /\?>/);
+
+// https://www.w3.org/TR/xml11/#NT-PubidChar
+// `[13] PubidChar ::= #x20 | #xD | #xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%]`
+var PubidChar = /[\x20\x0D\x0Aa-zA-Z0-9-'()+,./:=?;!*#@$_%]/;
+
+// https://www.w3.org/TR/xml11/#NT-PubidLiteral
+// `[12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"`
+var PubidLiteral = regg('"', PubidChar, '*"', '|', "'", chars_without(PubidChar, "'"), "*'");
+
+// https://www.w3.org/TR/xml11/#NT-CharData
+// `[14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)`
+
+var COMMENT_START = '';
+// https://www.w3.org/TR/xml11/#NT-Comment
+// `[15] Comment ::= ''`
+var Comment = reg(COMMENT_START, regg(chars_without(Char, '-'), '|', reg('-', chars_without(Char, '-'))), '*', COMMENT_END);
+
+var PCDATA = '#PCDATA';
+// https://www.w3.org/TR/xml11/#NT-Mixed
+// `[51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' | '(' S? '#PCDATA' S? ')'`
+// https://www.w3.org/TR/xml-names/#NT-Mixed
+// `[51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? QName)* S? ')*' | '(' S? '#PCDATA' S? ')'`
+// [VC: Proper Group/PE Nesting] [VC: No Duplicate Types]
+var Mixed = regg(
+ reg(/\(/, S_OPT, PCDATA, regg(S_OPT, /\|/, S_OPT, QName), '*', S_OPT, /\)\*/),
+ '|',
+ reg(/\(/, S_OPT, PCDATA, S_OPT, /\)/)
+);
+
+var _children_quantity = /[?*+]?/;
+/*
+ `[49] choice ::= '(' S? cp ( S? '|' S? cp )+ S? ')'` [VC: Proper Group/PE Nesting]
+ `[50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'` [VC: Proper Group/PE Nesting]
+ simplification to solve circular referencing, but doesn't check validity constraint "Proper Group/PE Nesting"
+ var _choice_or_seq = reg('[', NameChar_s, SChar_s, chars(_children_quantity), '()|,]*');
+ ```
+ [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
+ === (Name | '(' S? cp ( S? '|' S? cp )+ S? ')' | '(' S? cp ( S? ',' S? cp )* S? ')') ('?' | '*' | '+')?
+ !== (Name | [_choice_or_seq]*) ('?' | '*' | '+')?
+ ```
+ simplification to solve circular referencing, but doesn't check validity constraint "Proper Group/PE Nesting"
+ var cp = reg(regg(Name, '|', _choice_or_seq), _children_quantity);
+*/
+/*
+Inefficient regular expression (High)
+This part of the regular expression may cause exponential backtracking on strings starting with '(|' and containing many repetitions of '|'.
+https://github.com/xmldom/xmldom/security/code-scanning/91
+var choice = regg(/\(/, S_OPT, cp, regg(S_OPT, /\|/, S_OPT, cp), '+', S_OPT, /\)/);
+*/
+/*
+Inefficient regular expression (High)
+This part of the regular expression may cause exponential backtracking on strings starting with '(,' and containing many repetitions of ','.
+https://github.com/xmldom/xmldom/security/code-scanning/92
+var seq = regg(/\(/, S_OPT, cp, regg(S_OPT, /,/, S_OPT, cp), '*', S_OPT, /\)/);
+*/
+
+// `[47] children ::= (choice | seq) ('?' | '*' | '+')?`
+// simplification to solve circular referencing, but doesn't check validity constraint "Proper Group/PE Nesting"
+var children = reg(/\([^>]+\)/, _children_quantity /*regg(choice, '|', seq), _children_quantity*/);
+
+// https://www.w3.org/TR/xml11/#NT-contentspec
+// `[46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children`
+var contentspec = regg('EMPTY', '|', 'ANY', '|', Mixed, '|', children);
+
+var ELEMENTDECL_START = ''`
+// https://www.w3.org/TR/xml-names/#NT-elementdecl
+// `[17] elementdecl ::= ''`
+// because of https://www.w3.org/TR/xml11/#NT-PEReference
+// since xmldom is not supporting replacements of PEReferences in the DTD
+// this also supports PEReference in the possible places
+var elementdecl = reg(ELEMENTDECL_START, S, regg(QName, '|', PEReference), S, regg(contentspec, '|', PEReference), S_OPT, '>');
+
+// https://www.w3.org/TR/xml11/#NT-NotationType
+// `[58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'`
+// [VC: Notation Attributes] [VC: One Notation Per Element Type] [VC: No Notation on Empty Element] [VC: No Duplicate Tokens]
+var NotationType = reg('NOTATION', S, /\(/, S_OPT, Name, regg(S_OPT, /\|/, S_OPT, Name), '*', S_OPT, /\)/);
+// https://www.w3.org/TR/xml11/#NT-Enumeration
+// `[59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'`
+// [VC: Enumeration] [VC: No Duplicate Tokens]
+var Enumeration = reg(/\(/, S_OPT, Nmtoken, regg(S_OPT, /\|/, S_OPT, Nmtoken), '*', S_OPT, /\)/);
+
+// https://www.w3.org/TR/xml11/#NT-EnumeratedType
+// `[57] EnumeratedType ::= NotationType | Enumeration`
+var EnumeratedType = regg(NotationType, '|', Enumeration);
+
+/*
+```
+[55] StringType ::= 'CDATA'
+[56] TokenizedType ::= 'ID' [VC: ID] [VC: One ID per Element Type] [VC: ID Attribute Default]
+ | 'IDREF' [VC: IDREF]
+ | 'IDREFS' [VC: IDREF]
+ | 'ENTITY' [VC: Entity Name]
+ | 'ENTITIES' [VC: Entity Name]
+ | 'NMTOKEN' [VC: Name Token]
+ | 'NMTOKENS' [VC: Name Token]
+ [54] AttType ::= StringType | TokenizedType | EnumeratedType
+```*/
+var AttType = regg(/CDATA|ID|IDREF|IDREFS|ENTITY|ENTITIES|NMTOKEN|NMTOKENS/, '|', EnumeratedType);
+
+// `[60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue)`
+// [WFC: No < in Attribute Values] [WFC: No External Entity References]
+// [VC: Fixed Attribute Default] [VC: Required Attribute] [VC: Attribute Default Value Syntactically Correct]
+var DefaultDecl = regg(/#REQUIRED|#IMPLIED/, '|', regg(regg('#FIXED', S), '?', AttValue));
+
+// https://www.w3.org/TR/xml11/#NT-AttDef
+// [53] AttDef ::= S Name S AttType S DefaultDecl
+// https://www.w3.org/TR/xml-names/#NT-AttDef
+// [1] NSAttName ::= PrefixedAttName | DefaultAttName
+// [2] PrefixedAttName ::= 'xmlns:' NCName [NSC: Reserved Prefixes and Namespace Names]
+// [3] DefaultAttName ::= 'xmlns'
+// [21] AttDef ::= S (QName | NSAttName) S AttType S DefaultDecl
+// === S Name S AttType S DefaultDecl
+// xmldom is not distinguishing between QName and NSAttName on this level
+// to support XML without namespaces in DTD we can not restrict it to QName
+var AttDef = regg(S, Name, S, AttType, S, DefaultDecl);
+
+var ATTLIST_DECL_START = ''`
+// https://www.w3.org/TR/xml-names/#NT-AttlistDecl
+// `[20] AttlistDecl ::= ''`
+// to support XML without namespaces in DTD we can not restrict it to QName
+var AttlistDecl = reg(ATTLIST_DECL_START, S, Name, AttDef, '*', S_OPT, '>');
+
+// https://html.spec.whatwg.org/multipage/urls-and-fetching.html#about:legacy-compat
+var ABOUT_LEGACY_COMPAT = 'about:legacy-compat';
+var ABOUT_LEGACY_COMPAT_SystemLiteral = regg('"' + ABOUT_LEGACY_COMPAT + '"', '|', "'" + ABOUT_LEGACY_COMPAT + "'");
+var SYSTEM = 'SYSTEM';
+var PUBLIC = 'PUBLIC';
+// https://www.w3.org/TR/xml11/#NT-ExternalID
+// `[75] ExternalID ::= 'SYSTEM' S SystemLiteral | 'PUBLIC' S PubidLiteral S SystemLiteral`
+var ExternalID = regg(regg(SYSTEM, S, SystemLiteral), '|', regg(PUBLIC, S, PubidLiteral, S, SystemLiteral));
+var ExternalID_match = reg(
+ '^',
+ regg(
+ regg(SYSTEM, S, '(?', SystemLiteral, ')'),
+ '|',
+ regg(PUBLIC, S, '(?', PubidLiteral, ')', S, '(?', SystemLiteral, ')')
+ )
+);
+// Full-string anchored matcher for requireWellFormed serializer checks
+// https://w3c.github.io/DOM-Parsing/#xml-serializing-a-document-node
+var PubidLiteral_match = reg('^', PubidLiteral, '$');
+// Full-string anchored matcher for requireWellFormed serializer checks
+// https://w3c.github.io/DOM-Parsing/#xml-serializing-a-document-node
+var SystemLiteral_match = reg('^', SystemLiteral, '$');
+
+// https://www.w3.org/TR/xml11/#NT-NDataDecl
+// `[76] NDataDecl ::= S 'NDATA' S Name` [VC: Notation Declared]
+var NDataDecl = regg(S, 'NDATA', S, Name);
+
+// https://www.w3.org/TR/xml11/#NT-EntityDef
+// `[73] EntityDef ::= EntityValue | (ExternalID NDataDecl?)`
+var EntityDef = regg(EntityValue, '|', regg(ExternalID, NDataDecl, '?'));
+
+var ENTITY_DECL_START = ''`
+var GEDecl = reg(ENTITY_DECL_START, S, Name, S, EntityDef, S_OPT, '>');
+// https://www.w3.org/TR/xml11/#NT-PEDef
+// `[74] PEDef ::= EntityValue | ExternalID`
+var PEDef = regg(EntityValue, '|', ExternalID);
+// https://www.w3.org/TR/xml11/#NT-PEDecl
+// `[72] PEDecl ::= ''`
+var PEDecl = reg(ENTITY_DECL_START, S, '%', S, Name, S, PEDef, S_OPT, '>');
+// https://www.w3.org/TR/xml11/#NT-EntityDecl
+// `[70] EntityDecl ::= GEDecl | PEDecl`
+var EntityDecl = regg(GEDecl, '|', PEDecl);
+
+// https://www.w3.org/TR/xml11/#NT-PublicID
+// `[83] PublicID ::= 'PUBLIC' S PubidLiteral`
+var PublicID = reg(PUBLIC, S, PubidLiteral);
+// https://www.w3.org/TR/xml11/#NT-NotationDecl
+// `[82] NotationDecl ::= ''` [VC: Unique Notation Name]
+var NotationDecl = reg('');
+
+// https://www.w3.org/TR/xml11/#NT-Eq
+// `[25] Eq ::= S? '=' S?`
+var Eq = reg(S_OPT, '=', S_OPT);
+// https://www.w3.org/TR/xml/#NT-VersionNum
+// `[26] VersionNum ::= '1.' [0-9]+`
+// https://www.w3.org/TR/xml11/#NT-VersionNum
+// `[26] VersionNum ::= '1.1'`
+var VersionNum = /1[.]\d+/;
+// https://www.w3.org/TR/xml11/#NT-VersionInfo
+// `[24] VersionInfo ::= S 'version' Eq ("'" VersionNum "'" | '"' VersionNum '"')`
+var VersionInfo = reg(S, 'version', Eq, regg("'", VersionNum, "'", '|', '"', VersionNum, '"'));
+// https://www.w3.org/TR/xml11/#NT-EncName
+// `[81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*`
+var EncName = /[A-Za-z][-A-Za-z0-9._]*/;
+// https://www.w3.org/TR/xml11/#NT-EncDecl
+// `[80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' | "'" EncName "'" )`
+var EncodingDecl = regg(S, 'encoding', Eq, regg('"', EncName, '"', '|', "'", EncName, "'"));
+// https://www.w3.org/TR/xml11/#NT-SDDecl
+// `[32] SDDecl ::= S 'standalone' Eq (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no') '"'))`
+var SDDecl = regg(S, 'standalone', Eq, regg("'", regg('yes', '|', 'no'), "'", '|', '"', regg('yes', '|', 'no'), '"'));
+// https://www.w3.org/TR/xml11/#NT-XMLDecl
+// [23] XMLDecl ::= ''
+var XMLDecl = reg(/^<\?xml/, VersionInfo, EncodingDecl, '?', SDDecl, '?', S_OPT, /\?>/);
+
+/*
+ https://www.w3.org/TR/xml/#NT-markupdecl
+ https://www.w3.org/TR/xml11/#NT-markupdecl
+ `[29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl | NotationDecl | PI | Comment`
+ var markupdecl = regg(elementdecl, '|', AttlistDecl, '|', EntityDecl, '|', NotationDecl, '|', PI_unsafe, '|', Comment);
+*/
+/*
+ https://www.w3.org/TR/xml-names/#NT-doctypedecl
+`[28a] DeclSep ::= PEReference | S`
+ https://www.w3.org/TR/xml11/#NT-intSubset
+```
+ [28b] intSubset ::= (markupdecl | DeclSep)*
+ === (markupdecl | PEReference | S)*
+```
+ [WFC: PE Between Declarations]
+ var intSubset = reg(regg(markupdecl, '|', PEReference, '|', S), '*');
+*/
+var DOCTYPE_DECL_START = ''`
+ https://www.afterwardsw3.org/TR/xml-names/#NT-doctypedecl
+ `[16] doctypedecl ::= ''`
+ var doctypedecl = reg('');
+*/
+
+var CDATA_START = '';
+var CDStart = //;
+var CData = reg(Char, '*?', CDEnd);
+/*
+ https://www.w3.org/TR/xml/#dt-cdsection
+ `[18] CDSect ::= CDStart CData CDEnd`
+ `[19] CDStart ::= '' Char*))`
+ `[21] CDEnd ::= ']]>'`
+*/
+var CDSect = reg(CDStart, CData);
+
+// unit tested
+exports.chars = chars;
+exports.chars_without = chars_without;
+exports.detectUnicodeSupport = detectUnicodeSupport;
+exports.reg = reg;
+exports.regg = regg;
+exports.ABOUT_LEGACY_COMPAT = ABOUT_LEGACY_COMPAT;
+exports.ABOUT_LEGACY_COMPAT_SystemLiteral = ABOUT_LEGACY_COMPAT_SystemLiteral;
+exports.AttlistDecl = AttlistDecl;
+exports.CDATA_START = CDATA_START;
+exports.CDATA_END = CDATA_END;
+exports.CDSect = CDSect;
+exports.Char = Char;
+exports.Comment = Comment;
+exports.COMMENT_START = COMMENT_START;
+exports.COMMENT_END = COMMENT_END;
+exports.DOCTYPE_DECL_START = DOCTYPE_DECL_START;
+exports.elementdecl = elementdecl;
+exports.EntityDecl = EntityDecl;
+exports.EntityValue = EntityValue;
+exports.ExternalID = ExternalID;
+exports.ExternalID_match = ExternalID_match;
+exports.Name = Name;
+exports.Name_exact = Name_exact;
+exports.NCName_exact = NCName_exact;
+exports.NotationDecl = NotationDecl;
+exports.Reference = Reference;
+exports.PEReference = PEReference;
+exports.PI = PI;
+exports.PUBLIC = PUBLIC;
+exports.PubidLiteral = PubidLiteral;
+exports.PubidLiteral_match = PubidLiteral_match;
+exports.QName = QName;
+exports.QName_exact = QName_exact;
+exports.QName_group = QName_group;
+exports.S = S;
+exports.SChar_s = SChar_s;
+exports.S_OPT = S_OPT;
+exports.SYSTEM = SYSTEM;
+exports.SystemLiteral = SystemLiteral;
+exports.SystemLiteral_match = SystemLiteral_match;
+exports.InvalidChar = InvalidChar;
+exports.UNICODE_REPLACEMENT_CHARACTER = UNICODE_REPLACEMENT_CHARACTER;
+exports.UNICODE_SUPPORT = UNICODE_SUPPORT;
+exports.XMLDecl = XMLDecl;
diff --git a/node_modules/@xmldom/xmldom/lib/index.js b/node_modules/@xmldom/xmldom/lib/index.js
new file mode 100644
index 000000000..6e873df9a
--- /dev/null
+++ b/node_modules/@xmldom/xmldom/lib/index.js
@@ -0,0 +1,41 @@
+'use strict';
+var conventions = require('./conventions');
+exports.assign = conventions.assign;
+exports.hasDefaultHTMLNamespace = conventions.hasDefaultHTMLNamespace;
+exports.isHTMLMimeType = conventions.isHTMLMimeType;
+exports.isValidMimeType = conventions.isValidMimeType;
+exports.MIME_TYPE = conventions.MIME_TYPE;
+exports.NAMESPACE = conventions.NAMESPACE;
+
+var errors = require('./errors');
+exports.DOMException = errors.DOMException;
+exports.DOMExceptionName = errors.DOMExceptionName;
+exports.ExceptionCode = errors.ExceptionCode;
+exports.ParseError = errors.ParseError;
+
+var dom = require('./dom');
+exports.Attr = dom.Attr;
+exports.CDATASection = dom.CDATASection;
+exports.CharacterData = dom.CharacterData;
+exports.Comment = dom.Comment;
+exports.Document = dom.Document;
+exports.DocumentFragment = dom.DocumentFragment;
+exports.DocumentType = dom.DocumentType;
+exports.DOMImplementation = dom.DOMImplementation;
+exports.Element = dom.Element;
+exports.Entity = dom.Entity;
+exports.EntityReference = dom.EntityReference;
+exports.LiveNodeList = dom.LiveNodeList;
+exports.NamedNodeMap = dom.NamedNodeMap;
+exports.Node = dom.Node;
+exports.NodeList = dom.NodeList;
+exports.Notation = dom.Notation;
+exports.ProcessingInstruction = dom.ProcessingInstruction;
+exports.Text = dom.Text;
+exports.XMLSerializer = dom.XMLSerializer;
+
+var domParser = require('./dom-parser');
+exports.DOMParser = domParser.DOMParser;
+exports.normalizeLineEndings = domParser.normalizeLineEndings;
+exports.onErrorStopParsing = domParser.onErrorStopParsing;
+exports.onWarningStopParsing = domParser.onWarningStopParsing;
diff --git a/node_modules/@xmldom/xmldom/lib/sax.js b/node_modules/@xmldom/xmldom/lib/sax.js
new file mode 100644
index 000000000..5b73d93a1
--- /dev/null
+++ b/node_modules/@xmldom/xmldom/lib/sax.js
@@ -0,0 +1,983 @@
+'use strict';
+
+var conventions = require('./conventions');
+var g = require('./grammar');
+var errors = require('./errors');
+
+var isHTMLEscapableRawTextElement = conventions.isHTMLEscapableRawTextElement;
+var isHTMLMimeType = conventions.isHTMLMimeType;
+var isHTMLRawTextElement = conventions.isHTMLRawTextElement;
+var hasOwn = conventions.hasOwn;
+var NAMESPACE = conventions.NAMESPACE;
+var ParseError = errors.ParseError;
+var DOMException = errors.DOMException;
+
+//var handlers = 'resolveEntity,getExternalSubset,characters,endDocument,endElement,endPrefixMapping,ignorableWhitespace,processingInstruction,setDocumentLocator,skippedEntity,startDocument,startElement,startPrefixMapping,notationDecl,unparsedEntityDecl,error,fatalError,warning,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,comment,endCDATA,endDTD,endEntity,startCDATA,startDTD,startEntity'.split(',')
+
+//S_TAG, S_ATTR, S_EQ, S_ATTR_NOQUOT_VALUE
+//S_ATTR_SPACE, S_ATTR_END, S_TAG_SPACE, S_TAG_CLOSE
+var S_TAG = 0; //tag name offerring
+var S_ATTR = 1; //attr name offerring
+var S_ATTR_SPACE = 2; //attr name end and space offer
+var S_EQ = 3; //=space?
+var S_ATTR_NOQUOT_VALUE = 4; //attr value(no quot value only)
+var S_ATTR_END = 5; //attr value end and no space(quot end)
+var S_TAG_SPACE = 6; //(attr value end || tag end ) && (space offer)
+var S_TAG_CLOSE = 7; //closed el
+
+function XMLReader() {}
+
+XMLReader.prototype = {
+ parse: function (source, defaultNSMap, entityMap) {
+ var domBuilder = this.domBuilder;
+ domBuilder.startDocument();
+ _copy(defaultNSMap, (defaultNSMap = Object.create(null)));
+ parse(source, defaultNSMap, entityMap, domBuilder, this.errorHandler);
+ domBuilder.endDocument();
+ },
+};
+
+/**
+ * Detecting everything that might be a reference,
+ * including those without ending `;`, since those are allowed in HTML.
+ * The entityReplacer takes care of verifying and transforming each occurrence,
+ * and reports to the errorHandler on those that are not OK,
+ * depending on the context.
+ */
+var ENTITY_REG = /?\w+;?/g;
+
+function parse(source, defaultNSMapCopy, entityMap, domBuilder, errorHandler) {
+ var isHTML = isHTMLMimeType(domBuilder.mimeType);
+ if (source.indexOf(g.UNICODE_REPLACEMENT_CHARACTER) >= 0) {
+ errorHandler.warning('Unicode replacement character detected, source encoding issues?');
+ }
+
+ function fixedFromCharCode(code) {
+ // String.prototype.fromCharCode does not supports
+ // > 2 bytes unicode chars directly
+ if (code > 0xffff) {
+ code -= 0x10000;
+ var surrogate1 = 0xd800 + (code >> 10),
+ surrogate2 = 0xdc00 + (code & 0x3ff);
+
+ return String.fromCharCode(surrogate1, surrogate2);
+ } else {
+ return String.fromCharCode(code);
+ }
+ }
+
+ function entityReplacer(a) {
+ var complete = a[a.length - 1] === ';' ? a : a + ';';
+ if (!isHTML && complete !== a) {
+ errorHandler.error('EntityRef: expecting ;');
+ return a;
+ }
+ var match = g.Reference.exec(complete);
+ if (!match || match[0].length !== complete.length) {
+ errorHandler.error('entity not matching Reference production: ' + a);
+ return a;
+ }
+ var k = complete.slice(1, -1);
+ if (hasOwn(entityMap, k)) {
+ return entityMap[k];
+ } else if (k.charAt(0) === '#') {
+ return fixedFromCharCode(parseInt(k.substring(1).replace('x', '0x')));
+ } else {
+ errorHandler.error('entity not found:' + a);
+ return a;
+ }
+ }
+
+ function appendText(end) {
+ //has some bugs
+ if (end > start) {
+ var xt = source.substring(start, end).replace(ENTITY_REG, entityReplacer);
+ locator && position(start);
+ domBuilder.characters(xt, 0, end - start);
+ start = end;
+ }
+ }
+
+ var lineStart = 0;
+ var lineEnd = 0;
+ var linePattern = /\r\n?|\n|$/g;
+ var locator = domBuilder.locator;
+
+ function position(p, m) {
+ while (p >= lineEnd && (m = linePattern.exec(source))) {
+ lineStart = lineEnd;
+ lineEnd = m.index + m[0].length;
+ locator.lineNumber++;
+ }
+ locator.columnNumber = p - lineStart + 1;
+ }
+
+ var parseStack = [{ currentNSMap: defaultNSMapCopy }];
+ var unclosedTags = [];
+ var start = 0;
+ while (true) {
+ try {
+ var tagStart = source.indexOf('<', start);
+ if (tagStart < 0) {
+ if (!isHTML && unclosedTags.length > 0) {
+ return errorHandler.fatalError('unclosed xml tag(s): ' + unclosedTags.join(', '));
+ }
+ if (!source.substring(start).match(/^\s*$/)) {
+ var doc = domBuilder.doc;
+ var text = doc.createTextNode(source.substring(start));
+ if (doc.documentElement) {
+ // `return errorHandler.error` is not a common pattern,
+ // it is usually only used with `.fatalError`s.
+ // In this case it is intentional, because it allows to stop parsing
+ // and returning doc after reporting the extra content that will not be part of the document.
+ return errorHandler.error('Extra content at the end of the document');
+ }
+ doc.appendChild(text);
+ domBuilder.currentElement = text;
+ }
+ return;
+ }
+ if (tagStart > start) {
+ var fromSource = source.substring(start, tagStart);
+ if (!isHTML && unclosedTags.length === 0) {
+ fromSource = fromSource.replace(new RegExp(g.S_OPT.source, 'g'), '');
+ fromSource && errorHandler.error("Unexpected content outside root element: '" + fromSource + "'");
+ }
+ appendText(tagStart);
+ }
+ switch (source.charAt(tagStart + 1)) {
+ case '/':
+ var end = source.indexOf('>', tagStart + 2);
+ var tagNameRaw = source.substring(tagStart + 2, end > 0 ? end : undefined);
+ if (!tagNameRaw) {
+ return errorHandler.fatalError('end tag name missing');
+ }
+ var endTagNameStrict = g.reg('^', g.QName_group, g.S_OPT, '$');
+ var tagNameMatch = end > 0 && endTagNameStrict.exec(tagNameRaw);
+ if (!tagNameMatch) {
+ var leadingTagNameMatch = end > 0 && g.reg('^', g.QName_group).exec(tagNameRaw);
+ if (isHTML && leadingTagNameMatch) {
+ errorHandler.warning('end tag name contains invalid trailing characters: "' + tagNameRaw + '"');
+ tagNameMatch = leadingTagNameMatch;
+ } else if (
+ // Backward compatibility, remove this whole `else if` arm in the next breaking release
+ // (XML then falls through to the `fatalError` below, for a clean mode split: XML fatal,
+ // HTML warning). A valid end-tag name followed by a line break and trailing content was
+ // silently accepted while `reg` still used the `m` flag; re-adding `m` here matches exactly
+ // those inputs, kept recoverable and reported.
+ leadingTagNameMatch &&
+ new RegExp(endTagNameStrict.source, endTagNameStrict.flags + 'm').test(tagNameRaw)
+ ) {
+ errorHandler.error('end tag name is followed by a line break and trailing content: "' + tagNameRaw + '"');
+ tagNameMatch = leadingTagNameMatch;
+ } else {
+ return errorHandler.fatalError('end tag name contains invalid characters: "' + tagNameRaw + '"');
+ }
+ }
+ if (!domBuilder.currentElement && !domBuilder.doc.documentElement) {
+ // not enough information to provide a helpful error message,
+ // but parsing will throw since there is no root element
+ return;
+ }
+ var currentTagName =
+ unclosedTags[unclosedTags.length - 1] ||
+ domBuilder.currentElement.tagName ||
+ domBuilder.doc.documentElement.tagName ||
+ '';
+ if (currentTagName !== tagNameMatch[1]) {
+ var tagNameLower = tagNameMatch[1].toLowerCase();
+ if (!isHTML || currentTagName.toLowerCase() !== tagNameLower) {
+ return errorHandler.fatalError('Opening and ending tag mismatch: "' + currentTagName + '" != "' + tagNameRaw + '"');
+ }
+ }
+ var config = parseStack.pop();
+ unclosedTags.pop();
+ var localNSMap = config.localNSMap;
+ domBuilder.endElement(config.uri, config.localName, currentTagName);
+ if (localNSMap) {
+ for (var prefix in localNSMap) {
+ if (hasOwn(localNSMap, prefix)) {
+ domBuilder.endPrefixMapping(prefix);
+ }
+ }
+ }
+
+ end++;
+ break;
+ // end element
+ case '?': // ...?>
+ locator && position(tagStart);
+ end = parseProcessingInstruction(source, tagStart, domBuilder, errorHandler);
+ break;
+ case '!': // start) {
+ start = end;
+ } else {
+ //Possible sax fallback here, risk of positional error
+ appendText(Math.max(tagStart, start) + 1);
+ }
+ }
+}
+
+function copyLocator(f, t) {
+ t.lineNumber = f.lineNumber;
+ t.columnNumber = f.columnNumber;
+ return t;
+}
+
+/**
+ * @returns
+ * end of the elementStartPart(end of elementEndPart for selfClosed el)
+ * @see {@link #appendElement}
+ */
+function parseElementStartPart(source, start, el, currentNSMap, entityReplacer, errorHandler, isHTML) {
+ /**
+ * @param {string} qname
+ * @param {string} value
+ * @param {number} startIndex
+ */
+ function addAttribute(qname, value, startIndex) {
+ if (hasOwn(el.attributeNames, qname)) {
+ return errorHandler.fatalError('Attribute ' + qname + ' redefined');
+ }
+ if (!isHTML && value.indexOf('<') >= 0) {
+ return errorHandler.fatalError("Unescaped '<' not allowed in attributes values");
+ }
+ el.addValue(
+ qname,
+ // @see https://www.w3.org/TR/xml/#AVNormalize
+ // since the xmldom sax parser does not "interpret" DTD the following is not implemented:
+ // - recursive replacement of (DTD) entity references
+ // - trimming and collapsing multiple spaces into a single one for attributes that are not of type CDATA
+ value.replace(/[\t\n\r]/g, ' ').replace(ENTITY_REG, entityReplacer),
+ startIndex
+ );
+ }
+
+ var attrName;
+ var value;
+ var p = ++start;
+ var s = S_TAG; //status
+ while (true) {
+ var c = source.charAt(p);
+ if (s === S_TAG && c === '<') {
+ // A `<` can never occur inside a tag name. Without this guard the scan runs
+ // on to the next `>` (or EOF) before `setTagName` rejects the whole slice, so
+ // a document with many `<` inside a malformed tag makes each one-character
+ // recovery step re-scan to the distant `>` — O(n^2). Stopping at the `<` keeps
+ // each recovery step bounded. The candidate scanned so far is reported raw,
+ // consistent with the sibling invalid-tag-name throw below.
+ throw new Error('unexpected < in tag name: ' + source.slice(start, p));
+ }
+ switch (c) {
+ case '=':
+ if (s === S_ATTR) {
+ //attrName
+ attrName = source.slice(start, p);
+ s = S_EQ;
+ } else if (s === S_ATTR_SPACE) {
+ s = S_EQ;
+ } else {
+ //fatalError: equal must after attrName or space after attrName
+ throw new Error('attribute equal must after attrName');
+ }
+ break;
+ case "'":
+ case '"':
+ if (
+ s === S_EQ ||
+ s === S_ATTR //|| s == S_ATTR_SPACE
+ ) {
+ //equal
+ if (s === S_ATTR) {
+ errorHandler.warning('attribute value must after "="');
+ attrName = source.slice(start, p);
+ }
+ start = p + 1;
+ p = source.indexOf(c, start);
+ if (p > 0) {
+ value = source.slice(start, p);
+ addAttribute(attrName, value, start - 1);
+ s = S_ATTR_END;
+ } else {
+ //fatalError: no end quot match
+ throw new Error("attribute value no end '" + c + "' match");
+ }
+ } else if (s == S_ATTR_NOQUOT_VALUE) {
+ value = source.slice(start, p);
+ addAttribute(attrName, value, start);
+ errorHandler.warning('attribute "' + attrName + '" missed start quot(' + c + ')!!');
+ start = p + 1;
+ s = S_ATTR_END;
+ } else {
+ //fatalError: no equal before
+ throw new Error('attribute value must after "="');
+ }
+ break;
+ case '/':
+ switch (s) {
+ case S_TAG:
+ el.setTagName(source.slice(start, p));
+ case S_ATTR_END:
+ case S_TAG_SPACE:
+ case S_TAG_CLOSE:
+ s = S_TAG_CLOSE;
+ el.closed = true;
+ case S_ATTR_NOQUOT_VALUE:
+ case S_ATTR:
+ break;
+ case S_ATTR_SPACE:
+ el.closed = true;
+ break;
+ //case S_EQ:
+ default:
+ throw new Error("attribute invalid close char('/')");
+ }
+ break;
+ case '': //end document
+ errorHandler.error('unexpected end of input');
+ if (s == S_TAG) {
+ el.setTagName(source.slice(start, p));
+ }
+ return p;
+ case '>':
+ switch (s) {
+ case S_TAG:
+ el.setTagName(source.slice(start, p));
+ case S_ATTR_END:
+ case S_TAG_SPACE:
+ case S_TAG_CLOSE:
+ break; //normal
+ case S_ATTR_NOQUOT_VALUE: //Compatible state
+ case S_ATTR:
+ value = source.slice(start, p);
+ if (value.slice(-1) === '/') {
+ el.closed = true;
+ value = value.slice(0, -1);
+ }
+ case S_ATTR_SPACE:
+ if (s === S_ATTR_SPACE) {
+ value = attrName;
+ }
+ if (s == S_ATTR_NOQUOT_VALUE) {
+ errorHandler.warning('attribute "' + value + '" missed quot(")!');
+ addAttribute(attrName, value, start);
+ } else {
+ if (!isHTML) {
+ errorHandler.warning('attribute "' + value + '" missed value!! "' + value + '" instead!!');
+ }
+ addAttribute(value, value, start);
+ }
+ break;
+ case S_EQ:
+ if (!isHTML) {
+ return errorHandler.fatalError('AttValue: \' or " expected');
+ }
+ }
+ return p;
+ /*xml space '\x20' | #x9 | #xD | #xA; */
+ case '\u0080':
+ c = ' ';
+ default:
+ if (c <= ' ') {
+ //space
+ switch (s) {
+ case S_TAG:
+ el.setTagName(source.slice(start, p)); //tagName
+ s = S_TAG_SPACE;
+ break;
+ case S_ATTR:
+ attrName = source.slice(start, p);
+ s = S_ATTR_SPACE;
+ break;
+ case S_ATTR_NOQUOT_VALUE:
+ var value = source.slice(start, p);
+ errorHandler.warning('attribute "' + value + '" missed quot(")!!');
+ addAttribute(attrName, value, start);
+ case S_ATTR_END:
+ s = S_TAG_SPACE;
+ break;
+ //case S_TAG_SPACE:
+ //case S_EQ:
+ //case S_ATTR_SPACE:
+ // void();break;
+ //case S_TAG_CLOSE:
+ //ignore warning
+ }
+ } else {
+ //not space
+ //S_TAG, S_ATTR, S_EQ, S_ATTR_NOQUOT_VALUE
+ //S_ATTR_SPACE, S_ATTR_END, S_TAG_SPACE, S_TAG_CLOSE
+ switch (s) {
+ //case S_TAG:void();break;
+ //case S_ATTR:void();break;
+ //case S_ATTR_NOQUOT_VALUE:void();break;
+ case S_ATTR_SPACE:
+ if (!isHTML) {
+ errorHandler.warning('attribute "' + attrName + '" missed value!! "' + attrName + '" instead2!!');
+ }
+ addAttribute(attrName, attrName, start);
+ start = p;
+ s = S_ATTR;
+ break;
+ case S_ATTR_END:
+ errorHandler.warning('attribute space is required"' + attrName + '"!!');
+ case S_TAG_SPACE:
+ s = S_ATTR;
+ start = p;
+ break;
+ case S_EQ:
+ s = S_ATTR_NOQUOT_VALUE;
+ start = p;
+ break;
+ case S_TAG_CLOSE:
+ throw new Error("elements closed character '/' and '>' must be connected to");
+ }
+ }
+ } //end outer switch
+ p++;
+ }
+}
+
+/**
+ * @returns
+ * `true` if a new namespace has been defined.
+ */
+function appendElement(el, domBuilder, currentNSMap) {
+ var tagName = el.tagName;
+ var localNSMap = null;
+ var i = el.length;
+ while (i--) {
+ var a = el[i];
+ var qName = a.qName;
+ var value = a.value;
+ var nsp = qName.indexOf(':');
+ if (nsp > 0) {
+ var prefix = (a.prefix = qName.slice(0, nsp));
+ var localName = qName.slice(nsp + 1);
+ var nsPrefix = prefix === 'xmlns' && localName;
+ } else {
+ localName = qName;
+ prefix = null;
+ nsPrefix = qName === 'xmlns' && '';
+ }
+ //can not set prefix,because prefix !== ''
+ a.localName = localName;
+ //prefix == null for no ns prefix attribute
+ if (nsPrefix !== false) {
+ //hack!!
+ if (localNSMap == null) {
+ localNSMap = Object.create(null);
+ // Derive the child scope's namespace map by prototype-chain inheritance
+ // instead of a flat copy: lookups inherit ancestor prefixes transparently,
+ // so a document nesting N scopes retains O(N) map entries rather than
+ // sum(1..N) = O(N^2). `localNSMap` stays a flat own-only record of the
+ // prefixes declared at THIS element, so own-property enumeration
+ // (endPrefixMapping below) still reports only local declarations.
+ currentNSMap = Object.create(currentNSMap);
+ }
+ currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value;
+ a.uri = NAMESPACE.XMLNS;
+ domBuilder.startPrefixMapping(nsPrefix, value);
+ }
+ }
+ var i = el.length;
+ while (i--) {
+ a = el[i];
+ if (a.prefix) {
+ //no prefix attribute has no namespace
+ if (a.prefix === 'xml') {
+ a.uri = NAMESPACE.XML;
+ }
+ if (a.prefix !== 'xmlns') {
+ a.uri = currentNSMap[a.prefix];
+ }
+ }
+ }
+ var nsp = tagName.indexOf(':');
+ if (nsp > 0) {
+ prefix = el.prefix = tagName.slice(0, nsp);
+ localName = el.localName = tagName.slice(nsp + 1);
+ } else {
+ prefix = null; //important!!
+ localName = el.localName = tagName;
+ }
+ //no prefix element has default namespace
+ var ns = (el.uri = currentNSMap[prefix || '']);
+ domBuilder.startElement(ns, localName, tagName, el);
+ //endPrefixMapping and startPrefixMapping have not any help for dom builder
+ //localNSMap = null
+ if (el.closed) {
+ domBuilder.endElement(ns, localName, tagName);
+ if (localNSMap) {
+ for (prefix in localNSMap) {
+ if (hasOwn(localNSMap, prefix)) {
+ domBuilder.endPrefixMapping(prefix);
+ }
+ }
+ }
+ } else {
+ el.currentNSMap = currentNSMap;
+ el.localNSMap = localNSMap;
+ //parseStack.push(el);
+ return true;
+ }
+}
+
+function parseHtmlSpecialContent(source, elStartEnd, tagName, entityReplacer, domBuilder) {
+ // https://html.spec.whatwg.org/#raw-text-elements
+ // https://html.spec.whatwg.org/#escapable-raw-text-elements
+ // https://html.spec.whatwg.org/#cdata-rcdata-restrictions:raw-text-elements
+ // TODO: https://html.spec.whatwg.org/#cdata-rcdata-restrictions
+ var isEscapableRaw = isHTMLEscapableRawTextElement(tagName);
+ if (isEscapableRaw || isHTMLRawTextElement(tagName)) {
+ // The closing tag of a raw-text element matches case-insensitively
+ // (WHATWG HTML §13.2.5.14 RAWTEXT end tag name state). A case-sensitive
+ // search that missed the closing tag would return -1 and the `substring`
+ // below would treat -1 as a backward slice from position 0, re-emitting all
+ // prior source and amplifying output quadratically across repeated elements.
+ // The regex is anchored to `elStartEnd` via `lastIndex` so it scans forward
+ // only (O(distance), not the whole source).
+ var closeTag = new RegExp('' + tagName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + '>', 'ig');
+ closeTag.lastIndex = elStartEnd;
+ var match = closeTag.exec(source);
+ var elEndStart = match ? match.index : -1;
+ if (elEndStart < 0) {
+ // No closing tag: never slice with a -1 end index. Leave the element to
+ // the parse loop's normal recovery instead of back-capturing the source.
+ return elStartEnd + 1;
+ }
+ var text = source.substring(elStartEnd + 1, elEndStart);
+
+ if (isEscapableRaw) {
+ text = text.replace(ENTITY_REG, entityReplacer);
+ }
+ domBuilder.characters(text, 0, text.length);
+ return elEndStart;
+ }
+ return elStartEnd + 1;
+}
+
+function _copy(source, target) {
+ for (var n in source) {
+ if (hasOwn(source, n)) {
+ target[n] = source[n];
+ }
+ }
+}
+
+/**
+ * @typedef ParseUtils
+ * @property {function(relativeIndex: number?): string | undefined} char
+ * Provides look ahead access to a singe character relative to the current index.
+ * @property {function(): number} getIndex
+ * Provides read-only access to the current index.
+ * @property {function(reg: RegExp): string | null} getMatch
+ * Applies the provided regular expression enforcing that it starts at the current index and
+ * returns the complete matching string,
+ * and moves the current index by the length of the matching string.
+ * @property {function(): string} getSource
+ * Provides read-only access to the complete source.
+ * @property {function(places: number?): void} skip
+ * moves the current index by places (defaults to 1)
+ * @property {function(): number} skipBlanks
+ * Moves the current index by the amount of white space that directly follows the current index
+ * and returns the amount of whitespace chars skipped (0..n),
+ * or -1 if the end of the source was reached.
+ * @property {function(): string} substringFromIndex
+ * creates a substring from the current index to the end of `source`
+ * @property {function(compareWith: string): boolean} substringStartsWith
+ * Checks if `source` contains `compareWith`, starting from the current index.
+ * @property {function(compareWith: string): boolean} substringStartsWithCaseInsensitive
+ * Checks if `source` contains `compareWith`, starting from the current index,
+ * comparing the upper case of both sides.
+ * @see {@link parseUtils}
+ */
+
+/**
+ * A temporary scope for parsing and look ahead operations in `source`,
+ * starting from index `start`.
+ *
+ * Some operations move the current index by a number of positions,
+ * after which `getIndex` returns the new index.
+ *
+ * @param {string} source
+ * @param {number} start
+ * @returns {ParseUtils}
+ */
+function parseUtils(source, start) {
+ var index = start;
+
+ function char(n) {
+ n = n || 0;
+ return source.charAt(index + n);
+ }
+
+ function skip(n) {
+ n = n || 1;
+ index += n;
+ }
+
+ function skipBlanks() {
+ var blanks = 0;
+ while (index < source.length) {
+ var c = char();
+ if (c !== ' ' && c !== '\n' && c !== '\t' && c !== '\r') {
+ return blanks;
+ }
+ blanks++;
+ skip();
+ }
+ return -1;
+ }
+ function substringFromIndex() {
+ return source.substring(index);
+ }
+ function substringStartsWith(text) {
+ return source.substring(index, index + text.length) === text;
+ }
+ function substringStartsWithCaseInsensitive(text) {
+ return source.substring(index, index + text.length).toUpperCase() === text.toUpperCase();
+ }
+
+ function getMatch(args) {
+ var expr = g.reg('^', args);
+ var match = expr.exec(substringFromIndex());
+ if (match) {
+ skip(match[0].length);
+ return match[0];
+ }
+ return null;
+ }
+ return {
+ char: char,
+ getIndex: function () {
+ return index;
+ },
+ getMatch: getMatch,
+ getSource: function () {
+ return source;
+ },
+ skip: skip,
+ skipBlanks: skipBlanks,
+ substringFromIndex: substringFromIndex,
+ substringStartsWith: substringStartsWith,
+ substringStartsWithCaseInsensitive: substringStartsWithCaseInsensitive,
+ };
+}
+
+/**
+ * @param {ParseUtils} p
+ * @param {DOMHandler} errorHandler
+ * @returns {string}
+ */
+function parseDoctypeInternalSubset(p, errorHandler) {
+ /**
+ * @param {ParseUtils} p
+ * @param {DOMHandler} errorHandler
+ * @returns {string}
+ */
+ function parsePI(p, errorHandler) {
+ var match = g.PI.exec(p.substringFromIndex());
+ if (!match) {
+ return errorHandler.fatalError('processing instruction is not well-formed at position ' + p.getIndex());
+ }
+ if (match[1].toLowerCase() === 'xml') {
+ return errorHandler.fatalError(
+ 'xml declaration is only allowed at the start of the document, but found at position ' + p.getIndex()
+ );
+ }
+ p.skip(match[0].length);
+ return match[0];
+ }
+ // Parse internal subset
+ var source = p.getSource();
+ if (p.char() === '[') {
+ p.skip(1);
+ var intSubsetStart = p.getIndex();
+ while (p.getIndex() < source.length) {
+ p.skipBlanks();
+ if (p.char() === ']') {
+ var internalSubset = source.substring(intSubsetStart, p.getIndex());
+ p.skip(1);
+ return internalSubset;
+ }
+ var current = null;
+ // Only in external subset
+ // if (char() === '<' && char(1) === '!' && char(2) === '[') {
+ // parseConditionalSections(p, errorHandler);
+ // } else
+ if (p.char() === '<' && p.char(1) === '!') {
+ switch (p.char(2)) {
+ case 'E': // ELEMENT | ENTITY
+ if (p.char(3) === 'L') {
+ current = p.getMatch(g.elementdecl);
+ } else if (p.char(3) === 'N') {
+ current = p.getMatch(g.EntityDecl);
+ }
+ break;
+ case 'A': // ATTRIBUTE
+ current = p.getMatch(g.AttlistDecl);
+ break;
+ case 'N': // NOTATION
+ current = p.getMatch(g.NotationDecl);
+ break;
+ case '-': // COMMENT
+ current = p.getMatch(g.Comment);
+ break;
+ }
+ } else if (p.char() === '<' && p.char(1) === '?') {
+ current = parsePI(p, errorHandler);
+ } else if (p.char() === '%') {
+ current = p.getMatch(g.PEReference);
+ } else {
+ return errorHandler.fatalError('Error detected in Markup declaration');
+ }
+ if (!current) {
+ return errorHandler.fatalError('Error in internal subset at position ' + p.getIndex());
+ }
+ }
+ return errorHandler.fatalError('doctype internal subset is not well-formed, missing ]');
+ }
+}
+
+/**
+ * Called when the parser encounters an element starting with '') {
+ return errorHandler.fatalError('doctype not terminated with > at position ' + p.getIndex());
+ }
+ p.skip(1);
+ domBuilder.startDTD(doctype.name, doctype.publicId, doctype.systemId, doctype.internalSubset);
+ domBuilder.endDTD();
+ return p.getIndex();
+ }
+ default:
+ return errorHandler.fatalError('Not well-formed XML starting with " 0) {
+ return errorHandler.fatalError(
+ 'processing instruction at position ' + start + ' is an xml declaration which is only at the start of the document'
+ );
+ }
+ if (!g.XMLDecl.test(source.substring(start))) {
+ return errorHandler.fatalError('xml declaration is not well-formed');
+ }
+ }
+ domBuilder.processingInstruction(match[1], match[2]);
+ return start + match[0].length;
+}
+
+function ElementAttributes() {
+ this.attributeNames = Object.create(null);
+}
+
+ElementAttributes.prototype = {
+ setTagName: function (tagName) {
+ if (!g.QName_exact.test(tagName)) {
+ throw new Error('invalid tagName:' + tagName);
+ }
+ this.tagName = tagName;
+ },
+ addValue: function (qName, value, offset) {
+ if (!g.QName_exact.test(qName)) {
+ throw new Error('invalid attribute:' + qName);
+ }
+ this.attributeNames[qName] = this.length;
+ this[this.length++] = { qName: qName, value: value, offset: offset };
+ },
+ length: 0,
+ getLocalName: function (i) {
+ return this[i].localName;
+ },
+ getLocator: function (i) {
+ return this[i].locator;
+ },
+ getQName: function (i) {
+ return this[i].qName;
+ },
+ getURI: function (i) {
+ return this[i].uri;
+ },
+ getValue: function (i) {
+ return this[i].value;
+ },
+ // ,getIndex:function(uri, localName)){
+ // if(localName){
+ //
+ // }else{
+ // var qName = uri
+ // }
+ // },
+ // getValue:function(){return this.getValue(this.getIndex.apply(this,arguments))},
+ // getType:function(uri,localName){}
+ // getType:function(i){},
+};
+
+exports.XMLReader = XMLReader;
+exports.parseUtils = parseUtils;
+exports.parseDoctypeCommentOrCData = parseDoctypeCommentOrCData;
diff --git a/node_modules/@xmldom/xmldom/package.json b/node_modules/@xmldom/xmldom/package.json
new file mode 100644
index 000000000..c8a8a0b17
--- /dev/null
+++ b/node_modules/@xmldom/xmldom/package.json
@@ -0,0 +1,77 @@
+{
+ "name": "@xmldom/xmldom",
+ "version": "0.9.12",
+ "description": "A pure JavaScript W3C standard-based (XML DOM Level 2 Core) DOMParser and XMLSerializer module.",
+ "keywords": [
+ "w3c",
+ "dom",
+ "xml",
+ "parser",
+ "javascript",
+ "DOMParser",
+ "XMLSerializer",
+ "ponyfill"
+ ],
+ "homepage": "https://github.com/xmldom/xmldom",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/xmldom/xmldom.git"
+ },
+ "main": "lib/index.js",
+ "types": "index.d.ts",
+ "files": [
+ "CHANGELOG.md",
+ "LICENSE",
+ "readme.md",
+ "SECURITY.md",
+ "index.d.ts",
+ "lib"
+ ],
+ "config": {
+ "test_stack_size": 256
+ },
+ "scripts": {
+ "lint": "eslint examples lib test",
+ "format": "prettier --write examples lib test index.d.ts",
+ "format:check": "prettier --check examples lib test index.d.ts",
+ "changelog": "auto-changelog --unreleased-only",
+ "start": "nodemon --watch package.json --watch lib --watch test --exec 'npm --silent run test && npm --silent run lint'",
+ "test": "node --stack-size=$npm_package_config_test_stack_size ./node_modules/.bin/jest",
+ "fuzz": "jest --config=./jest.fuzz.config.js",
+ "test:types": "cd examples/typescript-node-es6 && ./pretest.sh 3 && ./pretest.sh 4 && ./pretest.sh 5 && node dist/index.js",
+ "testrelease": "npm test && eslint lib",
+ "version": "./changelog-has-version.sh",
+ "release": "np --no-yarn --test-script testrelease"
+ },
+ "engines": {
+ "node": ">=14.6"
+ },
+ "devDependencies": {
+ "@homer0/prettier-plugin-jsdoc": "10.0.1",
+ "auto-changelog": "2.5.1",
+ "eslint": "8.57.1",
+ "eslint-config-prettier": "10.1.8",
+ "eslint-plugin-anti-trojan-source": "1.1.7",
+ "eslint-plugin-es5": "1.5.0",
+ "eslint-plugin-n": "17.24.0",
+ "eslint-plugin-prettier": "5.5.6",
+ "get-stream": "6.0.1",
+ "jest": "29.7.0",
+ "nodemon": "3.1.14",
+ "np": "9.2.0",
+ "prettier": "3.8.3",
+ "xmltest": "2.0.3",
+ "yauzl": "3.4.0"
+ },
+ "bugs": {
+ "url": "https://github.com/xmldom/xmldom/issues"
+ },
+ "license": "MIT",
+ "auto-changelog": {
+ "prepend": true,
+ "remote": "origin",
+ "tagPrefix": "",
+ "template": "./auto-changelog.hbs"
+ },
+ "packageManager": "npm@11.19.0+sha512.48377f8478372aa1c4e47b763475b135836da82436a5700f2e5e8eb5084fc840f93c7b117eb3ad3b5f7d3194c81b6710a10d59448f6ddbcb21ac3fb672bdc003"
+}
diff --git a/node_modules/@xmldom/xmldom/readme.md b/node_modules/@xmldom/xmldom/readme.md
new file mode 100644
index 000000000..15c287271
--- /dev/null
+++ b/node_modules/@xmldom/xmldom/readme.md
@@ -0,0 +1,366 @@
+# @xmldom/xmldom
+
+***Since version 0.7.0 this package is published to npm as [`@xmldom/xmldom`](https://www.npmjs.com/package/@xmldom/xmldom) and no longer as [`xmldom`](https://www.npmjs.com/package/xmldom), because [we are no longer able to publish `xmldom`](https://github.com/xmldom/xmldom/issues/271).***
+*For better readability in the docs, we will continue to talk about this library as "xmldom".*
+
+[](https://github.com/xmldom/xmldom/blob/master/LICENSE)
+[](https://socket.dev/npm/package/@xmldom/xmldom)
+[](https://codecov.io/gh/xmldom/xmldom)
+[](https://packagephobia.com/result?p=@xmldom/xmldom)
+
+[](https://www.bestpractices.dev/projects/7879)
+[](https://securityscorecards.dev/viewer/?uri=github.com/xmldom/xmldom)
+[](https://socket.dev/npm/package/@xmldom/xmldom)
+
+[](https://www.npmjs.com/package/@xmldom/xmldom)
+[](https://www.npmjs.com/package/@xmldom/xmldom?activeTab=versions)
+[](https://www.npmjs.com/package/@xmldom/xmldom?activeTab=versions)
+
+[](https://github.com/xmldom/xmldom/issues?q=is%3Aissue+is%3Aopen+label%3Abug)
+[](https://github.com/xmldom/xmldom/issues?q=is%3Aissue+is%3Aopen+label%3Ahelp-wanted)
+
+xmldom is a javascript [ponyfill](https://ponyfill.com/) to provide the following APIs [that are present in modern browsers](https://caniuse.com/xml-serializer) to other runtimes:
+- convert an XML string into a DOM tree
+ ```
+ new DOMParser().parseFromString(xml, mimeType) => Document
+ ```
+- create, access and modify a DOM tree
+ ```
+ new DOMImplementation().createDocument(...) => Document
+ ```
+- serialize a DOM tree back into an XML string
+ ```
+ new XMLSerializer().serializeToString(node) => string
+ ```
+
+The target runtimes `xmldom` supports are currently Node >= v14.6 (and very likely any other [ES5 compatible runtime](https://compat-table.github.io/compat-table/es5/)).
+
+When deciding how to fix bugs or implement features, `xmldom` tries to stay as close as possible to the various [related specifications/standards](#specs).
+As indicated by the version starting with `0.`, this implementation is not feature complete and some implemented features differ from what the specifications describe.
+**Issues and PRs for such differences are always welcome, even when they only provide a failing test case.**
+
+This project was forked from it's [original source](https://github.com/jindw/xmldom) in 2019, more details about that transition can be found in the [CHANGELOG](CHANGELOG.md#maintainer-changes).
+
+## Usage
+
+### Install:
+
+```
+npm install @xmldom/xmldom
+```
+
+### Example:
+
+[In NodeJS](examples/nodejs/src/index.js)
+```javascript
+const { DOMParser, XMLSerializer } = require('@xmldom/xmldom')
+
+const source = `
+ test
+
+`
+
+const doc = new DOMParser().parseFromString(source, 'text/xml')
+
+const serialized = new XMLSerializer().serializeToString(doc)
+```
+
+Note: in Typescript ~~and ES6~~ (see [#316](https://github.com/xmldom/xmldom/issues/316)) you can use the `import` approach, as follows:
+
+```typescript
+import { DOMParser } from '@xmldom/xmldom'
+```
+
+## API Reference
+
+* [DOMParser](https://developer.mozilla.org/en-US/docs/Web/API/DOMParser):
+
+ ```javascript
+ parseFromString(xmlsource, mimeType)
+ ```
+ * **options extension** _by xmldom_ (not DOM standard!!)
+
+ ```javascript
+ // the options argument can be used to modify behavior
+ // for more details check the documentation on the code or type definition
+ new DOMParser(options)
+ ```
+
+ * [XMLSerializer](https://developer.mozilla.org/en-US/docs/Web/API/XMLSerializer)
+
+ ```javascript
+ serializeToString(node)
+ ```
+### DOM level2 method and attribute:
+
+All DOM node types listed below are exported for use with `instanceof` (e.g. `node instanceof Text`).
+They cannot be constructed directly — use the `Document` factory methods (`createTextNode`, `createComment`, `createDocumentFragment`, …) instead.
+
+* [Node](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247)
+
+ readonly class properties (aka `NodeType`),
+ these can be accessed from any `Node` instance `node`:
+ `if (node.nodeType === node.ELEMENT_NODE) {...`
+
+ 1. `ELEMENT_NODE` (`1`)
+ 2. `ATTRIBUTE_NODE` (`2`)
+ 3. `TEXT_NODE` (`3`)
+ 4. `CDATA_SECTION_NODE` (`4`)
+ 5. `ENTITY_REFERENCE_NODE` (`5`)
+ 6. `ENTITY_NODE` (`6`)
+ 7. `PROCESSING_INSTRUCTION_NODE` (`7`)
+ 8. `COMMENT_NODE` (`8`)
+ 9. `DOCUMENT_NODE` (`9`)
+ 10. `DOCUMENT_TYPE_NODE` (`10`)
+ 11. `DOCUMENT_FRAGMENT_NODE` (`11`)
+ 12. `NOTATION_NODE` (`12`)
+
+ attribute:
+ - `nodeValue` | `prefix` | `textContent`
+
+ readonly attribute:
+ - `nodeName` | `nodeType` | `parentNode` | `parentElement` | `childNodes` | `firstChild` | `lastChild` | `previousSibling` | `nextSibling` | `attributes` | `ownerDocument` | `namespaceURI` | `localName` | `isConnected` | `baseURI`
+
+ method:
+ * `insertBefore(newChild, refChild)`
+ * `replaceChild(newChild, oldChild)`
+ * `removeChild(oldChild)`
+ * `appendChild(newChild)`
+ * `hasChildNodes()`
+ * `cloneNode(deep)`
+ * `normalize()`
+ * `contains(otherNode)`
+ * `getRootNode()`
+ * `isEqualNode(otherNode)`
+ * `isSameNode(otherNode)`
+ * `isSupported(feature, version)`
+ * `hasAttributes()`
+* [DOMException](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/ecma-script-binding.html)
+
+ extends the Error type thrown as part of DOM API.
+
+ readonly class properties:
+ - `INDEX_SIZE_ERR` (`1`)
+ - `DOMSTRING_SIZE_ERR` (`2`)
+ - `HIERARCHY_REQUEST_ERR` (`3`)
+ - `WRONG_DOCUMENT_ERR` (`4`)
+ - `INVALID_CHARACTER_ERR` (`5`)
+ - `NO_DATA_ALLOWED_ERR` (`6`)
+ - `NO_MODIFICATION_ALLOWED_ERR` (`7`)
+ - `NOT_FOUND_ERR` (`8`)
+ - `NOT_SUPPORTED_ERR` (`9`)
+ - `INUSE_ATTRIBUTE_ERR` (`10`)
+ - `INVALID_STATE_ERR` (`11`)
+ - `SYNTAX_ERR` (`12`)
+ - `INVALID_MODIFICATION_ERR` (`13`)
+ - `NAMESPACE_ERR` (`14`)
+ - `INVALID_ACCESS_ERR` (`15`)
+
+ attributes:
+ - `code` with a value matching one of the above constants.
+
+* [DOMImplementation](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-102161490)
+
+ method:
+ - `hasFeature(feature, version)` (deprecated)
+ - `createDocumentType(qualifiedName, publicId, systemId)`
+ - `createDocument(namespaceURI, qualifiedName, doctype)`
+
+* [Document](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#i-Document) : Node
+
+ readonly attribute:
+ - `doctype` | `implementation` | `documentElement`
+
+ method:
+ - `createElement(tagName)`
+ - `createDocumentFragment()`
+ - `createTextNode(data)`
+ - `createComment(data)`
+ - `createCDATASection(data)`
+ - `createProcessingInstruction(target, data)`
+ - `createAttribute(name)`
+ - `createEntityReference(name)`
+ - `getElementsByTagName(tagname)`
+ - `importNode(importedNode, deep)`
+ - `createElementNS(namespaceURI, qualifiedName)`
+ - `createAttributeNS(namespaceURI, qualifiedName)`
+ - `getElementsByTagNameNS(namespaceURI, localName)`
+ - `getElementById(elementId)`
+
+* [DocumentFragment](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-B63ED1A3) : Node
+* [Element](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-745549614) : Node
+
+ readonly attribute:
+ - `tagName`
+
+ method:
+ - `getAttribute(name)`
+ - `setAttribute(name, value)`
+ - `removeAttribute(name)`
+ - `getAttributeNode(name)`
+ - `setAttributeNode(newAttr)`
+ - `removeAttributeNode(oldAttr)`
+ - `getElementsByTagName(name)`
+ - `getAttributeNS(namespaceURI, localName)`
+ - `setAttributeNS(namespaceURI, qualifiedName, value)`
+ - `removeAttributeNS(namespaceURI, localName)`
+ - `getAttributeNodeNS(namespaceURI, localName)`
+ - `setAttributeNodeNS(newAttr)`
+ - `getElementsByTagNameNS(namespaceURI, localName)`
+ - `hasAttribute(name)`
+ - `hasAttributeNS(namespaceURI, localName)`
+
+* [Attr](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-637646024) : Node
+
+ attribute:
+ - `value`
+
+ readonly attribute:
+ - `name` | `specified` | `ownerElement`
+
+* [NodeList](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-536297177)
+
+ readonly attribute:
+ - `length`
+
+ method:
+ - `item(index)`
+
+* [NamedNodeMap](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1780488922)
+
+ readonly attribute:
+ - `length`
+
+ method:
+ - `getNamedItem(name)`
+ - `setNamedItem(arg)`
+ - `removeNamedItem(name)`
+ - `item(index)`
+ - `getNamedItemNS(namespaceURI, localName)`
+ - `setNamedItemNS(arg)`
+ - `removeNamedItemNS(namespaceURI, localName)`
+
+* [CharacterData](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-FF21A306) : Node
+
+ method:
+ - `substringData(offset, count)`
+ - `appendData(arg)`
+ - `insertData(offset, arg)`
+ - `deleteData(offset, count)`
+ - `replaceData(offset, count, arg)`
+
+* [Text](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1312295772) : CharacterData
+
+ method:
+ - `splitText(offset)`
+
+* [CDATASection](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-667469212)
+* [Comment](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1728279322) : CharacterData
+
+* [DocumentType](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-412266927)
+
+ readonly attribute:
+ - `name` | `entities` | `notations` | `publicId` | `systemId` | `internalSubset`
+
+* Notation : Node
+
+ readonly attribute:
+ - `publicId` | `systemId`
+
+* Entity : Node
+
+ readonly attribute:
+ - `publicId` | `systemId` | `notationName`
+
+* EntityReference : Node
+* ProcessingInstruction : Node
+
+ attribute:
+ - `data`
+ readonly attribute:
+ - `target`
+
+### DOM level 3 support:
+
+* [Node](http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-textContent)
+
+ attribute:
+ - `textContent`
+
+ method:
+ - `isDefaultNamespace(namespaceURI)`
+ - `lookupNamespaceURI(prefix)`
+
+### DOM Living Standard support:
+
+* [ParentNode](https://dom.spec.whatwg.org/#interface-parentnode) mixin (on `Document`, `DocumentFragment`, `Element`)
+
+ readonly attribute:
+ - `children`
+
+### DOM extension by xmldom
+
+* [Node] Source position extension;
+
+ attribute:
+ - `lineNumber` //number starting from `1`
+ - `columnNumber` //number starting from `1`
+
+## Specs
+
+The implementation is based on several specifications:
+
+
+
+
+### DOM Parsing and Serialization
+
+From the [W3C DOM Parsing and Serialization (WD 2016)](https://www.w3.org/TR/2016/WD-DOM-Parsing-20160517/) `xmldom` provides an implementation for the interfaces:
+- `DOMParser`
+- `XMLSerializer`
+
+Note that there are some known deviations between this implementation and the W3 specifications.
+
+Note: [The latest version of this spec](https://w3c.github.io/DOM-Parsing/) has the status "Editors Draft", since it is under active development. One major change is that [the definition of the `DOMParser` interface has been moved to the HTML spec](https://w3c.github.io/DOM-Parsing/#the-domparser-interface)
+
+
+### DOM
+
+The original author claims that xmldom implements [DOM Level 2] in a "fully compatible" way and some parts of [DOM Level 3], but there are not enough tests to prove this. Both Specifications are now superseded by the [DOM Level 4 aka Living standard] wich has a much broader scope than xmldom.
+In the past, there have been multiple (even breaking) changes to align xmldom with the living standard,
+so if you find a difference that is not documented, any contribution to resolve the difference is very welcome (even just reporting it as an issue).
+
+xmldom implements the following interfaces:
+- `Attr`
+- `CDATASection`
+- `CharacterData`
+- `Comment`
+- `Document`
+- `DocumentFragment`
+- `DocumentType`
+- `DOMException`
+- `DOMImplementation`
+- `Element`
+- `Entity`
+- `EntityReference`
+- `LiveNodeList`
+- `NamedNodeMap`
+- `Node`
+- `NodeList`
+- `Notation`
+- `ProcessingInstruction`
+- `Text`
+
+more details are available in the (incomplete) [API Reference](#api-reference) section.
+
+### HTML
+
+xmldom does not have any goal of supporting the full spec, but it has some capability to parse, report and serialize things differently when it is told to parse HTML (by passing the HTML namespace).
+
+### SAX, XML, XMLNS
+
+xmldom has an own SAX parser implementation to do the actual parsing, which implements some interfaces in alignment with the Java interfaces SAX defines:
+- `XMLReader`
+- `DOMHandler`
+
+There is an idea/proposal to make it possible to replace it with something else in
diff --git a/node_modules/README b/node_modules/README
deleted file mode 100644
index 4666d00ba..000000000
--- a/node_modules/README
+++ /dev/null
@@ -1,2 +0,0 @@
-This includes third party modules.
-Respective licenses apply.
diff --git a/node_modules/karma-webodf/lib/adapter.js b/node_modules/karma-webodf/lib/adapter.js
deleted file mode 100644
index 57f58cc73..000000000
--- a/node_modules/karma-webodf/lib/adapter.js
+++ /dev/null
@@ -1,48 +0,0 @@
-/*global window, tester, tests, runNextTest, runtime*/
-/*jslint nomen: true, emptyblock: true, unparam: true*/
-
-(function (win) {
- "use strict";
- // signal to UnitTester that the tests should not start automatically.
- win.use_karma = true;
- /**
- * Returned start function is invoked by Karma runner when Karma is
- * ready (connected with a browser and loaded all the required files)
- *
- * @param {Object} karma Karma runner instance
- * @return {Function} start function
- */
- function createStartFn(karma) {
- return function () {
- var testCount = 0;
- tester.resourcePrefix = "tests/";
- tester.reporter = function (r) {
- testCount += 1;
- karma.info({total: testCount});
- karma.result(r);
- };
- // tell karma how many tests there are
- karma.info({total: testCount});
- runNextTest(tests, tester, function () {
- // tell karma to end the run
- karma.complete({
- coverage: window.__coverage__
- });
- });
- };
- }
- /**
- * Returned function is used for logging by Karma
- */
- function createDumpFn(karma, serialize) {
- // inside you could use a custom `serialize` function
- // to modify or attach messages or hook into logging
- return function () {
- karma.info({ dump: [].slice.call(arguments) });
- };
- }
- win.__karma__.start = createStartFn(window.__karma__);
- win.dump = createDumpFn(win.__karma__, function (value) {
- return value;
- });
-}(window));
diff --git a/node_modules/karma-webodf/lib/index.js b/node_modules/karma-webodf/lib/index.js
deleted file mode 100644
index 898ead36e..000000000
--- a/node_modules/karma-webodf/lib/index.js
+++ /dev/null
@@ -1,93 +0,0 @@
-/*jslint nomen: true*/
-/*global __dirname, module, require */
-function createPattern(path) {
- "use strict";
- return {pattern: path, included: true, served: true, watched: false};
-}
-
-function get(path, response) {
- "use strict";
- var fs = require('fs');
- fs.stat(path, function (err, stats) {
- var s;
- if (err) {
- response.writeHead(404);
- response.end();
- } else {
- response.writeHead(200, { 'content-length': stats.size });
- s = fs.createReadStream(path);
- s.pipe(response);
- }
- });
-}
-
-function put(path, request, response) {
- "use strict";
- var fs = require('fs'),
- s = fs.createWriteStream(path);
- request.pipe(s);
- request.on('end', function () {
- response.writeHead(200);
- response.end();
- });
-}
-
-function head(path, response) {
- "use strict";
- var fs = require('fs');
-console.log("HRMM " + path);
- fs.stat(path, function (err, stats) {
-console.log("HEAD " + err);
- if (err) {
- response.writeHead(404);
- } else {
- response.writeHead(200, { 'content-length': stats.size });
- }
- response.end();
- });
-}
-
-function unlink(path, response) {
- "use strict";
- var fs = require('fs');
- fs.unlink(path, function (err) {
- if (err) {
- response.writeHead(500);
- } else {
- response.writeHead(200);
- }
- response.end();
- });
-}
-
-function handleRequest(request, response) {
- "use strict";
- var path = request.url.slice(1);
- console.log(request.method + " " + path);
- if (request.method === 'GET') {
- get(path, response);
- } else if (request.method === 'PUT') {
- put(path, request, response);
- } else if (request.method === 'DELETE') {
- unlink(path, response);
- } else if (request.method === 'HEAD') {
- head(path, response);
- } else {
- response.end(500);
- }
-}
-
-function initWebODF(files) {
- "use strict";
- files.unshift(createPattern(__dirname + '/adapter.js'));
- var http = require('http'),
- server = http.createServer(handleRequest);
- server.listen(8642);
-}
-
-
-initWebODF.$inject = ['config.files'];
-
-module.exports = {
- 'framework:webodf': ['factory', initWebODF]
-};
diff --git a/node_modules/karma-webodf/package.json b/node_modules/karma-webodf/package.json
deleted file mode 100644
index 3a21f1da0..000000000
--- a/node_modules/karma-webodf/package.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "name": "karma-webodf",
- "version": "0.1.0",
- "description": "A Karma plugin - adapter for WebODF testing framework.",
- "main": "lib/index.js",
- "license": "AGPLv3"
-}
diff --git a/node_modules/xmldom/.gitattributes b/node_modules/xmldom/.gitattributes
deleted file mode 100644
index b15706354..000000000
--- a/node_modules/xmldom/.gitattributes
+++ /dev/null
@@ -1,4 +0,0 @@
-# Unset behaviour for some text-like files, as this is just a copy of original files,
-# with obviously DOS line endings
-
-* binary
diff --git a/node_modules/xmldom/.project b/node_modules/xmldom/.project
deleted file mode 100644
index 49691ced8..000000000
--- a/node_modules/xmldom/.project
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
- xmldom
-
-
-
-
-
-
-
-
diff --git a/node_modules/xmldom/__package__.js b/node_modules/xmldom/__package__.js
deleted file mode 100644
index 93af3495a..000000000
--- a/node_modules/xmldom/__package__.js
+++ /dev/null
@@ -1,4 +0,0 @@
-this.addScript('dom.js',['DOMImplementation','XMLSerializer']);
-this.addScript('dom-parser.js',['DOMHandler','DOMParser'],
- ['DOMImplementation','XMLReader']);
-this.addScript('sax.js','XMLReader');
\ No newline at end of file
diff --git a/node_modules/xmldom/changelog b/node_modules/xmldom/changelog
deleted file mode 100644
index e8fcc6f1b..000000000
--- a/node_modules/xmldom/changelog
+++ /dev/null
@@ -1,5 +0,0 @@
-0.1.8
- * Add: some test case from node-o3-xml(excludes xpath support)
- * Fix: remove existed attribute before setting (bug introduced in v0.1.5)
- * Fix: index direct access for childNodes and any NodeList collection(not w3c standard)
- * Fix: remove last child bug
\ No newline at end of file
diff --git a/node_modules/xmldom/dom-parser.js b/node_modules/xmldom/dom-parser.js
deleted file mode 100644
index 0a755525d..000000000
--- a/node_modules/xmldom/dom-parser.js
+++ /dev/null
@@ -1,253 +0,0 @@
-function DOMParser(options){
- this.options =
- options != true && //To the version (0.1.12) compatible
- options ||{locator:{}};
-
-}
-DOMParser.prototype.parseFromString = function(source,mimeType){
- var sax = new XMLReader();
- var options = this.options;
- var domBuilder = options.domBuilder || new DOMHandler();//contentHandler and LexicalHandler
- var errorHandler = options.errorHandler;
- var locator = options.locator;
- var defaultNSMap = {};
- var entityMap = {'lt':'<','gt':'>','amp':'&','quot':'"','apos':"'"}
- if(locator){
- domBuilder.setDocumentLocator(locator)
- }
-
- sax.errorHandler = buildErrorHandler(errorHandler,domBuilder,locator);
- sax.domBuilder = options.domBuilder || domBuilder;
- if(/\/x?html?$/.test(mimeType)){
- entityMap.nbsp = '\xa0';
- entityMap.copy = '\xa9';
- defaultNSMap['']= 'http://www.w3.org/1999/xhtml';
- }
- sax.parse(source,defaultNSMap,entityMap);
- return domBuilder.document;
-}
-function buildErrorHandler(errorImpl,domBuilder,locator){
- if(!errorImpl){
- if(domBuilder instanceof DOMHandler){
- return domBuilder;
- }
- errorImpl = domBuilder ;
- }
- var errorHandler = {}
- var isCallback = errorImpl instanceof Function;
- locator = locator||{}
- function build(key){
- var fn = errorImpl[key];
- if(!fn){
- if(isCallback){
- fn = errorImpl.length == 2?function(msg){errorImpl(key,msg)}:errorImpl;
- }else{
- var i=arguments.length;
- while(--i){
- if(fn = errorImpl[arguments[i]]){
- break;
- }
- }
- }
- }
- errorHandler[key] = fn && function(msg){
- fn(msg+_locator(locator));
- }||function(){};
- }
- build('warning','warn');
- build('error','warn','warning');
- build('fatalError','warn','warning','error');
- return errorHandler;
-}
-/**
- * +ContentHandler+ErrorHandler
- * +LexicalHandler+EntityResolver2
- * -DeclHandler-DTDHandler
- *
- * DefaultHandler:EntityResolver, DTDHandler, ContentHandler, ErrorHandler
- * DefaultHandler2:DefaultHandler,LexicalHandler, DeclHandler, EntityResolver2
- * @link http://www.saxproject.org/apidoc/org/xml/sax/helpers/DefaultHandler.html
- */
-function DOMHandler() {
- this.cdata = false;
-}
-function position(locator,node){
- node.lineNumber = locator.lineNumber;
- node.columnNumber = locator.columnNumber;
-}
-/**
- * @see org.xml.sax.ContentHandler#startDocument
- * @link http://www.saxproject.org/apidoc/org/xml/sax/ContentHandler.html
- */
-DOMHandler.prototype = {
- startDocument : function() {
- this.document = new DOMImplementation().createDocument(null, null, null);
- if (this.locator) {
- this.document.documentURI = this.locator.systemId;
- }
- },
- startElement:function(namespaceURI, localName, qName, attrs) {
- var doc = this.document;
- var el = doc.createElementNS(namespaceURI, qName||localName);
- var len = attrs.length;
- appendElement(this, el);
- this.currentElement = el;
-
- this.locator && position(this.locator,el)
- for (var i = 0 ; i < len; i++) {
- var namespaceURI = attrs.getURI(i);
- var value = attrs.getValue(i);
- var qName = attrs.getQName(i);
- var attr = doc.createAttributeNS(namespaceURI, qName);
- if( attr.getOffset){
- position(attr.getOffset(1),attr)
- }
- attr.value = attr.nodeValue = value;
- el.setAttributeNode(attr)
- }
- },
- endElement:function(namespaceURI, localName, qName) {
- var current = this.currentElement
- var tagName = current.tagName;
- this.currentElement = current.parentNode;
- },
- startPrefixMapping:function(prefix, uri) {
- },
- endPrefixMapping:function(prefix) {
- },
- processingInstruction:function(target, data) {
- var ins = this.document.createProcessingInstruction(target, data);
- this.locator && position(this.locator,ins)
- appendElement(this, ins);
- },
- ignorableWhitespace:function(ch, start, length) {
- },
- characters:function(chars, start, length) {
- chars = _toString.apply(this,arguments)
- //console.log(chars)
- if(this.currentElement && chars){
- if (this.cdata) {
- var charNode = this.document.createCDATASection(chars);
- this.currentElement.appendChild(charNode);
- } else {
- var charNode = this.document.createTextNode(chars);
- this.currentElement.appendChild(charNode);
- }
- this.locator && position(this.locator,charNode)
- }
- },
- skippedEntity:function(name) {
- },
- endDocument:function() {
- this.document.normalize();
- },
- setDocumentLocator:function (locator) {
- if(this.locator = locator){// && !('lineNumber' in locator)){
- locator.lineNumber = 0;
- }
- },
- //LexicalHandler
- comment:function(chars, start, length) {
- chars = _toString.apply(this,arguments)
- var comm = this.document.createComment(chars);
- this.locator && position(this.locator,comm)
- appendElement(this, comm);
- },
-
- startCDATA:function() {
- //used in characters() methods
- this.cdata = true;
- },
- endCDATA:function() {
- this.cdata = false;
- },
-
- startDTD:function(name, publicId, systemId) {
- var impl = this.document.implementation;
- if (impl && impl.createDocumentType) {
- var dt = impl.createDocumentType(name, publicId, systemId);
- this.locator && position(this.locator,dt)
- appendElement(this, dt);
- }
- },
- /**
- * @see org.xml.sax.ErrorHandler
- * @link http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html
- */
- warning:function(error) {
- console.warn(error,_locator(this.locator));
- },
- error:function(error) {
- console.error(error,_locator(this.locator));
- },
- fatalError:function(error) {
- console.error(error,_locator(this.locator));
- throw error;
- }
-}
-function _locator(l){
- if(l){
- return '\n@'+(l.systemId ||'')+'#[line:'+l.lineNumber+',col:'+l.columnNumber+']'
- }
-}
-function _toString(chars,start,length){
- if(typeof chars == 'string'){
- return chars.substr(start,length)
- }else{//java sax connect width xmldom on rhino(what about: "? && !(chars instanceof String)")
- if(chars.length >= start+length || start){
- return new java.lang.String(chars,start,length)+'';
- }
- return chars;
- }
-}
-
-/*
- * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/LexicalHandler.html
- * used method of org.xml.sax.ext.LexicalHandler:
- * #comment(chars, start, length)
- * #startCDATA()
- * #endCDATA()
- * #startDTD(name, publicId, systemId)
- *
- *
- * IGNORED method of org.xml.sax.ext.LexicalHandler:
- * #endDTD()
- * #startEntity(name)
- * #endEntity(name)
- *
- *
- * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/DeclHandler.html
- * IGNORED method of org.xml.sax.ext.DeclHandler
- * #attributeDecl(eName, aName, type, mode, value)
- * #elementDecl(name, model)
- * #externalEntityDecl(name, publicId, systemId)
- * #internalEntityDecl(name, value)
- * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/EntityResolver2.html
- * IGNORED method of org.xml.sax.EntityResolver2
- * #resolveEntity(String name,String publicId,String baseURI,String systemId)
- * #resolveEntity(publicId, systemId)
- * #getExternalSubset(name, baseURI)
- * @link http://www.saxproject.org/apidoc/org/xml/sax/DTDHandler.html
- * IGNORED method of org.xml.sax.DTDHandler
- * #notationDecl(name, publicId, systemId) {};
- * #unparsedEntityDecl(name, publicId, systemId, notationName) {};
- */
-"endDTD,startEntity,endEntity,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,resolveEntity,getExternalSubset,notationDecl,unparsedEntityDecl".replace(/\w+/g,function(key){
- DOMHandler.prototype[key] = function(){return null}
-})
-
-/* Private static helpers treated below as private instance methods, so don't need to add these to the public API; we might use a Relator to also get rid of non-standard public properties */
-function appendElement (hander,node) {
- if (!hander.currentElement) {
- hander.document.appendChild(node);
- } else {
- hander.currentElement.appendChild(node);
- }
-}//appendChild and setAttributeNS are preformance key
-
-if(typeof require == 'function'){
- var XMLReader = require('./sax').XMLReader;
- var DOMImplementation = require('./dom').DOMImplementation;
- exports.XMLSerializer = require('./dom').XMLSerializer ;
- exports.DOMParser = DOMParser;
-}
diff --git a/node_modules/xmldom/dom.js b/node_modules/xmldom/dom.js
deleted file mode 100644
index 7cb012dd6..000000000
--- a/node_modules/xmldom/dom.js
+++ /dev/null
@@ -1,1135 +0,0 @@
-/*
- * DOM Level 2
- * Object DOMException
- * @see http://www.w3.org/TR/REC-DOM-Level-1/ecma-script-language-binding.html
- * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/ecma-script-binding.html
- */
-
-function copy(src,dest){
- for(var p in src){
- dest[p] = src[p];
- }
-}
-/**
-^\w+\.prototype\.([_\w]+)\s*=\s*((?:.*\{\s*?[\r\n][\s\S]*?^})|\S.*?(?=[;\r\n]));?
-^\w+\.prototype\.([_\w]+)\s*=\s*(\S.*?(?=[;\r\n]));?
- */
-function _extends(Class,Super){
- var pt = Class.prototype;
- if(Object.create){
- var ppt = Object.create(Super.prototype)
- pt.__proto__ = ppt;
- }
- if(!(pt instanceof Super)){
- function t(){};
- t.prototype = Super.prototype;
- t = new t();
- copy(pt,t);
- Class.prototype = pt = t;
- }
- if(pt.constructor != Class){
- if(typeof Class != 'function'){
- console.error("unknow Class:"+Class)
- }
- pt.constructor = Class
- }
-}
-var htmlns = 'http://www.w3.org/1999/xhtml' ;
-// Node Types
-var NodeType = {}
-var ELEMENT_NODE = NodeType.ELEMENT_NODE = 1;
-var ATTRIBUTE_NODE = NodeType.ATTRIBUTE_NODE = 2;
-var TEXT_NODE = NodeType.TEXT_NODE = 3;
-var CDATA_SECTION_NODE = NodeType.CDATA_SECTION_NODE = 4;
-var ENTITY_REFERENCE_NODE = NodeType.ENTITY_REFERENCE_NODE = 5;
-var ENTITY_NODE = NodeType.ENTITY_NODE = 6;
-var PROCESSING_INSTRUCTION_NODE = NodeType.PROCESSING_INSTRUCTION_NODE = 7;
-var COMMENT_NODE = NodeType.COMMENT_NODE = 8;
-var DOCUMENT_NODE = NodeType.DOCUMENT_NODE = 9;
-var DOCUMENT_TYPE_NODE = NodeType.DOCUMENT_TYPE_NODE = 10;
-var DOCUMENT_FRAGMENT_NODE = NodeType.DOCUMENT_FRAGMENT_NODE = 11;
-var NOTATION_NODE = NodeType.NOTATION_NODE = 12;
-
-// ExceptionCode
-var ExceptionCode = {}
-var ExceptionMessage = {};
-var INDEX_SIZE_ERR = ExceptionCode.INDEX_SIZE_ERR = ((ExceptionMessage[1]="Index size error"),1);
-var DOMSTRING_SIZE_ERR = ExceptionCode.DOMSTRING_SIZE_ERR = ((ExceptionMessage[2]="DOMString size error"),2);
-var HIERARCHY_REQUEST_ERR = ExceptionCode.HIERARCHY_REQUEST_ERR = ((ExceptionMessage[3]="Hierarchy request error"),3);
-var WRONG_DOCUMENT_ERR = ExceptionCode.WRONG_DOCUMENT_ERR = ((ExceptionMessage[4]="Wrong document"),4);
-var INVALID_CHARACTER_ERR = ExceptionCode.INVALID_CHARACTER_ERR = ((ExceptionMessage[5]="Invalid character"),5);
-var NO_DATA_ALLOWED_ERR = ExceptionCode.NO_DATA_ALLOWED_ERR = ((ExceptionMessage[6]="No data allowed"),6);
-var NO_MODIFICATION_ALLOWED_ERR = ExceptionCode.NO_MODIFICATION_ALLOWED_ERR = ((ExceptionMessage[7]="No modification allowed"),7);
-var NOT_FOUND_ERR = ExceptionCode.NOT_FOUND_ERR = ((ExceptionMessage[8]="Not found"),8);
-var NOT_SUPPORTED_ERR = ExceptionCode.NOT_SUPPORTED_ERR = ((ExceptionMessage[9]="Not supported"),9);
-var INUSE_ATTRIBUTE_ERR = ExceptionCode.INUSE_ATTRIBUTE_ERR = ((ExceptionMessage[10]="Attribute in use"),10);
-//level2
-var INVALID_STATE_ERR = ExceptionCode.INVALID_STATE_ERR = ((ExceptionMessage[11]="Invalid state"),11);
-var SYNTAX_ERR = ExceptionCode.SYNTAX_ERR = ((ExceptionMessage[12]="Syntax error"),12);
-var INVALID_MODIFICATION_ERR = ExceptionCode.INVALID_MODIFICATION_ERR = ((ExceptionMessage[13]="Invalid modification"),13);
-var NAMESPACE_ERR = ExceptionCode.NAMESPACE_ERR = ((ExceptionMessage[14]="Invalid namespace"),14);
-var INVALID_ACCESS_ERR = ExceptionCode.INVALID_ACCESS_ERR = ((ExceptionMessage[15]="Invalid access"),15);
-
-
-function DOMException(code, message) {
- if(message instanceof Error){
- var error = message;
- }else{
- error = this;
- Error.call(this, ExceptionMessage[code]);
- this.message = ExceptionMessage[code];
- if(Error.captureStackTrace) Error.captureStackTrace(this, DOMException);
- }
- error.code = code;
- if(message) this.message = this.message + ": " + message;
- return error;
-};
-DOMException.prototype = Error.prototype;
-copy(ExceptionCode,DOMException)
-/**
- * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-536297177
- * The NodeList interface provides the abstraction of an ordered collection of nodes, without defining or constraining how this collection is implemented. NodeList objects in the DOM are live.
- * The items in the NodeList are accessible via an integral index, starting from 0.
- */
-function NodeList() {
-};
-NodeList.prototype = {
- /**
- * The number of nodes in the list. The range of valid child node indices is 0 to length-1 inclusive.
- * @standard level1
- */
- length:0,
- /**
- * Returns the indexth item in the collection. If index is greater than or equal to the number of nodes in the list, this returns null.
- * @standard level1
- * @param index unsigned long
- * Index into the collection.
- * @return Node
- * The node at the indexth position in the NodeList, or null if that is not a valid index.
- */
- item: function(index) {
- return this[index] || null;
- }
-};
-function LiveNodeList(node,refresh){
- this._node = node;
- this._refresh = refresh
- _updateLiveList(this);
-}
-function _updateLiveList(list){
- var inc = list._node._inc || list._node.ownerDocument._inc;
- if(list._inc != inc){
- var ls = list._refresh(list._node);
- //console.log(ls.length)
- __set__(list,'length',ls.length);
- copy(ls,list);
- list._inc = inc;
- }
-}
-LiveNodeList.prototype.item = function(i){
- _updateLiveList(this);
- return this[i];
-}
-
-_extends(LiveNodeList,NodeList);
-/**
- *
- * Objects implementing the NamedNodeMap interface are used to represent collections of nodes that can be accessed by name. Note that NamedNodeMap does not inherit from NodeList; NamedNodeMaps are not maintained in any particular order. Objects contained in an object implementing NamedNodeMap may also be accessed by an ordinal index, but this is simply to allow convenient enumeration of the contents of a NamedNodeMap, and does not imply that the DOM specifies an order to these Nodes.
- * NamedNodeMap objects in the DOM are live.
- * used for attributes or DocumentType entities
- */
-function NamedNodeMap() {
-};
-
-function _findNodeIndex(list,node){
- var i = list.length;
- while(i--){
- if(list[i] === node){return i}
- }
-}
-
-function _addNamedNode(el,list,newAttr,oldAttr){
- if(oldAttr){
- list[_findNodeIndex(list,oldAttr)] = newAttr;
- }else{
- list[list.length++] = newAttr;
- }
- if(el){
- newAttr.ownerElement = el;
- var doc = el.ownerDocument;
- if(doc){
- oldAttr && _onRemoveAttribute(doc,el,oldAttr);
- _onAddAttribute(doc,el,newAttr);
- }
- }
-}
-function _removeNamedNode(el,list,attr){
- var i = _findNodeIndex(list,attr);
- if(i>=0){
- var lastIndex = list.length-1
- while(i0 || key == 'xmlns'){
-// return null;
-// }
- var i = this.length;
- while(i--){
- var attr = this[i];
- if(attr.nodeName == key){
- return attr;
- }
- }
- },
- setNamedItem: function(attr) {
- var el = attr.ownerElement;
- if(el && el!=this._ownerElement){
- throw new DOMException(INUSE_ATTRIBUTE_ERR);
- }
- var oldAttr = this.getNamedItem(attr.nodeName);
- _addNamedNode(this._ownerElement,this,attr,oldAttr);
- return oldAttr;
- },
- /* returns Node */
- setNamedItemNS: function(attr) {// raises: WRONG_DOCUMENT_ERR,NO_MODIFICATION_ALLOWED_ERR,INUSE_ATTRIBUTE_ERR
- var el = attr.ownerElement, oldAttr;
- if(el && el!=this._ownerElement){
- throw new DOMException(INUSE_ATTRIBUTE_ERR);
- }
- oldAttr = this.getNamedItemNS(attr.namespaceURI,attr.localName);
- _addNamedNode(this._ownerElement,this,attr,oldAttr);
- return oldAttr;
- },
-
- /* returns Node */
- removeNamedItem: function(key) {
- var attr = this.getNamedItem(key);
- _removeNamedNode(this._ownerElement,this,attr);
- return attr;
-
-
- },// raises: NOT_FOUND_ERR,NO_MODIFICATION_ALLOWED_ERR
-
- //for level2
- removeNamedItemNS:function(namespaceURI,localName){
- var attr = this.getNamedItemNS(namespaceURI,localName);
- _removeNamedNode(this._ownerElement,this,attr);
- return attr;
- },
- getNamedItemNS: function(namespaceURI, localName) {
- var i = this.length;
- while(i--){
- var node = this[i];
- if(node.localName == localName && node.namespaceURI == namespaceURI){
- return node;
- }
- }
- return null;
- }
-};
-/**
- * @see http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-102161490
- */
-function DOMImplementation(/* Object */ features) {
- this._features = {};
- if (features) {
- for (var feature in features) {
- this._features = features[feature];
- }
- }
-};
-
-DOMImplementation.prototype = {
- hasFeature: function(/* string */ feature, /* string */ version) {
- var versions = this._features[feature.toLowerCase()];
- if (versions && (!version || version in versions)) {
- return true;
- } else {
- return false;
- }
- },
- // Introduced in DOM Level 2:
- createDocument:function(namespaceURI, qualifiedName, doctype){// raises:INVALID_CHARACTER_ERR,NAMESPACE_ERR,WRONG_DOCUMENT_ERR
- var doc = new Document();
- doc.doctype = doctype;
- if(doctype){
- doc.appendChild(doctype);
- }
- doc.implementation = this;
- doc.childNodes = new NodeList();
- if(qualifiedName){
- var root = doc.createElementNS(namespaceURI,qualifiedName);
- doc.appendChild(root);
- }
- return doc;
- },
- // Introduced in DOM Level 2:
- createDocumentType:function(qualifiedName, publicId, systemId){// raises:INVALID_CHARACTER_ERR,NAMESPACE_ERR
- var node = new DocumentType();
- node.name = qualifiedName;
- node.nodeName = qualifiedName;
- node.publicId = publicId;
- node.systemId = systemId;
- // Introduced in DOM Level 2:
- //readonly attribute DOMString internalSubset;
-
- //TODO:..
- // readonly attribute NamedNodeMap entities;
- // readonly attribute NamedNodeMap notations;
- return node;
- }
-};
-
-
-/**
- * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247
- */
-
-function Node() {
-};
-
-Node.prototype = {
- firstChild : null,
- lastChild : null,
- previousSibling : null,
- nextSibling : null,
- attributes : null,
- parentNode : null,
- childNodes : null,
- ownerDocument : null,
- nodeValue : null,
- namespaceURI : null,
- prefix : null,
- localName : null,
- // Modified in DOM Level 2:
- insertBefore:function(newChild, refChild){//raises
- return _insertBefore(this,newChild,refChild);
- },
- replaceChild:function(newChild, oldChild){//raises
- this.insertBefore(newChild,oldChild);
- if(oldChild){
- this.removeChild(oldChild);
- }
- },
- removeChild:function(oldChild){
- return _removeChild(this,oldChild);
- },
- appendChild:function(newChild){
- return this.insertBefore(newChild,null);
- },
- hasChildNodes:function(){
- return this.firstChild != null;
- },
- cloneNode:function(deep){
- return cloneNode(this.ownerDocument||this,this,deep);
- },
- // Modified in DOM Level 2:
- normalize:function(){
- var child = this.firstChild;
- while(child){
- var next = child.nextSibling;
- if(next && next.nodeType == TEXT_NODE && child.nodeType == TEXT_NODE){
- this.removeChild(next);
- child.appendData(next.data);
- }else{
- child.normalize();
- child = next;
- }
- }
- },
- // Introduced in DOM Level 2:
- isSupported:function(feature, version){
- return this.ownerDocument.implementation.hasFeature(feature,version);
- },
- // Introduced in DOM Level 2:
- hasAttributes:function(){
- return this.attributes.length>0;
- },
- lookupPrefix:function(namespaceURI){
- var el = this;
- while(el){
- var map = el._nsMap;
- //console.dir(map)
- if(map){
- for(var n in map){
- if(map[n] == namespaceURI){
- return n;
- }
- }
- }
- el = el.nodeType == 2?el.ownerDocument : el.parentNode;
- }
- return null;
- },
- // Introduced in DOM Level 3:
- lookupNamespaceURI:function(prefix){
- var el = this;
- while(el){
- var map = el._nsMap;
- //console.dir(map)
- if(map){
- if(prefix in map){
- return map[prefix] ;
- }
- }
- el = el.nodeType == 2?el.ownerDocument : el.parentNode;
- }
- return null;
- },
- // Introduced in DOM Level 3:
- isDefaultNamespace:function(namespaceURI){
- var prefix = this.lookupPrefix(namespaceURI);
- return prefix == null;
- }
-};
-
-
-function _xmlEncoder(c){
- return c == '<' && '<' ||
- c == '>' && '>' ||
- c == '&' && '&' ||
- c == '"' && '"' ||
- ''+c.charCodeAt()+';'
-}
-
-
-copy(NodeType,Node);
-copy(NodeType,Node.prototype);
-
-/**
- * @param callback return true for continue,false for break
- * @return boolean true: break visit;
- */
-function _visitNode(node,callback){
- if(callback(node)){
- return true;
- }
- if(node = node.firstChild){
- do{
- if(_visitNode(node,callback)){return true}
- }while(node=node.nextSibling)
- }
-}
-
-
-
-function Document(){
-}
-function _onAddAttribute(doc,el,newAttr){
- doc && doc._inc++;
- var ns = newAttr.namespaceURI ;
- if(ns == 'http://www.w3.org/2000/xmlns/'){
- //update namespace
- el._nsMap[newAttr.prefix?newAttr.localName:''] = newAttr.value
- }
-}
-function _onRemoveAttribute(doc,el,newAttr,remove){
- doc && doc._inc++;
- var ns = newAttr.namespaceURI ;
- if(ns == 'http://www.w3.org/2000/xmlns/'){
- //update namespace
- delete el._nsMap[newAttr.prefix?newAttr.localName:'']
- }
-}
-function _onUpdateChild(doc,el,newChild){
- if(doc && doc._inc){
- doc._inc++;
- //update childNodes
- var cs = el.childNodes;
- if(newChild){
- cs[cs.length++] = newChild;
- }else{
- //console.log(1)
- var child = el.firstChild;
- var i = 0;
- while(child){
- cs[i++] = child;
- child =child.nextSibling;
- }
- cs.length = i;
- }
- }
-}
-
-/**
- * attributes;
- * children;
- *
- * writeable properties:
- * nodeValue,Attr:value,CharacterData:data
- * prefix
- */
-function _removeChild(parentNode,child){
- var previous = child.previousSibling;
- var next = child.nextSibling;
- if(previous){
- previous.nextSibling = next;
- }else{
- parentNode.firstChild = next
- }
- if(next){
- next.previousSibling = previous;
- }else{
- parentNode.lastChild = previous;
- }
- _onUpdateChild(parentNode.ownerDocument,parentNode);
- return child;
-}
-/**
- * preformance key(refChild == null)
- */
-function _insertBefore(parentNode,newChild,nextChild){
- var cp = newChild.parentNode;
- if(cp){
- cp.removeChild(newChild);//remove and update
- }
- if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){
- var newFirst = newChild.firstChild;
- var newLast = newChild.lastChild;
- }else{
- newFirst = newLast = newChild;
- }
- var pre = nextChild ? nextChild.previousSibling : parentNode.lastChild;
-
- newFirst.previousSibling = pre;
- newLast.nextSibling = nextChild;
-
-
- if(pre){
- pre.nextSibling = newFirst;
- }else{
- parentNode.firstChild = newFirst;
- }
- if(nextChild == null){
- parentNode.lastChild = newLast;
- }else{
- nextChild.previousSibling = newLast;
- }
- do{
- newFirst.parentNode = parentNode;
- }while(newFirst !== newLast && (newFirst= newFirst.nextSibling))
- _onUpdateChild(parentNode.ownerDocument||parentNode,parentNode);
- //console.log(parentNode.lastChild.nextSibling == null)
- if (newChild.nodeType == DOCUMENT_FRAGMENT_NODE) {
- newChild.firstChild = newChild.lastChild = null;
- }
- return newChild;
-}
-function _appendSingleChild(parentNode,newChild){
- var cp = newChild.parentNode;
- if(cp){
- var pre = parentNode.lastChild;
- cp.removeChild(newChild);//remove and update
- var pre = parentNode.lastChild;
- }
- var pre = parentNode.lastChild;
- newChild.parentNode = parentNode;
- newChild.previousSibling = pre;
- newChild.nextSibling = null;
- if(pre){
- pre.nextSibling = newChild;
- }else{
- parentNode.firstChild = newChild;
- }
- parentNode.lastChild = newChild;
- _onUpdateChild(parentNode.ownerDocument,parentNode,newChild);
- return newChild;
- //console.log("__aa",parentNode.lastChild.nextSibling == null)
-}
-Document.prototype = {
- //implementation : null,
- nodeName : '#document',
- nodeType : DOCUMENT_NODE,
- doctype : null,
- documentElement : null,
- _inc : 1,
-
- insertBefore : function(newChild, refChild){//raises
- if(newChild.nodeType == DOCUMENT_FRAGMENT_NODE){
- var child = newChild.firstChild;
- while(child){
- var next = child.nextSibling;
- this.insertBefore(child,refChild);
- child = next;
- }
- return newChild;
- }
- if(this.documentElement == null && newChild.nodeType == 1){
- this.documentElement = newChild;
- }
-
- return _insertBefore(this,newChild,refChild),(newChild.ownerDocument = this),newChild;
- },
- removeChild : function(oldChild){
- if(this.documentElement == oldChild){
- this.documentElement = null;
- }
- return _removeChild(this,oldChild);
- },
- // Introduced in DOM Level 2:
- importNode : function(importedNode,deep){
- return importNode(this,importedNode,deep);
- },
- // Introduced in DOM Level 2:
- getElementById : function(id){
- var rtv = null;
- _visitNode(this.documentElement,function(node){
- if(node.nodeType == 1){
- if(node.getAttribute('id') == id){
- rtv = node;
- return true;
- }
- }
- })
- return rtv;
- },
-
- //document factory method:
- createElement : function(tagName){
- var node = new Element();
- node.ownerDocument = this;
- node.nodeName = tagName;
- node.tagName = tagName;
- node.childNodes = new NodeList();
- var attrs = node.attributes = new NamedNodeMap();
- attrs._ownerElement = node;
- return node;
- },
- createDocumentFragment : function(){
- var node = new DocumentFragment();
- node.ownerDocument = this;
- node.childNodes = new NodeList();
- return node;
- },
- createTextNode : function(data){
- var node = new Text();
- node.ownerDocument = this;
- node.appendData(data)
- return node;
- },
- createComment : function(data){
- var node = new Comment();
- node.ownerDocument = this;
- node.appendData(data)
- return node;
- },
- createCDATASection : function(data){
- var node = new CDATASection();
- node.ownerDocument = this;
- node.appendData(data)
- return node;
- },
- createProcessingInstruction : function(target,data){
- var node = new ProcessingInstruction();
- node.ownerDocument = this;
- node.tagName = node.target = target;
- node.nodeValue= node.data = data;
- return node;
- },
- createAttribute : function(name){
- var node = new Attr();
- node.ownerDocument = this;
- node.name = name;
- node.nodeName = name;
- node.localName = name;
- node.specified = true;
- return node;
- },
- createEntityReference : function(name){
- var node = new EntityReference();
- node.ownerDocument = this;
- node.nodeName = name;
- return node;
- },
- // Introduced in DOM Level 2:
- createElementNS : function(namespaceURI,qualifiedName){
- var node = new Element();
- var pl = qualifiedName.split(':');
- var attrs = node.attributes = new NamedNodeMap();
- node.childNodes = new NodeList();
- node.ownerDocument = this;
- node.nodeName = qualifiedName;
- node.tagName = qualifiedName;
- node.namespaceURI = namespaceURI;
- if(pl.length == 2){
- node.prefix = pl[0];
- node.localName = pl[1];
- }else{
- //el.prefix = null;
- node.localName = qualifiedName;
- }
- attrs._ownerElement = node;
- return node;
- },
- // Introduced in DOM Level 2:
- createAttributeNS : function(namespaceURI,qualifiedName){
- var node = new Attr();
- var pl = qualifiedName.split(':');
- node.ownerDocument = this;
- node.nodeName = qualifiedName;
- node.name = qualifiedName;
- node.namespaceURI = namespaceURI;
- node.specified = true;
- if(pl.length == 2){
- node.prefix = pl[0];
- node.localName = pl[1];
- }else{
- //el.prefix = null;
- node.localName = qualifiedName;
- }
- return node;
- }
-};
-_extends(Document,Node);
-
-
-function Element() {
- this._nsMap = {};
-};
-Element.prototype = {
- nodeType : ELEMENT_NODE,
- hasAttribute : function(name){
- return this.getAttributeNode(name)!=null;
- },
- getAttribute : function(name){
- var attr = this.getAttributeNode(name);
- return attr && attr.value || '';
- },
- getAttributeNode : function(name){
- return this.attributes.getNamedItem(name);
- },
- setAttribute : function(name, value){
- var attr = this.ownerDocument.createAttribute(name);
- attr.value = attr.nodeValue = "" + value;
- this.setAttributeNode(attr)
- },
- removeAttribute : function(name){
- var attr = this.getAttributeNode(name)
- attr && this.removeAttributeNode(attr);
- },
-
- //four real opeartion method
- appendChild:function(newChild){
- if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){
- return this.insertBefore(newChild,null);
- }else{
- return _appendSingleChild(this,newChild);
- }
- },
- setAttributeNode : function(newAttr){
- return this.attributes.setNamedItem(newAttr);
- },
- setAttributeNodeNS : function(newAttr){
- return this.attributes.setNamedItemNS(newAttr);
- },
- removeAttributeNode : function(oldAttr){
- return this.attributes.removeNamedItem(oldAttr.nodeName);
- },
- //get real attribute name,and remove it by removeAttributeNode
- removeAttributeNS : function(namespaceURI, localName){
- var old = this.getAttributeNodeNS(namespaceURI, localName);
- old && this.removeAttributeNode(old);
- },
-
- hasAttributeNS : function(namespaceURI, localName){
- return this.getAttributeNodeNS(namespaceURI, localName)!=null;
- },
- getAttributeNS : function(namespaceURI, localName){
- var attr = this.getAttributeNodeNS(namespaceURI, localName);
- return attr && attr.value || '';
- },
- setAttributeNS : function(namespaceURI, qualifiedName, value){
- var attr = this.ownerDocument.createAttributeNS(namespaceURI, qualifiedName);
- attr.value = attr.nodeValue = value;
- this.setAttributeNode(attr)
- },
- getAttributeNodeNS : function(namespaceURI, localName){
- return this.attributes.getNamedItemNS(namespaceURI, localName);
- },
-
- getElementsByTagName : function(tagName){
- return new LiveNodeList(this,function(base){
- var ls = [];
- _visitNode(base,function(node){
- if(node !== base && node.nodeType == ELEMENT_NODE && (tagName === '*' || node.tagName == tagName)){
- ls.push(node);
- }
- });
- return ls;
- });
- },
- getElementsByTagNameNS : function(namespaceURI, localName){
- return new LiveNodeList(this,function(base){
- var ls = [];
- _visitNode(base,function(node){
- if(node !== base && node.nodeType === ELEMENT_NODE && node.namespaceURI === namespaceURI && (localName === '*' || node.localName == localName)){
- ls.push(node);
- }
- });
- return ls;
- });
- }
-};
-Document.prototype.getElementsByTagName = Element.prototype.getElementsByTagName;
-Document.prototype.getElementsByTagNameNS = Element.prototype.getElementsByTagNameNS;
-
-
-_extends(Element,Node);
-function Attr() {
-};
-Attr.prototype.nodeType = ATTRIBUTE_NODE;
-_extends(Attr,Node);
-
-
-function CharacterData() {
-};
-CharacterData.prototype = {
- data : '',
- substringData : function(offset, count) {
- return this.data.substring(offset, offset+count);
- },
- appendData: function(text) {
- text = this.data+text;
- this.nodeValue = this.data = text;
- this.length = text.length;
- },
- insertData: function(offset,text) {
- this.replaceData(offset,0,text);
-
- },
- appendChild:function(newChild){
- //if(!(newChild instanceof CharacterData)){
- throw new Error(ExceptionMessage[3])
- //}
- return Node.prototype.appendChild.apply(this,arguments)
- },
- deleteData: function(offset, count) {
- this.replaceData(offset,count,"");
- },
- replaceData: function(offset, count, text) {
- var start = this.data.substring(0,offset);
- var end = this.data.substring(offset+count);
- text = start + text + end;
- this.nodeValue = this.data = text;
- this.length = text.length;
- }
-}
-_extends(CharacterData,Node);
-function Text() {
-};
-Text.prototype = {
- nodeName : "#text",
- nodeType : TEXT_NODE,
- splitText : function(offset) {
- var text = this.data;
- var newText = text.substring(offset);
- text = text.substring(0, offset);
- this.data = this.nodeValue = text;
- this.length = text.length;
- var newNode = this.ownerDocument.createTextNode(newText);
- if(this.parentNode){
- this.parentNode.insertBefore(newNode, this.nextSibling);
- }
- return newNode;
- }
-}
-_extends(Text,CharacterData);
-function Comment() {
-};
-Comment.prototype = {
- nodeName : "#comment",
- nodeType : COMMENT_NODE
-}
-_extends(Comment,CharacterData);
-
-function CDATASection() {
-};
-CDATASection.prototype = {
- nodeName : "#cdata-section",
- nodeType : CDATA_SECTION_NODE
-}
-_extends(CDATASection,CharacterData);
-
-
-function DocumentType() {
-};
-DocumentType.prototype.nodeType = DOCUMENT_TYPE_NODE;
-_extends(DocumentType,Node);
-
-function Notation() {
-};
-Notation.prototype.nodeType = NOTATION_NODE;
-_extends(Notation,Node);
-
-function Entity() {
-};
-Entity.prototype.nodeType = ENTITY_NODE;
-_extends(Entity,Node);
-
-function EntityReference() {
-};
-EntityReference.prototype.nodeType = ENTITY_REFERENCE_NODE;
-_extends(EntityReference,Node);
-
-function DocumentFragment() {
-};
-DocumentFragment.prototype.nodeName = "#document-fragment";
-DocumentFragment.prototype.nodeType = DOCUMENT_FRAGMENT_NODE;
-_extends(DocumentFragment,Node);
-
-
-function ProcessingInstruction() {
-}
-ProcessingInstruction.prototype.nodeType = PROCESSING_INSTRUCTION_NODE;
-_extends(ProcessingInstruction,Node);
-function XMLSerializer(){}
-XMLSerializer.prototype.serializeToString = function(node){
- var buf = [];
- serializeToString(node,buf);
- return buf.join('');
-}
-Node.prototype.toString =function(){
- return XMLSerializer.prototype.serializeToString(this);
-}
-function serializeToString(node,buf){
- switch(node.nodeType){
- case ELEMENT_NODE:
- var attrs = node.attributes;
- var len = attrs.length;
- var child = node.firstChild;
- var nodeName = node.tagName;
- var isHTML = htmlns === node.namespaceURI
- buf.push('<',nodeName);
- for(var i=0;i');
- //if is cdata child node
- if(isHTML && /^script$/i.test(nodeName)){
- if(child){
- buf.push(child.data);
- }
- }else{
- while(child){
- serializeToString(child,buf);
- child = child.nextSibling;
- }
- }
- buf.push('',nodeName,'>');
- }else{
- buf.push('/>');
- }
- return;
- case DOCUMENT_NODE:
- case DOCUMENT_FRAGMENT_NODE:
- var child = node.firstChild;
- while(child){
- serializeToString(child,buf);
- child = child.nextSibling;
- }
- return;
- case ATTRIBUTE_NODE:
- return buf.push(' ',node.name,'="',node.value.replace(/[<&"]/g,_xmlEncoder),'"');
- case TEXT_NODE:
- return buf.push(node.data.replace(/[<&]/g,_xmlEncoder));
- case CDATA_SECTION_NODE:
- return buf.push( '');
- case COMMENT_NODE:
- return buf.push( "");
- case DOCUMENT_TYPE_NODE:
- var pubid = node.publicId;
- var sysid = node.systemId;
- buf.push('');
- }else if(sysid && sysid!='.'){
- buf.push(' SYSTEM "',sysid,'">');
- }else{
- var sub = node.internalSubset;
- if(sub){
- buf.push(" [",sub,"]");
- }
- buf.push(">");
- }
- return;
- case PROCESSING_INSTRUCTION_NODE:
- return buf.push( "",node.target," ",node.data,"?>");
- case ENTITY_REFERENCE_NODE:
- return buf.push( '&',node.nodeName,';');
- //case ENTITY_NODE:
- //case NOTATION_NODE:
- default:
- buf.push('??',node.nodeName);
- }
-}
-function importNode(doc,node,deep){
- var node2;
- switch (node.nodeType) {
- case ELEMENT_NODE:
- node2 = node.cloneNode(false);
- node2.ownerDocument = doc;
- var attrs = node2.attributes;
- var len = attrs.length;
- for(var i=0;i=0.1"
- },
- "dependencies": {},
- "devDependencies": {},
- "maintainers": [
- {
- "name": "jindw",
- "email": "jindw@xidea.org",
- "url": "http://www.xidea.org"
- }
- ],
- "contributors": [
- {
- "name": "Yaron Naveh",
- "email": "yaronn01@gmail.com",
- "url": "http://webservices20.blogspot.com/"
- },
- {
- "name": "Harutyun Amirjanyan",
- "email": "amirjanyan@gmail.com",
- "url": "https://github.com/nightwing"
- },
- {
- "name": "bigeasy",
- "email": "alan@prettyrobots.com",
- "url": "http://www.prettyrobots.com/"
- }
- ],
- "bugs": {
- "email": "jindw@xidea.org",
- "url": "http://github.com/jindw/xmldom/issues"
- },
- "licenses": [
- {
- "type": "LGPL",
- "url": "http://www.gnu.org/licenses/lgpl.html"
- }
- ],
- "readme": "Introduction\n-------\nAnother xml parser for nodejs/browser/rhino for java.\nFully compatible with `W3C DOM level2`; and some compatible with `level3`.\nsupport `DOMParser` and `XMLSerializer` interface such as in browser.\n\nInstall:\n-------\n>npm install xmldom\n\nExample:\n====\n```javascript\nvar DOMParser = require('xmldom').DOMParser;\nvar doc = new DOMParser().parseFromString(\n '\\n'+\n '\\ttest\\n'+\n '\\t\\n'+\n '\\t\\n'+\n ''\n ,'text/xml');\ndoc.documentElement.setAttribute('x','y');\ndoc.documentElement.setAttributeNS('./lite','c:x','y2');\nvar nsAttr = doc.documentElement.getAttributeNS('./lite','x')\nconsole.info(nsAttr)\nconsole.info(doc)\n```\nAPI Reference\n=====\n\n * [DOMParser](https://developer.mozilla.org/en/DOMParser):\n\n\t```javascript\n\tparseFromString(xmlsource,mimeType)\n\t```\n\t* **options extension** _by xmldom_(not BOM standard!!)\n\n\t```javascript\n\t//added the options argument\n\tnew DOMParser(options)\n\t\n\t//errorHandler is supported\n\tnew DOMParser({\n\t\t/**\n\t\t * youcan override the errorHandler for xml parser\n\t\t * @link http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html\n\t\t */\n\t\terrorHandler:{warning:callback,error:callback,fatalError:callback}\n\t})\n\t\t\n\t```\n\n * [XMLSerializer](https://developer.mozilla.org/en/XMLSerializer)\n \n\t```javascript\n\tserializeToString(node)\n\t```\nDOM level2 method and attribute:\n------\n\n * [Node](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247)\n\t\n\t\tattribute:\n\t\t\tnodeValue|prefix\n\t\treadonly attribute:\n\t\t\tnodeName|nodeType|parentNode|childNodes|firstChild|lastChild|previousSibling|nextSibling|attributes|ownerDocument|namespaceURI|localName\n\t\tmethod:\t\n\t\t\tinsertBefore(newChild, refChild)\n\t\t\treplaceChild(newChild, oldChild)\n\t\t\tremoveChild(oldChild)\n\t\t\tappendChild(newChild)\n\t\t\thasChildNodes()\n\t\t\tcloneNode(deep)\n\t\t\tnormalize()\n\t\t\tisSupported(feature, version)\n\t\t\thasAttributes()\n\n * [DOMImplementation](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-102161490)\n\t\t\n\t\tmethod:\n\t\t\thasFeature(feature, version)\n\t\t\tcreateDocumentType(qualifiedName, publicId, systemId)\n\t\t\tcreateDocument(namespaceURI, qualifiedName, doctype)\n\n * [Document](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#i-Document) : Node\n\t\t\n\t\treadonly attribute:\n\t\t\tdoctype|implementation|documentElement\n\t\tmethod:\n\t\t\tcreateElement(tagName)\n\t\t\tcreateDocumentFragment()\n\t\t\tcreateTextNode(data)\n\t\t\tcreateComment(data)\n\t\t\tcreateCDATASection(data)\n\t\t\tcreateProcessingInstruction(target, data)\n\t\t\tcreateAttribute(name)\n\t\t\tcreateEntityReference(name)\n\t\t\tgetElementsByTagName(tagname)\n\t\t\timportNode(importedNode, deep)\n\t\t\tcreateElementNS(namespaceURI, qualifiedName)\n\t\t\tcreateAttributeNS(namespaceURI, qualifiedName)\n\t\t\tgetElementsByTagNameNS(namespaceURI, localName)\n\t\t\tgetElementById(elementId)\n\n * [DocumentFragment](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-B63ED1A3) : Node\n * [Element](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-745549614) : Node\n\t\t\n\t\treadonly attribute:\n\t\t\ttagName\n\t\tmethod:\n\t\t\tgetAttribute(name)\n\t\t\tsetAttribute(name, value)\n\t\t\tremoveAttribute(name)\n\t\t\tgetAttributeNode(name)\n\t\t\tsetAttributeNode(newAttr)\n\t\t\tremoveAttributeNode(oldAttr)\n\t\t\tgetElementsByTagName(name)\n\t\t\tgetAttributeNS(namespaceURI, localName)\n\t\t\tsetAttributeNS(namespaceURI, qualifiedName, value)\n\t\t\tremoveAttributeNS(namespaceURI, localName)\n\t\t\tgetAttributeNodeNS(namespaceURI, localName)\n\t\t\tsetAttributeNodeNS(newAttr)\n\t\t\tgetElementsByTagNameNS(namespaceURI, localName)\n\t\t\thasAttribute(name)\n\t\t\thasAttributeNS(namespaceURI, localName)\n\n * [Attr](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-637646024) : Node\n\t\n\t\tattribute:\n\t\t\tvalue\n\t\treadonly attribute:\n\t\t\tname|specified|ownerElement\n\n * [NodeList](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-536297177)\n\t\t\n\t\treadonly attribute:\n\t\t\tlength\n\t\tmethod:\n\t\t\titem(index)\n\t\n * [NamedNodeMap](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1780488922)\n\n\t\treadonly attribute:\n\t\t\tlength\n\t\tmethod:\n\t\t\tgetNamedItem(name)\n\t\t\tsetNamedItem(arg)\n\t\t\tremoveNamedItem(name)\n\t\t\titem(index)\n\t\t\tgetNamedItemNS(namespaceURI, localName)\n\t\t\tsetNamedItemNS(arg)\n\t\t\tremoveNamedItemNS(namespaceURI, localName)\n\t\t\n * [CharacterData](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-FF21A306) : Node\n\t\n\t\tmethod:\n\t\t\tsubstringData(offset, count)\n\t\t\tappendData(arg)\n\t\t\tinsertData(offset, arg)\n\t\t\tdeleteData(offset, count)\n\t\t\treplaceData(offset, count, arg)\n\t\t\n * [Text](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1312295772) : CharacterData\n\t\n\t\tmethod:\n\t\t\tsplitText(offset)\n\t\t\t\n * [CDATASection](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-667469212)\n * [Comment](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1728279322) : CharacterData\n\t\n * [DocumentType](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-412266927)\n\t\n\t\treadonly attribute:\n\t\t\tname|entities|notations|publicId|systemId|internalSubset\n\t\t\t\n * Notation : Node\n\t\n\t\treadonly attribute:\n\t\t\tpublicId|systemId\n\t\t\t\n * Entity : Node\n\t\n\t\treadonly attribute:\n\t\t\tpublicId|systemId|notationName\n\t\t\t\n * EntityReference : Node \n * ProcessingInstruction : Node \n\t\n\t\tattribute:\n\t\t\tdata\n\t\treadonly attribute:\n\t\t\ttarget\n\t\t\nDOM level 3 support:\n-----\n\n * [Node](http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-textContent)\n\t\t\n\t\tattribute:\n\t\t\ttextContent\n\t\tmethod:\n\t\t\tisDefaultNamespace(namespaceURI){\n\t\t\tlookupNamespaceURI(prefix)\n\nDOM extension by xmldom\n---\n * [Node]\n\tSource position extension; \n\t\tattribute:\n\t\t\t//Numbered starting from '1'\n\t\t\tlineNumber\n\t\t\t//Numbered starting from '1'\n\t\t\tcolumnNumber\n",
- "_id": "xmldom@0.1.13",
- "dist": {
- "shasum": "54a7bcad1fc60da141d25a1db785286ca06ee7a4"
- },
- "_from": "/home/th/Downloads/xmldom-0.1.13.tgz"
-}
diff --git a/node_modules/xmldom/readme.md b/node_modules/xmldom/readme.md
deleted file mode 100644
index b1deb8028..000000000
--- a/node_modules/xmldom/readme.md
+++ /dev/null
@@ -1,213 +0,0 @@
-Introduction
--------
-Another xml parser for nodejs/browser/rhino for java.
-Fully compatible with `W3C DOM level2`; and some compatible with `level3`.
-support `DOMParser` and `XMLSerializer` interface such as in browser.
-
-Install:
--------
->npm install xmldom
-
-Example:
-====
-```javascript
-var DOMParser = require('xmldom').DOMParser;
-var doc = new DOMParser().parseFromString(
- '\n'+
- '\ttest\n'+
- '\t\n'+
- '\t\n'+
- ''
- ,'text/xml');
-doc.documentElement.setAttribute('x','y');
-doc.documentElement.setAttributeNS('./lite','c:x','y2');
-var nsAttr = doc.documentElement.getAttributeNS('./lite','x')
-console.info(nsAttr)
-console.info(doc)
-```
-API Reference
-=====
-
- * [DOMParser](https://developer.mozilla.org/en/DOMParser):
-
- ```javascript
- parseFromString(xmlsource,mimeType)
- ```
- * **options extension** _by xmldom_(not BOM standard!!)
-
- ```javascript
- //added the options argument
- new DOMParser(options)
-
- //errorHandler is supported
- new DOMParser({
- /**
- * youcan override the errorHandler for xml parser
- * @link http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html
- */
- errorHandler:{warning:callback,error:callback,fatalError:callback}
- })
-
- ```
-
- * [XMLSerializer](https://developer.mozilla.org/en/XMLSerializer)
-
- ```javascript
- serializeToString(node)
- ```
-DOM level2 method and attribute:
-------
-
- * [Node](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247)
-
- attribute:
- nodeValue|prefix
- readonly attribute:
- nodeName|nodeType|parentNode|childNodes|firstChild|lastChild|previousSibling|nextSibling|attributes|ownerDocument|namespaceURI|localName
- method:
- insertBefore(newChild, refChild)
- replaceChild(newChild, oldChild)
- removeChild(oldChild)
- appendChild(newChild)
- hasChildNodes()
- cloneNode(deep)
- normalize()
- isSupported(feature, version)
- hasAttributes()
-
- * [DOMImplementation](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-102161490)
-
- method:
- hasFeature(feature, version)
- createDocumentType(qualifiedName, publicId, systemId)
- createDocument(namespaceURI, qualifiedName, doctype)
-
- * [Document](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#i-Document) : Node
-
- readonly attribute:
- doctype|implementation|documentElement
- method:
- createElement(tagName)
- createDocumentFragment()
- createTextNode(data)
- createComment(data)
- createCDATASection(data)
- createProcessingInstruction(target, data)
- createAttribute(name)
- createEntityReference(name)
- getElementsByTagName(tagname)
- importNode(importedNode, deep)
- createElementNS(namespaceURI, qualifiedName)
- createAttributeNS(namespaceURI, qualifiedName)
- getElementsByTagNameNS(namespaceURI, localName)
- getElementById(elementId)
-
- * [DocumentFragment](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-B63ED1A3) : Node
- * [Element](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-745549614) : Node
-
- readonly attribute:
- tagName
- method:
- getAttribute(name)
- setAttribute(name, value)
- removeAttribute(name)
- getAttributeNode(name)
- setAttributeNode(newAttr)
- removeAttributeNode(oldAttr)
- getElementsByTagName(name)
- getAttributeNS(namespaceURI, localName)
- setAttributeNS(namespaceURI, qualifiedName, value)
- removeAttributeNS(namespaceURI, localName)
- getAttributeNodeNS(namespaceURI, localName)
- setAttributeNodeNS(newAttr)
- getElementsByTagNameNS(namespaceURI, localName)
- hasAttribute(name)
- hasAttributeNS(namespaceURI, localName)
-
- * [Attr](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-637646024) : Node
-
- attribute:
- value
- readonly attribute:
- name|specified|ownerElement
-
- * [NodeList](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-536297177)
-
- readonly attribute:
- length
- method:
- item(index)
-
- * [NamedNodeMap](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1780488922)
-
- readonly attribute:
- length
- method:
- getNamedItem(name)
- setNamedItem(arg)
- removeNamedItem(name)
- item(index)
- getNamedItemNS(namespaceURI, localName)
- setNamedItemNS(arg)
- removeNamedItemNS(namespaceURI, localName)
-
- * [CharacterData](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-FF21A306) : Node
-
- method:
- substringData(offset, count)
- appendData(arg)
- insertData(offset, arg)
- deleteData(offset, count)
- replaceData(offset, count, arg)
-
- * [Text](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1312295772) : CharacterData
-
- method:
- splitText(offset)
-
- * [CDATASection](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-667469212)
- * [Comment](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1728279322) : CharacterData
-
- * [DocumentType](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-412266927)
-
- readonly attribute:
- name|entities|notations|publicId|systemId|internalSubset
-
- * Notation : Node
-
- readonly attribute:
- publicId|systemId
-
- * Entity : Node
-
- readonly attribute:
- publicId|systemId|notationName
-
- * EntityReference : Node
- * ProcessingInstruction : Node
-
- attribute:
- data
- readonly attribute:
- target
-
-DOM level 3 support:
------
-
- * [Node](http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-textContent)
-
- attribute:
- textContent
- method:
- isDefaultNamespace(namespaceURI){
- lookupNamespaceURI(prefix)
-
-DOM extension by xmldom
----
- * [Node]
- Source position extension;
- attribute:
- //Numbered starting from '1'
- lineNumber
- //Numbered starting from '1'
- columnNumber
diff --git a/node_modules/xmldom/sax.js b/node_modules/xmldom/sax.js
deleted file mode 100644
index 901dfe01c..000000000
--- a/node_modules/xmldom/sax.js
+++ /dev/null
@@ -1,551 +0,0 @@
-//[4] NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
-//[4a] NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
-//[5] Name ::= NameStartChar (NameChar)*
-var nameStartChar = /[A-Z_a-z\xC0-\xD6\xD8-\xF6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]///\u10000-\uEFFFF
-var nameChar = new RegExp("[\\-\\.0-9"+nameStartChar.source.slice(1,-1)+"\u00B7\u0300-\u036F\\ux203F-\u2040]");
-var tagNamePattern = new RegExp('^'+nameStartChar.source+nameChar.source+'*(?:\:'+nameStartChar.source+nameChar.source+'*)?$');
-//var tagNamePattern = /^[a-zA-Z_][\w\-\.]*(?:\:[a-zA-Z_][\w\-\.]*)?$/
-//var handlers = 'resolveEntity,getExternalSubset,characters,endDocument,endElement,endPrefixMapping,ignorableWhitespace,processingInstruction,setDocumentLocator,skippedEntity,startDocument,startElement,startPrefixMapping,notationDecl,unparsedEntityDecl,error,fatalError,warning,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,comment,endCDATA,endDTD,endEntity,startCDATA,startDTD,startEntity'.split(',')
-
-//S_TAG, S_ATTR, S_EQ, S_V
-//S_ATTR_S, S_E, S_S, S_C
-var S_TAG = 0;//tag name offerring
-var S_ATTR = 1;//attr name offerring
-var S_ATTR_S=2;//attr name end and space offer
-var S_EQ = 3;//=space?
-var S_V = 4;//attr value(no quot value only)
-var S_E = 5;//attr value end and no space(quot end)
-var S_S = 6;//(attr value end || tag end ) && (space offer)
-var S_C = 7;//closed el
-
-function XMLReader(){
-}
-
-XMLReader.prototype = {
- parse:function(source,defaultNSMap,entityMap){
- var domBuilder = this.domBuilder;
- domBuilder.startDocument();
- _copy(defaultNSMap ,defaultNSMap = {})
- parse(source,defaultNSMap,entityMap,
- domBuilder,this.errorHandler);
- domBuilder.endDocument();
- }
-}
-function parse(source,defaultNSMapCopy,entityMap,domBuilder,errorHandler){
- function entityReplacer(a){
- var k = a.slice(1,-1);
- if(k in entityMap){
- return entityMap[k];
- }else if(k.charAt(0) === '#'){
- return String.fromCharCode(parseInt(k.substr(1).replace('x','0x')))
- }else{
- errorHandler.error('entity not found:'+a);
- return a;
- }
- }
- function appendText(end){//has some bugs
- var xt = source.substring(start,end).replace(/?\w+;/g,entityReplacer);
- locator&&position(start);
- domBuilder.characters(xt,0,end-start);
- start = end
- }
- function position(start,m){
- while(start>=endPos && (m = linePattern.exec(source))){
- startPos = m.index;
- endPos = startPos + m[0].length;
- locator.lineNumber++;
- //console.log('line++:',locator,startPos,endPos)
- }
- locator.columnNumber = start-startPos+1;
- }
- var startPos = 0;
- var endPos = 0;
- var linePattern = /.+(?:\r\n?|\n)|.*$/g
- var locator = domBuilder.locator;
-
- var parseStack = [{currentNSMap:defaultNSMapCopy}]
- var closeMap = {};
- var start = 0;
- while(true){
- var i = source.indexOf('<',start);
- if(i>start){
- appendText(i);
- }
- switch(source.charAt(i+1)){
- case '/':
- var end = source.indexOf('>',i+3);
- var tagName = source.substring(i+2,end);
- var config = parseStack.pop();
- var localNSMap = config.localNSMap;
-
- if(config.tagName != tagName){
- errorHandler.fatalError("end tag name: "+tagName+' is not match the current start tagName:'+config.tagName );
- }
- domBuilder.endElement(config.uri,config.localName,tagName);
- if(localNSMap){
- for(var prefix in localNSMap){
- domBuilder.endPrefixMapping(prefix) ;
- }
- }
- end++;
- break;
- // end elment
- case '?':// ...?>
- locator&&position(i);
- end = parseInstruction(source,i,domBuilder);
- break;
- case '!':// 0){
- value = source.slice(start,p).replace(/?\w+;/g,entityReplacer);
- el.add(attrName,value,start-1);
- s = S_E;
- }else{
- //fatalError: no end quot match
- throw new Error('attribute value no end \''+c+'\' match');
- }
- }else if(s == S_V){
- value = source.slice(start,p).replace(/?\w+;/g,entityReplacer);
- //console.log(attrName,value,start,p)
- el.add(attrName,value,start);
- //console.dir(el)
- errorHandler.warning('attribute "'+attrName+'" missed start quot('+c+')!!');
- start = p+1;
- s = S_E
- }else{
- //fatalError: no equal before
- throw new Error('attribute value must after "="');
- }
- break;
- case '/':
- switch(s){
- case S_TAG:
- el.setTagName(source.slice(start,p));
- case S_E:
- case S_S:
- case S_C:
- s = S_C;
- el.closed = true;
- case S_V:
- case S_ATTR:
- case S_ATTR_S:
- break;
- //case S_EQ:
- default:
- throw new Error("attribute invalid close char('/')")
- }
- break;
- case '>':
- switch(s){
- case S_TAG:
- el.setTagName(source.slice(start,p));
- case S_E:
- case S_S:
- case S_C:
- break;//normal
- case S_V://Compatible state
- case S_ATTR:
- value = source.slice(start,p);
- if(value.slice(-1) === '/'){
- el.closed = true;
- value = value.slice(0,-1)
- }
- case S_ATTR_S:
- if(s === S_ATTR_S){
- value = attrName;
- }
- if(s == S_V){
- errorHandler.warning('attribute "'+value+'" missed quot(")!!');
- el.add(attrName,value.replace(/?\w+;/g,entityReplacer),start)
- }else{
- errorHandler.warning('attribute "'+value+'" missed value!! "'+value+'" instead!!')
- el.add(value,value,start)
- }
- break;
- case S_EQ:
- throw new Error('attribute value missed!!');
- }
-// console.log(tagName,tagNamePattern,tagNamePattern.test(tagName))
- return p;
- /*xml space '\x20' | #x9 | #xD | #xA; */
- case '\u0080':
- c = ' ';
- default:
- if(c<= ' '){//space
- switch(s){
- case S_TAG:
- el.setTagName(source.slice(start,p));//tagName
- s = S_S;
- break;
- case S_ATTR:
- attrName = source.slice(start,p)
- s = S_ATTR_S;
- break;
- case S_V:
- var value = source.slice(start,p).replace(/?\w+;/g,entityReplacer);
- errorHandler.warning('attribute "'+value+'" missed quot(")!!');
- el.add(attrName,value,start)
- case S_E:
- s = S_S;
- break;
- //case S_S:
- //case S_EQ:
- //case S_ATTR_S:
- // void();break;
- //case S_C:
- //ignore warning
- }
- }else{//not space
-//S_TAG, S_ATTR, S_EQ, S_V
-//S_ATTR_S, S_E, S_S, S_C
- switch(s){
- //case S_TAG:void();break;
- //case S_ATTR:void();break;
- //case S_V:void();break;
- case S_ATTR_S:
- errorHandler.warning('attribute "'+attrName+'" missed value!! "'+attrName+'" instead!!')
- el.add(attrName,attrName,start);
- start = p;
- s = S_ATTR;
- break;
- case S_E:
- errorHandler.warning('attribute space is required"'+attrName+'"!!')
- case S_S:
- s = S_ATTR;
- start = p;
- break;
- case S_EQ:
- s = S_V;
- start = p;
- break;
- case S_C:
- throw new Error("elements closed character '/' and '>' must be connected to");
- }
- }
- }
- p++;
- }
-}
-/**
- * @return end of the elementStartPart(end of elementEndPart for selfClosed el)
- */
-function appendElement(el,domBuilder,parseStack){
- var tagName = el.tagName;
- var localNSMap = null;
- var currentNSMap = parseStack[parseStack.length-1].currentNSMap;
- var i = el.length;
- while(i--){
- var a = el[i];
- var qName = a.qName;
- var value = a.value;
- var nsp = qName.indexOf(':');
- if(nsp>0){
- var prefix = a.prefix = qName.slice(0,nsp);
- var localName = qName.slice(nsp+1);
- var nsPrefix = prefix === 'xmlns' && localName
- }else{
- localName = qName;
- prefix = null
- nsPrefix = qName === 'xmlns' && ''
- }
- //can not set prefix,because prefix !== ''
- a.localName = localName ;
- //prefix == null for no ns prefix attribute
- if(nsPrefix !== false){//hack!!
- if(localNSMap == null){
- localNSMap = {}
- _copy(currentNSMap,currentNSMap={})
- }
- currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value;
- a.uri = 'http://www.w3.org/2000/xmlns/'
- domBuilder.startPrefixMapping(nsPrefix, value)
- }
- }
- var i = el.length;
- while(i--){
- a = el[i];
- var prefix = a.prefix;
- if(prefix){//no prefix attribute has no namespace
- if(prefix === 'xml'){
- a.uri = 'http://www.w3.org/XML/1998/namespace';
- }if(prefix !== 'xmlns'){
- a.uri = currentNSMap[prefix]
- }
- }
- }
- var nsp = tagName.indexOf(':');
- if(nsp>0){
- prefix = el.prefix = tagName.slice(0,nsp);
- localName = el.localName = tagName.slice(nsp+1);
- }else{
- prefix = null;//important!!
- localName = el.localName = tagName;
- }
- //no prefix element has default namespace
- var ns = el.uri = currentNSMap[prefix || ''];
- domBuilder.startElement(ns,localName,tagName,el);
- //endPrefixMapping and startPrefixMapping have not any help for dom builder
- //localNSMap = null
- if(el.closed){
- domBuilder.endElement(ns,localName,tagName);
- if(localNSMap){
- for(prefix in localNSMap){
- domBuilder.endPrefixMapping(prefix)
- }
- }
- }else{
- el.currentNSMap = currentNSMap;
- el.localNSMap = localNSMap;
- parseStack.push(el);
- }
-}
-function parseHtmlSpecialContent(source,elStartEnd,tagName,entityReplacer,domBuilder){
- if(/^(?:script|textarea)$/i.test(tagName)){
- var elEndStart = source.indexOf(''+tagName+'>',elStartEnd);
- var text = source.substring(elStartEnd+1,elEndStart);
- if(/[&<]/.test(text)){
- if(/^script$/i.test(tagName)){
- //if(!/\]\]>/.test(text)){
- //lexHandler.startCDATA();
- domBuilder.characters(text,0,text.length);
- //lexHandler.endCDATA();
- return elEndStart;
- //}
- }//}else{//text area
- text = text.replace(/?\w+;/g,entityReplacer);
- domBuilder.characters(text,0,text.length);
- return elEndStart;
- //}
-
- }
- }
- return elStartEnd+1;
-}
-function fixSelfClosed(source,elStartEnd,tagName,closeMap){
- //if(tagName in closeMap){
- var pos = closeMap[tagName];
- if(pos == null){
- //console.log(tagName)
- pos = closeMap[tagName] = source.lastIndexOf(''+tagName+'>')
- }
- return pos',start+4);
- //append comment source.substring(4,end)//\n\n something\nx', 'text/xml');
- var test = doc.documentElement;
- var a = test.firstChild.nextSibling;
- assertPosition(doc.firstChild, 1, 1);
- assertPosition(doc.firstChild.nextSibling, 1, 1+''.length);
- assertPosition(test, 2, 1);
- //assertPosition(test.firstChild, 1, 7);
- assertPosition(a, 3, 3);
- assertPosition(a.firstChild, 3, 19);
- assertPosition(a.firstChild.nextSibling, 3, 19+''.length);
- assertPosition(test.lastChild, 4, 5);
- },
- 'error positions':function(){
- var error = []
- var parser = new DOMParser({
- locator:{systemId:'c:/test/1.xml'},
- errorHandler:function(msg){
- error.push(msg);
- }
- });
- var doc = parser.parseFromString('