diff --git a/.github/workflows/ci_workflow.yml b/.github/workflows/ci_workflow.yml index 53b3d398c..69c652d5a 100644 --- a/.github/workflows/ci_workflow.yml +++ b/.github/workflows/ci_workflow.yml @@ -32,14 +32,14 @@ jobs: strategy: matrix: os: [ubuntu-latest] - node-version: [18.19, 20.13] + node-version: [18.19, 20.13, 22.x] outputs: sha: ${{ steps.get-sha.outputs.SHA }} steps: - name: Harden Runner - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit @@ -57,7 +57,7 @@ jobs: echo "SHA: ${{ steps.get-sha.outputs.SHA }}" - name: Set up node ${{ matrix.node-version}} - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # ratchet:actions/setup-node@v4.0.2 + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: node-version: ${{ matrix.node-version }} @@ -65,7 +65,7 @@ jobs: run: corepack enable - name: Get yarn cache ${{ matrix.node-version}} - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # ratchet:actions/setup-node@v4.0.2 + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: cache: 'yarn' @@ -109,7 +109,7 @@ jobs: - name: Upload build artifacts (main && develop) # upload build artifacts for current node version and main or develop branch only if: matrix.node-version == 20.13 && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop') - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # ratchet:actions/upload-artifact@v4.3.3 + uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # ratchet:actions/upload-artifact@v4.3.6 with: name: dist path: ${{ github.workspace }}/${{ env.DIST_DIR }} @@ -136,7 +136,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit @@ -149,7 +149,7 @@ jobs: path: ${{ env.DEV_GH_PAGES_DIR }} - name: Download build artifacts - uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # ratchet:actions/upload-artifact@v4.1.7 + uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # ratchet:actions/upload-artifact@v4.1.8 with: name: dist path: ${{ github.workspace }}/${{ env.DIST_DIR }} @@ -208,14 +208,14 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit - name: Checkout repository uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Set up node ${{ matrix.node-version}} - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: node-version: ${{ matrix.node-version }} cache: 'yarn' @@ -248,7 +248,7 @@ jobs: node-version: [20.13] steps: - name: Harden Runner - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit @@ -258,7 +258,7 @@ jobs: - name: Create Release id: create_release if: ${{ success() && startsWith(github.ref, 'refs/tags/') }} - uses: softprops/action-gh-release@a74c6b72af54cfa997e81df42d94703d6313a2d0 # v2.0.6 + uses: softprops/action-gh-release@c062e08bd532815e2082a85e87e3ef29c3e6d191 # v2.0.8 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} TAG_VERSION: ${{ steps.get_version.outputs.VERSION }} diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index ee77a3664..40da09c11 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -26,7 +26,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit @@ -36,13 +36,13 @@ jobs: fetch-depth: 2 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@23acc5c183826b7a8a97bce3cecc52db901f8251 # v3.25.10 + uses: github/codeql-action/init@429e1977040da7a23b6822b13c129cd1ba93dbb2 # v3.26.2 with: languages: ${{ matrix.language }} # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@23acc5c183826b7a8a97bce3cecc52db901f8251 # v3.25.10 + uses: github/codeql-action/autobuild@429e1977040da7a23b6822b13c129cd1ba93dbb2 # v3.26.2 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@23acc5c183826b7a8a97bce3cecc52db901f8251 # v3.25.10 + uses: github/codeql-action/analyze@429e1977040da7a23b6822b13c129cd1ba93dbb2 # v3.26.2 with: category: '/language:${{matrix.language}}' diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index 1792f0181..bf2dcfbae 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -17,11 +17,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit - name: 'Checkout Repository' uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: 'Dependency Review' - uses: actions/dependency-review-action@72eb03d02c7872a771aacd928f3123ac62ad6d3a # v4.3.3 + uses: actions/dependency-review-action@5a2ce3f5b92ee19cbb1541a4984c76d921601d7c # v4.3.4 diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index ae73940b6..b6da2ca47 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -31,7 +31,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit @@ -41,7 +41,7 @@ jobs: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@dc50aa9510b46c811795eb24b2f1ba02a914e534 # v2.3.3 + uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0 with: results_file: results.sarif results_format: sarif @@ -63,7 +63,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6 with: name: SARIF file path: results.sarif @@ -71,6 +71,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@23acc5c183826b7a8a97bce3cecc52db901f8251 # v3.25.10 + uses: github/codeql-action/upload-sarif@429e1977040da7a23b6822b13c129cd1ba93dbb2 # v3.26.2 with: sarif_file: results.sarif diff --git a/.github/workflows/visualize-repo.yml b/.github/workflows/visualize-repo.yml index a5c441696..0c71b6f2d 100644 --- a/.github/workflows/visualize-repo.yml +++ b/.github/workflows/visualize-repo.yml @@ -14,7 +14,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit diff --git a/.husky/commit-msg b/.husky/commit-msg index b6c171501..04b13f458 100755 --- a/.husky/commit-msg +++ b/.husky/commit-msg @@ -1,5 +1,2 @@ -#!/bin/sh -. "$(dirname "$0")/_/husky.sh" - # cf. https://typicode.github.io/husky/#/?id=husky_git_params-ie-commitlint- yarn commitlint --edit "$1" diff --git a/.husky/pre-commit b/.husky/pre-commit index 8b393a899..1860b2afb 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,5 +1,2 @@ -#!/bin/sh -. "$(dirname "$0")/_/husky.sh" - # cf. https://typicode.github.io/husky/#/?id=package-scripts yarn run lint-staged diff --git a/CHANGELOG.md b/CHANGELOG.md index d19937034..130f3be8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,217 @@ All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines. +## [0.14.0](https://github.com/webern-unibas-ch/awg-app/compare/v0.12.3...v0.14.0) (2024-08-19) + +### Note + +Version 0.13.0 was intentionally skipped in honor of Arnold Schönberg, Anton Webern's lifelong teacher and friend, who feared the number 13 ([Triskaidekaphobia](https://en.wikipedia.org/wiki/Triskaidekaphobia)). + +### Features + +- **assets:** add corrections in Op12: EH + F ([8b42d86](https://github.com/webern-unibas-ch/awg-app/commit/8b42d864944d259b48fd649d906cf9c078d27540); thanks to [@masthom](https://github.com/masthom)) +- **assets:** add files for m36 ([5e2ffe6](https://github.com/webern-unibas-ch/awg-app/commit/5e2ffe64f3392efe6f3ad53930c5c9e6182203f2); thanks to [@chael-mi](https://github.com/chael-mi)) +- **assets:** add files for m38 ([03a6c17](https://github.com/webern-unibas-ch/awg-app/commit/03a6c17fd9dca14ecfa86be24b9c713b2ebe3afe); thanks to [@chael-mi](https://github.com/chael-mi)) +- **assets:** add preface content ([3a0210c](https://github.com/webern-unibas-ch/awg-app/commit/3a0210c26559265a63565c5eddda0be46e99ae6a); thanks to [@masthom](https://github.com/masthom)) +- **assets:** move complexes to separate assets file ([fe5571f](https://github.com/webern-unibas-ch/awg-app/commit/fe5571fa47ae820cbc326478e49d401cd091b309)) +- **assets:** move outline to separate assets file ([1e8997d](https://github.com/webern-unibas-ch/awg-app/commit/1e8997d3850e3af4056d369d573166bcef606d1b)) +- **core:** add EditionComplexes service ([c83edf3](https://github.com/webern-unibas-ch/awg-app/commit/c83edf3bf7e0057f8f6bab6f45f56a27b107a639)) +- **core:** add EditionOutline service ([7972875](https://github.com/webern-unibas-ch/awg-app/commit/7972875134ac3adb8a9bae642d548da1aefe2538)) +- **edition:** activate edition complex M 36 ([311b0b4](https://github.com/webern-unibas-ch/awg-app/commit/311b0b4c767ce56add9dd280a2cab81df787d94e)) +- **edition:** activate edition complex M 38 ([5b2a9bf](https://github.com/webern-unibas-ch/awg-app/commit/5b2a9bf6896e1d5c794678cdb685a0467a3e75d7)) +- **edition:** activate preface in app ([4213ea6](https://github.com/webern-unibas-ch/awg-app/commit/4213ea6358706c3443bdddcd3813a2c02bfd42a9)) +- **edition:** add initService & activate EditionOutline service in app ([2eb12d2](https://github.com/webern-unibas-ch/awg-app/commit/2eb12d230bfa4bcb13dfe4761431eead414816f9)) +- **edition:** add option to place folio items next to systems ([06ed541](https://github.com/webern-unibas-ch/awg-app/commit/06ed541e9ca5b3faf2d4930c667bdfccd01ea29f)) +- **edition:** add preface component and methods ([d4af6e8](https://github.com/webern-unibas-ch/awg-app/commit/d4af6e8b40e609759b971e85adcedde199e6fcb4)) +- **edition:** add ScrollToTop button to edition view ([3c75bbd](https://github.com/webern-unibas-ch/awg-app/commit/3c75bbd984ff032c2308e661733d80e8d26628e3)) +- **edition:** add textcritical comment blocks with headers ([7cf3a9b](https://github.com/webern-unibas-ch/awg-app/commit/7cf3a9b3b81247a730588fa0260ede4fdaeaa334)) +- **shared:** add ErrorAlertComponent ([dfbf6ce](https://github.com/webern-unibas-ch/awg-app/commit/dfbf6ce3bd96f35085ec8518560c70761426e650)) + +### Bug Fixes + +- **app:** fix import paths ([8183d6f](https://github.com/webern-unibas-ch/awg-app/commit/8183d6fc2d276cc856586b585def2a7fcd3b251a)) +- **assets:** add missing colons ([3a256a4](https://github.com/webern-unibas-ch/awg-app/commit/3a256a407391c421025fe2e908f5088ef3bc6f44)) +- **assets:** add missing data files and placeholders for m36 ([feca45b](https://github.com/webern-unibas-ch/awg-app/commit/feca45baf7a028d1017269e91c23297c3900d7ab)) +- **assets:** add missing data files and placeholders for m38 ([62f0ad2](https://github.com/webern-unibas-ch/awg-app/commit/62f0ad297e6227a1034525fe500b094859333945)) +- **assets:** add missing italics ([67c1120](https://github.com/webern-unibas-ch/awg-app/commit/67c1120d932d4340ef5fe414fa05e55cda6fefd1)) +- **assets:** add missing M to source list in m36 ([5aab381](https://github.com/webern-unibas-ch/awg-app/commit/5aab38148620c79fe40158f63f968e6966116c2a)) +- **assets:** adjust corrections op12 to new block style ([8512841](https://github.com/webern-unibas-ch/awg-app/commit/851284112feb80d5327c9d37aba806e84db470f8)) +- **assets:** fix addendum for source E in op25 ([3621bd1](https://github.com/webern-unibas-ch/awg-app/commit/3621bd158e749bb825953d5faca38d029796a9fc); thanks to [@masthom](https://github.com/masthom)) +- **assets:** fix link boxes and textcritics for m36 ([153811c](https://github.com/webern-unibas-ch/awg-app/commit/153811c6fe4bd91d24aac454f26c64c355768df3)) +- **assets:** fix link boxes and textcritics for m38 ([d4fd615](https://github.com/webern-unibas-ch/awg-app/commit/d4fd61555cf856bd335ab2e076a1c26957716f3e)) +- **assets:** fix M number of M 135 ([97fbf07](https://github.com/webern-unibas-ch/awg-app/commit/97fbf07fe93f52de1bc954082f9ebc85753272d1)) +- **assets:** fix order of sources in op. 4 ([d4b9538](https://github.com/webern-unibas-ch/awg-app/commit/d4b95388c0e414c90a4cc55134eea509c3710095)) +- **assets:** fix source lists for m36 and m38 ([4ea7ddf](https://github.com/webern-unibas-ch/awg-app/commit/4ea7ddf3f554e8dfbf24553183271c0ed7b3a0b5)) +- **assets:** fix textcritics for m36 ([a1c2d20](https://github.com/webern-unibas-ch/awg-app/commit/a1c2d2044f96b3ca4a0cdeadd46e224b604581a6)) +- **assets:** fix typo in op25 ([463683d](https://github.com/webern-unibas-ch/awg-app/commit/463683d20c479fd54c2f0b90200e90510f2e554d)) +- **assets:** fix typos and missing infos ([b93a4a4](https://github.com/webern-unibas-ch/awg-app/commit/b93a4a450639ea76b94e541336a3c4dbf60c87b9)) +- **assets:** fix whitespace in intro op12 ([f01c916](https://github.com/webern-unibas-ch/awg-app/commit/f01c9169bad4f2ed89bf3c373efc103bd86f466a)) +- **assets:** optimize svgs for m36 with SVGO ([a747bf0](https://github.com/webern-unibas-ch/awg-app/commit/a747bf0b12ed636364a0c4871594296f3a10700b)) +- **assets:** optimize svgs for m38 with SVGO ([ed6bca2](https://github.com/webern-unibas-ch/awg-app/commit/ed6bca244947d1024d26db986e4fe1767b659630)) +- **assets:** remove doc file ([1773fe8](https://github.com/webern-unibas-ch/awg-app/commit/1773fe8cd6f563108125613aed5104a1d33bf89a)) +- **assets:** remove parentheses from C & D in op. 23 ([5eb4d0d](https://github.com/webern-unibas-ch/awg-app/commit/5eb4d0deceaa3e0994172e1f576e6ab9898ffd8b)) +- **assets:** remove Textfassung for m39 from source list ([f882bf7](https://github.com/webern-unibas-ch/awg-app/commit/f882bf73655dbbe0d1a3ce755fe30c79bbfdee71)) +- **assets:** rename files for m38 ([745abcb](https://github.com/webern-unibas-ch/awg-app/commit/745abcb546f47bf4f424cd924719e26d6a0b2bde)) +- **assets:** update contained M numbers in m34–m38 ([9ffa781](https://github.com/webern-unibas-ch/awg-app/commit/9ffa7815a90e722f1049bd69b638bcae6a4192ba)) +- **assets:** update folio convolute for m36 ([46fa626](https://github.com/webern-unibas-ch/awg-app/commit/46fa626701ece99966f98f9d0d26526c28ba2efa)) +- **assets:** update folio convolute for m38 ([1de1aa5](https://github.com/webern-unibas-ch/awg-app/commit/1de1aa59416a795bc1c3dbb219782174162dc442)) +- **assets:** update m22 ([51e0cf0](https://github.com/webern-unibas-ch/awg-app/commit/51e0cf04c045b769a79091b313ccb72be915aee8)) +- **assets:** update m34 ([a42d5bd](https://github.com/webern-unibas-ch/awg-app/commit/a42d5bd8e97122d3b06f8ef1876233215a0d219b)) +- **assets:** update m35_42 ([c99842a](https://github.com/webern-unibas-ch/awg-app/commit/c99842a894201d284ea505e51069a1d01ae27147)) +- **assets:** update m37 ([e318db3](https://github.com/webern-unibas-ch/awg-app/commit/e318db3923c1cde37d4c496d44e016be26a5f814)) +- **assets:** update source description for m36 ([8543e91](https://github.com/webern-unibas-ch/awg-app/commit/8543e91d771eec2d7400de253cd77bae2972f115)) +- **assets:** update source description for m38 ([e2530cf](https://github.com/webern-unibas-ch/awg-app/commit/e2530cf4aad675599d9c58247285042edef54be1)) +- **assets:** use angular white space instead of nbsp ([6fc51e6](https://github.com/webern-unibas-ch/awg-app/commit/6fc51e692de2e4238fbca680b14c4f359c79c241)) +- **assets:** use correct syntax for missing sources in op3 and op4 ([168c9e1](https://github.com/webern-unibas-ch/awg-app/commit/168c9e1db63aa01a8a3f3dafa25a4063cc3f3f95)) +- **core:** remove unused var and method from navbar ([490937c](https://github.com/webern-unibas-ch/awg-app/commit/490937c27d5ace98a07b30aae85c32f870beb4ec)) +- **edition:** activate EditionComplexes service in app ([b9200f0](https://github.com/webern-unibas-ch/awg-app/commit/b9200f095b224cbf3b518c3b94f3111bcb001756)) +- **edition:** add missing glyphs ([e261a31](https://github.com/webern-unibas-ch/awg-app/commit/e261a3141277638cce185c93293f1c64964c9203)) +- **edition:** add pedal to glyphs ([e4880c9](https://github.com/webern-unibas-ch/awg-app/commit/e4880c9a0aa46342e9ce76aa3bea3d0f2af7f44d)) +- **edition:** auto-generate message for empty textcritics ([b18f999](https://github.com/webern-unibas-ch/awg-app/commit/b18f999f6d4e4615e8596b9b44779debd4290a8f)) +- **edition:** clean up code ([2c8d513](https://github.com/webern-unibas-ch/awg-app/commit/2c8d5132d884b0e9c8e0e9109cafbede7027e003)) +- **edition:** fix track-by indices for EditionSeries ([3aa2da3](https://github.com/webern-unibas-ch/awg-app/commit/3aa2da32f8ea6756749c3f3fd14ab49f8fa3c00d)) +- **edition:** remove deprecated data files ([d5fb3fe](https://github.com/webern-unibas-ch/awg-app/commit/d5fb3fedce24906cc02ff3887ad3c615e4a99996)) +- **edition:** remove landscape image from jumbotron ([79f2766](https://github.com/webern-unibas-ch/awg-app/commit/79f276604e278364804bb97389bf536747aa81cd)) +- **edition:** remove unused edition type component ([0459b53](https://github.com/webern-unibas-ch/awg-app/commit/0459b53aad604a6ce91182d7ff4294540f4e504c)) +- **edition:** remove unused method from edition service ([6e7b8dc](https://github.com/webern-unibas-ch/awg-app/commit/6e7b8dca332d0a64ae9db40f4b9f44b87716bfc8)) +- **edition:** remove unused type from complex model ([c8b1882](https://github.com/webern-unibas-ch/awg-app/commit/c8b1882423fb6adc137fadfc4980817b053308b7)) +- **edition:** simplify handling of sources in SourceList ([9c34a77](https://github.com/webern-unibas-ch/awg-app/commit/9c34a77562b8456601baac1dd57044c076c5d3c4)) +- **edition:** use correct constant for AWG III/5 ([d6b52a7](https://github.com/webern-unibas-ch/awg-app/commit/d6b52a7e8ce9e93449cd5026df69bdceb1815e14)) +- **edition:** use jumbotron for complex titles ([4f47a9a](https://github.com/webern-unibas-ch/awg-app/commit/4f47a9a2395d516927563284bb11c50662d2be34)) +- **edition:** use loading spinner for all edition views ([1c2135e](https://github.com/webern-unibas-ch/awg-app/commit/1c2135e0a5646c6256ca06a538e9bd47f87b0865)) +- **edition:** use shared ErrorAlertComponent ([e230c68](https://github.com/webern-unibas-ch/awg-app/commit/e230c6834590bb249f6a17796145304185fc7283)) + +### Code Refactoring + +- **assets:** use blocks for textcritics ([77e50a1](https://github.com/webern-unibas-ch/awg-app/commit/77e50a1c9ebf127125a5c83b7539562442f9ae03)) +- **assets:** use complex id as object key in JSON structure ([6216c48](https://github.com/webern-unibas-ch/awg-app/commit/6216c48ca4bb4acb01ca999cbf78543ab42637f8)) +- **core:** rename EditionComplexes service folder ([21994a5](https://github.com/webern-unibas-ch/awg-app/commit/21994a52a7fbfa717ea88d10de5652107e2f6b2f)) +- **edition:** move complex creation logic from data to model ([66e9613](https://github.com/webern-unibas-ch/awg-app/commit/66e9613c0b6695d4fddf1fbd5ae071324f096b0b)) +- **edition:** move series and section into pubStatement ([172a729](https://github.com/webern-unibas-ch/awg-app/commit/172a729cce9335cd5c9688226eb2b6c1b27e8736)) +- **edition:** rename class for intro paragraph ([fa99e4f](https://github.com/webern-unibas-ch/awg-app/commit/fa99e4f24af196137a4e54f1642f43506025e9b8)) +- **edition:** rename complex json data model ([b58a0d4](https://github.com/webern-unibas-ch/awg-app/commit/b58a0d403ea32c2bf1c9b4133108a2842436a84a)) +- **edition:** rename edition complex subclasses ([0e6bc38](https://github.com/webern-unibas-ch/awg-app/commit/0e6bc38144b7f2f54f3e5d63da800d1d88849d4a)) +- **edition:** rename edition related service and comp methods ([ac1b098](https://github.com/webern-unibas-ch/awg-app/commit/ac1b09815453ee0a83a901bde657082c2a02e47d)) +- **edition:** rename method for EditionView setup ([d0d4094](https://github.com/webern-unibas-ch/awg-app/commit/d0d40948dc3a1a2833426a419d63bb507d87f07b)) +- **edition:** rename parts of edition outline model ([308b8ae](https://github.com/webern-unibas-ch/awg-app/commit/308b8ae6ee7cf94d3d5ebdda64d0c13a3d840b1f)) +- **edition:** rename respStatment ([242c934](https://github.com/webern-unibas-ch/awg-app/commit/242c934272fa6a70584c1124f2cd3cdcb6b59a74)) +- **edition:** simplify and fully test GraphVisualizerService ([dce9676](https://github.com/webern-unibas-ch/awg-app/commit/dce967666dadedf9053da2a92232326cd15e0415)) +- **edition:** simplify generation of edition breadcrumb ([d9d9a5d](https://github.com/webern-unibas-ch/awg-app/commit/d9d9a5d9bb0fd4d081e1d5b482ad4ae1b30d0fd4)) +- **edition:** sort methods in editionDataService ([c7b048d](https://github.com/webern-unibas-ch/awg-app/commit/c7b048d69c7d6a23204a224eff4cb8bbd55614b2)) + +### Tests + +- **app:** fix syntax of remaining tests ([e057b49](https://github.com/webern-unibas-ch/awg-app/commit/e057b4912a9f1b2da3d80d495f5913e5b6f0b3de)) +- **app:** fix syntax of some more tests ([25c395b](https://github.com/webern-unibas-ch/awg-app/commit/25c395be97b219dbe338dc3fd44342706959945b)) +- **app:** fix tests after changes ([11ff7ab](https://github.com/webern-unibas-ch/awg-app/commit/11ff7aba433d82986100ec9f318aa8f562576ffa)) +- **app:** fix tests for AppComponent ([52d7a6a](https://github.com/webern-unibas-ch/awg-app/commit/52d7a6a394f66dbf259216f916bce2e897c12d7a)) +- **app:** fix typos and order in some tests ([9355e33](https://github.com/webern-unibas-ch/awg-app/commit/9355e33b7d7876b3aeb502885a600cb3de1ac1c2)) +- **app:** fix updated models and services in tests ([6f78602](https://github.com/webern-unibas-ch/awg-app/commit/6f78602e402b021e403aa3bfec4ee6aadae9761b)) +- **edition:** add more tests for edition sheets ([7308d6f](https://github.com/webern-unibas-ch/awg-app/commit/7308d6fa4c83153770830fab7f8029be2d7e6cb2)) +- **edition:** add tests for EditionSectionsComponent ([d626e57](https://github.com/webern-unibas-ch/awg-app/commit/d626e57468f57e38c1d1ff32c8c622aafbc2ee86)) +- **edition:** add tests for preface service methods ([b3efad1](https://github.com/webern-unibas-ch/awg-app/commit/b3efad199fc456f30e832068fc21885aa4676792)) +- **edition:** fix incorrect awg constant ([f8b8291](https://github.com/webern-unibas-ch/awg-app/commit/f8b829149b57c962f39e448d5c52b0e8a43fc5f8)) +- **edition:** fix intro paragraph class after change ([b2e99b4](https://github.com/webern-unibas-ch/awg-app/commit/b2e99b4d012ec00419d9f479605fb1d193e8d4da)) +- **edition:** fix tests after changes ([89abcbb](https://github.com/webern-unibas-ch/awg-app/commit/89abcbb6aa09db60f63d050228e1b21ff9cfdb7e)) +- **edition:** fix tests after changes ([d0e738e](https://github.com/webern-unibas-ch/awg-app/commit/d0e738eec6de46dce044a77d9ca79e385adab414)) +- **edition:** fix tests for EditionComplexes service ([40a3d93](https://github.com/webern-unibas-ch/awg-app/commit/40a3d93c569c91184fa78d43451551ef86f9024e)) +- **edition:** fix tests for textcritical comment blocks ([d419ae9](https://github.com/webern-unibas-ch/awg-app/commit/d419ae98767196007a90db6b5a66c397ee4e490c)) +- **edition:** remove focus from test ([12c6551](https://github.com/webern-unibas-ch/awg-app/commit/12c6551d6ed5c8e5c8d40b9659eb2b8021d7b12c)) +- **edition:** use regular edition outline in EditionView test ([97b5926](https://github.com/webern-unibas-ch/awg-app/commit/97b592625c7f14a71d748ef20d5110aed8bfd77b)) + +### Continuous Integration + +- **gh-actions:** include node 22 in workflow ([2684667](https://github.com/webern-unibas-ch/awg-app/commit/2684667984427ab9a3b4bead1da4e317d1381ecd)) +- **gh-actions:** pin fixed node version temporarily ([eb8e8c5](https://github.com/webern-unibas-ch/awg-app/commit/eb8e8c56a1e899c764c010f0cd0a76965ab0c763)) +- **gh-actions:** switch back to latest node v22 ([19a196d](https://github.com/webern-unibas-ch/awg-app/commit/19a196d3375956ee79e07c66ed3f47b8d017f02c)) + +### Documentation + +- **edition:** add JSDocs to new SourceDescription sub-classes ([bfd6360](https://github.com/webern-unibas-ch/awg-app/commit/bfd636080a97e7252cfbd08b41c925c8bb7768ad)) + +### Styles + +- **edition:** use shadow for cards ([2c4dad6](https://github.com/webern-unibas-ch/awg-app/commit/2c4dad6e35dbab8f9c2c635f2f8d6fa2769505b6)) +- **search:** fix error class ([a424df0](https://github.com/webern-unibas-ch/awg-app/commit/a424df0c4c6f6ae34d08a8a1306e34f34222a519)) + +### Build System + +- **deps-dev:** bump @commitlint/cli in the commitlint group ([8eadc48](https://github.com/webern-unibas-ch/awg-app/commit/8eadc4816d9af96fc6b1feae5a51e90147c99060)) +- **deps-dev:** bump @types/node from 18.19.39 to 18.19.40 ([88a8559](https://github.com/webern-unibas-ch/awg-app/commit/88a8559e07401fb362eb65db9017028ff81faa75)) +- **deps-dev:** bump @types/node from 18.19.40 to 18.19.41 ([7b2b8fe](https://github.com/webern-unibas-ch/awg-app/commit/7b2b8fe47d4335a178f2109397c8777c7260b244)) +- **deps-dev:** bump @types/node from 18.19.41 to 18.19.42 ([ef03a45](https://github.com/webern-unibas-ch/awg-app/commit/ef03a45bd47943ccaa0517d74bf1fe926347cd52)) +- **deps-dev:** bump @types/node from 18.19.42 to 20.14.14 ([a7a517e](https://github.com/webern-unibas-ch/awg-app/commit/a7a517e6a1fe9b957ad9df5aace977bb6772af8b)) +- **deps-dev:** bump eslint-plugin-jsdoc from 48.10.2 to 48.11.0 ([ba58324](https://github.com/webern-unibas-ch/awg-app/commit/ba583245841157874a353fe551302ed6c42133ed)) +- **deps-dev:** bump eslint-plugin-jsdoc from 48.11.0 to 50.0.0 ([13d1071](https://github.com/webern-unibas-ch/awg-app/commit/13d107130553229a51c3a878eeb3e2d1fd005d27)) +- **deps-dev:** bump eslint-plugin-jsdoc from 48.5.0 to 48.5.2 ([be1bd20](https://github.com/webern-unibas-ch/awg-app/commit/be1bd209680d2cbb96b5efee71c0ada2414daf5c)) +- **deps-dev:** bump eslint-plugin-jsdoc from 48.5.2 to 48.6.0 ([47d0c31](https://github.com/webern-unibas-ch/awg-app/commit/47d0c31a88d2f0986920f86325bab2a7d7875c66)) +- **deps-dev:** bump eslint-plugin-jsdoc from 48.6.0 to 48.7.0 ([ddcf59a](https://github.com/webern-unibas-ch/awg-app/commit/ddcf59a419bf5f9348d2339aa578ff3652fe132b)) +- **deps-dev:** bump eslint-plugin-jsdoc from 48.7.0 to 48.8.3 ([cec7fed](https://github.com/webern-unibas-ch/awg-app/commit/cec7fedba402c4259693a386dfc9aa92c8bc7f92)) +- **deps-dev:** bump eslint-plugin-jsdoc from 48.8.3 to 48.9.2 ([490d1ff](https://github.com/webern-unibas-ch/awg-app/commit/490d1ffaa39523330d2b24b0c0d85e97fd82b752)) +- **deps-dev:** bump eslint-plugin-jsdoc from 48.9.2 to 48.10.2 ([53d904b](https://github.com/webern-unibas-ch/awg-app/commit/53d904b13aa33513e73827c8b59f8b4170b03d9f)) +- **deps-dev:** bump eslint-plugin-jsdoc from 50.0.0 to 50.0.1 ([4069d81](https://github.com/webern-unibas-ch/awg-app/commit/4069d81491763d30c06ac52426293e2175c3b187)) +- **deps-dev:** bump eslint-plugin-jsdoc from 50.0.1 to 50.2.1 ([e399969](https://github.com/webern-unibas-ch/awg-app/commit/e399969a0b184c4958c81eb3c3f9a933eface7bb)) +- **deps-dev:** bump eslint-plugin-jsdoc from 50.2.1 to 50.2.2 ([09fabda](https://github.com/webern-unibas-ch/awg-app/commit/09fabda42f6c81e099e5d72eb6bf27027b5ac819)) +- **deps-dev:** bump eslint-plugin-prettier from 5.1.3 to 5.2.1 ([fb531b4](https://github.com/webern-unibas-ch/awg-app/commit/fb531b4d5b214ba1519db8d871c1076bc2ace6fa)) +- **deps-dev:** bump husky from 9.0.11 to 9.1.1 ([aa0566f](https://github.com/webern-unibas-ch/awg-app/commit/aa0566f3413d9bcf44014e2e581d80cf1e76fe35)) +- **deps-dev:** bump husky from 9.1.1 to 9.1.2 ([612f448](https://github.com/webern-unibas-ch/awg-app/commit/612f44860baed9c975d9126abaa2b07f2ca2f117)) +- **deps-dev:** bump husky from 9.1.2 to 9.1.4 ([baa3501](https://github.com/webern-unibas-ch/awg-app/commit/baa350151922dcd0048caba49b63518c0acb4628)) +- **deps-dev:** bump jasmine-core from 5.1.2 to 5.2.0 ([b903c1e](https://github.com/webern-unibas-ch/awg-app/commit/b903c1ee3c01f5c3c2cbaf3abac3c62ca028dac1)) +- **deps-dev:** bump karma from 6.4.3 to 6.4.4 ([3e9ba46](https://github.com/webern-unibas-ch/awg-app/commit/3e9ba4665182b8f58f4907a7192365e390894b78)) +- **deps-dev:** bump lint-staged from 15.2.7 to 15.2.8 ([f4513de](https://github.com/webern-unibas-ch/awg-app/commit/f4513de5d45e51b23531e9fff1c4fd69071e195d)) +- **deps-dev:** bump lint-staged from 15.2.8 to 15.2.9 ([32b44c2](https://github.com/webern-unibas-ch/awg-app/commit/32b44c2925c049cb857d19746613157fcb066e2f)) +- **deps-dev:** bump prettier from 3.3.2 to 3.3.3 ([bd8330c](https://github.com/webern-unibas-ch/awg-app/commit/bd8330c6d86c70b8f870fb39bcfb6035947ad3ee)) +- **deps-dev:** bump the angular-cli-devkit group with 2 updates ([2285f9b](https://github.com/webern-unibas-ch/awg-app/commit/2285f9bca446f055f8298ee8b3ef968d000e4703)) +- **deps-dev:** bump the angular-cli-devkit group with 2 updates ([9f4319d](https://github.com/webern-unibas-ch/awg-app/commit/9f4319d3e34e4f241ec37378842aac2b2a10bf74)) +- **deps-dev:** bump the angular-cli-devkit group with 2 updates ([61e438e](https://github.com/webern-unibas-ch/awg-app/commit/61e438e11e56547bc3c6ecff2066b891a36f37f2)) +- **deps-dev:** bump the angular-cli-devkit group with 2 updates ([f9fb819](https://github.com/webern-unibas-ch/awg-app/commit/f9fb819ff4f0eb2649848fe38dbd810f347ba0ab)) +- **deps-dev:** bump the angular-cli-devkit group with 2 updates ([46432b5](https://github.com/webern-unibas-ch/awg-app/commit/46432b509d1b77a50ab8289f246deafaebd5fa68)) +- **deps-dev:** bump the angular-cli-devkit group with 2 updates ([688da7e](https://github.com/webern-unibas-ch/awg-app/commit/688da7ec256c46472e4352c09c1f0d2ec491b19b)) +- **deps-dev:** bump the angular-cli-devkit group with 2 updates ([26fce92](https://github.com/webern-unibas-ch/awg-app/commit/26fce928e28d4f4a743231ec8aa96820c0656029)) +- **deps-dev:** bump the angular-eslint group with 5 updates ([5f37c41](https://github.com/webern-unibas-ch/awg-app/commit/5f37c419bdc27f33ec965931ab4a835e65ff710f)) +- **deps-dev:** bump the angular-eslint group with 5 updates ([73b4783](https://github.com/webern-unibas-ch/awg-app/commit/73b47838a8bf5ec447ad2dcdb6395f61f72eaebb)) +- **deps-dev:** bump the typescript-eslint group with 2 updates ([f58e89b](https://github.com/webern-unibas-ch/awg-app/commit/f58e89b794c8995cc5da10230bc79dae70df97b0)) +- **deps-dev:** bump the typescript-eslint group with 2 updates ([94a0151](https://github.com/webern-unibas-ch/awg-app/commit/94a01519fc1654e6b2a1e57ba526329dddacfefc)) +- **deps-dev:** bump the typescript-eslint group with 2 updates ([185e1d9](https://github.com/webern-unibas-ch/awg-app/commit/185e1d9dfa140ad0231991dd5cdd2bac1cbdd8bf)) +- **deps-dev:** bump the typescript-eslint group with 2 updates ([5db38a8](https://github.com/webern-unibas-ch/awg-app/commit/5db38a80fd5319ac749c19de91654b1eb59ac80a)) +- **deps-dev:** bump the typescript-eslint group with 2 updates ([4010d7a](https://github.com/webern-unibas-ch/awg-app/commit/4010d7a1a1451df6c8ef160e5e498caede477f79)) +- **deps-dev:** bump the typescript-eslint group with 2 updates ([6e2bf13](https://github.com/webern-unibas-ch/awg-app/commit/6e2bf13266eab01fc3f3ea2368922fbfa9150d93)) +- **deps-dev:** bump the typescript-eslint group with 2 updates ([edae3ff](https://github.com/webern-unibas-ch/awg-app/commit/edae3ffa154c44d705e8247021be6a3368db7763)) +- **deps-dev:** bump the typescript-eslint group with 2 updates ([00e701c](https://github.com/webern-unibas-ch/awg-app/commit/00e701c8ef6cad84734186b61906368c286cbb5e)) +- **deps-dev:** bump typescript from 5.5.2 to 5.5.4 ([e5dd837](https://github.com/webern-unibas-ch/awg-app/commit/e5dd83730a004b817c79ef258e45b34656e021f9)) +- **deps-dev:** update husky ([6e58c7c](https://github.com/webern-unibas-ch/awg-app/commit/6e58c7c0236087f2b31597c1090afe3adb2d0772)) +- **deps:** bump @codemirror/legacy-modes from 6.4.0 to 6.4.1 ([59cb709](https://github.com/webern-unibas-ch/awg-app/commit/59cb7097a6d263bcfa44f8ab629adeae28dc3dc5)) +- **deps:** bump @fortawesome/free-solid-svg-icons ([192df83](https://github.com/webern-unibas-ch/awg-app/commit/192df8366ff5b8b568aa928fd178ad5e09082026)) +- **deps:** bump actions/dependency-review-action from 4.3.3 to 4.3.4 ([9a2bd0c](https://github.com/webern-unibas-ch/awg-app/commit/9a2bd0cb11694ad87e4e15b1078329f14e9a8b85)) +- **deps:** bump actions/download-artifact from 4.1.7 to 4.1.8 ([003e5d0](https://github.com/webern-unibas-ch/awg-app/commit/003e5d0ddfb4d310904ecb086196d3e8c2954c7e)) +- **deps:** bump actions/setup-node from 4.0.2 to 4.0.3 ([5dc9a95](https://github.com/webern-unibas-ch/awg-app/commit/5dc9a95d047aabcf2013ff839714063391591e67)) +- **deps:** bump actions/upload-artifact from 4.3.3 to 4.3.4 ([1cd8e55](https://github.com/webern-unibas-ch/awg-app/commit/1cd8e555ea7727fde0d1f377291725d50cd36b55)) +- **deps:** bump actions/upload-artifact from 4.3.4 to 4.3.5 ([5c795e4](https://github.com/webern-unibas-ch/awg-app/commit/5c795e431fb0ef10a4ec7c3eea04ee6277460b6f)) +- **deps:** bump actions/upload-artifact from 4.3.5 to 4.3.6 ([7cc20df](https://github.com/webern-unibas-ch/awg-app/commit/7cc20df20411b3c04ab0b4e3c3791b58d59729d0)) +- **deps:** bump axios from 1.7.2 to 1.7.4 ([42e32d1](https://github.com/webern-unibas-ch/awg-app/commit/42e32d1154c4e1552eb1f61e26be37010e4889ec)) +- **deps:** bump github/codeql-action from 3.25.10 to 3.25.11 ([f135634](https://github.com/webern-unibas-ch/awg-app/commit/f13563420f6067da96618390d3d4573f0a338b53)) +- **deps:** bump github/codeql-action from 3.25.11 to 3.25.12 ([80de336](https://github.com/webern-unibas-ch/awg-app/commit/80de33633cb73937d73fa5e0e3573c4e86efc6ac)) +- **deps:** bump github/codeql-action from 3.25.12 to 3.25.13 ([cb03a00](https://github.com/webern-unibas-ch/awg-app/commit/cb03a00684d6c05ce4c86ed33e566a0bb46b59a0)) +- **deps:** bump github/codeql-action from 3.25.13 to 3.25.15 ([b053cf9](https://github.com/webern-unibas-ch/awg-app/commit/b053cf99ae1e7a0e427a415d51a713d93937c547)) +- **deps:** bump github/codeql-action from 3.25.15 to 3.26.0 ([3fa2067](https://github.com/webern-unibas-ch/awg-app/commit/3fa2067eb64ee807a0274cb4037cb6f4e41b6e96)) +- **deps:** bump github/codeql-action from 3.26.0 to 3.26.1 ([91455ad](https://github.com/webern-unibas-ch/awg-app/commit/91455adc853e67c8388b6ac12980d1eec284d5b2)) +- **deps:** bump github/codeql-action from 3.26.1 to 3.26.2 ([9a2c7ae](https://github.com/webern-unibas-ch/awg-app/commit/9a2c7aea2fe6c5cb67cf273c8b08e6badb6bcef4)) +- **deps:** bump n3 from 1.17.4 to 1.20.3 ([239a91f](https://github.com/webern-unibas-ch/awg-app/commit/239a91f390f55b5a0d199b36bd997360b044d05e)) +- **deps:** bump n3 from 1.20.3 to 1.20.4 ([965de9b](https://github.com/webern-unibas-ch/awg-app/commit/965de9bf734225a01e1b5443fef43fad77eedee3)) +- **deps:** bump ossf/scorecard-action from 2.3.3 to 2.4.0 ([0df58ee](https://github.com/webern-unibas-ch/awg-app/commit/0df58eed5b81397548e075631f87eb58ccb26d5f)) +- **deps:** bump softprops/action-gh-release from 2.0.6 to 2.0.8 ([86c7296](https://github.com/webern-unibas-ch/awg-app/commit/86c729603f101fdd5ddfecf86f5afbd770a7e409)) +- **deps:** bump step-security/harden-runner from 2.8.1 to 2.9.0 ([4fce8a7](https://github.com/webern-unibas-ch/awg-app/commit/4fce8a709e9f4b2fe2238589f01ce2f4e453cc0a)) +- **deps:** bump step-security/harden-runner from 2.9.0 to 2.9.1 ([1df7522](https://github.com/webern-unibas-ch/awg-app/commit/1df75228c0d65864d817719368bfcc6e605e6e6a)) +- **deps:** bump the angular group with 11 updates ([986c124](https://github.com/webern-unibas-ch/awg-app/commit/986c124c9ed37fa626e43f7d8b81c5ce7d14727c)) +- **deps:** bump the angular group with 11 updates ([cb33669](https://github.com/webern-unibas-ch/awg-app/commit/cb336690cc4195d4f840105565ecb0051f0c8c55)) +- **deps:** bump the angular group with 11 updates ([d8de582](https://github.com/webern-unibas-ch/awg-app/commit/d8de58266ba658348a715e43020adc17037c0aaf)) +- **deps:** bump the angular group with 11 updates ([2b8ec44](https://github.com/webern-unibas-ch/awg-app/commit/2b8ec44a161d9791776be8f041d13f20540d2a7f)) +- **deps:** bump the angular group with 11 updates ([e7589fe](https://github.com/webern-unibas-ch/awg-app/commit/e7589fe92525767d164a850f9a3be92c64806ba5)) +- **deps:** bump the angular group with 11 updates ([972d326](https://github.com/webern-unibas-ch/awg-app/commit/972d32656c33cfb5ed35e0edee30ac708053f2ff)) +- **deps:** bump the angular group with 11 updates ([a132ec2](https://github.com/webern-unibas-ch/awg-app/commit/a132ec2951c9fd8710f731eabb387003cb19f3f9)) +- **deps:** bump zone.js from 0.14.7 to 0.14.8 ([ef54a7d](https://github.com/webern-unibas-ch/awg-app/commit/ef54a7dc4c986b3fab6382de55ac70b4a8198f32)) +- **deps:** bump zone.js from 0.14.8 to 0.14.10 ([dc5f651](https://github.com/webern-unibas-ch/awg-app/commit/dc5f65162025246fef64775327b5c30f5ee3745d)) + ## [0.12.3](https://github.com/webern-unibas-ch/awg-app/compare/v0.12.2...v0.12.3) (2024-07-01) ### Features diff --git a/package.json b/package.json index 86684112d..0fd8c5749 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "awg-app", - "version": "0.12.3", + "version": "0.14.0", "license": "MIT", "author": { "name": "Stefan Münnich", @@ -84,19 +84,19 @@ "deploy:ci": "ng deploy --no-build --message=\"Release $npm_package_name (v$npm_package_version) on gh-pages\"" }, "dependencies": { - "@angular/animations": "^18.0.5", - "@angular/common": "^18.0.5", - "@angular/compiler": "^18.0.5", - "@angular/core": "^18.0.5", - "@angular/forms": "^18.0.5", - "@angular/localize": "^18.0.5", - "@angular/platform-browser": "^18.0.5", - "@angular/platform-browser-dynamic": "^18.0.5", - "@angular/platform-server": "^18.0.5", - "@angular/router": "^18.0.5", - "@codemirror/legacy-modes": "^6.4.0", + "@angular/animations": "^18.2.0", + "@angular/common": "^18.2.0", + "@angular/compiler": "^18.2.0", + "@angular/core": "^18.2.0", + "@angular/forms": "^18.2.0", + "@angular/localize": "^18.2.0", + "@angular/platform-browser": "^18.2.0", + "@angular/platform-browser-dynamic": "^18.2.0", + "@angular/platform-server": "^18.2.0", + "@angular/router": "^18.2.0", + "@codemirror/legacy-modes": "^6.4.1", "@fortawesome/angular-fontawesome": "^0.15.0", - "@fortawesome/free-solid-svg-icons": "^6.5.2", + "@fortawesome/free-solid-svg-icons": "^6.6.0", "@kolkov/ngx-gallery": "2.0.1", "@ng-bootstrap/ng-bootstrap": "^17.0.0", "@popperjs/core": "^2.11.8", @@ -109,31 +109,31 @@ "d3-zoom": "^3.0.0", "font-awesome": "^4.7.0", "json2typescript": "^1.5.1", - "n3": "^1.17.4", + "n3": "^1.20.4", "ngx-json-viewer": "^3.2.1", "rdfstore": "musicenfanthen/rdfstore-js#v0.9.18-alpha.16", "rxjs": "~7.8.1", "stream": "^0.0.3", "tslib": "^2.6.2", - "zone.js": "~0.14.7" + "zone.js": "~0.14.10" }, "devDependencies": { - "@angular-devkit/build-angular": "^18.0.6", - "@angular-eslint/builder": "^18.1.0", - "@angular-eslint/eslint-plugin": "^18.1.0", - "@angular-eslint/eslint-plugin-template": "^18.1.0", - "@angular-eslint/schematics": "^18.1.0", - "@angular-eslint/template-parser": "^18.1.0", - "@angular/cli": "^18.0.6", - "@angular/compiler-cli": "^18.0.5", - "@commitlint/cli": "^19.3.0", + "@angular-devkit/build-angular": "^18.2.0", + "@angular-eslint/builder": "^18.3.0", + "@angular-eslint/eslint-plugin": "^18.3.0", + "@angular-eslint/eslint-plugin-template": "^18.3.0", + "@angular-eslint/schematics": "^18.3.0", + "@angular-eslint/template-parser": "^18.3.0", + "@angular/cli": "^18.2.0", + "@angular/compiler-cli": "^18.2.0", + "@commitlint/cli": "^19.4.0", "@commitlint/config-angular": "^19.3.0", "@compodoc/compodoc": "^1.1.25", "@types/d3": "^7.4.3", "@types/jasmine": "~5.1.4", - "@types/node": "^18.19.39", - "@typescript-eslint/eslint-plugin": "^7.14.1", - "@typescript-eslint/parser": "^7.14.1", + "@types/node": "^20.14.14", + "@typescript-eslint/eslint-plugin": "^8.1.0", + "@typescript-eslint/parser": "^8.1.0", "angular-cli-ghpages": "^2.0.1", "commit-and-tag-version": "^12.4.1", "conventional-recommended-bump": "^10.0.0", @@ -142,20 +142,20 @@ "eslint-plugin-angular": "^4.1.0", "eslint-plugin-deprecation": "^3.0.0", "eslint-plugin-import": "^2.29.1", - "eslint-plugin-jsdoc": "^48.5.0", - "eslint-plugin-prettier": "^5.1.3", + "eslint-plugin-jsdoc": "^50.2.2", + "eslint-plugin-prettier": "^5.2.1", "gzipper": "^7.2.0", - "husky": "^9.0.11", - "jasmine-core": "~5.1.2", - "karma": "~6.4.3", + "husky": "^9.1.4", + "jasmine-core": "~5.2.0", + "karma": "~6.4.4", "karma-chrome-launcher": "~3.2.0", "karma-coverage": "^2.2.1", "karma-jasmine": "~5.1.0", "karma-jasmine-html-reporter": "^2.1.0", - "lint-staged": "^15.2.7", - "prettier": "^3.3.2", + "lint-staged": "^15.2.9", + "prettier": "^3.3.3", "source-map-explorer": "^2.5.3", - "typescript": "~5.5.2", + "typescript": "~5.5.4", "webpack-bundle-analyzer": "^4.10.2" }, "engines": { diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts index ad958d703..fa9afc787 100644 --- a/src/app/app.component.spec.ts +++ b/src/app/app.component.spec.ts @@ -2,6 +2,7 @@ import { Location } from '@angular/common'; import { Component, DebugElement } from '@angular/core'; import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { Title } from '@angular/platform-browser'; import { Router, RouterModule, Routes } from '@angular/router'; import Spy = jasmine.Spy; @@ -9,7 +10,7 @@ import Spy = jasmine.Spy; import { cleanStylesFromDOM } from '@testing/clean-up-helper'; import { expectSpyCall, expectToBe, getAndExpectDebugElementByDirective } from '@testing/expect-helper'; -import { AnalyticsService } from '@awg-core/services'; +import { AnalyticsService, EditionInitService } from '@awg-core/services'; import { AppComponent } from './app.component'; @@ -30,9 +31,14 @@ export class RoutedTestMockComponent {} export class RoutedTest2MockComponent {} export const MOCK_ROUTES: Routes = [ - { path: '', redirectTo: 'test', pathMatch: 'full' }, - { path: 'test', component: RoutedTestMockComponent }, - { path: 'test2', component: RoutedTest2MockComponent }, + { path: '', redirectTo: 'test1', pathMatch: 'full' }, + { path: 'test1', component: RoutedTestMockComponent, data: { title: 'Custom Page Title 1' } }, + { + path: 'test2', + component: RoutedTest2MockComponent, + data: {}, + children: [{ path: 'test3', component: RoutedTestMockComponent, data: { title: 'Custom Page Title 3' } }], + }, ]; describe('AppComponent (DONE)', () => { @@ -40,12 +46,18 @@ describe('AppComponent (DONE)', () => { let fixture: ComponentFixture; let compDe: DebugElement; - let router: Router; let location: Location; + let router: Router; + let titleService: Title; let mockAnalyticsService: Partial; + let mockEditionInitService: Partial; + + let getTitleSpy: Spy; + let setTitleSpy: Spy; let initialzeAnalyticsSpy: Spy; let trackpageViewSpy: Spy; + let initializeEditionSpy: Spy; beforeEach(waitForAsync(() => { // Create a mocked AnalyticsService with an `initializeAnalytics` and `trackPageView` spy @@ -58,6 +70,13 @@ describe('AppComponent (DONE)', () => { }, }; + // Create a mocked EditionInitService with an `initializeEdition` spy + mockEditionInitService = { + initializeEdition: (): void => { + // Intentional empty test override + }, + }; + TestBed.configureTestingModule({ imports: [RouterModule.forRoot(MOCK_ROUTES)], declarations: [ @@ -68,11 +87,18 @@ describe('AppComponent (DONE)', () => { RoutedTestMockComponent, RoutedTest2MockComponent, ], - providers: [{ provide: AnalyticsService, useValue: mockAnalyticsService }], + providers: [ + { provide: AnalyticsService, useValue: mockAnalyticsService }, + { provide: EditionInitService, useValue: mockEditionInitService }, + Title, + ], }).compileComponents(); // Spies for service methods + getTitleSpy = spyOn(Title.prototype, 'getTitle').and.returnValue('Default Page Title'); + setTitleSpy = spyOn(Title.prototype, 'setTitle').and.callThrough(); initialzeAnalyticsSpy = spyOn(mockAnalyticsService, 'initializeAnalytics').and.callThrough(); + initializeEditionSpy = spyOn(mockEditionInitService, 'initializeEdition').and.callThrough(); trackpageViewSpy = spyOn(mockAnalyticsService, 'trackPageView').and.callThrough(); })); @@ -84,8 +110,9 @@ describe('AppComponent (DONE)', () => { component = fixture.componentInstance; compDe = fixture.debugElement; - router = TestBed.inject(Router); location = TestBed.inject(Location); + router = TestBed.inject(Router); + titleService = TestBed.inject(Title); // Workaround for ngZone issue; // Cf. https://github.com/angular/angular/issues/25837 @@ -109,9 +136,12 @@ describe('AppComponent (DONE)', () => { expect(component).toBeTruthy(); })); - it('... injected service should use provided mockValue', () => { + it('... injected services should use provided mockValues', () => { const analyticsService = TestBed.inject(AnalyticsService); - expect(analyticsService === mockAnalyticsService).toBe(true); + expectToBe(analyticsService === mockAnalyticsService, true); + + const editionInitService = TestBed.inject(EditionInitService); + expectToBe(editionInitService === mockEditionInitService, true); }); describe('router setup (self-test)', () => { @@ -119,18 +149,18 @@ describe('AppComponent (DONE)', () => { expectToBe(location.path(), ''); })); - it("... should redirect to /test from '' redirect", waitForAsync(() => { + it("... should redirect to /test1 from '' redirect", waitForAsync(() => { fixture.ngZone.run(() => { router.navigate(['']).then(() => { - expectToBe(location.path(), '/test'); + expectToBe(location.path(), '/test1'); }); }); })); - it("... should navigate to 'test' from /test", waitForAsync(() => { + it("... should navigate to 'test1' from /test1", waitForAsync(() => { fixture.ngZone.run(() => { - router.navigate(['/test']).then(() => { - expectToBe(location.path(), '/test'); + router.navigate(['/test1']).then(() => { + expectToBe(location.path(), '/test1'); }); }); })); @@ -142,6 +172,14 @@ describe('AppComponent (DONE)', () => { }); }); })); + + it("... should navigate to '/test2/test3' from /test2/test3", waitForAsync(() => { + fixture.ngZone.run(() => { + router.navigate(['/test2/test3']).then(() => { + expectToBe(location.path(), '/test2/test3'); + }); + }); + })); }); describe('BEFORE initial data binding', () => { @@ -157,7 +195,7 @@ describe('AppComponent (DONE)', () => { it('... should call AnalyticsService to track page view after navigation', waitForAsync(() => { fixture.ngZone.run(() => { router.navigate(['']).then(() => { - expectSpyCall(trackpageViewSpy, 1, '/test'); + expectSpyCall(trackpageViewSpy, 1, '/test1'); }); }); })); @@ -165,13 +203,13 @@ describe('AppComponent (DONE)', () => { it('... should call AnalyticsService to track page view after navigation changed', waitForAsync(() => { fixture.ngZone.run(() => { router.navigate(['']).then(() => { - expectSpyCall(trackpageViewSpy, 1, '/test'); + expectSpyCall(trackpageViewSpy, 1, '/test1'); - router.navigate(['test2']).then(() => { + router.navigate(['/test2']).then(() => { expectSpyCall(trackpageViewSpy, 2, '/test2'); - router.navigate(['test']).then(() => { - expectSpyCall(trackpageViewSpy, 3, '/test'); + router.navigate(['/test1']).then(() => { + expectSpyCall(trackpageViewSpy, 3, '/test1'); }); }); }); @@ -179,6 +217,12 @@ describe('AppComponent (DONE)', () => { })); }); + describe('EditionInit', () => { + it('... should call EditionInitService to initialize edition', () => { + expectSpyCall(initializeEditionSpy, 1); + }); + }); + describe('VIEW', () => { it('... should contain one header component (stubbed)', () => { getAndExpectDebugElementByDirective(compDe, NavbarStubComponent, 1, 1); @@ -192,5 +236,35 @@ describe('AppComponent (DONE)', () => { getAndExpectDebugElementByDirective(compDe, FooterStubComponent, 1, 1); }); }); + + describe('Title', () => { + it('... should have called getTitle', () => { + expectSpyCall(getTitleSpy, 1); + }); + + it('... should not have called setTitle', () => { + expectSpyCall(setTitleSpy, 0); + }); + + it('... should set the custom page title from route data if available', waitForAsync(() => { + fixture.ngZone.run(() => { + router.navigate(['/test1']).then(() => { + expectSpyCall(setTitleSpy, 1, 'Custom Page Title 1'); + + router.navigate(['/test2/test3']).then(() => { + expectSpyCall(setTitleSpy, 2, 'Custom Page Title 3'); + }); + }); + }); + })); + + it('... should set the default page title if route data title is not available', waitForAsync(() => { + fixture.ngZone.run(() => { + router.navigate(['/test2']).then(() => { + expectSpyCall(setTitleSpy, 1, 'Default Page Title'); + }); + }); + })); + }); }); }); diff --git a/src/app/app.component.ts b/src/app/app.component.ts index b84ab2daf..9d56d5b9c 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -6,7 +6,7 @@ import { filter, map } from 'rxjs/operators'; import { NgbConfig } from '@ng-bootstrap/ng-bootstrap'; -import { AnalyticsService } from '@awg-core/services'; +import { AnalyticsService, EditionInitService } from '@awg-core/services'; /** * The main component of the AWG App. @@ -33,6 +33,7 @@ export class AppComponent { constructor( private readonly activatedRoute: ActivatedRoute, private analyticsService: AnalyticsService, + private editionInitService: EditionInitService, ngbConfig: NgbConfig, private readonly router: Router, private titleService: Title @@ -47,6 +48,9 @@ export class AppComponent { // Init analytics this.analyticsService.initializeAnalytics(); + // Init edition complexes and outline + this.editionInitService.initializeEdition(); + // Track router events this.router.events .pipe( diff --git a/src/app/app.globals.ts b/src/app/app.globals.ts index 0c64d79be..ec89388bb 100644 --- a/src/app/app.globals.ts +++ b/src/app/app.globals.ts @@ -1,15 +1,15 @@ // THIS IS AN AUTO-GENERATED FILE. DO NOT CHANGE IT MANUALLY! -// Generated last time on Mon, Jul 1, 2024 3:28:42 PM +// Generated last time on Mon, Aug 19, 2024 7:32:05 PM /** * The latest version of the AWG App */ -export const appVersion = '0.12.3'; +export const appVersion = '0.14.0'; /** * The release date of the latest version of the AWG App */ -export const appVersionReleaseDate = '01. Juli 2024'; +export const appVersionReleaseDate = '19. August 2024'; /** * The URL of the AWG App diff --git a/src/app/core/footer/footer-declaration/footer-declaration.component.spec.ts b/src/app/core/footer/footer-declaration/footer-declaration.component.spec.ts index 8d1e0345b..8573ca84e 100644 --- a/src/app/core/footer/footer-declaration/footer-declaration.component.spec.ts +++ b/src/app/core/footer/footer-declaration/footer-declaration.component.spec.ts @@ -70,11 +70,8 @@ describe('FooterDeclarationComponent (DONE)', () => { const versionDateEl = versionDateDes[0].nativeElement; // Check output - expect(versionEl.textContent).toBeDefined(); - expect(versionEl.textContent).toBeFalsy(); - - expect(versionDateEl.textContent).toBeDefined(); - expect(versionDateEl.textContent).toBeFalsy(); + expectToBe(versionEl.textContent, ''); + expectToBe(versionDateEl.textContent, ''); }); }); }); @@ -133,7 +130,7 @@ describe('FooterDeclarationComponent (DONE)', () => { const imprintLinkDe = linkDes[0]; // Contact link DebugElement const imprintLink = routerLinks[0]; // Contact link directive - expect(imprintLink.navigatedTo).toBeNull(); + expectToBe(imprintLink.navigatedTo, null); click(imprintLinkDe); fixture.detectChanges(); @@ -146,7 +143,7 @@ describe('FooterDeclarationComponent (DONE)', () => { const documentationLinkDe = linkDes[1]; // Contact link DebugElement const documentationLink = routerLinks[1]; // Contact link directive - expect(documentationLink.navigatedTo).toBeNull(); + expectToBe(documentationLink.navigatedTo, null); click(documentationLinkDe); fixture.detectChanges(); diff --git a/src/app/core/footer/footer.component.spec.ts b/src/app/core/footer/footer.component.spec.ts index 5872ceb3f..31e1cde84 100644 --- a/src/app/core/footer/footer.component.spec.ts +++ b/src/app/core/footer/footer.component.spec.ts @@ -97,7 +97,7 @@ describe('FooterComponent (DONE)', () => { it('... injected service should use provided mockValue', () => { const coreService = TestBed.inject(CoreService); - expect(mockCoreService === coreService).toBeTrue(); + expectToBe(mockCoreService === coreService, true); }); describe('BEFORE initial data binding', () => { diff --git a/src/app/core/interceptors/caching/caching.interceptor.spec.ts b/src/app/core/interceptors/caching/caching.interceptor.spec.ts index 75c05297f..b02da4a47 100644 --- a/src/app/core/interceptors/caching/caching.interceptor.spec.ts +++ b/src/app/core/interceptors/caching/caching.interceptor.spec.ts @@ -134,12 +134,12 @@ describe('CachingInterceptor (DONE)', () => { // Spied service call returns created response expectToEqual(httpCacheService.get(expectedRequest), expectedResponse); // Real service does not have created response - expect((httpCacheService as any)._cachedResponses.has(expectedRequest.urlWithParams)).toBeFalse(); + expectToBe((httpCacheService as any)._cachedResponses.has(expectedRequest.urlWithParams), false); })); it('... should clear mock cache after each run', waitForAsync(() => { - expect(mockCache.get(expectedRequest)).toBeNull(); - expect(httpCacheService.get(expectedRequest)).toBeNull(); + expectToBe(mockCache.get(expectedRequest), null); + expectToBe(httpCacheService.get(expectedRequest), null); })); it('... should use mock console', () => { @@ -231,7 +231,7 @@ describe('CachingInterceptor (DONE)', () => { const expectedRequest = new HttpRequest('GET', expectedUrl); // Mock cache is empty - expect(mockCache.get(expectedRequest)).toBeNull(); + expectToBe(mockCache.get(expectedRequest), null); // Subscribe to GET Http Request const sub = httpClient.get(expectedUrl).subscribe({ @@ -293,7 +293,7 @@ describe('CachingInterceptor (DONE)', () => { const expectedRequest = new HttpRequest('GET', expectedUrl); // No cached response in cache - expect(mockCache.get(expectedRequest)).toBeNull(); + expectToBe(mockCache.get(expectedRequest), null); // Subscribe to GET Http Request httpClient.get(expectedUrl).subscribe({ diff --git a/src/app/core/navbar/navbar.component.html b/src/app/core/navbar/navbar.component.html index 81bf10b99..3f040cb8c 100644 --- a/src/app/core/navbar/navbar.component.html +++ b/src/app/core/navbar/navbar.component.html @@ -50,14 +50,21 @@ routerLinkActive="active" >{{ editionRouteConstants.ROWTABLES.full }} + {{ editionRouteConstants.PREFACE.full }} @for (editionComplex of DISPLAYED_EDITION_COMPLEXES; track editionComplex.complexId.short) {
diff --git a/src/app/core/navbar/navbar.component.spec.ts b/src/app/core/navbar/navbar.component.spec.ts index c8c7373b6..41da104b5 100644 --- a/src/app/core/navbar/navbar.component.spec.ts +++ b/src/app/core/navbar/navbar.component.spec.ts @@ -3,18 +3,6 @@ import { DebugElement, NgModule } from '@angular/core'; import { ComponentFixture, fakeAsync, TestBed, waitForAsync } from '@angular/core/testing'; import { Router } from '@angular/router'; -import { cleanStylesFromDOM } from '@testing/clean-up-helper'; -import { click, clickAndAwaitChanges } from '@testing/click-helper'; -import { - expectSpyCall, - expectToBe, - expectToContain, - expectToEqual, - getAndExpectDebugElementByCss, - getAndExpectDebugElementByDirective, -} from '@testing/expect-helper'; -import { RouterLinkStubDirective } from '@testing/router-stubs'; - import Spy = jasmine.Spy; import { FontAwesomeTestingModule } from '@fortawesome/angular-fontawesome/testing'; @@ -28,13 +16,25 @@ import { } from '@fortawesome/free-solid-svg-icons'; import { NgbCollapseModule, NgbConfig, NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap'; +import { cleanStylesFromDOM } from '@testing/clean-up-helper'; +import { click, clickAndAwaitChanges } from '@testing/click-helper'; +import { + expectSpyCall, + expectToBe, + expectToContain, + expectToEqual, + getAndExpectDebugElementByCss, + getAndExpectDebugElementByDirective, +} from '@testing/expect-helper'; +import { RouterLinkStubDirective } from '@testing/router-stubs'; + import { LOGOSDATA } from '@awg-core/core-data'; import { Logos } from '@awg-core/core-models'; import { CoreService } from '@awg-core/services'; -import { EDITION_COMPLEXES } from '@awg-views/edition-view/data'; import { EDITION_ROUTE_CONSTANTS } from '@awg-views/edition-view/edition-route-constants'; import { EditionComplex } from '@awg-views/edition-view/models'; +import { EditionComplexesService } from '@awg-views/edition-view/services'; import { NavbarComponent } from './navbar.component'; @@ -44,6 +44,7 @@ function generateExpectedOrderOfRouterlinks(editionComplexes: EditionComplex[]): ['/home'], [EDITION_ROUTE_CONSTANTS.EDITION.route, EDITION_ROUTE_CONSTANTS.SERIES.route], [EDITION_ROUTE_CONSTANTS.EDITION.route, EDITION_ROUTE_CONSTANTS.ROWTABLES.route], + [EDITION_ROUTE_CONSTANTS.EDITION.route, EDITION_ROUTE_CONSTANTS.PREFACE.route], ]; const editionLinks = editionComplexes.flatMap(complex => [ @@ -66,7 +67,6 @@ describe('NavbarComponent (DONE)', () => { let routerLinks; let coreServiceSpy: Spy; - let getEditionComplexSpy: Spy; let isActiveRouteSpy: Spy; let routerSpy: Spy; let provideMetaDataSpy: Spy; @@ -84,7 +84,6 @@ describe('NavbarComponent (DONE)', () => { let expectedStructureIcon: IconDefinition; let expectedEditionComplexes: EditionComplex[]; - let expectedSelectedEditionComplex: EditionComplex = EDITION_COMPLEXES.OP12; let expectedOrderOfRouterlinks: string[][]; const expectedEditionRouteConstants: typeof EDITION_ROUTE_CONSTANTS = EDITION_ROUTE_CONSTANTS; @@ -117,6 +116,10 @@ describe('NavbarComponent (DONE)', () => { }).compileComponents(); })); + beforeAll(() => { + EditionComplexesService.initializeEditionComplexesList(); + }); + beforeEach(() => { fixture = TestBed.createComponent(NavbarComponent); component = fixture.componentInstance; @@ -126,19 +129,18 @@ describe('NavbarComponent (DONE)', () => { expectedLogos = LOGOSDATA; expectedEditionComplexes = [ - EDITION_COMPLEXES.OP3, - EDITION_COMPLEXES.OP4, - EDITION_COMPLEXES.OP12, - EDITION_COMPLEXES.OP23, - EDITION_COMPLEXES.OP25, - EDITION_COMPLEXES.M22, - EDITION_COMPLEXES.M30, - EDITION_COMPLEXES.M31, - EDITION_COMPLEXES.M34, - EDITION_COMPLEXES.M35_42, - EDITION_COMPLEXES.M37, + EditionComplexesService.getEditionComplexById('OP3'), + EditionComplexesService.getEditionComplexById('OP4'), + EditionComplexesService.getEditionComplexById('OP12'), + EditionComplexesService.getEditionComplexById('OP23'), + EditionComplexesService.getEditionComplexById('OP25'), + EditionComplexesService.getEditionComplexById('M22'), + EditionComplexesService.getEditionComplexById('M30'), + EditionComplexesService.getEditionComplexById('M31'), + EditionComplexesService.getEditionComplexById('M34'), + EditionComplexesService.getEditionComplexById('M35_42'), + EditionComplexesService.getEditionComplexById('M37'), ]; - expectedSelectedEditionComplex = expectedEditionComplexes[0]; expectedOrderOfRouterlinks = generateExpectedOrderOfRouterlinks(expectedEditionComplexes); expectedContactIcon = faEnvelope; @@ -151,7 +153,6 @@ describe('NavbarComponent (DONE)', () => { // `.and.callThrough` will track the spy down the nested describes, see // https://jasmine.github.io/2.0/introduction.html#section-Spies:_%3Ccode%3Eand.callThrough%3C/code%3E coreServiceSpy = spyOn(mockCoreService, 'getLogos').and.callThrough(); - getEditionComplexSpy = spyOn(component, 'getEditionComplex').and.callThrough(); isActiveRouteSpy = spyOn(component, 'isActiveRoute').and.callThrough(); routerSpy = mockRouter.isActive as jasmine.Spy; provideMetaDataSpy = spyOn(component, 'provideMetaData').and.callThrough(); @@ -168,7 +169,7 @@ describe('NavbarComponent (DONE)', () => { it('... injected service should use provided mockValue', () => { const coreService = TestBed.inject(CoreService); - expect(mockCoreService === coreService).toBe(true); + expectToBe(mockCoreService === coreService, true); }); describe('BEFORE initial data binding', () => { @@ -185,7 +186,7 @@ describe('NavbarComponent (DONE)', () => { }); it('... should have `isCollapsed = true`', () => { - expect(component.isCollapsed).toBeTrue(); + expectToBe(component.isCollapsed, true); }); it('... should have `DISPLAYED_EDITION_COMPLEXES`', () => { @@ -204,10 +205,6 @@ describe('NavbarComponent (DONE)', () => { expect(component.logos).toBeUndefined(); }); - it('... should not have `selectedEditionComplex`', () => { - expect(component.selectedEditionComplex).toBeUndefined(); - }); - describe('VIEW', () => { it('... should contain 1 navbar', () => { getAndExpectDebugElementByCss(compDe, 'nav.navbar', 1, 1); @@ -319,20 +316,6 @@ describe('NavbarComponent (DONE)', () => { }); }); - describe('#getEditionComplex()', () => { - it('... should have a method `getEditionComplex`', () => { - expect(component.getEditionComplex).toBeDefined(); - }); - - it('... should not have been called', () => { - expectSpyCall(getEditionComplexSpy, 0); - }); - - it('... should not have `selectedEditionComplex`', () => { - expect(component.selectedEditionComplex).toBeUndefined(); - }); - }); - describe('#isActiveRoute()', () => { it('... should have a method `isActiveRoute`', () => { expect(component.isActiveRoute).toBeDefined(); @@ -384,15 +367,15 @@ describe('NavbarComponent (DONE)', () => { it('... should toggle `isCollapsed`', () => { component.toggleNav(); - expect(component.isCollapsed).toBeFalse(); + expectToBe(component.isCollapsed, false); component.toggleNav(); - expect(component.isCollapsed).toBeTrue(); + expectToBe(component.isCollapsed, true); component.toggleNav(); - expect(component.isCollapsed).toBeFalse(); + expectToBe(component.isCollapsed, false); }); }); }); @@ -453,7 +436,7 @@ describe('NavbarComponent (DONE)', () => { expectToEqual(faIconIns, expectedContactIcon); }); - describe('... second nav-item link', () => { + describe('... second nav-item link (edition)', () => { let navItemDe: DebugElement[]; let navItemLinkDe: DebugElement[]; @@ -466,7 +449,6 @@ describe('NavbarComponent (DONE)', () => { })); it('... should have a dropdown menu', () => { - // Expect dropdown menu getAndExpectDebugElementByCss(navItemDe[1], 'div.dropdown-menu', 1, 1); }); @@ -482,48 +464,56 @@ describe('NavbarComponent (DONE)', () => { expectToBe(headerEl.textContent, 'Allgemein'); }); - it('... should be followed by 2 dropdown items', () => { - const firstItemDe = getAndExpectDebugElementByCss( + it('... should be followed by 3 dropdown items for edition overview, rowtables and preface', () => { + const overviewDe = getAndExpectDebugElementByCss( navItemDe[1], 'div.dropdown-menu > a.dropdown-item:nth-child(2)', 1, 1 ); - const secondItemDe = getAndExpectDebugElementByCss( + const rowtablesDe = getAndExpectDebugElementByCss( navItemDe[1], 'div.dropdown-menu > a.dropdown-item:nth-child(3)', 1, 1 ); + const prefaceDe = getAndExpectDebugElementByCss( + navItemDe[1], + 'div.dropdown-menu > a.dropdown-item:nth-child(4)', + 1, + 1 + ); - const firstItemEl = firstItemDe[0].nativeElement; - const secondItemEl = secondItemDe[0].nativeElement; + const overviewEl = overviewDe[0].nativeElement; + const rowtablesEl = rowtablesDe[0].nativeElement; + const prefaceEl = prefaceDe[0].nativeElement; - expectToBe(firstItemEl.textContent, EDITION_ROUTE_CONSTANTS.SERIES.full); - expectToBe(secondItemEl.textContent, EDITION_ROUTE_CONSTANTS.ROWTABLES.full); + expectToBe(overviewEl.textContent, EDITION_ROUTE_CONSTANTS.SERIES.full); + expectToBe(rowtablesEl.textContent, EDITION_ROUTE_CONSTANTS.ROWTABLES.full); + expectToBe(prefaceEl.textContent, EDITION_ROUTE_CONSTANTS.PREFACE.full); }); it('... should have another dropdown header `Auswahl Skizzenkomplexe` surrounded by dividers', () => { getAndExpectDebugElementByCss( navItemDe[1], - 'div.dropdown-menu > div.dropdown-divider:nth-child(4)', + 'div.dropdown-menu > div.dropdown-divider:nth-child(5)', 1, 1 ); - getAndExpectDebugElementByCss( + const headerDe = getAndExpectDebugElementByCss( navItemDe[1], - 'div.dropdown-menu > div.dropdown-divider:nth-child(6)', + 'div.dropdown-menu > h6.dropdown-header:nth-child(6)', 1, 1 ); + const headerEl = headerDe[0].nativeElement; - const headerDe = getAndExpectDebugElementByCss( + getAndExpectDebugElementByCss( navItemDe[1], - 'div.dropdown-menu > h6.dropdown-header:nth-child(5)', + 'div.dropdown-menu > div.dropdown-divider:nth-child(7)', 1, 1 ); - const headerEl = headerDe[0].nativeElement; expectToBe(headerEl.textContent, 'Auswahl Skizzenkomplexe'); }); @@ -567,7 +557,11 @@ describe('NavbarComponent (DONE)', () => { const headerSpanDe = getAndExpectDebugElementByCss(headerDe[0], 'span', 1, 1); const headerSpanEl = headerSpanDe[0].nativeElement; - const headerSiglum = `[AWG ${expectedEditionComplexes[index].series.short}/${expectedEditionComplexes[index].section.short}] `; + const awg = EDITION_ROUTE_CONSTANTS.EDITION.short; + const series = expectedEditionComplexes[index].pubStatement.series.short; + const section = expectedEditionComplexes[index].pubStatement.section.short; + + const headerSiglum = `[${awg} ${series}/${section}] `; const headerId = expectedEditionComplexes[index].complexId.full; expectToContain(headerEl.textContent, headerSiglum); @@ -598,17 +592,6 @@ describe('NavbarComponent (DONE)', () => { }); }); - describe('#getEditionComplex()', () => { - it('... should have been called', () => { - expectSpyCall(getEditionComplexSpy, 1); - }); - - it('... should get `selectedEditionComplex`', () => { - expect(component.selectedEditionComplex).toBeDefined(); - expectToEqual(component.selectedEditionComplex, expectedSelectedEditionComplex); - }); - }); - describe('#isActiveRoute()', () => { it('... should have been called 2 times', () => { expectSpyCall(isActiveRouteSpy, 2); @@ -618,14 +601,14 @@ describe('NavbarComponent (DONE)', () => { const expectedActiveRoute = '/active-route'; routerSpy.and.returnValue(true); - expect(component.isActiveRoute(expectedActiveRoute)).toBeTrue(); + expectToBe(component.isActiveRoute(expectedActiveRoute), true); }); it('... should return false if a given route is not active', () => { const expectedActiveRoute = '/non-active-route'; routerSpy.and.returnValue(false); - expect(component.isActiveRoute(expectedActiveRoute)).toBeFalse(); + expectToBe(component.isActiveRoute(expectedActiveRoute), false); }); }); @@ -672,7 +655,7 @@ describe('NavbarComponent (DONE)', () => { const linkDe = linkDes[index]; const expectedRouterLink = expectedOrderOfRouterlinks[index]; - expect(routerLink.navigatedTo).toBeNull(); + expectToBe(routerLink.navigatedTo, null); click(linkDe); fixture.detectChanges(); diff --git a/src/app/core/navbar/navbar.component.ts b/src/app/core/navbar/navbar.component.ts index 4e0a0223b..81f6351c7 100644 --- a/src/app/core/navbar/navbar.component.ts +++ b/src/app/core/navbar/navbar.component.ts @@ -5,9 +5,9 @@ import { faEnvelope, faFileAlt, faHome, faNetworkWired, faSearch } from '@fortaw import { Logos } from '@awg-core/core-models'; import { CoreService } from '@awg-core/services'; -import { EDITION_COMPLEXES } from '@awg-views/edition-view/data'; import { EDITION_ROUTE_CONSTANTS } from '@awg-views/edition-view/edition-route-constants'; import { EditionComplex } from '@awg-views/edition-view/models'; +import { EditionComplexesService } from '@awg-views/edition-view/services'; /** * The Header component. @@ -70,30 +70,23 @@ export class NavbarComponent implements OnInit { */ logos: Logos; - /** - * Public variable: selectedEditionComplex. - * - * It keeps the currently selected edition complex. - */ - selectedEditionComplex: EditionComplex; - /** * Readonly variable: DISPLAYED_EDITION_COMPLEXES. * * It keeps the array of displayed edition complexes. */ readonly DISPLAYED_EDITION_COMPLEXES: EditionComplex[] = [ - EDITION_COMPLEXES.OP3, - EDITION_COMPLEXES.OP4, - EDITION_COMPLEXES.OP12, - EDITION_COMPLEXES.OP23, - EDITION_COMPLEXES.OP25, - EDITION_COMPLEXES.M22, - EDITION_COMPLEXES.M30, - EDITION_COMPLEXES.M31, - EDITION_COMPLEXES.M34, - EDITION_COMPLEXES.M35_42, - EDITION_COMPLEXES.M37, + EditionComplexesService.getEditionComplexById('OP3'), + EditionComplexesService.getEditionComplexById('OP4'), + EditionComplexesService.getEditionComplexById('OP12'), + EditionComplexesService.getEditionComplexById('OP23'), + EditionComplexesService.getEditionComplexById('OP25'), + EditionComplexesService.getEditionComplexById('M22'), + EditionComplexesService.getEditionComplexById('M30'), + EditionComplexesService.getEditionComplexById('M31'), + EditionComplexesService.getEditionComplexById('M34'), + EditionComplexesService.getEditionComplexById('M35_42'), + EditionComplexesService.getEditionComplexById('M37'), ]; /** @@ -125,7 +118,6 @@ export class NavbarComponent implements OnInit { * when initializing the component. */ ngOnInit() { - this.getEditionComplex(); this.provideMetaData(); } @@ -147,17 +139,6 @@ export class NavbarComponent implements OnInit { }); } - /** - * Public method: getEditionComplex. - * - * It gets the selected edition complex. - * - * @returns {void} Sets the selectedEditionComplex variable. - */ - getEditionComplex(): void { - this.selectedEditionComplex = this.DISPLAYED_EDITION_COMPLEXES[0]; - } - /** * Public method: provideMetaData. * diff --git a/src/app/core/services/analytics-sercvice/analytics.service.spec.ts b/src/app/core/services/analytics-sercvice/analytics.service.spec.ts index ead665c9d..c25cf6c15 100644 --- a/src/app/core/services/analytics-sercvice/analytics.service.spec.ts +++ b/src/app/core/services/analytics-sercvice/analytics.service.spec.ts @@ -93,7 +93,7 @@ describe('AnalyticsService (DONE)', () => { }); it('... should clear mock analytics store after each run', () => { - expect(mockAnalytics.getGtag(0)).toBeNull(); + expectToBe(mockAnalytics.getGtag(0), null); }); }); @@ -107,7 +107,7 @@ describe('AnalyticsService (DONE)', () => { setupAnalytics(analyticsService, null, expectedAnalyticsId); expectSpyCall(initializeAnalyticsSpy, 1); - expect((analyticsService as any)._isInitialized).toBeFalse(); + expectToBe((analyticsService as any)._isInitialized, false); }); it('... should not initialize the analytics tracker without analyticsId', () => { @@ -115,14 +115,14 @@ describe('AnalyticsService (DONE)', () => { setupAnalytics(analyticsService, expectedAnalyticsEndpoint, null); expectSpyCall(initializeAnalyticsSpy, 1); - expect((analyticsService as any)._isInitialized).toBeFalse(); + expectToBe((analyticsService as any)._isInitialized, false); }); it('... should initialize the analytics tracker with given endpoint and id', () => { setupAnalytics(analyticsService, expectedAnalyticsEndpoint, expectedAnalyticsId); expectSpyCall(initializeAnalyticsSpy, 1); - expect((analyticsService as any)._isInitialized).toBeTrue(); + expectToBe((analyticsService as any)._isInitialized, true); }); it('... should log a replacement message in develop mode', () => { @@ -180,7 +180,7 @@ describe('AnalyticsService (DONE)', () => { analyticsService.trackPageView(expectedPage); expectSpyCall(gtagSpy, 0, null); - expect(gtagSpy.calls.any()).toBeFalse(); + expectToBe(gtagSpy.calls.any(), false); }); it('... should do nothing if isInitialized is set to false', () => { @@ -189,7 +189,7 @@ describe('AnalyticsService (DONE)', () => { analyticsService.trackPageView(expectedPage); expectSpyCall(gtagSpy, 0, null); - expect(gtagSpy.calls.any()).toBeFalse(); + expectToBe(gtagSpy.calls.any(), false); }); it('... should run if analytics is initialized successfully', () => { @@ -216,7 +216,7 @@ describe('AnalyticsService (DONE)', () => { analyticsService.trackPageView(null); expectSpyCall(gtagSpy, 0, null); - expect(gtagSpy.calls.any()).toBeFalse(); + expectToBe(gtagSpy.calls.any(), false); }); it('... should track the given page', () => { diff --git a/src/app/core/services/api-service/api.service.spec.ts b/src/app/core/services/api-service/api.service.spec.ts index 7a6ccb289..31958d6dd 100644 --- a/src/app/core/services/api-service/api.service.spec.ts +++ b/src/app/core/services/api-service/api.service.spec.ts @@ -92,8 +92,7 @@ describe('ApiService', () => { }); it("... should have empty 'httpGetUrl'", () => { - expect(apiService.httpGetUrl).toBeDefined(); - expect(apiService.httpGetUrl).toBeFalsy(); + expectToBe(apiService.httpGetUrl, ''); }); }); @@ -159,6 +158,7 @@ describe('ApiService', () => { expectToBe(call.request.method, 'GET'); expectToBe(call.request.responseType, 'json'); expectToEqual(call.request.url, expectedUrl); + expect(call.request.params).toBeDefined(); expectToBe(call.request.params.keys().length, 0); })); @@ -182,6 +182,7 @@ describe('ApiService', () => { expectToBe(call.request.method, 'GET'); expectToBe(call.request.responseType, 'json'); expectToEqual(call.request.url, expectedUrl); + expect(call.request.params).toBeDefined(); expectToBe(call.request.params.keys().length, 2); expectToBe(call.request.params.get('searchtype'), expectedSearchType); diff --git a/src/app/core/services/conversion-service/conversion.service.spec.ts b/src/app/core/services/conversion-service/conversion.service.spec.ts index 46583d147..08c7a16ae 100644 --- a/src/app/core/services/conversion-service/conversion.service.spec.ts +++ b/src/app/core/services/conversion-service/conversion.service.spec.ts @@ -73,7 +73,7 @@ describe('ConversionService', () => { const result = conversionService.convertFullTextSearchResults(searchResponse); - expect(result).toEqual(searchResponse); + expectToEqual(result, searchResponse); }); it('... subjects are null', () => { @@ -82,7 +82,7 @@ describe('ConversionService', () => { const result = conversionService.convertFullTextSearchResults(searchResponse); - expect(result).toEqual(searchResponse); + expectToEqual(result, searchResponse); }); it('... subjects are empty', () => { @@ -91,7 +91,7 @@ describe('ConversionService', () => { const result = conversionService.convertFullTextSearchResults(searchResponse); - expect(result).toEqual(searchResponse); + expectToEqual(result, searchResponse); }); }); @@ -245,7 +245,7 @@ describe('ConversionService', () => { const result = conversionService.prepareFullTextSearchResultText(searchResponseWithQuery, searchUrl); - expect(typeof result).toEqual('string'); + expectToBe(typeof result, 'string'); }); describe('... should return correct text', () => { @@ -339,7 +339,7 @@ describe('ConversionService', () => { const result = (conversionService as any)._cleanSubjectValueLabels(subject); - expect(result.valuelabel).toBeNull(); + expectToBe(result.valuelabel, null); expectToBe(result.obj_id, ''); }); @@ -463,7 +463,7 @@ describe('ConversionService', () => { const result = (conversionService as any)._convertDateValue(dateObj); - expect(typeof result).toEqual('string'); + expectToBe(typeof result, 'string'); }); it('should return the converted date string without " (G)"', () => { @@ -543,7 +543,7 @@ describe('ConversionService', () => { const result = (conversionService as any)._convertLinkValue(valueId, firstProp, restype); - expect(typeof result).toEqual('string'); + expectToBe(typeof result, 'string'); }); it('... should return a linked value', () => { @@ -642,7 +642,7 @@ describe('ConversionService', () => { const result = (conversionService as any)._convertRichtextValue(str, JSON.stringify(jsonAttrs)); - expect(typeof result).toEqual('string'); + expectToBe(typeof result, 'string'); }); it('... should correctly convert a rich text value with Standoff to HTML', () => { @@ -728,7 +728,7 @@ describe('ConversionService', () => { const result = (conversionService as any)._convertStandoffToHTML(str, JSON.stringify(jsonAttrs)); - expect(typeof result).toEqual('string'); + expectToBe(typeof result, 'string'); }); it('... should correctly convert a rich text value with Standoff to HTML', () => { diff --git a/src/app/core/services/edition-init-service/edition-init.service.spec.ts b/src/app/core/services/edition-init-service/edition-init.service.spec.ts new file mode 100644 index 000000000..ab24a010c --- /dev/null +++ b/src/app/core/services/edition-init-service/edition-init.service.spec.ts @@ -0,0 +1,88 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import { TestBed } from '@angular/core/testing'; + +import Spy = jasmine.Spy; + +import { cleanStylesFromDOM } from '@testing/clean-up-helper'; +import { expectSpyCall, expectToEqual } from '@testing/expect-helper'; + +import { EDITION_ROUTE_CONSTANTS } from '@awg-app/views/edition-view/edition-route-constants'; +import { EditionComplexesService, EditionOutlineService } from '@awg-app/views/edition-view/services'; + +import { EditionInitService } from './edition-init.service'; + +describe('EditionInitService (DONE)', () => { + let editionInitService: EditionInitService; + + let initializeEditionComplexesListSpy: Spy; + let initializeEditionOutlineSpy: Spy; + + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [EditionInitService], + }); + + // Inject service + editionInitService = TestBed.inject(EditionInitService); + + // Spies for service methods + initializeEditionComplexesListSpy = spyOn( + EditionComplexesService, + 'initializeEditionComplexesList' + ).and.callThrough(); + initializeEditionOutlineSpy = spyOn(EditionOutlineService, 'initializeEditionOutline').and.callThrough(); + }); + + afterAll(() => { + cleanStylesFromDOM(); + }); + + it('... should create', () => { + expect(editionInitService).toBeTruthy(); + }); + + describe('#initializeEdition()', () => { + it('... should have a method `initializeEdition`', () => { + expect(editionInitService.initializeEdition).toBeDefined(); + }); + + it('... should initialize the edition view', () => { + editionInitService.initializeEdition(); + + expectSpyCall(initializeEditionComplexesListSpy, 1); + expectSpyCall(initializeEditionOutlineSpy, 1); + }); + + it('... should make the EditionComplexesList available', () => { + editionInitService.initializeEdition(); + + const editionComplexesList = EditionComplexesService.getEditionComplexesList(); + + expect(editionComplexesList).toBeDefined(); + expect(editionComplexesList).not.toBe({}); + + // Test for samples + expect(editionComplexesList['OP3']).toBeDefined(); + expect(editionComplexesList['M22']).toBeDefined(); + + // Test for sample properties + expect(editionComplexesList['OP3'].titleStatement).toBeDefined(); + expect(editionComplexesList['OP3'].respStatement).toBeDefined(); + expect(editionComplexesList['OP3'].pubStatement).toBeDefined(); + }); + + it('... should make the EditionOutline available', () => { + editionInitService.initializeEdition(); + + const editionOutline = EditionOutlineService.getEditionOutline(); + + expect(editionOutline).toBeDefined(); + expect(editionOutline).not.toBe([]); + + // Test for samples + expectToEqual(editionOutline[0].series, EDITION_ROUTE_CONSTANTS.SERIES_1); + expectToEqual(editionOutline[1].series, EDITION_ROUTE_CONSTANTS.SERIES_2); + expectToEqual(editionOutline[2].series, EDITION_ROUTE_CONSTANTS.SERIES_3); + }); + }); +}); diff --git a/src/app/core/services/edition-init-service/edition-init.service.ts b/src/app/core/services/edition-init-service/edition-init.service.ts new file mode 100644 index 000000000..2fefd7aad --- /dev/null +++ b/src/app/core/services/edition-init-service/edition-init.service.ts @@ -0,0 +1,28 @@ +import { Injectable } from '@angular/core'; + +import { EditionComplexesService, EditionOutlineService } from '@awg-views/edition-view/services'; + +/** + * The EditionInit service. + * + * It handles the initialization of the edition view. + * + * Provided in: `root`. + */ +@Injectable({ + providedIn: 'root', +}) +export class EditionInitService { + /** + * Public method: initializeEdition. + * + * It initializes the edition view by initializing + * the edition complexes list and the edition outline. + * + * @returns {void} Initializes the edition view. + */ + initializeEdition(): void { + EditionComplexesService.initializeEditionComplexesList(); + EditionOutlineService.initializeEditionOutline(); + } +} diff --git a/src/app/core/services/edition-init-service/index.ts b/src/app/core/services/edition-init-service/index.ts new file mode 100644 index 000000000..178f31691 --- /dev/null +++ b/src/app/core/services/edition-init-service/index.ts @@ -0,0 +1 @@ +export * from './edition-init.service'; diff --git a/src/app/core/services/gnd-service/gnd.service.spec.ts b/src/app/core/services/gnd-service/gnd.service.spec.ts index 013c0af28..925a04b15 100644 --- a/src/app/core/services/gnd-service/gnd.service.spec.ts +++ b/src/app/core/services/gnd-service/gnd.service.spec.ts @@ -119,7 +119,7 @@ describe('GndService (DONE)', () => { expectedStorage.removeItem('testkey'); - expect(mockStorage.getItem('testkey')).toBeNull(); + expectToBe(mockStorage.getItem('testkey'), null); }); it('... should use correct mock storage', () => { @@ -129,7 +129,7 @@ describe('GndService (DONE)', () => { expectedStorage.setItem('testkey', 'testvalue'); expectToBe(mockStorage.getItem('testkey'), 'testvalue'); - expect(otherMockStorage.getItem('testkey')).toBeNull(); + expectToBe(otherMockStorage.getItem('testkey'), null); mockStorage.clear(); otherMockStorage.clear(); @@ -137,7 +137,7 @@ describe('GndService (DONE)', () => { expectedOtherStorage.setItem('testkey', 'testvalue'); expectToBe(otherMockStorage.getItem('testkey'), 'testvalue'); - expect(mockStorage.getItem('testkey')).toBeNull(); + expectToBe(mockStorage.getItem('testkey'), null); otherMockStorage.clear(); }); @@ -155,7 +155,7 @@ describe('GndService (DONE)', () => { expectedStorage.removeItem('testkey'); - expect(mockStorage.getItem('testkey')).toBeNull(); + expectToBe(mockStorage.getItem('testkey'), null); }); it('... should remove the correct item', () => { @@ -167,17 +167,17 @@ describe('GndService (DONE)', () => { expectedStorage.removeItem('testkey'); - expect(mockStorage.getItem('testkey')).toBeNull(); + expectToBe(mockStorage.getItem('testkey'), null); expectToBe(mockStorage.getItem('testkey2'), 'testvalue2'); expectedStorage.removeItem('testkey2'); - expect(mockStorage.getItem('testkey')).toBeNull(); - expect(mockStorage.getItem('testkey2')).toBeNull(); + expectToBe(mockStorage.getItem('testkey'), null); + expectToBe(mockStorage.getItem('testkey2'), null); }); it('... should clear mock storage after each run', () => { - expect(mockStorage.getItem('testkey')).toBeNull(); + expectToBe(mockStorage.getItem('testkey'), null); }); }); @@ -204,59 +204,59 @@ describe('GndService (DONE)', () => { describe('... should not do anything if', () => { it('... gndEvent is undefined', () => { - expect(mockStorage.getItem(expectedGndKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedGndKey), null); gndService.exposeGnd(undefined); expectSpyCall(setGndToSessionStorageSpy, 0); expectSpyCall(removeGndFromSessionStorageSpy, 0); - expect(mockStorage.getItem(expectedGndKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedGndKey), null); }); it('... gndEvent is null', () => { - expect(mockStorage.getItem(expectedGndKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedGndKey), null); gndService.exposeGnd(null); expectSpyCall(setGndToSessionStorageSpy, 0); expectSpyCall(removeGndFromSessionStorageSpy, 0); - expect(mockStorage.getItem(expectedGndKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedGndKey), null); }); it('... gndEvent has undefined type', () => { - expect(mockStorage.getItem(expectedGndKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedGndKey), null); gndService.exposeGnd(new GndEvent(undefined, '123')); expectSpyCall(setGndToSessionStorageSpy, 0); expectSpyCall(removeGndFromSessionStorageSpy, 0); - expect(mockStorage.getItem(expectedGndKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedGndKey), null); }); it('... gndEvent has type null', () => { - expect(mockStorage.getItem(expectedGndKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedGndKey), null); gndService.exposeGnd(new GndEvent(null, '123')); expectSpyCall(setGndToSessionStorageSpy, 0); expectSpyCall(removeGndFromSessionStorageSpy, 0); - expect(mockStorage.getItem(expectedGndKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedGndKey), null); }); it('... gndEvent has GET type', () => { const expectedDefaultMessage = 'Got an uncatched GND event'; - expect(mockStorage.getItem(expectedGndKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedGndKey), null); gndService.exposeGnd(new GndEvent(GndEventType.GET, '123')); expectSpyCall(setGndToSessionStorageSpy, 0); expectSpyCall(removeGndFromSessionStorageSpy, 0); - expect(mockStorage.getItem(expectedGndKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedGndKey), null); expectSpyCall(consoleSpy, 1, expectedDefaultMessage); expectToBe(mockConsole.get(0), expectedDefaultMessage); @@ -272,7 +272,7 @@ describe('GndService (DONE)', () => { }); it('... should set key/value pair to storage if given gndEvent type is `set`', () => { - expect(mockStorage.getItem(expectedGndKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedGndKey), null); gndService.exposeGnd(expectedSetEvent); @@ -338,39 +338,37 @@ describe('GndService (DONE)', () => { it('... should set an item to the correct storage if given gndEvent value has gnd link', () => { const otherMockStorage = mockLocalStorage; - expect(mockStorage.getItem(expectedGndKey)).toBeNull(); - expect(otherMockStorage.getItem(expectedGndKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedGndKey), null); + expectToBe(otherMockStorage.getItem(expectedGndKey), null); gndService.exposeGnd(expectedSetEvent); - expectToEqual(mockStorage.getItem(expectedGndKey), expectedItem); - expect(otherMockStorage.getItem(expectedGndKey)).not.toEqual(expectedItem); - expect(otherMockStorage.getItem(expectedGndKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedGndKey), expectedItem); + expectToBe(otherMockStorage.getItem(expectedGndKey), null); otherMockStorage.clear(); }); it('... should overwrite an existing gnd key if gndEvent value has gnd link', () => { - expect(mockStorage.getItem(expectedGndKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedGndKey), null); gndService.exposeGnd(expectedSetEvent); - expectToEqual(mockStorage.getItem(expectedGndKey), expectedItem); + expectToBe(mockStorage.getItem(expectedGndKey), expectedItem); gndService.exposeGnd(otherSetEvent); - expect(mockStorage.getItem(expectedGndKey)).not.toEqual(expectedItem); - expectToEqual(mockStorage.getItem(expectedGndKey), otherItem); + expectToBe(mockStorage.getItem(expectedGndKey), otherItem); }); it('... should return null if value has no gnd link', () => { - expect(mockStorage.getItem(expectedGndKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedGndKey), null); gndService.exposeGnd(noLinkGndSetEvent); - expect(mockStorage.getItem(expectedGndKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedGndKey), null); }); it('... should call helper function with input value to check if value has gnd link', () => { - expect(mockStorage.getItem(expectedGndKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedGndKey), null); const valueHasGndSpy = spyOn(gndService, '_valueHasGnd').and.callThrough(); gndService.exposeGnd(expectedSetEvent); @@ -385,7 +383,7 @@ describe('GndService (DONE)', () => { it('... should execute regex check and populate linkRegArr if value has gnd link', () => { expect(gndService.linkRegArr).toBeUndefined(); - expect(mockStorage.getItem(expectedGndKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedGndKey), null); const valueHasGndSpy = spyOn(gndService, '_valueHasGnd').and.callFake(checkValue => { gndService.linkRegArr = gndService.DNB_REG.exec(checkValue); @@ -400,7 +398,7 @@ describe('GndService (DONE)', () => { it('... should execute regex check and set linkRegArr = null if value has no gnd link', () => { expect(gndService.linkRegArr).toBeUndefined(); - expect(mockStorage.getItem(expectedGndKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedGndKey), null); const valueHasGndSpy = spyOn(gndService, '_valueHasGnd').and.callThrough(); gndService.exposeGnd(noLinkGndSetEvent); @@ -408,30 +406,30 @@ describe('GndService (DONE)', () => { expectSpyCall(valueHasGndSpy, 1, noLinkGndEventValue); expect(noLinkGndEventValue).not.toMatch(expectedDnbReg); - expect(gndService.linkRegArr).toBeNull(); + expectToBe(gndService.linkRegArr, null); }); it('... should return true (and set item) if value has gnd link', () => { expect(gndService.linkRegArr).toBeUndefined(); - expect(mockStorage.getItem(expectedGndKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedGndKey), null); const valueHasGndSpy = spyOn(gndService, '_valueHasGnd').and.callThrough(); gndService.exposeGnd(expectedSetEvent); expectSpyCall(valueHasGndSpy, 1, expectedGndEventValue); - expectToEqual(mockStorage.getItem(expectedGndKey), expectedItem); + expectToBe(mockStorage.getItem(expectedGndKey), expectedItem); }); it('... should return false (and set no item) if value has no gnd link', () => { expect(gndService.linkRegArr).toBeUndefined(); - expect(mockStorage.getItem(expectedGndKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedGndKey), null); const valueHasGndSpy = spyOn(gndService, '_valueHasGnd').and.callThrough(); gndService.exposeGnd(noLinkGndSetEvent); expectSpyCall(valueHasGndSpy, 1, noLinkGndEventValue); - expect(mockStorage.getItem(expectedGndKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedGndKey), null); }); }); }); @@ -445,14 +443,14 @@ describe('GndService (DONE)', () => { }); it('... should remove an item by key from the storage if given gndEvent type is `remove`', () => { - expect(mockStorage.getItem(expectedGndKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedGndKey), null); expectedStorage.setItem(expectedGndKey, expectedItem); - expectToEqual(mockStorage.getItem(expectedGndKey), expectedItem); + expectToBe(mockStorage.getItem(expectedGndKey), expectedItem); gndService.exposeGnd(expectedRemoveEvent); - expect(mockStorage.getItem(expectedGndKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedGndKey), null); }); it('... should expose null value if given gndEvent type is `remove`', () => { @@ -497,19 +495,19 @@ describe('GndService (DONE)', () => { const expectedOtherStorage = expectedLocalStorage; const otherMockStorage = mockLocalStorage; - expect(mockStorage.getItem(expectedGndKey)).toBeNull(); - expect(otherMockStorage.getItem(expectedGndKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedGndKey), null); + expectToBe(otherMockStorage.getItem(expectedGndKey), null); expectedStorage.setItem(expectedGndKey, expectedItem); expectedOtherStorage.setItem(expectedGndKey, otherItem); - expectToEqual(mockStorage.getItem(expectedGndKey), expectedItem); - expectToEqual(otherMockStorage.getItem(expectedGndKey), otherItem); + expectToBe(mockStorage.getItem(expectedGndKey), expectedItem); + expectToBe(otherMockStorage.getItem(expectedGndKey), otherItem); gndService.exposeGnd(expectedRemoveEvent); - expect(mockStorage.getItem(expectedGndKey)).toBeNull(); - expectToEqual(otherMockStorage.getItem(expectedGndKey), otherItem); + expectToBe(mockStorage.getItem(expectedGndKey), null); + expectToBe(otherMockStorage.getItem(expectedGndKey), otherItem); otherMockStorage.clear(); }); @@ -517,45 +515,45 @@ describe('GndService (DONE)', () => { it('... should remove the correct item from the storage', () => { const otherKey = 'otherKey'; - expect(mockStorage.getItem(expectedGndKey)).toBeNull(); - expect(mockStorage.getItem(otherKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedGndKey), null); + expectToBe(mockStorage.getItem(otherKey), null); expectedStorage.setItem(expectedGndKey, expectedItem); expectedStorage.setItem(otherKey, expectedItem); - expectToEqual(mockStorage.getItem(expectedGndKey), expectedItem); - expectToEqual(mockStorage.getItem(otherKey), expectedItem); + expectToBe(mockStorage.getItem(expectedGndKey), expectedItem); + expectToBe(mockStorage.getItem(otherKey), expectedItem); gndService.exposeGnd(expectedRemoveEvent); - expect(mockStorage.getItem(expectedGndKey)).toBeNull(); - expectToEqual(mockStorage.getItem(otherKey), expectedItem); + expectToBe(mockStorage.getItem(expectedGndKey), null); + expectToBe(mockStorage.getItem(otherKey), expectedItem); }); describe('... should do nothing if:', () => { it('- storage has not the gnd key', () => { - expect(mockStorage.getItem(expectedGndKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedGndKey), null); gndService.exposeGnd(expectedRemoveEvent); - expect(mockStorage.getItem(expectedGndKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedGndKey), null); }); it('- storage has other key but not the gnd key', () => { const otherKey = 'otherKey'; - expect(mockStorage.getItem(expectedGndKey)).toBeNull(); - expect(mockStorage.getItem(otherKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedGndKey), null); + expectToBe(mockStorage.getItem(otherKey), null); expectedStorage.setItem(otherKey, expectedItem); - expect(mockStorage.getItem(expectedGndKey)).toBeNull(); - expectToEqual(mockStorage.getItem(otherKey), expectedItem); + expectToBe(mockStorage.getItem(expectedGndKey), null); + expectToBe(mockStorage.getItem(otherKey), expectedItem); gndService.exposeGnd(expectedRemoveEvent); - expect(mockStorage.getItem(expectedGndKey)).toBeNull(); - expectToEqual(mockStorage.getItem(otherKey), expectedItem); + expectToBe(mockStorage.getItem(expectedGndKey), null); + expectToBe(mockStorage.getItem(otherKey), expectedItem); }); }); }); diff --git a/src/app/core/services/http-cache/http-cache.service.spec.ts b/src/app/core/services/http-cache/http-cache.service.spec.ts index caa9e48dc..9633c1b9b 100644 --- a/src/app/core/services/http-cache/http-cache.service.spec.ts +++ b/src/app/core/services/http-cache/http-cache.service.spec.ts @@ -71,7 +71,7 @@ describe('HttpCacheService (DONE)', () => { expect(expectedCachedResponse).toBeUndefined(); const expectedGetCache = httpCacheService.get(expectedRequest); - expect(expectedGetCache).toBeNull(); + expectToBe(expectedGetCache, null); }); it('... should return an HTTP response from cache if available', () => { diff --git a/src/app/core/services/index.ts b/src/app/core/services/index.ts index 1088a46bd..caadf977c 100644 --- a/src/app/core/services/index.ts +++ b/src/app/core/services/index.ts @@ -12,6 +12,7 @@ import { ApiService } from './api-service'; import { ConversionService } from './conversion-service'; import { CoreService } from './core-service'; import { DataStreamerService } from './data-streamer-service'; +import { EditionInitService } from './edition-init-service'; import { GndService } from './gnd-service'; import { HttpCacheService } from './http-cache'; import { LoadingService } from './loading-service'; @@ -25,6 +26,7 @@ export { ConversionService, CoreService, DataStreamerService, + EditionInitService, GndService, HttpCacheService, LoadingService, diff --git a/src/app/core/services/loading-service/loading.service.spec.ts b/src/app/core/services/loading-service/loading.service.spec.ts index 3c5bc338c..697c94c01 100644 --- a/src/app/core/services/loading-service/loading.service.spec.ts +++ b/src/app/core/services/loading-service/loading.service.spec.ts @@ -45,7 +45,7 @@ describe('LoadingService (DONE)', () => { it('... should return default false value', waitForAsync(() => { loadingService.getLoadingStatus().subscribe({ next: (isLoading: boolean) => { - expect(isLoading).toBeFalse(); + expectToBe(isLoading, false); }, }); })); diff --git a/src/app/core/services/storage-service/storage.service.spec.ts b/src/app/core/services/storage-service/storage.service.spec.ts index 79184cad8..eabf6fae1 100644 --- a/src/app/core/services/storage-service/storage.service.spec.ts +++ b/src/app/core/services/storage-service/storage.service.spec.ts @@ -67,7 +67,7 @@ describe('StorageService (DONE)', () => { expectedStorage.removeItem('testkey'); - expect(mockStorage.getItem('testkey')).toBeNull(); + expectToBe(mockStorage.getItem('testkey'), null); }); it('... should use correct mock storage', () => { @@ -77,7 +77,7 @@ describe('StorageService (DONE)', () => { expectedStorage.setItem('testkey', 'testvalue'); expectToBe(mockStorage.getItem('testkey'), 'testvalue'); - expect(otherMockStorage.getItem('testkey')).toBeNull(); + expectToBe(otherMockStorage.getItem('testkey'), null); mockStorage.clear(); otherMockStorage.clear(); @@ -85,7 +85,7 @@ describe('StorageService (DONE)', () => { expectedOtherStorage.setItem('testkey', 'testvalue'); expectToBe(otherMockStorage.getItem('testkey'), 'testvalue'); - expect(mockStorage.getItem('testkey')).toBeNull(); + expectToBe(mockStorage.getItem('testkey'), null); otherMockStorage.clear(); }); @@ -103,7 +103,7 @@ describe('StorageService (DONE)', () => { expectedStorage.removeItem('testkey'); - expect(mockStorage.getItem('testkey')).toBeNull(); + expectToBe(mockStorage.getItem('testkey'), null); }); it('... should remove the correct item', () => { @@ -115,17 +115,17 @@ describe('StorageService (DONE)', () => { expectedStorage.removeItem('testkey'); - expect(mockStorage.getItem('testkey')).toBeNull(); + expectToBe(mockStorage.getItem('testkey'), null); expectToBe(mockStorage.getItem('testkey2'), 'testvalue2'); expectedStorage.removeItem('testkey2'); - expect(mockStorage.getItem('testkey')).toBeNull(); - expect(mockStorage.getItem('testkey2')).toBeNull(); + expectToBe(mockStorage.getItem('testkey'), null); + expectToBe(mockStorage.getItem('testkey2'), null); }); it('... should clear mock storage after each run', () => { - expect(mockStorage.getItem('testkey')).toBeNull(); + expectToBe(mockStorage.getItem('testkey'), null); }); }); @@ -135,7 +135,7 @@ describe('StorageService (DONE)', () => { }); it('... should set a given key/item string pair to a given storage type', () => { - expect(mockStorage.getItem(expectedKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedKey), null); storageService.setStorageKey(sessionType, expectedKey, expectedItem); expectToBe(mockStorage.getItem(expectedKey), expectedItem); @@ -144,8 +144,8 @@ describe('StorageService (DONE)', () => { it('... should set item to the correct storage type', () => { const otherMockStorage = mockLocalStorage; - expect(mockStorage.getItem(expectedKey)).toBeNull(); - expect(otherMockStorage.getItem(expectedKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedKey), null); + expectToBe(otherMockStorage.getItem(expectedKey), null); storageService.setStorageKey(sessionType, expectedKey, expectedItem); storageService.setStorageKey(localType, expectedKey, otherItem); @@ -157,14 +157,14 @@ describe('StorageService (DONE)', () => { }); it('... should set a new key/item when a key does not exist', () => { - expect(mockStorage.getItem(expectedKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedKey), null); storageService.setStorageKey(sessionType, expectedKey, expectedItem); expectToBe(mockStorage.getItem(expectedKey), expectedItem); }); it('... should overwrite an existing item with the correct item when a key exists', () => { - expect(mockStorage.getItem(expectedKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedKey), null); storageService.setStorageKey(sessionType, expectedKey, expectedItem); expectToBe(mockStorage.getItem(expectedKey), expectedItem); @@ -175,55 +175,55 @@ describe('StorageService (DONE)', () => { describe('... should do nothing if:', () => { it('- storage type is undefined ', () => { - expect(mockStorage.getItem(expectedKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedKey), null); storageService.setStorageKey(undefined, expectedKey, expectedItem); - expect(mockStorage.getItem(expectedKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedKey), null); }); it('- storage type is null', () => { - expect(mockStorage.getItem(expectedKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedKey), null); storageService.setStorageKey(null, expectedKey, expectedItem); - expect(mockStorage.getItem(expectedKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedKey), null); }); it('- storage is not available', () => { - expect(mockStorage.getItem(expectedKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedKey), null); spyOn(storageService, '_storageIsAvailable').and.returnValue(false); storageService.setStorageKey(sessionType, expectedKey, expectedItem); - expect(mockStorage.getItem(expectedKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedKey), null); }); it('- storage is not supported', () => { - expect(mockStorage.getItem(expectedKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedKey), null); spyOn(storageService, '_storageIsSupported').and.returnValue(false); storageService.setStorageKey(sessionType, expectedKey, expectedItem); - expect(mockStorage.getItem(expectedKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedKey), null); }); it('- key is undefined ', () => { - expect(mockStorage.getItem(expectedKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedKey), null); storageService.setStorageKey(sessionType, undefined, expectedItem); - expect(mockStorage.getItem(expectedKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedKey), null); }); it('- key is null', () => { - expect(mockStorage.getItem(expectedKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedKey), null); storageService.setStorageKey(sessionType, null, expectedItem); - expect(mockStorage.getItem(expectedKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedKey), null); }); it('- value is undefined ', () => { - expect(mockStorage.getItem(expectedKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedKey), null); storageService.setStorageKey(sessionType, expectedKey, undefined); - expect(mockStorage.getItem(expectedKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedKey), null); }); it('- value is null', () => { - expect(mockStorage.getItem(expectedKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedKey), null); storageService.setStorageKey(sessionType, expectedKey, null); - expect(mockStorage.getItem(expectedKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedKey), null); }); }); }); @@ -234,7 +234,7 @@ describe('StorageService (DONE)', () => { }); it('... should get an item by key from a given storage type', () => { - expect(mockStorage.getItem(expectedKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedKey), null); expectedStorage.setItem(expectedKey, expectedItem); expectToBe(storageService.getStorageKey(sessionType, expectedKey), expectedItem); @@ -244,8 +244,8 @@ describe('StorageService (DONE)', () => { const expectedOtherStorage = expectedLocalStorage; const otherMockStorage = mockLocalStorage; - expect(mockStorage.getItem(expectedKey)).toBeNull(); - expect(otherMockStorage.getItem(expectedKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedKey), null); + expectToBe(otherMockStorage.getItem(expectedKey), null); expectedStorage.setItem(expectedKey, expectedItem); expectedOtherStorage.setItem(expectedKey, otherItem); @@ -257,50 +257,50 @@ describe('StorageService (DONE)', () => { }); it('... should return null for non existing keys', () => { - expect(mockStorage.getItem(expectedKey)).toBeNull(); - expect(storageService.getStorageKey(sessionType, expectedKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedKey), null); + expectToBe(storageService.getStorageKey(sessionType, expectedKey), null); }); describe('... should do nothing if:', () => { it('- storage type is undefined ', () => { - expect(mockStorage.getItem(expectedKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedKey), null); expectedStorage.setItem(expectedKey, expectedItem); - expect(storageService.getStorageKey(undefined, expectedKey)).toBeNull(); + expectToBe(storageService.getStorageKey(undefined, expectedKey), null); }); it('- storage type is null', () => { - expect(mockStorage.getItem(expectedKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedKey), null); expectedStorage.setItem(expectedKey, expectedItem); - expect(storageService.getStorageKey(null, expectedKey)).toBeNull(); + expectToBe(storageService.getStorageKey(null, expectedKey), null); }); it('- storage has not the given key', () => { - expect(mockStorage.getItem(expectedKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedKey), null); expectedStorage.setItem(expectedKey, expectedItem); spyOn(storageService, '_storageHasKey').and.returnValue(false); - expect(storageService.getStorageKey(sessionType, expectedKey)).toBeNull(); + expectToBe(storageService.getStorageKey(sessionType, expectedKey), null); }); it('- storage is not supported', () => { - expect(mockStorage.getItem(expectedKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedKey), null); expectedStorage.setItem(expectedKey, expectedItem); spyOn(storageService, '_storageIsSupported').and.returnValue(undefined); - expect(storageService.getStorageKey(sessionType, expectedKey)).toBeNull(); + expectToBe(storageService.getStorageKey(sessionType, expectedKey), null); }); it('- storage is not available', () => { - expect(mockStorage.getItem(expectedKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedKey), null); expectedStorage.setItem(expectedKey, expectedItem); spyOn(storageService, '_storageIsAvailable').and.returnValue(undefined); - expect(storageService.getStorageKey(sessionType, expectedKey)).toBeNull(); + expectToBe(storageService.getStorageKey(sessionType, expectedKey), null); }); }); }); @@ -311,44 +311,44 @@ describe('StorageService (DONE)', () => { }); it('... should remove an item by key from a given storage type', () => { - expect(mockStorage.getItem(expectedKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedKey), null); storageService.setStorageKey(sessionType, expectedKey, expectedItem); expectToBe(mockStorage.getItem(expectedKey), expectedItem); storageService.removeStorageKey(sessionType, expectedKey); - expect(mockStorage.getItem(expectedKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedKey), null); }); it('... should remove item from the correct storage type', () => { const expectedOtherStorage = expectedLocalStorage; const otherMockStorage = mockLocalStorage; - expect(mockStorage.getItem(expectedKey)).toBeNull(); - expect(otherMockStorage.getItem(expectedKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedKey), null); + expectToBe(otherMockStorage.getItem(expectedKey), null); expectedStorage.setItem(expectedKey, expectedItem); expectedOtherStorage.setItem(expectedKey, otherItem); storageService.removeStorageKey(sessionType, expectedKey); - expect(mockStorage.getItem(expectedKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedKey), null); expectToBe(otherMockStorage.getItem(expectedKey), otherItem); storageService.removeStorageKey(localType, expectedKey); - expect(otherMockStorage.getItem(expectedKey)).toBeNull(); + expectToBe(otherMockStorage.getItem(expectedKey), null); otherMockStorage.clear(); }); it('... should return for non existing items', () => { - expect(mockStorage.getItem(expectedKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedKey), null); expect(storageService.removeStorageKey(sessionType, expectedKey)).toBeUndefined(); }); describe('... should do nothing if:', () => { it('- storage type is undefined ', () => { - expect(mockStorage.getItem(expectedKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedKey), null); expectedStorage.setItem(expectedKey, expectedItem); expectToBe(mockStorage.getItem(expectedKey), expectedItem); @@ -359,7 +359,7 @@ describe('StorageService (DONE)', () => { }); it('- storage type is null', () => { - expect(mockStorage.getItem(expectedKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedKey), null); expectedStorage.setItem(expectedKey, expectedItem); expectToBe(mockStorage.getItem(expectedKey), expectedItem); @@ -370,7 +370,7 @@ describe('StorageService (DONE)', () => { }); it('- storage has not the given key', () => { - expect(mockStorage.getItem(expectedKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedKey), null); expectedStorage.setItem(expectedKey, expectedItem); expectToBe(mockStorage.getItem(expectedKey), expectedItem); @@ -382,7 +382,7 @@ describe('StorageService (DONE)', () => { }); it('- storage is not supported', () => { - expect(mockStorage.getItem(expectedKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedKey), null); expectedStorage.setItem(expectedKey, expectedItem); expectToBe(expectedStorage.getItem(expectedKey), expectedItem); @@ -394,7 +394,7 @@ describe('StorageService (DONE)', () => { }); it('- storage is not available', () => { - expect(mockStorage.getItem(expectedKey)).toBeNull(); + expectToBe(mockStorage.getItem(expectedKey), null); expectedStorage.setItem(expectedKey, expectedItem); expectToBe(mockStorage.getItem(expectedKey), expectedItem); diff --git a/src/app/core/services/utility-service/utility.service.spec.ts b/src/app/core/services/utility-service/utility.service.spec.ts index 389ae020e..1ec7d7b75 100644 --- a/src/app/core/services/utility-service/utility.service.spec.ts +++ b/src/app/core/services/utility-service/utility.service.spec.ts @@ -1,5 +1,7 @@ import { TestBed } from '@angular/core/testing'; +import { expectToBe } from '@testing/expect-helper'; + import { UtilityService } from './utility.service'; describe('UtilityService (DONE)', () => { @@ -24,22 +26,22 @@ describe('UtilityService (DONE)', () => { it('... should return true if a given array is not empty', () => { const checkArray = [1]; - expect(utils.isNotEmptyArray(checkArray)).toBeTrue(); + expectToBe(utils.isNotEmptyArray(checkArray), true); }); it('... should return false if a given array is empty', () => { const checkArray = []; - expect(utils.isNotEmptyArray(checkArray)).toBeFalse(); + expectToBe(utils.isNotEmptyArray(checkArray), false); }); it('... should return false if a given array is null', () => { const checkArray = null; - expect(utils.isNotEmptyArray(checkArray)).toBeFalse(); + expectToBe(utils.isNotEmptyArray(checkArray), false); }); it('... should return false if a given array is undefined', () => { const checkArray = undefined; - expect(utils.isNotEmptyArray(checkArray)).toBeFalse(); + expectToBe(utils.isNotEmptyArray(checkArray), false); }); }); @@ -50,32 +52,32 @@ describe('UtilityService (DONE)', () => { it('... should return true if a given object is not empty', () => { const checkObj = { a: 1 }; - expect(utils.isNotEmptyObject(checkObj)).toBeTrue(); + expectToBe(utils.isNotEmptyObject(checkObj), true); }); it('... should return false if a given object is empty', () => { const checkObj = {}; - expect(utils.isNotEmptyObject(checkObj)).toBeFalse(); + expectToBe(utils.isNotEmptyObject(checkObj), false); }); it('... should return false if a given object is an Array', () => { const checkObj = [1, 2, 3]; - expect(utils.isNotEmptyObject(checkObj)).toBeFalse(); + expectToBe(utils.isNotEmptyObject(checkObj), false); }); it('... should return false if a given object is an empty Array', () => { const checkObj = []; - expect(utils.isNotEmptyObject(checkObj)).toBeFalse(); + expectToBe(utils.isNotEmptyObject(checkObj), false); }); it('... should return false if a given object is undefined', () => { const checkObj = undefined; - expect(utils.isNotEmptyObject(checkObj)).toBeFalse(); + expectToBe(utils.isNotEmptyObject(checkObj), false); }); it('... should return false if a given object is null', () => { const checkObj = null; - expect(utils.isNotEmptyObject(checkObj)).toBeFalse(); + expectToBe(utils.isNotEmptyObject(checkObj), false); }); }); @@ -88,13 +90,13 @@ describe('UtilityService (DONE)', () => { it('... id is undefined', () => { const result = utils.isSketchId(undefined); - expect(result).toBeFalse(); + expectToBe(result, false); }); it('... id is null', () => { const result = utils.isSketchId(null); - expect(result).toBeFalse(); + expectToBe(result, false); }); it('... id does not include `_Sk`', () => { @@ -102,7 +104,7 @@ describe('UtilityService (DONE)', () => { const result = utils.isSketchId(id); - expect(result).toBeFalse(); + expectToBe(result, false); }); }); @@ -111,7 +113,7 @@ describe('UtilityService (DONE)', () => { const result = utils.isSketchId(id); - expect(result).toBeTrue(); + expectToBe(result, true); }); it('... should return true if id includes `SkRT`', () => { @@ -119,7 +121,7 @@ describe('UtilityService (DONE)', () => { const result = utils.isSketchId(id); - expect(result).toBeTrue(); + expectToBe(result, true); }); }); }); diff --git a/src/app/core/view-container/view-container.component.spec.ts b/src/app/core/view-container/view-container.component.spec.ts index 7560a8323..17a423c14 100644 --- a/src/app/core/view-container/view-container.component.spec.ts +++ b/src/app/core/view-container/view-container.component.spec.ts @@ -52,11 +52,10 @@ describe('ViewContainerComponent (DONE)', () => { // Main outlet should not be named expect(routletDes[0].attributes).toBeDefined(); - expect(routletDes[0].attributes['name']).not.toBeDefined(); + expect(routletDes[0].attributes['name']).toBeUndefined(); // Secondary outlet should be named 'side' expect(routletDes[1].attributes).toBeDefined(); - expect(routletDes[1].attributes['name']).toBeDefined(); expectToBe(routletDes[1].attributes['name'], 'side'); }); }); diff --git a/src/app/shared/address/address.component.spec.ts b/src/app/shared/address/address.component.spec.ts index 8e6e5ba67..f80c15595 100644 --- a/src/app/shared/address/address.component.spec.ts +++ b/src/app/shared/address/address.component.spec.ts @@ -2,7 +2,7 @@ import { DebugElement } from '@angular/core'; import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { cleanStylesFromDOM } from '@testing/clean-up-helper'; -import { getAndExpectDebugElementByCss } from '@testing/expect-helper'; +import { expectToBe, getAndExpectDebugElementByCss } from '@testing/expect-helper'; import { METADATA } from '@awg-core/core-data'; import { MetaContact, MetaPage, MetaSectionTypes } from '@awg-core/core-models'; @@ -63,11 +63,8 @@ describe('AddressComponent (DONE)', () => { const headerDes = getAndExpectDebugElementByCss(compDe, 'address p#awg-address-header a', 1, 1); const headerEl = headerDes[0].nativeElement; - expect(headerEl.href).toBeDefined(); - expect(headerEl.href).toBeFalsy(); - - expect(headerEl.textContent).toBeDefined(); - expect(headerEl.textContent).toBeFalsy(); + expectToBe(headerEl.href, ''); + expectToBe(headerEl.textContent, ''); }); it('... should not render the address content information yet', () => { @@ -93,25 +90,14 @@ describe('AddressComponent (DONE)', () => { const phoneEl = phoneDes[0].nativeElement; const emailEl = emailDes[0].nativeElement; - expect(institutionEl.textContent).toBeDefined(); - expect(institutionEl.textContent).toBeFalsy(); - - expect(streetEl.textContent).toBeDefined(); - expect(streetEl.textContent).toBeFalsy(); - - expect(postalCityEl.textContent).toBeDefined(); - expect(postalCityEl.textContent).toBeFalsy(); + expectToBe(institutionEl.textContent, ''); + expectToBe(streetEl.textContent, ''); + expectToBe(postalCityEl.textContent, ''); + expectToBe(countryEl.textContent, ''); - expect(countryEl.textContent).toBeDefined(); - expect(countryEl.textContent).toBeFalsy(); - - expect(phoneEl.textContent).toBeDefined(); - expect(phoneEl.textContent).toBeFalsy(); - - expect(emailEl.href).toBeDefined(); - expect(emailEl.href).toBeFalsy(); - expect(emailEl.textContent).toBeDefined(); - expect(emailEl.textContent).toBeFalsy(); + expectToBe(phoneEl.textContent, ''); + expectToBe(emailEl.href, ''); + expectToBe(emailEl.textContent, ''); }); }); }); @@ -131,15 +117,8 @@ describe('AddressComponent (DONE)', () => { const headerDes = getAndExpectDebugElementByCss(compDe, 'address p#awg-address-header a', 1, 1); const headerEl = headerDes[0].nativeElement; - expect(headerEl.href).toBeTruthy(); - expect(headerEl.href) - .withContext(`should be ${expectedPageMetaData.awgProjectUrl}`) - .toBe(expectedPageMetaData.awgProjectUrl); - - expect(headerEl.textContent).toBeTruthy(); - expect(headerEl.textContent) - .withContext(`should be ${expectedPageMetaData.awgProjectName}`) - .toBe(expectedPageMetaData.awgProjectName); + expectToBe(headerEl.href, expectedPageMetaData.awgProjectUrl); + expectToBe(headerEl.textContent, expectedPageMetaData.awgProjectName); }); it('... should render the address content institution information', () => { @@ -151,10 +130,7 @@ describe('AddressComponent (DONE)', () => { ); const institutionEl = institutionDes[0].nativeElement; - expect(institutionEl.textContent).toBeTruthy(); - expect(institutionEl.textContent) - .withContext(`should be ${expectedContactMetaData.address.institution}`) - .toBe(expectedContactMetaData.address.institution); + expectToBe(institutionEl.textContent, expectedContactMetaData.address.institution); }); it('... should render the address content street information', () => { @@ -166,10 +142,7 @@ describe('AddressComponent (DONE)', () => { ); const streetEl = streetDes[0].nativeElement; - expect(streetEl.textContent).toBeTruthy(); - expect(streetEl.textContent) - .withContext(`should be ${expectedContactMetaData.address.street}`) - .toBe(expectedContactMetaData.address.street); + expectToBe(streetEl.textContent, expectedContactMetaData.address.street); }); it('... should render the address content postal city information', () => { @@ -184,10 +157,7 @@ describe('AddressComponent (DONE)', () => { const expectedPostalCity = expectedContactMetaData.address.postalCode + '\xA0' + expectedContactMetaData.address.city; - expect(postalCityEl.textContent).toBeTruthy(); - expect(postalCityEl.textContent) - .withContext(`should be ${expectedPostalCity}`) - .toBe(expectedPostalCity); + expectToBe(postalCityEl.textContent, expectedPostalCity); }); it('... should render the address content country information', () => { @@ -199,10 +169,7 @@ describe('AddressComponent (DONE)', () => { ); const countryEl = countryDes[0].nativeElement; - expect(countryEl.textContent).toBeTruthy(); - expect(countryEl.textContent) - .withContext(`should be ${expectedContactMetaData.address.country}`) - .toBe(expectedContactMetaData.address.country); + expectToBe(countryEl.textContent, expectedContactMetaData.address.country); }); it('... should render the address content phone information', () => { @@ -217,8 +184,7 @@ describe('AddressComponent (DONE)', () => { const expectedPhone = expectedContactMetaData.phone.label + '\xA0' + expectedContactMetaData.phone.number; - expect(phoneEl.textContent).toBeTruthy(); - expect(phoneEl.textContent).withContext(`should be ${expectedPhone}`).toBe(expectedPhone); + expectToBe(phoneEl.textContent, expectedPhone); }); it('... should render the address content email information', () => { @@ -230,14 +196,8 @@ describe('AddressComponent (DONE)', () => { ); const emailEl = emailDes[0].nativeElement; - expect(emailEl.href).toBeTruthy(); - expect(emailEl.href) - .withContext(`should be ${expectedContactMetaData.email.mailto}`) - .toBe(expectedContactMetaData.email.mailto); - expect(emailEl.textContent).toBeTruthy(); - expect(emailEl.textContent) - .withContext(`should be ${expectedContactMetaData.email.safeString}`) - .toBe(expectedContactMetaData.email.safeString); + expectToBe(emailEl.href, expectedContactMetaData.email.mailto); + expectToBe(emailEl.textContent, expectedContactMetaData.email.safeString); }); }); }); diff --git a/src/app/shared/codemirror/codemirror.component.spec.ts b/src/app/shared/codemirror/codemirror.component.spec.ts index 7b56ea822..1f61cbf16 100644 --- a/src/app/shared/codemirror/codemirror.component.spec.ts +++ b/src/app/shared/codemirror/codemirror.component.spec.ts @@ -8,7 +8,7 @@ import { sparql } from '@codemirror/legacy-modes/mode/sparql'; import { EditorState, EditorStateConfig, Extension } from '@codemirror/state'; import { basicSetup } from 'codemirror'; -import { expectSpyCall, getAndExpectDebugElementByCss } from '@testing/expect-helper'; +import { expectSpyCall, expectToBe, expectToEqual, getAndExpectDebugElementByCss } from '@testing/expect-helper'; import { CmMode, CodeMirrorComponent } from './codemirror.component'; @@ -70,7 +70,7 @@ describe('CodemirrorComponent', () => { describe('VIEW', () => { it('... should contain one div.codemirrorhost', () => { // Div debug element - const accordionDes = getAndExpectDebugElementByCss(compDe, 'div.codemirrorhost', 1, 1); + getAndExpectDebugElementByCss(compDe, 'div.codemirrorhost', 1, 1); }); }); }); @@ -86,13 +86,11 @@ describe('CodemirrorComponent', () => { }); it('... should have mode', () => { - expect(component.mode).toBeDefined(); - expect(component.mode).withContext(`should equal ${expectedMode}`).toEqual(expectedMode); + expectToEqual(component.mode, expectedMode); }); it('... should have content', () => { - expect(component.content).toBeDefined(); - expect(component.content).withContext(`should equal ${expectedContent}`).toEqual(expectedContent); + expectToBe(component.content, expectedContent); }); describe('#init()', () => { @@ -111,17 +109,13 @@ describe('CodemirrorComponent', () => { fixture.detectChanges(); expectSpyCall(initSpy, 2, expectedState); - expect(component.editor.state).toBeDefined(); - expect(component.editor.state).withContext(`should equal ${expectedState}`).toEqual(expectedState); + expectToEqual(component.editor.state, expectedState); }); it('... should init the editor with the correct content if given', () => { expectSpyCall(initSpy, 1); - expect(component.editor.state.doc.toString()).toBeDefined(); - expect(component.editor.state.doc.toString()) - .withContext(`should equal ${expectedContent}`) - .toEqual(expectedContent); + expectToBe(component.editor.state.doc.toString(), expectedContent); }); it('... should init an empty editor if no content is given', () => { @@ -132,8 +126,7 @@ describe('CodemirrorComponent', () => { fixture.detectChanges(); expectSpyCall(initSpy, 1); - expect(component.editor.state.doc.toString()).toBeDefined(); - expect(component.editor.state.doc.toString()).withContext(`should equal ''`).toEqual(''); + expectToBe(component.editor.state.doc.toString(), ''); }); }); diff --git a/src/app/shared/error-alert/error-alert.component.html b/src/app/shared/error-alert/error-alert.component.html new file mode 100644 index 000000000..b305535d4 --- /dev/null +++ b/src/app/shared/error-alert/error-alert.component.html @@ -0,0 +1,5 @@ +
+
+
{{ errorObject | json }}
+
+
diff --git a/src/app/views/edition-view/edition-outlets/edition-type/edition-type.component.scss b/src/app/shared/error-alert/error-alert.component.scss similarity index 100% rename from src/app/views/edition-view/edition-outlets/edition-type/edition-type.component.scss rename to src/app/shared/error-alert/error-alert.component.scss diff --git a/src/app/shared/error-alert/error-alert.component.spec.ts b/src/app/shared/error-alert/error-alert.component.spec.ts new file mode 100644 index 000000000..8268c9f27 --- /dev/null +++ b/src/app/shared/error-alert/error-alert.component.spec.ts @@ -0,0 +1,77 @@ +import { JsonPipe } from '@angular/common'; +import { DebugElement } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { expectToBe, expectToContain, getAndExpectDebugElementByCss } from '@testing/expect-helper'; + +import { ErrorAlertComponent } from './error-alert.component'; + +describe('ErrorAlertComponent', () => { + let component: ErrorAlertComponent; + let fixture: ComponentFixture; + let compDe: DebugElement; + + let expectedErrorObject: any; + + const jsonPipe = new JsonPipe(); + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ErrorAlertComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(ErrorAlertComponent); + component = fixture.componentInstance; + compDe = fixture.debugElement; + + // Test data + expectedErrorObject = { status: 404, statusText: 'got Error' }; + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + describe('BEFORE initial data binding', () => { + it('... should not have `errorObject`', () => { + expect(component.errorObject).toBeUndefined(); + }); + + describe('VIEW', () => { + it('... should have an outer div.awg-error-message', () => { + getAndExpectDebugElementByCss(compDe, 'div.awg-error-message', 1, 1); + }); + + it('... should have a centered danger alert in div.awg-error-message', () => { + const divDes = getAndExpectDebugElementByCss(compDe, 'div.awg-error-message ', 1, 1); + + getAndExpectDebugElementByCss(divDes[0], 'div.text-center > div.alert-danger', 1, 1); + }); + + it('... should not display an error message in div.alert yet', () => { + const alertDes = getAndExpectDebugElementByCss(compDe, 'div.alert-danger', 1, 1); + const alertEl = alertDes[0].nativeElement; + + expectToBe(alertEl.textContent, ''); + }); + }); + }); + + describe('AFTER initial data binding', () => { + beforeEach(() => { + component.errorObject = expectedErrorObject; + + // Trigger initial data binding + fixture.detectChanges(); + }); + + describe('VIEW', () => { + it('... should display an error message in div.alert', () => { + const alertDes = getAndExpectDebugElementByCss(compDe, 'div.alert-danger', 1, 1); + const alertEl = alertDes[0].nativeElement; + + expectToContain(alertEl.textContent, jsonPipe.transform(expectedErrorObject)); + }); + }); + }); +}); diff --git a/src/app/shared/error-alert/error-alert.component.ts b/src/app/shared/error-alert/error-alert.component.ts new file mode 100644 index 000000000..ad74ea9bd --- /dev/null +++ b/src/app/shared/error-alert/error-alert.component.ts @@ -0,0 +1,22 @@ +import { Component, Input } from '@angular/core'; + +/** + * The ErrorAlertComponent. + * + * It contains an error alert message that is + * provided via the {@link SharedModule}. + */ +@Component({ + selector: 'awg-error-alert', + templateUrl: './error-alert.component.html', + styleUrl: './error-alert.component.scss', +}) +export class ErrorAlertComponent { + /** + * Input variable: errorObject. + * + * It keeps the error object for the component. + */ + @Input() + errorObject: any; +} diff --git a/src/app/shared/external-link/external-link.directive.spec.ts b/src/app/shared/external-link/external-link.directive.spec.ts index 4785c1212..2a7483351 100644 --- a/src/app/shared/external-link/external-link.directive.spec.ts +++ b/src/app/shared/external-link/external-link.directive.spec.ts @@ -4,6 +4,7 @@ import { By } from '@angular/platform-browser'; import { cleanStylesFromDOM } from '@testing/clean-up-helper'; +import { expectToBe } from '@testing/expect-helper'; import { ExternalLinkDirective } from './external-link.directive'; @Component({ @@ -63,47 +64,33 @@ describe('ExternalLinkDirective', () => { // All elements with an attached ExternalLinkDirective (a[href]) aDes = fixture.debugElement.queryAll(By.directive(ExternalLinkDirective)); - expect(aDes).toBeDefined(); - expect(aDes.length).withContext('should be 4').toBe(4); + expectToBe(aDes.length, 4); }); it('... should have 1 anchor element without href attributes', () => { bareADes = fixture.debugElement.queryAll(By.css('a:not([href])')); - expect(bareADes).toBeDefined(); - expect(bareADes.length).withContext('should be 1').toBe(1); + expectToBe(bareADes.length, 1); }); it('... should apply [href|target|rel] values to 1st anchor element (external)', () => { aDes = fixture.debugElement.queryAll(By.directive(ExternalLinkDirective)); const aEl = aDes[0].nativeElement; - expect(aEl.href).toBeTruthy(); - expect(aEl.href).withContext(`should be ${expectedExternalLink}`).toBe(expectedExternalLink); - - expect(aEl.rel).toBeTruthy(); - expect(aEl.rel).withContext(`should be ${expectedRelAttr}`).toBe(expectedRelAttr); - - expect(aEl.target).toBeTruthy(); - expect(aEl.target).withContext(`should be ${expectedTargetAttr}`).toBe(expectedTargetAttr); - - expect(aEl.innerText).withContext('should be "Link External"').toBe('Link External'); + expectToBe(aEl.href, expectedExternalLink); + expectToBe(aEl.rel, expectedRelAttr); + expectToBe(aEl.target, expectedTargetAttr); + expectToBe(aEl.innerText, 'Link External'); }); it('... should apply [href|target|rel] values to 2nd anchor element (dynamic external)', () => { aDes = fixture.debugElement.queryAll(By.directive(ExternalLinkDirective)); const aEl = aDes[1].nativeElement; - expect(aEl.href).toBeTruthy(); - expect(aEl.href).withContext(`should be ${expectedExternalLink}`).toBe(expectedExternalLink); - - expect(aEl.rel).toBeTruthy(); - expect(aEl.rel).withContext(`should be ${expectedRelAttr}`).toBe(expectedRelAttr); - - expect(aEl.target).toBeTruthy(); - expect(aEl.target).withContext(`should be ${expectedTargetAttr}`).toBe(expectedTargetAttr); - - expect(aEl.innerText).withContext('should be "Link External Dynamic"').toBe('Link External Dynamic'); + expectToBe(aEl.href, expectedExternalLink); + expectToBe(aEl.rel, expectedRelAttr); + expectToBe(aEl.target, expectedTargetAttr); + expectToBe(aEl.innerText, 'Link External Dynamic'); }); it('... should not apply [target|rel] values to 3rd anchor element (internal)', () => { @@ -112,13 +99,10 @@ describe('ExternalLinkDirective', () => { const expectedHref = aEl.baseURI + aEl.hostname + expectedInternalLink; - expect(aEl.href).toBeTruthy(); - expect(aEl.href).withContext(`should be ${expectedHref}`).toBe(expectedHref); - - expect(aEl.rel).withContext('should be empty string').not.toBeTruthy(); - expect(aEl.target).withContext('should be empty string').not.toBeTruthy(); - - expect(aEl.innerText).withContext('should be "Link Internal"').toBe('Link Internal'); + expectToBe(aEl.href, expectedHref); + expectToBe(aEl.rel, ''); + expectToBe(aEl.target, ''); + expectToBe(aEl.innerText, 'Link Internal'); }); it('... should not apply [target|rel] values to 4th anchor element (dynamic internal)', () => { @@ -127,24 +111,19 @@ describe('ExternalLinkDirective', () => { const expectedHref = aEl.baseURI + aEl.hostname + expectedInternalLink; - expect(aEl.href).toBeTruthy(); - expect(aEl.href).withContext(`should be ${expectedHref}`).toBe(expectedHref); - - expect(aEl.rel).withContext('should be empty string').not.toBeTruthy(); - expect(aEl.target).withContext('should be empty string').not.toBeTruthy(); - - expect(aEl.innerText).withContext('should be "Link Internal Dynamic"').toBe('Link Internal Dynamic'); + expectToBe(aEl.href, expectedHref); + expectToBe(aEl.rel, ''); + expectToBe(aEl.target, ''); + expectToBe(aEl.innerText, 'Link Internal Dynamic'); }); it('... should not apply [href|target|rel] values to bare anchor', () => { bareADes = fixture.debugElement.queryAll(By.css('a:not([href])')); - expect(bareADes[0].properties['href']).withContext('should be empty string').not.toBeTruthy(); - expect(bareADes[0].properties['target']).withContext('should be empty string').not.toBeTruthy(); - expect(bareADes[0].properties['rel']).withContext('should be empty string').not.toBeTruthy(); - expect(bareADes[0].properties['innerText']) - .withContext('should be "Link without href"') - .toBe('Link without href'); + expectToBe(bareADes[0].properties['href'], ''); + expectToBe(bareADes[0].properties['target'], ''); + expectToBe(bareADes[0].properties['rel'], ''); + expectToBe(bareADes[0].properties['innerText'], 'Link without href'); }); it('... should reflect input change for [href] values', () => { @@ -156,15 +135,9 @@ describe('ExternalLinkDirective', () => { aDes = fixture.debugElement.queryAll(By.directive(ExternalLinkDirective)); const aEl = aDes[1].nativeElement; - expect(aEl.href).toBeTruthy(); - expect(aEl.href).withContext(`should be ${expectedNewExternalLink}`).toBe(expectedNewExternalLink); - - expect(aEl.rel).toBeTruthy(); - expect(aEl.rel).withContext(`should be ${expectedRelAttr}`).toBe(expectedRelAttr); - - expect(aEl.target).toBeTruthy(); - expect(aEl.target).withContext(`should be ${expectedTargetAttr}`).toBe(expectedTargetAttr); - - expect(aEl.innerText).withContext('should be "Link External Dynamic"').toBe('Link External Dynamic'); + expectToBe(aEl.href, expectedNewExternalLink); + expectToBe(aEl.rel, expectedRelAttr); + expectToBe(aEl.target, expectedTargetAttr); + expectToBe(aEl.innerText, 'Link External Dynamic'); }); }); diff --git a/src/app/shared/heading/heading.component.spec.ts b/src/app/shared/heading/heading.component.spec.ts index dbd47d027..a661e61c3 100644 --- a/src/app/shared/heading/heading.component.spec.ts +++ b/src/app/shared/heading/heading.component.spec.ts @@ -3,7 +3,7 @@ import { DebugElement } from '@angular/core'; import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { cleanStylesFromDOM } from '@testing/clean-up-helper'; -import { getAndExpectDebugElementByCss } from '@testing/expect-helper'; +import { expectToContain, getAndExpectDebugElementByCss } from '@testing/expect-helper'; import { HeadingComponent } from './heading.component'; @@ -71,11 +71,8 @@ describe('HeadingComponent (DONE)', () => { const divEl = divDes[0].nativeElement; const headerEl = headerDes[0].nativeElement; - expect(divEl.id).toBeDefined(); - expect(divEl.id).withContext(`should contain ${expectedId}`).toContain(expectedId); - - expect(headerEl.textContent).toBeDefined(); - expect(headerEl.textContent).withContext(`should contain ${expectedTitle}`).toContain(expectedTitle); + expectToContain(divEl.id, expectedId); + expectToContain(headerEl.textContent, expectedTitle); }); }); }); diff --git a/src/app/shared/json-viewer/json-viewer.component.spec.ts b/src/app/shared/json-viewer/json-viewer.component.spec.ts index df6888eec..972e0578c 100644 --- a/src/app/shared/json-viewer/json-viewer.component.spec.ts +++ b/src/app/shared/json-viewer/json-viewer.component.spec.ts @@ -6,7 +6,13 @@ import { By } from '@angular/platform-browser'; import { cleanStylesFromDOM } from '@testing/clean-up-helper'; import { click } from '@testing/click-helper'; import { detectChangesOnPush } from '@testing/detect-changes-on-push-helper'; -import { getAndExpectDebugElementByCss, getAndExpectDebugElementByDirective } from '@testing/expect-helper'; +import { + expectToBe, + expectToContain, + expectToEqual, + getAndExpectDebugElementByCss, + getAndExpectDebugElementByDirective, +} from '@testing/expect-helper'; import { NgbConfig, NgbNavLink, NgbNavModule, NgbNavOutlet } from '@ng-bootstrap/ng-bootstrap'; @@ -131,24 +137,20 @@ describe('JsonViewerComponent (DONE)', () => { getAndExpectDebugElementByCss(bodyDe[0], 'nav[ngbNav]', 1, 1); const navLinkDes = getNavLinks(fixture); - expect(navLinkDes).toBeTruthy(); - expect(navLinkDes.length).withContext('should have 2 navLinks').toBe(2); + expectToBe(navLinkDes.length, 2); }); it('... should have one Formatted and one Plain navItem and display titles', () => { const navLinks = getNavLinks(fixture); - expect(navLinks[0].textContent).toBeTruthy(); - expect(navLinks[0].textContent).withContext(`should be 'Formatted'`).toBe('Formatted'); - - expect(navLinks[1].textContent).toBeTruthy(); - expect(navLinks[1].textContent).withContext(`should be 'Plain'`).toBe('Plain'); + expectToBe(navLinks[0].textContent, 'Formatted'); + expectToBe(navLinks[1].textContent, 'Plain'); }); it('... should not render navItem content yet', () => { const navContent = getNavContents(fixture); - expect(navContent.length).withContext(`should be 0`).toBe(0); + expectToBe(navContent.length, 0); }); it('... should not contain ngx-json-viewer component (stubbed)', () => { @@ -171,7 +173,7 @@ describe('JsonViewerComponent (DONE)', () => { it('... should render navItem content and select first navItem (Formatted) by default', () => { const navContent = getNavContents(fixture); - expect(navContent.length).toBe(1); + expectToBe(navContent.length, 1); expectNavPanel(fixture, [true, false], ['content1']); }); @@ -211,8 +213,7 @@ describe('JsonViewerComponent (DONE)', () => { const viewerDes = getAndExpectDebugElementByDirective(compDe, NgxJsonViewerStubComponent, 1, 0); const viewerCmp = viewerDes[0].injector.get(NgxJsonViewerStubComponent) as NgxJsonViewerStubComponent; - expect(viewerCmp.json).toBeDefined(); - expect(viewerCmp.json).withContext(`should equal: ${expectedData}`).toEqual(expectedData); + expectToEqual(viewerCmp.json, expectedData); }); it('... should render `jsonViewerData` in Plain view', async () => { @@ -227,9 +228,8 @@ describe('JsonViewerComponent (DONE)', () => { const jsonPipe = new JsonPipe(); const pipedData = jsonPipe.transform(expectedData); - expect(navContent.length).withContext('should be 1').toBe(1); - expect(navContent[0].textContent).toBeTruthy(); - expect(navContent[0].textContent).withContext(`should contain ${pipedData}`).toContain(pipedData); + expectToBe(navContent.length, 1); + expectToContain(navContent[0].textContent, pipedData); }); }); }); diff --git a/src/app/shared/modal/modal.component.spec.ts b/src/app/shared/modal/modal.component.spec.ts index da1162c02..124a2c83d 100644 --- a/src/app/shared/modal/modal.component.spec.ts +++ b/src/app/shared/modal/modal.component.spec.ts @@ -6,7 +6,7 @@ import { ModalDismissReasons, NgbModal, NgbModalModule } from '@ng-bootstrap/ng- import Spy = jasmine.Spy; import { cleanStylesFromDOM } from '@testing/clean-up-helper'; -import { expectSpyCall, getAndExpectDebugElementByCss } from '@testing/expect-helper'; +import { expectSpyCall, expectToBe, getAndExpectDebugElementByCss } from '@testing/expect-helper'; import { CompileHtmlComponent } from '@awg-shared/compile-html'; @@ -102,21 +102,16 @@ describe('ModalComponent', () => { }); it('... should have modal title', () => { - expect(component.modalTitle).toBeDefined(); - expect(component.modalTitle).withContext(`should be ${expectedModalTitle}`).toBe(expectedModalTitle); + expectToBe(component.modalTitle, expectedModalTitle); }); it('... should have modal close label', () => { - expect(component.modalCloseLabel).toBeDefined(); - expect(component.modalCloseLabel) - .withContext(`should be ${expectedModalCloseLabel}`) - .toBe(expectedModalCloseLabel); + expectToBe(component.modalCloseLabel, expectedModalCloseLabel); }); it('... should recognize the modal template', () => { - expect(component.modalTemplate).toBeDefined(); - expect(component.modalTemplate).withContext(`should be a TemplateRef`).toBeInstanceOf(TemplateRef); - expect(component.modalTemplate).withContext(`should be a wrapperComponent.modal`).toBe(wrapperComponent.modal); + expectToBe(component.modalTemplate, wrapperComponent.modal); + expect(component.modalTemplate).toBeInstanceOf(TemplateRef); }); it('... should recognize the modal template in wrapper component', () => { @@ -146,8 +141,7 @@ describe('ModalComponent', () => { const titleDes = getAndExpectDebugElementByCss(headerDes[0], 'h4.modal-title', 1, 1); const titleEl = titleDes[0].nativeElement; - expect(titleEl).toBeDefined(); - expect(titleEl.textContent).withContext(`should be ${expectedModalTitle}`).toBe(expectedModalTitle); + expectToBe(titleEl.textContent, expectedModalTitle); }); it('... should have close button without label in div.modal-header', () => { @@ -155,8 +149,7 @@ describe('ModalComponent', () => { const buttonDes = getAndExpectDebugElementByCss(headerDes[0], 'button.btn-close', 1, 1); const buttonEl = buttonDes[0].nativeElement; - expect(buttonEl).toBeDefined(); - expect(buttonEl.textContent).withContext(`should be ''`).toBe(''); + expectToBe(buttonEl.textContent, ''); }); it('... should have one div.modal-body', () => { @@ -174,10 +167,7 @@ describe('ModalComponent', () => { const htmlSnippet = mockDocument.createElement('p'); htmlSnippet.innerHTML = EXPECTED_MODAL_CONTENT_SNIPPETS[expectedSnippetKey1]; - expect(bodyEl).toBeDefined(); - expect(bodyEl.textContent.trim()) - .withContext(`should be ${htmlSnippet.textContent.trim()}`) - .toBe(htmlSnippet.textContent.trim()); + expectToBe(bodyEl.textContent.trim(), htmlSnippet.textContent.trim()); }); it('... should have one div.modal-footer', () => { @@ -194,10 +184,7 @@ describe('ModalComponent', () => { const buttonDes = getAndExpectDebugElementByCss(footerDes[0], 'button.awg-modal-button', 1, 1); const buttonEl = buttonDes[0].nativeElement; - expect(buttonEl).toBeDefined(); - expect(buttonEl.textContent.trim()) - .withContext(`should be ${expectedModalCloseLabel}`) - .toBe(expectedModalCloseLabel); + expectToBe(buttonEl.textContent.trim(), expectedModalCloseLabel); }); }); @@ -217,26 +204,19 @@ describe('ModalComponent', () => { }); it('... should set the correct modal content if snippet is known', () => { - expect(component.modalContent).toBeDefined(); - expect(component.modalContent) - .withContext(` should be ${EXPECTED_MODAL_CONTENT_SNIPPETS[expectedSnippetKey1]}`) - .toBe(EXPECTED_MODAL_CONTENT_SNIPPETS[expectedSnippetKey1]); + expectToBe(component.modalContent, EXPECTED_MODAL_CONTENT_SNIPPETS[expectedSnippetKey1]); component.open(expectedSnippetKey2); fixture.detectChanges(); - expect(component.modalContent).toBeDefined(); - expect(component.modalContent) - .withContext(` should be ${EXPECTED_MODAL_CONTENT_SNIPPETS[expectedSnippetKey2]}`) - .toBe(EXPECTED_MODAL_CONTENT_SNIPPETS[expectedSnippetKey2]); + expectToBe(component.modalContent, EXPECTED_MODAL_CONTENT_SNIPPETS[expectedSnippetKey2]); }); it('... should set the modal content to empty string if snippet is unknown', () => { component.open(expectedUnknownSnippetKey); fixture.detectChanges(); - expect(component.modalContent).toBeDefined(); - expect(component.modalContent).withContext(`should be empty string`).toBe(''); + expectToBe(component.modalContent, ''); }); it('... should return the close result of the modal', async () => { @@ -251,8 +231,7 @@ describe('ModalComponent', () => { ngbModal.open(component.modalTemplate, { ariaLabelledBy: 'awg-modal' }).result ).toBeResolvedTo(closeMessage); - expect(component.closeResult).toBeDefined(); - expect(component.closeResult).toBe(expectedCloseResult); + expectToBe(component.closeResult, expectedCloseResult); }); describe('should return the dismiss reason of the modal', async () => { @@ -268,10 +247,7 @@ describe('ModalComponent', () => { ngbModal.open(component.modalTemplate, { ariaLabelledBy: 'awg-modal' }).result ).toBeRejectedWith(dismissEvent); - expect(component.closeResult).toBeDefined(); - expect(component.closeResult) - .withContext(`should be ${expectedDismissReason}`) - .toBe(expectedDismissReason); + expectToBe(component.closeResult, expectedDismissReason); }); it('... when pressing ESC key', async () => { @@ -286,10 +262,7 @@ describe('ModalComponent', () => { ngbModal.open(component.modalTemplate, { ariaLabelledBy: 'awg-modal' }).result ).toBeRejectedWith(dismissEvent); - expect(component.closeResult).toBeDefined(); - expect(component.closeResult) - .withContext(`should be ${expectedDismissReason}`) - .toBe(expectedDismissReason); + expectToBe(component.closeResult, expectedDismissReason); }); it('... when clicking on backdrop', async () => { @@ -304,10 +277,7 @@ describe('ModalComponent', () => { ngbModal.open(component.modalTemplate, { ariaLabelledBy: 'awg-modal' }).result ).toBeRejectedWith(dismissEvent); - expect(component.closeResult).toBeDefined(); - expect(component.closeResult) - .withContext(`should be ${expectedDismissReason}`) - .toBe(expectedDismissReason); + expectToBe(component.closeResult, expectedDismissReason); }); }); }); diff --git a/src/app/shared/open-street-map/open-street-map.component.spec.ts b/src/app/shared/open-street-map/open-street-map.component.spec.ts index a6e8c796d..7c19c5ccb 100644 --- a/src/app/shared/open-street-map/open-street-map.component.spec.ts +++ b/src/app/shared/open-street-map/open-street-map.component.spec.ts @@ -104,16 +104,14 @@ describe('OpenStreetMapComponent (DONE)', () => { const mapDes = getAndExpectDebugElementByCss(compDe, 'iframe#awg-osm-embed-map', 1, 1); const mapEl = mapDes[0].nativeElement; - expect(mapEl.src).toBeDefined(); - expect(mapEl.src).toBeFalsy(); + expectToBe(mapEl.src, ''); }); it('... should not have the link to OSM homepage yet', () => { const linkDes = getAndExpectDebugElementByCss(compDe, 'div#awg-osm-link a', 1, 1); const linkEl = linkDes[0].nativeElement; - expect(linkEl.href).toBeDefined(); - expect(linkEl.href).toBeFalsy(); + expectToBe(linkEl.href, ''); }); }); }); diff --git a/src/app/shared/order-by-pipe/order-by.pipe.spec.ts b/src/app/shared/order-by-pipe/order-by.pipe.spec.ts index 39c4b051a..ce8ae372c 100644 --- a/src/app/shared/order-by-pipe/order-by.pipe.spec.ts +++ b/src/app/shared/order-by-pipe/order-by.pipe.spec.ts @@ -390,13 +390,14 @@ describe('OrderByPipe (DONE)', () => { const parse = value => parseInt(value.replace(/[^0-9]/g, ''), 10); - expect( + expectToEqual( pipe.transform(arr, null, false, true, (a, b) => { const newA = parse(a); const newB = parse(b); return newA > newB ? 1 : -1; - }) - ).toEqual(res); + }), + res + ); }); describe('test not valid values for comparator', () => { diff --git a/src/app/shared/router-link-button-group/router-link-button-group.component.spec.ts b/src/app/shared/router-link-button-group/router-link-button-group.component.spec.ts index aaab3302d..40e3a4722 100644 --- a/src/app/shared/router-link-button-group/router-link-button-group.component.spec.ts +++ b/src/app/shared/router-link-button-group/router-link-button-group.component.spec.ts @@ -203,7 +203,7 @@ describe('RouterLinkButtonGroupComponent (DONE)', () => { const fulltextLinkDe = linkDes[0]; // Fulltext link DebugElement const fulltextLink = routerLinks[0]; // Fulltext link directive - expect(fulltextLink.navigatedTo).toBeNull(); + expectToBe(fulltextLink.navigatedTo, null); click(fulltextLinkDe); fixture.detectChanges(); @@ -216,7 +216,7 @@ describe('RouterLinkButtonGroupComponent (DONE)', () => { const linkDe = linkDes[index]; const expectedRouterLink = expectedOrderOfRouterlinks[index]; - expect(routerLink.navigatedTo).toBeNull(); + expectToBe(routerLink.navigatedTo, null); click(linkDe); fixture.detectChanges(); diff --git a/src/app/shared/scroll-to-top/scroll-to-top.component.html b/src/app/shared/scroll-to-top/scroll-to-top.component.html new file mode 100644 index 000000000..5f6a3b49a --- /dev/null +++ b/src/app/shared/scroll-to-top/scroll-to-top.component.html @@ -0,0 +1,5 @@ +@if (isScrolled) { + +} diff --git a/src/app/shared/scroll-to-top/scroll-to-top.component.scss b/src/app/shared/scroll-to-top/scroll-to-top.component.scss new file mode 100644 index 000000000..9a2d5a5ae --- /dev/null +++ b/src/app/shared/scroll-to-top/scroll-to-top.component.scss @@ -0,0 +1,13 @@ +.awg-scroll-to-top { + position: fixed; + bottom: 30px; + right: 30px; + text-align: right; + color: white; + z-index: 1000; + + &:hover { + cursor: pointer; + color: #f0f0f0; + } +} diff --git a/src/app/shared/scroll-to-top/scroll-to-top.component.spec.ts b/src/app/shared/scroll-to-top/scroll-to-top.component.spec.ts new file mode 100644 index 000000000..bd4b83a47 --- /dev/null +++ b/src/app/shared/scroll-to-top/scroll-to-top.component.spec.ts @@ -0,0 +1,198 @@ +import { DebugElement } from '@angular/core'; +import { ComponentFixture, fakeAsync, TestBed, waitForAsync } from '@angular/core/testing'; + +import Spy = jasmine.Spy; + +import { FontAwesomeTestingModule } from '@fortawesome/angular-fontawesome/testing'; +import { faArrowUp, IconDefinition } from '@fortawesome/free-solid-svg-icons'; + +import { cleanStylesFromDOM } from '@testing/clean-up-helper'; +import { clickAndAwaitChanges } from '@testing/click-helper'; +import { detectChangesOnPush } from '@testing/detect-changes-on-push-helper'; +import { expectSpyCall, expectToBe, expectToEqual, getAndExpectDebugElementByCss } from '@testing/expect-helper'; + +import { ScrollToTopComponent } from './scroll-to-top.component'; + +describe('ScrollToTopComponent (DONE)', () => { + let component: ScrollToTopComponent; + let fixture: ComponentFixture; + let compDe: DebugElement; + + let scrollToTopSpy: Spy; + + let expectedScrollThreshold: number; + let expectedArrowIcon: IconDefinition; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + imports: [FontAwesomeTestingModule], + declarations: [ScrollToTopComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(ScrollToTopComponent); + component = fixture.componentInstance; + compDe = fixture.debugElement; + + // Trigger initial data binding + fixture.detectChanges(); + + // Test data + expectedScrollThreshold = 300; + expectedArrowIcon = faArrowUp; + + // Spies on component functions + // `.and.callThrough` will track the spy down the nested describes, see + // https://jasmine.github.io/2.0/introduction.html#section-Spies:_%3Ccode%3Eand.callThrough%3C/code%3E + scrollToTopSpy = spyOn(component, 'scrollToTop').and.callThrough(); + })); + + afterAll(() => { + cleanStylesFromDOM(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('... should have `faArrowUp`', () => { + expectToEqual(component.faArrowUp, faArrowUp); + }); + + it('... should not have `isScrolled`', () => { + expect(component.isScrolled).toBeUndefined(); + }); + + describe('#VIEW', () => { + describe('... should contain no button.awg-scroll-to-top if', () => { + it('... isScrolled is undefined', () => { + component.isScrolled = undefined; + detectChangesOnPush(fixture); + + getAndExpectDebugElementByCss(compDe, 'button.awg-scroll-to-top', 0, 0); + }); + + it('... isScrolled is false', () => { + component.isScrolled = false; + detectChangesOnPush(fixture); + + getAndExpectDebugElementByCss(compDe, 'button.awg-scroll-to-top', 0, 0); + }); + }); + + describe('... with isScrolled set to true', () => { + beforeEach(() => { + component.isScrolled = true; + detectChangesOnPush(fixture); + }); + + it('... should contain one button.awg-scroll-to-top if isScrolled is true', () => { + getAndExpectDebugElementByCss(compDe, 'button.awg-scroll-to-top', 1, 1); + }); + + it('... should display arrow icon in scroll button ', () => { + const btnDes = getAndExpectDebugElementByCss(compDe, 'button.awg-scroll-to-top', 1, 1); + const faIconDes = getAndExpectDebugElementByCss(btnDes[0], 'fa-icon', 1, 1); + const faIconIns = faIconDes[0].componentInstance.icon; + + expectToEqual(faIconIns, expectedArrowIcon); + }); + + it('... should trigger `scrollToTop` method on button click', fakeAsync(() => { + const btnDes = getAndExpectDebugElementByCss(compDe, 'button.awg-scroll-to-top', 1, 1); + + // Trigger click with click helper & wait for changes + clickAndAwaitChanges(btnDes[0], fixture); + + expectSpyCall(scrollToTopSpy, 1); + })); + }); + }); + + describe('#Hostlistener checkScroll()', () => { + it('... should have a hostlistener `checkScroll`', () => { + expect(component.checkScroll).toBeDefined(); + }); + + it('... should default to 0 if window.scrollY is undefined', () => { + const scrollEventBelowThreshold = new Event('scroll') as any; + Object.defineProperty(scrollEventBelowThreshold, 'currentTarget', { + value: { scrollY: undefined }, + writable: true, + }); + component.checkScroll(scrollEventBelowThreshold); + + expectToBe(component.isScrolled, false); + }); + + it('... should set `isScrolled` to true if scrollY is above threshold', () => { + const scrollEventAboveThreshold = new Event('scroll') as any; + Object.defineProperty(scrollEventAboveThreshold, 'currentTarget', { + value: { scrollY: expectedScrollThreshold + 1 }, + writable: true, + }); + component.checkScroll(scrollEventAboveThreshold); + + expectToBe(component.isScrolled, true); + }); + + it('... should set `isScrolled` to false if scrollY is below threshold', () => { + const scrollEventBelowThreshold = new Event('scroll') as any; + Object.defineProperty(scrollEventBelowThreshold, 'currentTarget', { + value: { scrollY: expectedScrollThreshold - 1 }, + writable: true, + }); + component.checkScroll(scrollEventBelowThreshold); + + expectToBe(component.isScrolled, false); + }); + + it('... should toggle `isScrolled` based on scrollY position of scroll event', () => { + const scrollEventBelowThreshold = new Event('scroll') as any; + Object.defineProperty(scrollEventBelowThreshold, 'currentTarget', { + value: { scrollY: expectedScrollThreshold - 1 }, + writable: true, + }); + component.checkScroll(scrollEventBelowThreshold); + + expectToBe(component.isScrolled, false); + + const scrollEventAboveThreshold = new Event('scroll'); + Object.defineProperty(scrollEventAboveThreshold, 'currentTarget', { + value: { scrollY: expectedScrollThreshold + 1 }, + writable: true, + }); + component.checkScroll(scrollEventAboveThreshold); + + expectToBe(component.isScrolled, true); + }); + }); + + describe('#scrollToTop()', () => { + it('... should have a method `scrollToTop`', () => { + expect(component.scrollToTop).toBeDefined(); + }); + + it('... should trigger window:scrollTo with correct parameters', () => { + const scrollToSpy = spyOn(window, 'scrollTo'); + + component.scrollToTop(); + + expectSpyCall(scrollToSpy, 1, { top: 0, behavior: 'smooth' }); + }); + + it('... should scroll to top of page', () => { + const scrollEventBelowThreshold = new Event('scroll') as any; + Object.defineProperty(scrollEventBelowThreshold, 'currentTarget', { + value: { scrollY: expectedScrollThreshold + 1 }, + writable: true, + }); + component.checkScroll(scrollEventBelowThreshold); + + expectToBe(component.isScrolled, true); + + component.scrollToTop(); + + expectToBe(window.scrollY, 0); + }); + }); +}); diff --git a/src/app/shared/scroll-to-top/scroll-to-top.component.ts b/src/app/shared/scroll-to-top/scroll-to-top.component.ts new file mode 100644 index 000000000..6fc26f755 --- /dev/null +++ b/src/app/shared/scroll-to-top/scroll-to-top.component.ts @@ -0,0 +1,56 @@ +import { ChangeDetectionStrategy, Component, HostListener } from '@angular/core'; + +import { faArrowUp } from '@fortawesome/free-solid-svg-icons'; + +/** + * The ScrollToTop component. + * + * It contains the scroll-to-top button + * that is provided via the {@link SharedModule}. + */ +@Component({ + selector: 'awg-scroll-to-top', + templateUrl: './scroll-to-top.component.html', + styleUrl: './scroll-to-top.component.scss', + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class ScrollToTopComponent { + /** + * Public variable: faArrowUp. + * + * It instantiates fontawesome's faArrowUp icon. + */ + faArrowUp = faArrowUp; + + /** + * Public variable: isScrolled. + * + * It keeps track of the visibility of the scroll-to-top button. + */ + isScrolled: boolean; + + /** + * HostListener: checkScroll. + * + * It checks the scroll position on the document and + * sets the visibility of the scroll-to-top button. + */ + @HostListener('window:scroll', ['$event']) checkScroll(event: Event) { + const window = event.currentTarget as Window; + const scrollPosition = window.scrollY || 0; + const SCROLL_THRESHOLD = 300; + + this.isScrolled = scrollPosition >= SCROLL_THRESHOLD; + } + + /** + * Public method: scrollToTop. + * + * It scrolls to the top of the page. + * + * @returns {void} Scrolls to the top of the page. + */ + scrollToTop(): void { + window.scrollTo({ top: 0, behavior: 'smooth' }); + } +} diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index 9ea343ed7..3691fa79c 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -15,12 +15,14 @@ import { CompileHtmlModule } from './compile-html'; // // Shared components import { AddressComponent } from './address/address.component'; +import { ErrorAlertComponent } from './error-alert/error-alert.component'; import { HeadingComponent } from './heading/heading.component'; import { JsonViewerComponent } from './json-viewer/json-viewer.component'; import { LicenseComponent } from './license/license.component'; import { ModalComponent } from './modal/modal.component'; import { OpenStreetMapComponent } from './open-street-map/open-street-map.component'; import { RouterLinkButtonGroupComponent } from './router-link-button-group/router-link-button-group.component'; +import { ScrollToTopComponent } from './scroll-to-top/scroll-to-top.component'; import { TablePaginationComponent } from './table/table-pagination/table-pagination.component'; import { TableComponent } from './table/table.component'; import { ToastComponent } from './toast/toast.component'; @@ -55,12 +57,14 @@ import { OrderByPipe } from './order-by-pipe/order-by.pipe'; ], declarations: [ AddressComponent, + ErrorAlertComponent, HeadingComponent, JsonViewerComponent, LicenseComponent, ModalComponent, OpenStreetMapComponent, RouterLinkButtonGroupComponent, + ScrollToTopComponent, TableComponent, TablePaginationComponent, ToastComponent, @@ -82,12 +86,14 @@ import { OrderByPipe } from './order-by-pipe/order-by.pipe'; SharedNgbootstrapModule, AddressComponent, + ErrorAlertComponent, HeadingComponent, JsonViewerComponent, LicenseComponent, ModalComponent, OpenStreetMapComponent, RouterLinkButtonGroupComponent, + ScrollToTopComponent, TableComponent, ToastComponent, TwelveToneSpinnerComponent, diff --git a/src/app/shared/table/table-pagination/table-pagination.component.spec.ts b/src/app/shared/table/table-pagination/table-pagination.component.spec.ts index ce72fc3cb..56f765ae5 100644 --- a/src/app/shared/table/table-pagination/table-pagination.component.spec.ts +++ b/src/app/shared/table/table-pagination/table-pagination.component.spec.ts @@ -7,6 +7,8 @@ import { NgbConfig, NgbPagination, NgbPaginationModule } from '@ng-bootstrap/ng- import { expectSpyCall, + expectToBe, + expectToEqual, getAndExpectDebugElementByCss, getAndExpectDebugElementByDirective, } from '@testing/expect-helper'; @@ -78,9 +80,7 @@ describe('TablePaginationComponent (DONE)', () => { }); it('... should have FILTER_PAG_REGEX', () => { - expect(component.FILTER_PAG_REGEX).toBeDefined(); - - expect(component.FILTER_PAG_REGEX).withContext(`should equal /\\D/g`).toEqual(/\D/g); + expectToEqual(component.FILTER_PAG_REGEX, /\D/g); }); it('... should not have called formatInput', () => { @@ -118,15 +118,11 @@ describe('TablePaginationComponent (DONE)', () => { }); it('... should have collectionSize', () => { - expect(component.collectionSize).toBeDefined(); - expect(component.collectionSize) - .withContext(`should equal ${expectedCollectionSize}`) - .toEqual(expectedCollectionSize); + expectToBe(component.collectionSize, expectedCollectionSize); }); it('... should have page', () => { - expect(component.page).toBeDefined(); - expect(component.page).withContext(`should equal ${expectedPage}`).toEqual(expectedPage); + expectToBe(component.page, expectedPage); }); describe('VIEW', () => { @@ -201,8 +197,7 @@ describe('TablePaginationComponent (DONE)', () => { const labelDe = getAndExpectDebugElementByCss(divDe[0], 'label#paginationInputLabel', 1, 1); const labelEl = labelDe[0].nativeElement; - expect(labelEl.textContent).toBeTruthy(); - expect(labelEl.textContent).withContext(`should be ${expectedLabel}`).toBe(expectedLabel); + expectToBe(labelEl.textContent, expectedLabel); }); it('... should display recent page in input', () => { @@ -217,8 +212,7 @@ describe('TablePaginationComponent (DONE)', () => { ); const inputEl = inputDe[0].nativeElement; - expect(inputEl.value).toBeTruthy(); - expect(inputEl.value).withContext(`should be ${expectedInputValue}`).toBe(expectedInputValue); + expectToBe(inputEl.value, expectedInputValue); }); it('... should display `von pages.length` in span', () => { @@ -230,8 +224,7 @@ describe('TablePaginationComponent (DONE)', () => { const spanDe = getAndExpectDebugElementByCss(divDe[0], 'span#paginationDescription', 1, 1); const spanEl = spanDe[0].nativeElement; - expect(spanEl.textContent).toBeTruthy(); - expect(spanEl.textContent.trim()).withContext(`should be ${expectedSpanText}`).toBe(expectedSpanText); + expectToBe(spanEl.textContent.trim(), expectedSpanText); }); }); @@ -257,7 +250,7 @@ describe('TablePaginationComponent (DONE)', () => { input.value = '3'; component.replaceNonNumberInput(input); - expect(input.value).toBe('3'); + expectToBe(input.value, '3'); }); it('... by replacing non-numbers with empty string', () => { @@ -265,7 +258,7 @@ describe('TablePaginationComponent (DONE)', () => { input.value = 'Test'; component.replaceNonNumberInput(input); - expect(input.value).toBe(''); + expectToBe(input.value, ''); }); }); }); @@ -341,8 +334,7 @@ describe('TablePaginationComponent (DONE)', () => { component.selectPage(expectedNewPage.toString()); - expect(component.page).toBeTruthy(); - expect(component.page).withContext(`should be ${expectedNewPage}`).toBe(expectedNewPage); + expectToBe(component.page, expectedNewPage); }); it('... to 1 if the given value cannot be parsed to an integer', () => { @@ -350,29 +342,25 @@ describe('TablePaginationComponent (DONE)', () => { component.selectPage(expectedNewPage); - expect(component.page).toBeTruthy(); - expect(component.page).withContext(`should be 1`).toBe(1); + expectToBe(component.page, 1); const expectedNewPage2 = 'NaN'; component.selectPage(expectedNewPage2); - expect(component.page).toBeTruthy(); - expect(component.page).withContext(`should be 1`).toBe(1); + expectToBe(component.page, 1); const expectedNewPage3 = '_123'; component.selectPage(expectedNewPage3); - expect(component.page).toBeTruthy(); - expect(component.page).withContext(`should be 1`).toBe(1); + expectToBe(component.page, 1); }); it('... to 1 if the given value is undefined', () => { component.selectPage(undefined); - expect(component.page).toBeTruthy(); - expect(component.page).withContext(`should be 1`).toBe(1); + expectToBe(component.page, 1); }); }); }); diff --git a/src/app/shared/table/table.component.spec.ts b/src/app/shared/table/table.component.spec.ts index b2bd59f47..2241d9374 100644 --- a/src/app/shared/table/table.component.spec.ts +++ b/src/app/shared/table/table.component.spec.ts @@ -165,8 +165,8 @@ describe('TableComponent', () => { }); it('... should have faSortUp and faSortDown icons', () => { - expectToBe(component.faSortUp, faSortUp); - expectToBe(component.faSortDown, faSortDown); + expectToEqual(component.faSortUp, faSortUp); + expectToEqual(component.faSortDown, faSortDown); }); it('... should have tableOptions', () => { @@ -244,14 +244,10 @@ describe('TableComponent', () => { expectToEqual(component.tableData.filteredRows, expectedRowInputData); expect(component.tableData.paginatedRows$).toBeDefined(); - expectAsync(lastValueFrom(component.tableData.paginatedRows$)) - .withContext(`should be resolved to ${expectedRowInputData}`) - .toBeResolvedTo(expectedRowInputData); + expectAsync(lastValueFrom(component.tableData.paginatedRows$)).toBeResolvedTo(expectedRowInputData); expect(component.tableData.totalRows$).toBeDefined(); - expectAsync(lastValueFrom(component.tableData.totalRows$)) - .withContext(`should be resolved to ${expectedRowInputData}`) - .toBeResolvedTo(expectedRowInputData); + expectAsync(lastValueFrom(component.tableData.totalRows$)).toBeResolvedTo(expectedRowInputData); })); describe('... to empty object', () => { @@ -268,14 +264,10 @@ describe('TableComponent', () => { expectToEqual(component.tableData.filteredRows, []); expect(component.tableData.paginatedRows$).toBeDefined(); - expectAsync(lastValueFrom(component.tableData.paginatedRows$)) - .withContext(`should be resolved to []`) - .toBeResolvedTo([]); + expectAsync(lastValueFrom(component.tableData.paginatedRows$)).toBeResolvedTo([]); expect(component.tableData.totalRows$).toBeDefined(); - expectAsync(lastValueFrom(component.tableData.totalRows$)) - .withContext(`should be resolved to []`) - .toBeResolvedTo([]); + expectAsync(lastValueFrom(component.tableData.totalRows$)).toBeResolvedTo([]); })); it('... if rowInputData is not given', waitForAsync(() => { @@ -291,14 +283,10 @@ describe('TableComponent', () => { expectToEqual(component.tableData.filteredRows, []); expect(component.tableData.paginatedRows$).toBeDefined(); - expectAsync(lastValueFrom(component.tableData.paginatedRows$)) - .withContext(`should be resolved to []`) - .toBeResolvedTo([]); + expectAsync(lastValueFrom(component.tableData.paginatedRows$)).toBeResolvedTo([]); expect(component.tableData.totalRows$).toBeDefined(); - expectAsync(lastValueFrom(component.tableData.totalRows$)) - .withContext(`should be resolved to []`) - .toBeResolvedTo([]); + expectAsync(lastValueFrom(component.tableData.totalRows$)).toBeResolvedTo([]); })); it('... if both headerInputData and rowInputData are not given', waitForAsync(() => { @@ -314,14 +302,10 @@ describe('TableComponent', () => { expectToEqual(component.tableData.filteredRows, []); expect(component.tableData.paginatedRows$).toBeDefined(); - expectAsync(lastValueFrom(component.tableData.paginatedRows$)) - .withContext(`should be resolved to []`) - .toBeResolvedTo([]); + expectAsync(lastValueFrom(component.tableData.paginatedRows$)).toBeResolvedTo([]); expect(component.tableData.totalRows$).toBeDefined(); - expectAsync(lastValueFrom(component.tableData.totalRows$)) - .withContext(`should be resolved to []`) - .toBeResolvedTo([]); + expectAsync(lastValueFrom(component.tableData.totalRows$)).toBeResolvedTo([]); })); }); }); @@ -375,18 +359,14 @@ describe('TableComponent', () => { // First call happens on ngOnInit() expectSpyCall(onPageSizeChangeSpy, 2, expectedSearchFilter); - expect(component.searchFilter).toBeDefined(); - expect(component.searchFilter) - .withContext(`should equal ${expectedSearchFilter}`) - .toBe(expectedSearchFilter); + expectToBe(component.searchFilter, expectedSearchFilter); inputEl.value = otherSearchFilter; inputEl.dispatchEvent(new Event('input')); fixture.detectChanges(); expectSpyCall(onPageSizeChangeSpy, 3, otherSearchFilter); - expect(component.searchFilter).toBeDefined(); - expect(component.searchFilter).withContext(`should equal ${otherSearchFilter}`).toBe(otherSearchFilter); + expectToBe(component.searchFilter, otherSearchFilter); }); it('... should trigger on change of selectedPageSize in upper dropdown menu', fakeAsync(() => { @@ -575,14 +555,10 @@ describe('TableComponent', () => { expectToEqual(component.tableData.filteredRows, []); expect(component.tableData.paginatedRows$).toBeDefined(); - await expectAsync(lastValueFrom(component.tableData.paginatedRows$)) - .withContext(`should be resolved to []`) - .toBeResolvedTo([]); + await expectAsync(lastValueFrom(component.tableData.paginatedRows$)).toBeResolvedTo([]); expect(component.tableData.totalRows$).toBeDefined(); - await expectAsync(lastValueFrom(component.tableData.totalRows$)) - .withContext(`should be resolved to []`) - .toBeResolvedTo([]); + await expectAsync(lastValueFrom(component.tableData.totalRows$)).toBeResolvedTo([]); }); }); @@ -596,9 +572,7 @@ describe('TableComponent', () => { expect(component.tableData).toBeDefined(); expectAsync(lastValueFrom(component.tableData.paginatedRows$)).toBeResolved(); - expectAsync(lastValueFrom(component.tableData.paginatedRows$)) - .withContext(`should be resolved to ${expectedPaginatedRows}`) - .toBeResolvedTo(expectedPaginatedRows); + expectAsync(lastValueFrom(component.tableData.paginatedRows$)).toBeResolvedTo(expectedPaginatedRows); })); describe('should not do anything', () => { diff --git a/src/app/shared/toast/toast.component.spec.ts b/src/app/shared/toast/toast.component.spec.ts index c50d50d0f..c44329d17 100644 --- a/src/app/shared/toast/toast.component.spec.ts +++ b/src/app/shared/toast/toast.component.spec.ts @@ -1,7 +1,7 @@ import { Component, DebugElement, EventEmitter, Input, Output, TemplateRef, ViewChild } from '@angular/core'; import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { getAndExpectDebugElementByDirective } from '@testing/expect-helper'; +import { expectToBe, expectToEqual, getAndExpectDebugElementByDirective } from '@testing/expect-helper'; import { ToastComponent } from './toast.component'; import { Toast, ToastService } from './toast.service'; @@ -24,7 +24,7 @@ class NgbToastStubComponent { @Input() autohide: string; @Input() - delay: string; + delay: number; @Output() hide: EventEmitter = new EventEmitter(); } @@ -81,8 +81,8 @@ describe('ToastComponent (DONE)', () => { it('... should have added one toast to toast service', () => { expect(toastService.toasts).toBeDefined(); - expect(toastService.toasts.length).withContext(`should be 1`).toBe(1); - expect(toastService.toasts[0]).withContext(`should equal ${expectedToast}`).toEqual(expectedToast); + expectToBe(toastService.toasts.length, 1); + expectToEqual(toastService.toasts[0], expectedToast); }); describe('VIEW', () => { @@ -94,38 +94,28 @@ describe('ToastComponent (DONE)', () => { const toastDes = getAndExpectDebugElementByDirective(compDe, NgbToastStubComponent, 1, 1); const toastCmp = toastDes[0].injector.get(NgbToastStubComponent) as NgbToastStubComponent; - expect(toastCmp.header).toBeDefined(); - expect(toastCmp.header) - .withContext(`should be ${expectedToast.options.header}`) - .toBe(expectedToast.options.header); + expectToBe(toastCmp.header, expectedToast.options.header); }); it('... should pass down classname to ngb-toast component (stubbed) if given', () => { const toastDes = getAndExpectDebugElementByDirective(compDe, NgbToastStubComponent, 1, 1); const toastCmp = toastDes[0].injector.get(NgbToastStubComponent) as NgbToastStubComponent; - expect(toastCmp.class).toBeDefined(); - expect(toastCmp.class) - .withContext(`should be ${expectedToast.options.classname}`) - .toBe(expectedToast.options.classname); + expectToBe(toastCmp.class, expectedToast.options.classname); }); it('... should pass down autohide=true to ngb-toast component (stubbed)', () => { const toastDes = getAndExpectDebugElementByDirective(compDe, NgbToastStubComponent, 1, 1); const toastCmp = toastDes[0].injector.get(NgbToastStubComponent) as NgbToastStubComponent; - expect(toastCmp.autohide).toBeDefined(); - expect(toastCmp.autohide).toBeTrue(); + expectToBe(toastCmp.autohide, true); }); it('... should pass down delay to ngb-toast component (stubbed)', () => { const toastDes = getAndExpectDebugElementByDirective(compDe, NgbToastStubComponent, 1, 1); const toastCmp = toastDes[0].injector.get(NgbToastStubComponent) as NgbToastStubComponent; - expect(toastCmp.delay).toBeDefined(); - expect(toastCmp.delay) - .withContext(`should be ${expectedToast.options.delay}`) - .toBe(expectedToast.options.delay); + expectToBe(toastCmp.delay, expectedToast.options.delay); }); it('... should pass down default delay (=5000) to ngb-toast component (stubbed) if no delay is given', () => { @@ -139,8 +129,7 @@ describe('ToastComponent (DONE)', () => { const toastDes = getAndExpectDebugElementByDirective(compDe, NgbToastStubComponent, 1, 1); const toastCmp = toastDes[0].injector.get(NgbToastStubComponent) as NgbToastStubComponent; - expect(toastCmp.delay).toBeDefined(); - expect(toastCmp.delay).withContext(`should be 5000`).toBe(5000); + expectToBe(toastCmp.delay, 5000); }); it('... should remove toast from service on hide', () => { @@ -149,8 +138,7 @@ describe('ToastComponent (DONE)', () => { toastCmp.hide.emit(); - expect(toastService.toasts).toBeDefined(); - expect(toastService.toasts.length).withContext(`should be 0`).toBe(0); + expectToBe(toastService.toasts.length, 0); }); }); @@ -162,7 +150,7 @@ describe('ToastComponent (DONE)', () => { it('... should return false if given toast is not a template, but string', () => { const check = component.isTemplate(expectedToast); - expect(check).toBeFalse(); + expectToBe(check, false); }); it('... should return true if given toast is a template', () => { @@ -173,7 +161,7 @@ describe('ToastComponent (DONE)', () => { const check = component.isTemplate(expectedTplToast); - expect(check).toBeTrue(); + expectToBe(check, true); }); }); }); diff --git a/src/app/shared/toast/toast.service.spec.ts b/src/app/shared/toast/toast.service.spec.ts index 7ec7fdca6..4500aafe3 100644 --- a/src/app/shared/toast/toast.service.spec.ts +++ b/src/app/shared/toast/toast.service.spec.ts @@ -1,6 +1,8 @@ import { Component, TemplateRef, ViewChild } from '@angular/core'; import { TestBed } from '@angular/core/testing'; +import { expectToBe, expectToEqual } from '@testing/expect-helper'; + import { Toast, ToastService } from './toast.service'; // Mock component to get templateRef @@ -45,8 +47,7 @@ describe('ToastService (DONE)', () => { }); it('... should have empty toast array', () => { - expect(toastService.toasts).toBeTruthy(); - expect(toastService.toasts).withContext('should equal empty array []').toEqual([]); + expectToEqual(toastService.toasts, []); }); describe('#add()', () => { @@ -59,8 +60,8 @@ describe('ToastService (DONE)', () => { toastService.add(expectedToast1); expect(toastService.toasts).toBeTruthy(); - expect(toastService.toasts.length).withContext('should have one entry').toBe(1); - expect(toastService.toasts[0]).withContext(`should equal ${expectedToast1}`).toEqual(expectedToast1); + expectToBe(toastService.toasts.length, 1); + expectToEqual(toastService.toasts[0], expectedToast1); }); it('... should add given template to toast array', () => { @@ -74,8 +75,8 @@ describe('ToastService (DONE)', () => { toastService.add(expectedTplToast); expect(toastService.toasts).toBeTruthy(); - expect(toastService.toasts.length).withContext('should have one entry').toBe(1); - expect(toastService.toasts[0]).withContext(`should equal ${expectedTplToast}`).toEqual(expectedTplToast); + expectToBe(toastService.toasts.length, 1); + expectToEqual(toastService.toasts[0], expectedTplToast); }); it('... should only add textOrTpl if options not given', () => { @@ -83,8 +84,8 @@ describe('ToastService (DONE)', () => { toastService.add(expectedToast1); expect(toastService.toasts).toBeTruthy(); - expect(toastService.toasts.length).withContext('should have one entry').toBe(1); - expect(toastService.toasts[0]).withContext(`should equal ${expectedToast1}`).toEqual(expectedToast1); + expectToBe(toastService.toasts.length, 1); + expectToEqual(toastService.toasts[0], expectedToast1); }); it('... should add options if given with text message', () => { @@ -92,8 +93,8 @@ describe('ToastService (DONE)', () => { toastService.add(expectedToast2); expect(toastService.toasts).toBeTruthy(); - expect(toastService.toasts.length).withContext('should have one entry').toBe(1); - expect(toastService.toasts[0]).withContext(`should equal ${expectedToast2}`).toEqual(expectedToast2); + expectToBe(toastService.toasts.length, 1); + expectToEqual(toastService.toasts[0], expectedToast2); }); it('... should add options if given with template message', () => { @@ -107,8 +108,8 @@ describe('ToastService (DONE)', () => { toastService.add(expectedTplToast); expect(toastService.toasts).toBeTruthy(); - expect(toastService.toasts.length).withContext('should have one entry').toBe(1); - expect(toastService.toasts[0]).withContext(`should equal ${expectedTplToast}`).toEqual(expectedTplToast); + expectToBe(toastService.toasts.length, 1); + expectToEqual(toastService.toasts[0], expectedTplToast); }); }); @@ -129,9 +130,9 @@ describe('ToastService (DONE)', () => { toastService.remove(expectedOtherToast); expect(toastService.toasts).toBeTruthy(); - expect(toastService.toasts.length).withContext('should have two entries').toBe(2); - expect(toastService.toasts[0]).withContext(`should equal ${expectedToast1}`).toEqual(expectedToast1); - expect(toastService.toasts[1]).withContext(`should equal ${expectedToast2}`).toEqual(expectedToast2); + expectToBe(toastService.toasts.length, 2); + expectToEqual(toastService.toasts[0], expectedToast1); + expectToEqual(toastService.toasts[1], expectedToast2); }); it('... should do nothing if options do not match', () => { @@ -140,9 +141,9 @@ describe('ToastService (DONE)', () => { toastService.remove(otherOptionsToast); expect(toastService.toasts).toBeTruthy(); - expect(toastService.toasts.length).withContext('should have two entries').toBe(2); - expect(toastService.toasts[0]).withContext(`should equal ${expectedToast1}`).toEqual(expectedToast1); - expect(toastService.toasts[1]).withContext(`should equal ${expectedToast2}`).toEqual(expectedToast2); + expectToBe(toastService.toasts.length, 2); + expectToEqual(toastService.toasts[0], expectedToast1); + expectToEqual(toastService.toasts[1], expectedToast2); }); it('... should remove existing toast from toast array (without options)', () => { @@ -150,11 +151,8 @@ describe('ToastService (DONE)', () => { toastService.remove(expectedToast1); expect(toastService.toasts).toBeTruthy(); - expect(toastService.toasts.length).withContext('should have one entry').toBe(1); - expect(toastService.toasts[0]) - .withContext(`should not equal ${expectedToast1}`) - .not.toEqual(expectedToast1); - expect(toastService.toasts[0]).withContext(`should equal ${expectedToast2}`).toEqual(expectedToast2); + expectToBe(toastService.toasts.length, 1); + expectToEqual(toastService.toasts[0], expectedToast2); }); it('... should remove existing toast from toast array (with options)', () => { @@ -162,11 +160,8 @@ describe('ToastService (DONE)', () => { toastService.remove(expectedToast2); expect(toastService.toasts).toBeTruthy(); - expect(toastService.toasts.length).withContext('should have one entry').toBe(1); - expect(toastService.toasts[0]).withContext(`should equal ${expectedToast1}`).toEqual(expectedToast1); - expect(toastService.toasts[1]) - .withContext(`should not equal ${expectedToast2}`) - .not.toEqual(expectedToast2); + expectToBe(toastService.toasts.length, 1); + expectToEqual(toastService.toasts[0], expectedToast1); }); }); }); diff --git a/src/app/shared/view-handle-button-group/view-handle-button-group.component.spec.ts b/src/app/shared/view-handle-button-group/view-handle-button-group.component.spec.ts index e05d11ca8..5f537de0f 100644 --- a/src/app/shared/view-handle-button-group/view-handle-button-group.component.spec.ts +++ b/src/app/shared/view-handle-button-group/view-handle-button-group.component.spec.ts @@ -7,11 +7,12 @@ import { faDiagramProject, faGripHorizontal, faTable } from '@fortawesome/free-s import { NgbTooltip } from '@ng-bootstrap/ng-bootstrap'; import Spy = jasmine.Spy; -import { expectSpyCall, getAndExpectDebugElementByCss } from '@testing/expect-helper'; +import { expectSpyCall, expectToBe, getAndExpectDebugElementByCss } from '@testing/expect-helper'; -import { ViewHandleButtonGroupComponent } from './view-handle-button-group.component'; import { ViewHandle, ViewHandleTypes } from './view-handle.model'; +import { ViewHandleButtonGroupComponent } from './view-handle-button-group.component'; + describe('ViewHandleButtonGroupComponent (DONE)', () => { let component: ViewHandleButtonGroupComponent; let fixture: ComponentFixture; @@ -178,8 +179,8 @@ describe('ViewHandleButtonGroupComponent (DONE)', () => { }); it('... should create the viewHandleControlForm with correct viewHandleControl value', () => { - expect(component.viewHandleControlForm.controls['viewHandleControl'].value).toBeTruthy(); - expect(component.viewHandleControlForm.controls['viewHandleControl'].value).toBe( + expectToBe( + component.viewHandleControlForm.controls['viewHandleControl'].value, expectedSelectedViewType ); }); @@ -188,8 +189,7 @@ describe('ViewHandleButtonGroupComponent (DONE)', () => { expect(component.viewHandleControl).toBeDefined(); expect(component.viewHandleControl).toBeInstanceOf(UntypedFormControl); - expect(component.viewHandleControl.value).toBeTruthy(); - expect(component.viewHandleControl.value).toBe(expectedSelectedViewType); + expectToBe(component.viewHandleControl.value, expectedSelectedViewType); }); it('... should trigger the `listenToUserInputChange()` method', () => { @@ -355,8 +355,8 @@ describe('ViewHandleButtonGroupComponent (DONE)', () => { }); it('... should return the type of a given view handle', () => { - expect(component.viewHandleTracker(0, expectedViewHandles[0])).toBe(ViewHandleTypes.GRAPH); - expect(component.viewHandleTracker(1, expectedViewHandles[1])).toBe(ViewHandleTypes.TABLE); + expectToBe(component.viewHandleTracker(0, expectedViewHandles[0]), ViewHandleTypes.GRAPH); + expectToBe(component.viewHandleTracker(1, expectedViewHandles[1]), ViewHandleTypes.TABLE); }); }); @@ -377,7 +377,7 @@ describe('ViewHandleButtonGroupComponent (DONE)', () => { ); for (let i = 0; i < expectedViewHandles.length; i++) { - expect(inputDes[i].nativeElement.type).toBe('radio'); + expectToBe(inputDes[i].nativeElement.type, 'radio'); } }); @@ -396,10 +396,7 @@ describe('ViewHandleButtonGroupComponent (DONE)', () => { ); for (let i = 0; i < expectedViewHandles.length; i++) { - expect(inputDes[i].attributes['ng-reflect-value']).toBeTruthy(); - expect(inputDes[i].attributes['ng-reflect-value']) - .withContext(`should be ${expectedViewHandles[i].type}`) - .toBe(expectedViewHandles[i].type); + expectToBe(inputDes[i].attributes['ng-reflect-value'], expectedViewHandles[i].type); } }); @@ -421,20 +418,9 @@ describe('ViewHandleButtonGroupComponent (DONE)', () => { const inputEl2 = inputDes[1].nativeElement; const inputEl3 = inputDes[2].nativeElement; - expect(inputEl1.id).toBeTruthy(); - expect(inputEl1.id) - .withContext(`should be '${expectedViewHandles}-view-button'`) - .toBe(`${expectedViewHandles[0].type}-view-button`); - - expect(inputEl2.id).toBeTruthy(); - expect(inputEl2.id) - .withContext(`should be '${expectedViewHandles}-view-button'`) - .toBe(`${expectedViewHandles[1].type}-view-button`); - - expect(inputEl3.id).toBeTruthy(); - expect(inputEl3.id) - .withContext(`should be '${expectedViewHandles}-view-button'`) - .toBe(`${expectedViewHandles[2].type}-view-button`); + expectToBe(inputEl1.id, `${expectedViewHandles[0].type}-view-button`); + expectToBe(inputEl2.id, `${expectedViewHandles[1].type}-view-button`); + expectToBe(inputEl3.id, `${expectedViewHandles[2].type}-view-button`); }); it('... should have as many label elements in div.btn-group as viewHandles given', () => { @@ -491,10 +477,7 @@ describe('ViewHandleButtonGroupComponent (DONE)', () => { ); for (let i = 0; i < expectedViewHandles.length; i++) { - expect(labelDes[i].attributes['for']).toBeTruthy(); - expect(labelDes[i].attributes['for']) - .withContext(`should be ${expectedViewHandles[i].type}-view-button`) - .toBe(`${expectedViewHandles[i].type}-view-button`); + expectToBe(labelDes[i].attributes['for'], `${expectedViewHandles[i].type}-view-button`); } }); @@ -513,10 +496,7 @@ describe('ViewHandleButtonGroupComponent (DONE)', () => { ); for (let i = 0; i < expectedViewHandles.length; i++) { - expect(labelDes[i].attributes['ng-reflect-ngb-tooltip']).toBeTruthy(); - expect(labelDes[i].attributes['ng-reflect-ngb-tooltip']) - .withContext(`should be '${expectedViewHandles[i].type} view'`) - .toBe(expectedViewHandles[i].type + ' view'); + expectToBe(labelDes[i].attributes['ng-reflect-ngb-tooltip'], expectedViewHandles[i].type + ' view'); } }); }); diff --git a/src/app/side-info/contact-info/contact-info.component.spec.ts b/src/app/side-info/contact-info/contact-info.component.spec.ts index 1e3fa9e56..d23acc937 100644 --- a/src/app/side-info/contact-info/contact-info.component.spec.ts +++ b/src/app/side-info/contact-info/contact-info.component.spec.ts @@ -7,6 +7,8 @@ import Spy = jasmine.Spy; import { cleanStylesFromDOM } from '@testing/clean-up-helper'; import { expectSpyCall, + expectToBe, + expectToEqual, getAndExpectDebugElementByCss, getAndExpectDebugElementByDirective, } from '@testing/expect-helper'; @@ -14,8 +16,8 @@ import { import { AppConfig } from '@awg-app/app.config'; import { METADATA } from '@awg-core/core-data'; import { MetaContact, MetaPage, MetaSectionTypes } from '@awg-core/core-models'; - import { CoreService } from '@awg-core/services'; + import { ContactInfoComponent } from './contact-info.component'; // Mock address component @@ -103,13 +105,12 @@ describe('ContactInfoComponent (DONE)', () => { it('... injected service should use provided mockValue', () => { const coreService = TestBed.inject(CoreService); - expect(mockCoreService === coreService).toBe(true); + expectToBe(mockCoreService === coreService, true); }); describe('BEFORE initial data binding', () => { it('... should have contact info header', () => { - expect(component.contactInfoHeader).toBeDefined(); - expect(component.contactInfoHeader).toBe(expectedContactInfoHeader); + expectToBe(component.contactInfoHeader, expectedContactInfoHeader); }); it('... should not have metadata nor open street map links', () => { @@ -153,8 +154,7 @@ describe('ContactInfoComponent (DONE)', () => { const headerDes = getAndExpectDebugElementByCss(compDe, 'h5#awg-contact-info-header', 1, 1); const headerEl = headerDes[0].nativeElement; - expect(headerEl).toBeDefined(); - expect(headerEl.textContent).toBeFalsy(); + expectToBe(headerEl.textContent, ''); }); it('... should contain one address component (stubbed)', () => { @@ -204,17 +204,11 @@ describe('ContactInfoComponent (DONE)', () => { }); it('... should return pageMetaData', () => { - expect(component.pageMetaData).toBeDefined(); - expect(component.pageMetaData) - .withContext(`should be ${expectedPageMetaData}`) - .toBe(expectedPageMetaData); + expectToEqual(component.pageMetaData, expectedPageMetaData); }); it('... should return contactMetaData', () => { - expect(component.contactMetaData).toBeDefined(); - expect(component.contactMetaData) - .withContext(`should be ${expectedContactMetaData}`) - .toBe(expectedContactMetaData); + expectToEqual(component.contactMetaData, expectedContactMetaData); }); }); @@ -224,17 +218,11 @@ describe('ContactInfoComponent (DONE)', () => { }); it('... should return osmEmbedUrl', () => { - expect(component.osmEmbedUrl).toBeDefined(); - expect(component.osmEmbedUrl) - .withContext(`should equal ${expectedOsmEmbedUrl}`) - .toEqual(expectedOsmEmbedUrl); + expectToEqual(component.osmEmbedUrl, expectedOsmEmbedUrl); }); it('... should return osmLinkUrl', () => { - expect(component.osmLinkUrl).toBeDefined(); - expect(component.osmLinkUrl) - .withContext(`should equal ${expectedOsmLinkUrl}`) - .toEqual(expectedOsmLinkUrl); + expectToEqual(component.osmLinkUrl, expectedOsmLinkUrl); }); }); @@ -243,38 +231,23 @@ describe('ContactInfoComponent (DONE)', () => { const headerDes = getAndExpectDebugElementByCss(compDe, 'h5#awg-contact-info-header', 1, 1); const headerEl = headerDes[0].nativeElement; - expect(headerEl).toBeDefined(); - expect(headerEl.textContent) - .withContext(`should be ${expectedContactInfoHeader}`) - .toBe(expectedContactInfoHeader); + expectToBe(headerEl.textContent, expectedContactInfoHeader); }); it('... should pass down `pageMetaData` and `contactMetaData` to address component', () => { const addressDes = getAndExpectDebugElementByDirective(compDe, AddressStubComponent, 1, 1); const addressCmp = addressDes[0].injector.get(AddressStubComponent) as AddressStubComponent; - expect(addressCmp.pageMetaData).toBeTruthy(); - expect(addressCmp.pageMetaData) - .withContext(`should be ${expectedPageMetaData}`) - .toBe(expectedPageMetaData); - - expect(addressCmp.contactMetaData).toBeTruthy(); - expect(addressCmp.contactMetaData) - .withContext(`should be ${expectedContactMetaData}`) - .toBe(expectedContactMetaData); + expectToEqual(addressCmp.pageMetaData, expectedPageMetaData); + expectToEqual(addressCmp.contactMetaData, expectedContactMetaData); }); it('... should pass down `osmEmbedUrl` and `osmLinkUrl` to OpenStreetMap component', () => { const osmDes = getAndExpectDebugElementByDirective(compDe, OpenStreetMapStubComponent, 1, 1); const osmCmp = osmDes[0].injector.get(OpenStreetMapStubComponent) as OpenStreetMapStubComponent; - expect(osmCmp.osmEmbedUrl).toBeTruthy(); - expect(osmCmp.osmEmbedUrl) - .withContext(`should equal ${expectedOsmEmbedUrl}`) - .toEqual(expectedOsmEmbedUrl); - - expect(osmCmp.osmLinkUrl).toBeTruthy(); - expect(osmCmp.osmLinkUrl).withContext(`should equal ${expectedOsmLinkUrl}`).toEqual(expectedOsmLinkUrl); + expectToEqual(osmCmp.osmEmbedUrl, expectedOsmEmbedUrl); + expectToEqual(osmCmp.osmLinkUrl, expectedOsmLinkUrl); }); }); }); diff --git a/src/app/side-info/edition-info/edition-info.component.html b/src/app/side-info/edition-info/edition-info.component.html index d23206914..dd4650c25 100644 --- a/src/app/side-info/edition-info/edition-info.component.html +++ b/src/app/side-info/edition-info/edition-info.component.html @@ -31,6 +31,16 @@
{{ editionInfoHeader }}
>{{ editionRouteConstants.ROWTABLES.full }}

+

+ {{ editionRouteConstants.PREFACE.full }} +

diff --git a/src/app/side-info/edition-info/edition-info.component.spec.ts b/src/app/side-info/edition-info/edition-info.component.spec.ts index c34f0f0ed..59b133070 100644 --- a/src/app/side-info/edition-info/edition-info.component.spec.ts +++ b/src/app/side-info/edition-info/edition-info.component.spec.ts @@ -16,9 +16,9 @@ import { } from '@testing/expect-helper'; import { RouterLinkStubDirective } from 'testing/router-stubs'; -import { EDITION_COMPLEXES } from '@awg-views/edition-view/data'; import { EDITION_ROUTE_CONSTANTS, EDITION_TYPE_CONSTANTS } from '@awg-views/edition-view/edition-route-constants'; import { EditionComplex } from '@awg-views/edition-view/models'; +import { EditionComplexesService } from '@awg-views/edition-view/services'; import { EditionInfoComponent } from './edition-info.component'; @@ -26,30 +26,32 @@ import { EditionInfoComponent } from './edition-info.component'; function generateExpectedOrderOfRouterlinks(editionComplexes: EditionComplex[]): string[][] { const editionOverviewLink = [[EDITION_ROUTE_CONSTANTS.EDITION.route, EDITION_ROUTE_CONSTANTS.SERIES.route]]; const rowTablesLink = [[EDITION_ROUTE_CONSTANTS.EDITION.route, EDITION_ROUTE_CONSTANTS.ROWTABLES.route]]; + const prefaceLink = [[EDITION_ROUTE_CONSTANTS.EDITION.route, EDITION_ROUTE_CONSTANTS.PREFACE.route]]; const editionLinks = editionComplexes.flatMap(complex => { const routes = [[complex.baseRoute, EDITION_ROUTE_CONSTANTS.EDITION_SHEETS.route]]; - if (complex === EDITION_COMPLEXES.OP25) { + if (complex === EditionComplexesService.getEditionComplexById('OP25')) { routes.push([complex.baseRoute, EDITION_ROUTE_CONSTANTS.EDITION_GRAPH.route]); } return routes; }); - return [...editionOverviewLink, ...rowTablesLink, ...editionLinks]; + return [...editionOverviewLink, ...rowTablesLink, ...prefaceLink, ...editionLinks]; } function generateExpectedOrderOfHeaders(editionComplexes: EditionComplex[]): string[] { const editionOverviewHeader = EDITION_ROUTE_CONSTANTS.SERIES.full; const rowTablesHeader = EDITION_ROUTE_CONSTANTS.ROWTABLES.full; + const prefaceHeader = EDITION_ROUTE_CONSTANTS.PREFACE.full; const editionHeaders = editionComplexes.flatMap(complex => { - if (complex === EDITION_COMPLEXES.OP25) { + if (complex === EditionComplexesService.getEditionComplexById('OP25')) { return [EDITION_TYPE_CONSTANTS.SKETCH_EDITION.full, EDITION_ROUTE_CONSTANTS.EDITION_GRAPH.full]; } return [EDITION_TYPE_CONSTANTS.SKETCH_EDITION.full]; }); - return [editionOverviewHeader, rowTablesHeader, ...editionHeaders]; + return [editionOverviewHeader, rowTablesHeader, prefaceHeader, ...editionHeaders]; } describe('EditionInfoComponent (DONE)', () => { @@ -93,17 +95,17 @@ describe('EditionInfoComponent (DONE)', () => { // Test data expectedEditionComplexes = [ - EDITION_COMPLEXES.OP3, - EDITION_COMPLEXES.OP4, - EDITION_COMPLEXES.OP12, - EDITION_COMPLEXES.OP23, - EDITION_COMPLEXES.OP25, - EDITION_COMPLEXES.M22, - EDITION_COMPLEXES.M30, - EDITION_COMPLEXES.M31, - EDITION_COMPLEXES.M34, - EDITION_COMPLEXES.M35_42, - EDITION_COMPLEXES.M37, + EditionComplexesService.getEditionComplexById('OP3'), + EditionComplexesService.getEditionComplexById('OP4'), + EditionComplexesService.getEditionComplexById('OP12'), + EditionComplexesService.getEditionComplexById('OP23'), + EditionComplexesService.getEditionComplexById('OP25'), + EditionComplexesService.getEditionComplexById('M22'), + EditionComplexesService.getEditionComplexById('M30'), + EditionComplexesService.getEditionComplexById('M31'), + EditionComplexesService.getEditionComplexById('M34'), + EditionComplexesService.getEditionComplexById('M35_42'), + EditionComplexesService.getEditionComplexById('M37'), ]; expectedOrderOfRouterlinks = generateExpectedOrderOfRouterlinks(expectedEditionComplexes); expectedOrderOfHeaders = generateExpectedOrderOfHeaders(expectedEditionComplexes); @@ -207,7 +209,7 @@ describe('EditionInfoComponent (DONE)', () => { }); }); - it('... should display item header buttons with rowtables and edition series', () => { + it('... should display item header buttons', () => { // Header debug elements const itemHeaderDes = getAndExpectDebugElementByCss(compDe, 'div.accordion-header', 3, 3); @@ -265,7 +267,7 @@ describe('EditionInfoComponent (DONE)', () => { expectToContain(itemBodyEl.classList, 'show'); }); - it('... should contain item body with 5 paragraphs in first item', () => { + it('... should contain item body with 3 paragraphs in first item', () => { // Div.accordion-item const itemDes = getAndExpectDebugElementByCss(compDe, 'div.accordion-item', 3, 3); @@ -273,7 +275,7 @@ describe('EditionInfoComponent (DONE)', () => { const itemBodyDes = getAndExpectDebugElementByCss(itemDes[0], 'div.accordion-body', 1, 1); // Paragraph - getAndExpectDebugElementByCss(itemBodyDes[0], 'p', 2, 2); + getAndExpectDebugElementByCss(itemBodyDes[0], 'p', 3, 3); }); it('... should contain item body with 5 paragraphs in second item', () => { @@ -364,7 +366,7 @@ describe('EditionInfoComponent (DONE)', () => { const linkDe = linkDes[index]; const expectedRouterLink = expectedOrderOfRouterlinks[index]; - expect(routerLink.navigatedTo).toBeNull(); + expectToBe(routerLink.navigatedTo, null); click(linkDe); fixture.detectChanges(); diff --git a/src/app/side-info/edition-info/edition-info.component.ts b/src/app/side-info/edition-info/edition-info.component.ts index 033ca2ddf..5330e3936 100644 --- a/src/app/side-info/edition-info/edition-info.component.ts +++ b/src/app/side-info/edition-info/edition-info.component.ts @@ -1,8 +1,8 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; -import { EDITION_COMPLEXES } from '@awg-views/edition-view/data'; import { EDITION_ROUTE_CONSTANTS, EDITION_TYPE_CONSTANTS } from '@awg-views/edition-view/edition-route-constants'; import { EditionComplex } from '@awg-views/edition-view/models'; +import { EditionComplexesService } from '@awg-views/edition-view/services'; /** * The EditionInfo component. @@ -29,17 +29,17 @@ export class EditionInfoComponent { * It keeps the array of displayed edition complexes. */ readonly DISPLAYED_EDITION_COMPLEXES: EditionComplex[] = [ - EDITION_COMPLEXES.OP3, - EDITION_COMPLEXES.OP4, - EDITION_COMPLEXES.OP12, - EDITION_COMPLEXES.OP23, - EDITION_COMPLEXES.OP25, - EDITION_COMPLEXES.M22, - EDITION_COMPLEXES.M30, - EDITION_COMPLEXES.M31, - EDITION_COMPLEXES.M34, - EDITION_COMPLEXES.M35_42, - EDITION_COMPLEXES.M37, + EditionComplexesService.getEditionComplexById('OP3'), + EditionComplexesService.getEditionComplexById('OP4'), + EditionComplexesService.getEditionComplexById('OP12'), + EditionComplexesService.getEditionComplexById('OP23'), + EditionComplexesService.getEditionComplexById('OP25'), + EditionComplexesService.getEditionComplexById('M22'), + EditionComplexesService.getEditionComplexById('M30'), + EditionComplexesService.getEditionComplexById('M31'), + EditionComplexesService.getEditionComplexById('M34'), + EditionComplexesService.getEditionComplexById('M35_42'), + EditionComplexesService.getEditionComplexById('M37'), ]; /** diff --git a/src/app/side-info/resource-info/resource-info.component.spec.ts b/src/app/side-info/resource-info/resource-info.component.spec.ts index 92c3a7dda..d0dddcb1f 100644 --- a/src/app/side-info/resource-info/resource-info.component.spec.ts +++ b/src/app/side-info/resource-info/resource-info.component.spec.ts @@ -1,6 +1,6 @@ import { JsonPipe } from '@angular/common'; import { Component, DebugElement } from '@angular/core'; -import { ComponentFixture, fakeAsync, TestBed, waitForAsync } from '@angular/core/testing'; +import { ComponentFixture, TestBed, fakeAsync, waitForAsync } from '@angular/core/testing'; import { AbstractControl, ReactiveFormsModule, UntypedFormBuilder } from '@angular/forms'; import { Router } from '@angular/router'; @@ -12,7 +12,7 @@ import Spy = jasmine.Spy; import { cleanStylesFromDOM } from '@testing/clean-up-helper'; import { clickAndAwaitChanges } from '@testing/click-helper'; -import { expectSpyCall, getAndExpectDebugElementByCss } from '@testing/expect-helper'; +import { expectSpyCall, expectToBe, expectToEqual, getAndExpectDebugElementByCss } from '@testing/expect-helper'; import { mockSearchResponseJson } from '@testing/mock-data'; import { mockConsole } from '@testing/mock-helper'; @@ -131,7 +131,7 @@ describe('ResourceInfoComponent (DONE)', () => { }); it('... injected service should use provided mockValue', () => { - expect(dataStreamerService === mockDataStreamerService).toBe(true); + expectToBe(dataStreamerService === mockDataStreamerService, true); }); describe('BEFORE initial data binding', () => { @@ -152,15 +152,14 @@ describe('ResourceInfoComponent (DONE)', () => { }); it('... should have empty resourceInfoData', () => { - expect(component.resourceInfoData).withContext('should be defined').toBeDefined(); - expect(component.resourceInfoData).withContext('should equal new ResourceInfo').toEqual(new ResourceInfo()); + expectToEqual(component.resourceInfoData, new ResourceInfo()); }); it('... should have fa-icons', () => { - expect(component.faArrowLeft).withContext('should be faArrowLeft').toBe(faArrowLeft); - expect(component.faChevronLeft).withContext('should be faChevronLeft').toBe(faChevronLeft); - expect(component.faChevronRight).withContext('should be faChevronRight').toBe(faChevronRight); - expect(component.faTimesCircle).withContext('should be faTimesCircle').toBe(faTimesCircle); + expectToEqual(component.faArrowLeft, faArrowLeft); + expectToEqual(component.faChevronLeft, faChevronLeft); + expectToEqual(component.faChevronRight, faChevronRight); + expectToEqual(component.faTimesCircle, faTimesCircle); }); describe('VIEW', () => { @@ -254,8 +253,7 @@ describe('ResourceInfoComponent (DONE)', () => { it('... should have got `resourceId` from dataStreamerService', () => { expectSpyCall(dataStreamerResourceIdSpy, 1); - expect(component.resourceId).withContext('should be truthy').toBeTruthy(); - expect(component.resourceId).withContext(`should be ${expectedResourceId}`).toBe(expectedResourceId); + expectToBe(component.resourceId, expectedResourceId); }); it('... should have got searchResponseWithQuery from dataStreamerService', () => { @@ -268,11 +266,8 @@ describe('ResourceInfoComponent (DONE)', () => { expectSpyCall(updateResourceInfoSpy, 1, [expectedResourceId, expectedResponseClone]); }); it('... should have set `goToIndex` and `resultSize` (via _updateResourceInfo)', () => { - expect(component.resultSize).withContext('should be truthy').toBeTruthy(); - expect(component.resultSize).withContext(`should be ${expectedResultSize}`).toBe(expectedResultSize); - - expect(component.goToIndex).withContext('should be truthy').toBeTruthy(); - expect(component.goToIndex).withContext(`should be ${expectedGoToIndex}`).toBe(expectedGoToIndex); + expectToBe(component.resultSize, expectedResultSize); + expectToBe(component.goToIndex, expectedGoToIndex); }); it('... should have called _buildForm with `goToIndex` and `resultSize`', () => { @@ -318,7 +313,7 @@ describe('ResourceInfoComponent (DONE)', () => { // Check console expectSpyCall(consoleSpy, 1, expectedLogMessage); - expect(mockConsole.get(0)).withContext(`should be ${expectedLogMessage}`).toEqual(expectedLogMessage); + expectToEqual(mockConsole.get(0), expectedLogMessage); }); }); @@ -330,11 +325,8 @@ describe('ResourceInfoComponent (DONE)', () => { }); it('... should set `goToIndex` and `resultSize`', () => { - expect(component.resultSize).withContext('should be truthy').toBeTruthy(); - expect(component.resultSize).withContext(`should be ${expectedResultSize}`).toBe(expectedResultSize); - - expect(component.goToIndex).withContext('should be truthy').toBeTruthy(); - expect(component.goToIndex).withContext(`should be ${expectedGoToIndex}`).toBe(expectedGoToIndex); + expectToBe(component.resultSize, expectedResultSize); + expectToBe(component.goToIndex, expectedGoToIndex); }); it('... should change `goToIndex` and `resultSize` depending on input', () => { @@ -346,11 +338,8 @@ describe('ResourceInfoComponent (DONE)', () => { (component as any)._updateResourceInfo(expectedResourceId, otherResponseClone); - expect(component.resultSize).withContext('should be truthy').toBeTruthy(); - expect(component.resultSize).withContext(`should be ${expectedResultSize}`).toBe(expectedResultSize); - - expect(component.goToIndex).withContext('should be truthy').toBeTruthy(); - expect(component.goToIndex).withContext(`should be ${expectedGoToIndex}`).toBe(expectedGoToIndex); + expectToBe(component.resultSize, expectedResultSize); + expectToBe(component.goToIndex, expectedGoToIndex); }); describe('... should set `resourceInfoData` if', () => { @@ -371,10 +360,7 @@ describe('ResourceInfoComponent (DONE)', () => { }, }; - expect(component.resourceInfoData).withContext('should be truthy').toBeTruthy(); - expect(component.resourceInfoData) - .withContext(`should be ${expectedResourceInfoData}`) - .toEqual(expectedResourceInfoData); + expectToEqual(component.resourceInfoData, expectedResourceInfoData); }); it('... only current and next resource given', () => { @@ -398,13 +384,9 @@ describe('ResourceInfoComponent (DONE)', () => { (component as any)._updateResourceInfo(expectedResourceId, otherResponseClone); - expect(component.goToIndex).withContext('should be 1').toBe(1); - expect(component.resultSize).withContext('should be 3').toBe(3); - - expect(component.resourceInfoData).withContext('should be truthy').toBeTruthy(); - expect(component.resourceInfoData) - .withContext(`should be ${expectedResourceInfoData}`) - .toEqual(expectedResourceInfoData); + expectToBe(component.goToIndex, 1); + expectToBe(component.resultSize, 3); + expectToEqual(component.resourceInfoData, expectedResourceInfoData); }); it('... only current and previous resource given', () => { @@ -428,15 +410,9 @@ describe('ResourceInfoComponent (DONE)', () => { (component as any)._updateResourceInfo(expectedResourceId, otherResponseClone); - expect(component.goToIndex).withContext(`should be ${expectedGoToIndex}`).toBe(expectedGoToIndex); - expect(component.resultSize) - .withContext(`should be ${expectedResultSize}`) - .toBe(expectedResultSize); - - expect(component.resourceInfoData).withContext('should be truthy').toBeTruthy(); - expect(component.resourceInfoData) - .withContext(`should be ${expectedResourceInfoData}`) - .toEqual(expectedResourceInfoData); + expectToBe(component.goToIndex, expectedGoToIndex); + expectToBe(component.resultSize, expectedResultSize); + expectToEqual(component.resourceInfoData, expectedResourceInfoData); }); it('... only current resource given', () => { @@ -459,15 +435,9 @@ describe('ResourceInfoComponent (DONE)', () => { (component as any)._updateResourceInfo(expectedResourceId, otherResponseClone); - expect(component.goToIndex).withContext(`should be ${expectedGoToIndex}`).toBe(expectedGoToIndex); - expect(component.resultSize) - .withContext(`should be ${expectedResultSize}`) - .toBe(expectedResultSize); - - expect(component.resourceInfoData).withContext('should be truthy').toBeTruthy(); - expect(component.resourceInfoData) - .withContext(`should be ${expectedResourceInfoData}`) - .toEqual(expectedResourceInfoData); + expectToBe(component.goToIndex, expectedGoToIndex); + expectToBe(component.resultSize, expectedResultSize); + expectToEqual(component.resourceInfoData, expectedResourceInfoData); }); it('... no previous and current resource given', () => { @@ -500,15 +470,9 @@ describe('ResourceInfoComponent (DONE)', () => { (component as any)._updateResourceInfo(expectedResourceId, otherResponseClone); - expect(component.goToIndex).withContext(`should be ${expectedGoToIndex}`).toBe(expectedGoToIndex); - expect(component.resultSize) - .withContext(`should be ${expectedResultSize}`) - .toBe(expectedResultSize); - - expect(component.resourceInfoData).withContext('should be truthy').toBeTruthy(); - expect(component.resourceInfoData) - .withContext(`should equal ${expectedResourceInfoData}`) - .toEqual(expectedResourceInfoData); + expectToBe(component.goToIndex, expectedGoToIndex); + expectToBe(component.resultSize, expectedResultSize); + expectToEqual(component.resourceInfoData, expectedResourceInfoData); }); }); }); @@ -557,10 +521,7 @@ describe('ResourceInfoComponent (DONE)', () => { expectedGoToIndex = 3; expect(component.resourceInfoFormGroup).toBeTruthy(); - expect(component.resourceInfoFormGroup.controls['resourceInfoIndex']).toBeTruthy(); - expect(component.resourceInfoFormGroup.controls['resourceInfoIndex'].value) - .withContext(`should equal ${expectedGoToIndex}`) - .toEqual(expectedGoToIndex); + expectToBe(component.resourceInfoFormGroup.controls['resourceInfoIndex'].value, expectedGoToIndex); }); it('... with empty index if none is given', () => { @@ -571,10 +532,7 @@ describe('ResourceInfoComponent (DONE)', () => { fixture.detectChanges(); expect(component.resourceInfoFormGroup).toBeTruthy(); - expect(component.resourceInfoFormGroup.controls['resourceInfoIndex']).toBeTruthy(); - expect(component.resourceInfoFormGroup.controls['resourceInfoIndex'].value) - .withContext(`should equal ${expectedEmptyIndex}`) - .toEqual(expectedEmptyIndex); + expectToBe(component.resourceInfoFormGroup.controls['resourceInfoIndex'].value, expectedEmptyIndex); }); }); @@ -631,10 +589,7 @@ describe('ResourceInfoComponent (DONE)', () => { actualValue: nanValue, }; - expect(errors['pattern']).toBeTruthy(); - expect(errors['pattern']) - .withContext(`should equal ${expectedPatternError}`) - .toEqual(expectedPatternError); + expectToEqual(errors['pattern'], expectedPatternError); }); it('any string', () => { @@ -647,10 +602,7 @@ describe('ResourceInfoComponent (DONE)', () => { actualValue: anyString, }; - expect(errors['pattern']).toBeTruthy(); - expect(errors['pattern']) - .withContext(`should equal ${expectedPatternError}`) - .toEqual(expectedPatternError); + expectToEqual(errors['pattern'], expectedPatternError); }); it('any array', () => { @@ -663,10 +615,7 @@ describe('ResourceInfoComponent (DONE)', () => { actualValue: anyArray, }; - expect(errors['pattern']).toBeTruthy(); - expect(errors['pattern']) - .withContext(`should equal ${expectedPatternError}`) - .toEqual(expectedPatternError); + expectToEqual(errors['pattern'], expectedPatternError); }); it('empty object', () => { @@ -679,10 +628,7 @@ describe('ResourceInfoComponent (DONE)', () => { actualValue: emptyObject, }; - expect(errors['pattern']).toBeTruthy(); - expect(errors['pattern']) - .withContext(`should equal ${expectedPatternError}`) - .toEqual(expectedPatternError); + expectToEqual(errors['pattern'], expectedPatternError); }); it('any object', () => { @@ -695,10 +641,7 @@ describe('ResourceInfoComponent (DONE)', () => { actualValue: anyObject, }; - expect(errors['pattern']).toBeTruthy(); - expect(errors['pattern']) - .withContext(`should equal ${expectedPatternError}`) - .toEqual(expectedPatternError); + expectToEqual(errors['pattern'], expectedPatternError); }); }); @@ -715,10 +658,7 @@ describe('ResourceInfoComponent (DONE)', () => { actualValue: tenDigitNegativeInteger, }; - expect(errors['pattern']).toBeTruthy(); - expect(errors['pattern']) - .withContext(`should equal ${expectedPatternError}`) - .toEqual(expectedPatternError); + expectToEqual(errors['pattern'], expectedPatternError); }); it('no 1-digit negative integers (-1)', () => { @@ -731,10 +671,7 @@ describe('ResourceInfoComponent (DONE)', () => { actualValue: oneDigitNegativeInteger, }; - expect(errors['pattern']).toBeTruthy(); - expect(errors['pattern']) - .withContext(`should equal ${expectedPatternError}`) - .toEqual(expectedPatternError); + expectToEqual(errors['pattern'], expectedPatternError); }); it('not 0', () => { @@ -747,10 +684,7 @@ describe('ResourceInfoComponent (DONE)', () => { actualValue: zero, }; - expect(errors['pattern']).toBeTruthy(); - expect(errors['pattern']) - .withContext(`should equal ${expectedPatternError}`) - .toEqual(expectedPatternError); + expectToEqual(errors['pattern'], expectedPatternError); }); it('no 11-digit positive integers (12345678901)', () => { @@ -763,10 +697,7 @@ describe('ResourceInfoComponent (DONE)', () => { actualValue: elevenDigitPositivInteger, }; - expect(errors['pattern']).toBeTruthy(); - expect(errors['pattern']) - .withContext(`should equal ${expectedPatternError}`) - .toEqual(expectedPatternError); + expectToEqual(errors['pattern'], expectedPatternError); }); it('no floating numbers (1.1)', () => { @@ -779,10 +710,7 @@ describe('ResourceInfoComponent (DONE)', () => { actualValue: floatingNumber, }; - expect(errors['pattern']).toBeTruthy(); - expect(errors['pattern']) - .withContext(`should equal ${expectedPatternError}`) - .toEqual(expectedPatternError); + expectToEqual(errors['pattern'], expectedPatternError); }); it('no big floating numbers (1234567890.0123456789)', () => { @@ -795,10 +723,7 @@ describe('ResourceInfoComponent (DONE)', () => { actualValue: bigFloatingNumber, }; - expect(errors['pattern']).toBeTruthy(); - expect(errors['pattern']) - .withContext(`should equal ${expectedPatternError}`) - .toEqual(expectedPatternError); + expectToEqual(errors['pattern'], expectedPatternError); }); }); @@ -839,8 +764,7 @@ describe('ResourceInfoComponent (DONE)', () => { const expectedError = { min: 1, actual: -1 }; - expect(errors['min']).toBeTruthy(); - expect(errors['min']).withContext(`should equal ${expectedError}`).toEqual(expectedError); + expectToEqual(errors['min'], expectedError); }); it('min error == TRUE for 0', () => { @@ -849,8 +773,7 @@ describe('ResourceInfoComponent (DONE)', () => { const expectedError = { min: 1, actual: 0 }; - expect(errors['min']).toBeTruthy(); - expect(errors['min']).withContext(`should equal ${expectedError}`).toEqual(expectedError); + expectToEqual(errors['min'], expectedError); }); it('min error == FALSE for 1', () => { @@ -875,8 +798,7 @@ describe('ResourceInfoComponent (DONE)', () => { const expectedError = { max: 5, actual: 6 }; - expect(errors['max']).toBeTruthy(); - expect(errors['max']).withContext(`should equal ${expectedError}`).toEqual(expectedError); + expectToEqual(errors['max'], expectedError); }); it('max error == FALSE for value equals resultSize', () => { @@ -900,14 +822,12 @@ describe('ResourceInfoComponent (DONE)', () => { it('... should return index position of a given `resourceId` in given search response', () => { const expectedResponseClone = JSON.parse(JSON.stringify(expectedSearchResponseWithQuery)); - expect( - (component as any)._findIndexPositionInSearchResultsById(expectedResourceId, expectedResponseClone) - ).toBeTruthy(); - expect( - (component as any)._findIndexPositionInSearchResultsById(expectedResourceId, expectedResponseClone) - ) - .withContext('should be 2') - .toBe(2); + const actualIndex = (component as any)._findIndexPositionInSearchResultsById( + expectedResourceId, + expectedResponseClone + ); + + expectToBe(actualIndex, 2); }); it('... should return -1 if resource id is not found in given search response', () => { @@ -921,12 +841,12 @@ describe('ResourceInfoComponent (DONE)', () => { otherResponseClone.data.subjects.slice(sliceIndex + 1, otherResponseClone.data.subjects.length) ); - expect( - (component as any)._findIndexPositionInSearchResultsById(expectedResourceId, otherResponseClone) - ).toBeTruthy(); - expect((component as any)._findIndexPositionInSearchResultsById(expectedResourceId, otherResponseClone)) - .withContext('should be -1') - .toBe(-1); + const actualIndex = (component as any)._findIndexPositionInSearchResultsById( + expectedResourceId, + otherResponseClone + ); + + expectToBe(actualIndex, -1); }); }); @@ -1093,7 +1013,7 @@ describe('ResourceInfoComponent (DONE)', () => { component.resourceInfoData.searchResults = null; component.navigateToSearchPanel(); - expect(component.resourceInfoData.searchResults).toBeNull(); + expectToBe(component.resourceInfoData.searchResults, null); expectSpyCall(navigationSpy, 1, [expectedRoute, expectedParams]); }); @@ -1110,9 +1030,7 @@ describe('ResourceInfoComponent (DONE)', () => { component.navigateToSearchPanel(); expect(component.resourceInfoData.searchResults).toBeTruthy(); - expect(component.resourceInfoData.searchResults.query) - .withContext('should be empty string (falsy)') - .toBeFalsy(); + expectToBe(component.resourceInfoData.searchResults.query, ''); expectSpyCall(navigationSpy, 1, [expectedRoute, expectedParams]); }); }); @@ -1149,9 +1067,7 @@ describe('ResourceInfoComponent (DONE)', () => { expect(component.resourceInfoData.searchResults).toBeTruthy(); expect(component.resourceInfoData.searchResults.query).toBeTruthy(); - expect(typeof component.resourceInfoData.searchResults.query) - .withContext(`should be string`) - .toBe('string'); + expectToBe(typeof component.resourceInfoData.searchResults.query, 'string'); expectSpyCall(navigationSpy, 1, [expectedRoute, expectedParams]); }); }); @@ -1183,9 +1099,7 @@ describe('ResourceInfoComponent (DONE)', () => { expect(component.resourceInfoData.searchResults).toBeTruthy(); expect(component.resourceInfoData.searchResults.query).toBeTruthy(); - expect(typeof component.resourceInfoData.searchResults.query) - .withContext(`should be object`) - .toBe('object'); + expectToBe(typeof component.resourceInfoData.searchResults.query, 'object'); expectSpyCall(navigationSpy, 1, [expectedRoute, expectedParams]); }); }); @@ -1262,7 +1176,7 @@ describe('ResourceInfoComponent (DONE)', () => { expect(iconDes[0].children[0]).toBeTruthy(); expect(iconDes[0].children[0].classes).toBeTruthy(); - expect(iconDes[0].children[0].classes['fa-arrow-left']).toBeTrue(); + expectToBe(iconDes[0].children[0].classes['fa-arrow-left'], true); }); it('... should display innerHTML text on first div button', () => { @@ -1272,8 +1186,7 @@ describe('ResourceInfoComponent (DONE)', () => { const expectedText = 'Zur Suche'; - expect(spanEl.innerText).toBeTruthy(); - expect(spanEl.innerText).withContext(`should be ${expectedText}`).toBe(expectedText); + expectToBe(spanEl.innerText, expectedText); }); it('... should display bold, small, muted text in second div', () => { @@ -1286,8 +1199,7 @@ describe('ResourceInfoComponent (DONE)', () => { expect(strongEl).toHaveClass('text-muted'); expect(strongEl).toHaveClass('small'); - expect(strongEl.innerText).toBeTruthy(); - expect(strongEl.innerText).withContext(`should be ${expectedText}`).toBe(expectedText); + expectToBe(strongEl.innerText, expectedText); }); it('... should display query in span in second div', () => { @@ -1299,10 +1211,7 @@ describe('ResourceInfoComponent (DONE)', () => { const spanDes = getAndExpectDebugElementByCss(divDes[1], 'span', 1, 1); const spanEl = spanDes[0].nativeElement; - expect(spanEl.innerText).toBeTruthy(); - expect(spanEl.innerText) - .withContext(`should be ${expectedQuery}`) - .toBe(jsonPipe.transform(expectedQuery)); + expectToBe(spanEl.innerText, jsonPipe.transform(expectedQuery)); }); it('... should display `---` without query in span in second div', () => { @@ -1316,8 +1225,7 @@ describe('ResourceInfoComponent (DONE)', () => { const expectedText = '---'; - expect(spanEl.innerText).toBeTruthy(); - expect(spanEl.innerText).withContext(`should be ${expectedText}`).toBe(expectedText); + expectToBe(spanEl.innerText, expectedText); }); }); @@ -1406,7 +1314,7 @@ describe('ResourceInfoComponent (DONE)', () => { const iconDes = getAndExpectDebugElementByCss(strongDes[0], 'fa-icon', 1, 1); expect(iconDes[0].children[0]).toBeTruthy(); expect(iconDes[0].children[0].classes).toBeTruthy(); - expect(iconDes[0].children[0].classes['fa-chevron-left']).toBeTrue(); + expectToBe(iconDes[0].children[0].classes['fa-chevron-left'], true); }); it('... should point to previous resource in span in strong element', () => { @@ -1427,10 +1335,7 @@ describe('ResourceInfoComponent (DONE)', () => { const expectedIndex = component.resourceInfoData.resources.previous.displayIndex; // = 2 const expectedInnerText = `Vorheriges Ergebnis (${expectedIndex}/${expectedResultSize})`; - expect(spanEl.innerText).toBeTruthy(); - expect(spanEl.innerText) - .withContext(`should be ${expectedInnerText}`) - .toBe(expectedInnerText); + expectToBe(spanEl.innerText, expectedInnerText); }); it('... should have two divs.single-line in second div', () => { @@ -1465,8 +1370,7 @@ describe('ResourceInfoComponent (DONE)', () => { const spanEl0 = spanDes[0].nativeElement; const title = component.resourceInfoData.resources.previous.title; // = Nelson 1974 - expect(spanEl0.innerText).toBeTruthy(); - expect(spanEl0.innerText).withContext(`should be ${title}`).toBe(title); + expectToBe(spanEl0.innerText, title); }); it('... should display previous subtitle in second div.single-line', () => { @@ -1485,8 +1389,7 @@ describe('ResourceInfoComponent (DONE)', () => { const spanEl1 = spanDes[1].nativeElement; const subTitle = component.resourceInfoData.resources.previous.subtitle; // = Bibliografie - expect(spanEl1.innerText).toBeTruthy(); - expect(spanEl1.innerText).withContext(`should be ${subTitle}`).toBe(subTitle); + expectToBe(spanEl1.innerText, subTitle); }); }); @@ -1503,10 +1406,7 @@ describe('ResourceInfoComponent (DONE)', () => { }); it('... should have current.displayIndex === 1', () => { - expect(component.resourceInfoData.resources.current.displayIndex).toBeTruthy(); - expect(component.resourceInfoData.resources.current.displayIndex) - .withContext('should be 1') - .toBe(1); + expectToBe(component.resourceInfoData.resources.current.displayIndex, 1); }); it('... should have list-group-item-danger class', () => { @@ -1556,7 +1456,7 @@ describe('ResourceInfoComponent (DONE)', () => { expect(iconDes[0].children[0]).toBeTruthy(); expect(iconDes[0].children[0].classes).toBeTruthy(); - expect(iconDes[0].children[0].classes['fa-circle-xmark']).toBeTrue(); + expectToBe(iconDes[0].children[0].classes['fa-circle-xmark'], true); }); it('... should have two empty divs.single-line in second div', () => { @@ -1581,15 +1481,8 @@ describe('ResourceInfoComponent (DONE)', () => { const whiteSpace = '\xA0'; // Hex code for a non-breaking space ' ' - expect(spanEl0.innerText).toBeTruthy(); - expect(spanEl0.innerText) - .withContext(`should be non-breaking whiteSpace ${whiteSpace}`) - .toBe(whiteSpace); - - expect(spanEl1.innerText).toBeTruthy(); - expect(spanEl1.innerText) - .withContext(`should be non-breaking whiteSpace ${whiteSpace}`) - .toBe(whiteSpace); + expectToBe(spanEl0.innerText, whiteSpace); + expectToBe(spanEl1.innerText, whiteSpace); }); }); }); @@ -1650,10 +1543,7 @@ describe('ResourceInfoComponent (DONE)', () => { const expectedIndex = component.resourceInfoData.resources.current.displayIndex; // = 3 const expectedInnerText = `Angezeigtes Ergebnis (${expectedIndex}/${expectedResultSize})`; - expect(spanEl.innerText).toBeTruthy(); - expect(spanEl.innerText) - .withContext(`should be ${expectedInnerText}`) - .toBe(expectedInnerText); + expectToBe(spanEl.innerText, expectedInnerText); }); it('... should contain one div with button and an input in form > div.input-group', () => { @@ -1687,22 +1577,10 @@ describe('ResourceInfoComponent (DONE)', () => { 1 ); - // FormControlName='resourceInfoIndex' - expect(inputDes[0].attributes['formControlName']).toBeTruthy(); - expect(inputDes[0].attributes['formControlName']) - .withContext('should be resourceInfoIndex') - .toBe('resourceInfoIndex'); - - // Type='number' - expect(inputDes[0].attributes['type']).toBeTruthy(); - expect(inputDes[0].attributes['type']).withContext('should be number').toBe('number'); - - // Size=4 - expect(inputDes[0].attributes['size']).toBeTruthy(); - expect(inputDes[0].attributes['size']).withContext('should be 4').toBe('4'); - // Step=1 - expect(inputDes[0].attributes['step']).toBeTruthy(); - expect(inputDes[0].attributes['step']).withContext('should be 1').toBe('1'); + expectToBe(inputDes[0].attributes['formControlName'], 'resourceInfoIndex'); + expectToBe(inputDes[0].attributes['type'], 'number'); + expectToBe(inputDes[0].attributes['size'], '4'); + expectToBe(inputDes[0].attributes['step'], '1'); }); describe('button', () => { @@ -1715,15 +1593,9 @@ describe('ResourceInfoComponent (DONE)', () => { ); const buttonEl = buttonDes[0].nativeElement; - // Type='submit' - expect(buttonDes[0].attributes['type']).toBeTruthy(); - expect(buttonDes[0].attributes['type']).withContext('should be submit').toBe('submit'); - - // Class=btn + expectToBe(buttonDes[0].attributes['type'], 'submit'); expect(buttonEl).toHaveClass('btn'); - - // Disabled = true - expect(buttonEl.disabled).toBeTrue(); + expectToBe(buttonEl.disabled, true); }); it('... should display innerHTML text', () => { @@ -1737,8 +1609,7 @@ describe('ResourceInfoComponent (DONE)', () => { const expectedText = 'Gehe zu'; - expect(buttonEl.innerText).toBeTruthy(); - expect(buttonEl.innerText).withContext(`should be ${expectedText}`).toBe(expectedText); + expectToBe(buttonEl.innerText, expectedText); }); it('... should have btn-outline-success class when form is valid', () => { @@ -1795,13 +1666,11 @@ describe('ResourceInfoComponent (DONE)', () => { const resourceInfoIndex = component.resourceInfoFormGroup.controls['resourceInfoIndex']; // Input index is current.displayIndex - expect(resourceInfoIndex.value) - .withContext( - `should be ${component.resourceInfoData.resources.current.displayIndex}` - ) - .toBe(component.resourceInfoData.resources.current.displayIndex); - // Disabled = true - expect(buttonEl.disabled).toBeTrue(); + expectToBe( + resourceInfoIndex.value, + component.resourceInfoData.resources.current.displayIndex + ); + expectToBe(buttonEl.disabled, true); }); it('... should be disabled when form is not valid', () => { @@ -1825,7 +1694,7 @@ describe('ResourceInfoComponent (DONE)', () => { expect(component.resourceInfoFormGroup.invalid).toBeTruthy(); // Disabled = true - expect(buttonEl.disabled).toBeTrue(); + expectToBe(buttonEl.disabled, true); }); it('... should be enabled when input index is not current.displayIndex and form is valid', () => { @@ -1849,14 +1718,10 @@ describe('ResourceInfoComponent (DONE)', () => { expect(component.resourceInfoFormGroup.invalid).toBeFalsy(); // Input index is different from current.displayIndex - expect(resourceInfoIndex.value) - .withContext( - `should not be ${component.resourceInfoData.resources.current.displayIndex}` - ) - .not.toBe(component.resourceInfoData.resources.current.displayIndex); - - // Disabled = false - expect(buttonEl.disabled).toBeFalse(); + expect(resourceInfoIndex.value).not.toBe( + component.resourceInfoData.resources.current.displayIndex + ); + expectToBe(buttonEl.disabled, false); }); it('... should not be able to navigate to resource by index when button is disabled', fakeAsync(() => { @@ -1872,7 +1737,8 @@ describe('ResourceInfoComponent (DONE)', () => { // --------------------------- // DISABLED: case 1 // Input index is current.displayIndex - expect(resourceInfoIndex.value).toBe( + expectToBe( + resourceInfoIndex.value, component.resourceInfoData.resources.current.displayIndex ); @@ -1881,7 +1747,7 @@ describe('ResourceInfoComponent (DONE)', () => { expect(component.resourceInfoFormGroup.invalid).toBeFalsy(); // Disabled = true - expect(buttonEl.disabled).toBeTrue(); + expectToBe(buttonEl.disabled, true); // Trigger click on button with click helper & wait for changes clickAndAwaitChanges(buttonDes[0], fixture); @@ -1901,7 +1767,7 @@ describe('ResourceInfoComponent (DONE)', () => { expect(component.resourceInfoFormGroup.invalid).toBeTruthy(); // Disabled = true - expect(buttonEl.disabled).toBeTrue(); + expectToBe(buttonEl.disabled, true); // Trigger click on button with click helper & wait for changes clickAndAwaitChanges(buttonDes[0], fixture); @@ -1936,7 +1802,7 @@ describe('ResourceInfoComponent (DONE)', () => { expect(component.resourceInfoFormGroup.invalid).toBeFalsy(); // Button.disabled = false - expect(buttonEl.disabled).toBeFalse(); + expectToBe(buttonEl.disabled, false); // Trigger click on button with click helper & wait for changes clickAndAwaitChanges(buttonDes[0], fixture); @@ -2032,7 +1898,7 @@ describe('ResourceInfoComponent (DONE)', () => { const iconDes = getAndExpectDebugElementByCss(strongDes[0], 'fa-icon', 1, 1); expect(iconDes[0].children[0]).toBeTruthy(); expect(iconDes[0].children[0].classes).toBeTruthy(); - expect(iconDes[0].children[0].classes['fa-chevron-right']).toBeTrue(); + expectToBe(iconDes[0].children[0].classes['fa-chevron-right'], true); }); it('... should point to previous resource in span in strong element', () => { @@ -2053,10 +1919,7 @@ describe('ResourceInfoComponent (DONE)', () => { const expectedIndex = component.resourceInfoData.resources.next.displayIndex; // = 4 const expectedInnerText = `Nächstes Ergebnis (${expectedIndex}/${expectedResultSize})`; - expect(spanEl.innerText).toBeTruthy(); - expect(spanEl.innerText) - .withContext(`should be ${expectedInnerText}`) - .toBe(expectedInnerText); + expectToBe(spanEl.innerText, expectedInnerText); }); it('... should have two divs.single-line in second div', () => { @@ -2091,8 +1954,7 @@ describe('ResourceInfoComponent (DONE)', () => { const spanEl0 = spanDes[0].nativeElement; const title = component.resourceInfoData.resources.next.title; // = BrownJ 2014 - expect(spanEl0.innerText).toBeTruthy(); - expect(spanEl0.innerText).withContext(`should be ${title}`).toBe(title); + expectToBe(spanEl0.innerText, title); }); it('... should display next subtitle in second div.single-line', () => { @@ -2112,8 +1974,7 @@ describe('ResourceInfoComponent (DONE)', () => { const spanEl1 = spanDes[1].nativeElement; const subTitle = component.resourceInfoData.resources.next.subtitle; // = Bibliografie - expect(spanEl1.innerText).toBeTruthy(); - expect(spanEl1.innerText).withContext(`should be ${subTitle}`).toBe(subTitle); + expectToBe(spanEl1.innerText, subTitle); }); }); @@ -2130,10 +1991,7 @@ describe('ResourceInfoComponent (DONE)', () => { }); it('... should have current.displayIndex === resultSize', () => { - expect(component.resourceInfoData.resources.current.displayIndex).toBeTruthy(); - expect(component.resourceInfoData.resources.current.displayIndex) - .withContext(`should be ${component.resultSize}`) - .toBe(component.resultSize); + expectToBe(component.resourceInfoData.resources.current.displayIndex, component.resultSize); }); it('... should have list-group-item-danger class', () => { @@ -2177,7 +2035,7 @@ describe('ResourceInfoComponent (DONE)', () => { const iconDes = getAndExpectDebugElementByCss(strongDes[0], 'fa-icon', 1, 1); expect(iconDes[0].children[0]).toBeTruthy(); expect(iconDes[0].children[0].classes).toBeTruthy(); - expect(iconDes[0].children[0].classes['fa-circle-xmark']).toBeTrue(); + expectToBe(iconDes[0].children[0].classes['fa-circle-xmark'], true); }); it('... should have two empty divs.single-line in second div', () => { @@ -2202,15 +2060,8 @@ describe('ResourceInfoComponent (DONE)', () => { const whiteSpace = '\xA0'; // Hex code for a non-breaking space ' ' - expect(spanEl0.innerText).withContext(`should be truthy`).toBeTruthy(); - expect(spanEl0.innerText) - .withContext(`should be non-breaking whiteSpace ${whiteSpace}`) - .toBe(whiteSpace); - - expect(spanEl1.innerText).withContext(`should be truthy`).toBeTruthy(); - expect(spanEl1.innerText) - .withContext(`should be non-breaking whiteSpace ${whiteSpace}`) - .toBe(whiteSpace); + expectToBe(spanEl0.innerText, whiteSpace); + expectToBe(spanEl1.innerText, whiteSpace); }); }); }); @@ -2224,8 +2075,8 @@ describe('ResourceInfoComponent (DONE)', () => { const aDe = getAndExpectDebugElementByCss(compDe, 'div.card-footer a', 1, 1); const aEl = aDe[0].nativeElement; - expect(aEl.href).withContext(`should be ${expectedHref}`).toBe(expectedHref); - expect(aEl.innerText).withContext(`should be ${expectedInnerText}`).toBe(expectedInnerText); + expectToBe(aEl.href, expectedHref); + expectToBe(aEl.innerText, expectedInnerText); }); }); }); diff --git a/src/app/side-info/structure-info/structure-info.component.spec.ts b/src/app/side-info/structure-info/structure-info.component.spec.ts index 5eb40b2be..54ef7ba3f 100644 --- a/src/app/side-info/structure-info/structure-info.component.spec.ts +++ b/src/app/side-info/structure-info/structure-info.component.spec.ts @@ -2,7 +2,7 @@ import { DebugElement } from '@angular/core'; import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { cleanStylesFromDOM } from '@testing/clean-up-helper'; -import { getAndExpectDebugElementByCss } from '@testing/expect-helper'; +import { expectToBe, expectToContain, expectToEqual, getAndExpectDebugElementByCss } from '@testing/expect-helper'; import { METADATA } from '@awg-core/core-data'; import { MetaSectionTypes, MetaStructure } from '@awg-core/core-models'; @@ -54,15 +54,12 @@ describe('StructureInfoComponent (DONE)', () => { it('... injected service should use provided mockValue', () => { const coreService = TestBed.inject(CoreService); - expect(mockCoreService === coreService).toBe(true); + expectToBe(mockCoreService === coreService, true); }); describe('BEFORE initial data binding', () => { it('... should have structureInfoHeader', () => { - expect(component.structureInfoHeader).toBeDefined(); - expect(component.structureInfoHeader) - .withContext(`should be ${expectedStructureInfoHeader}`) - .toBe(expectedStructureInfoHeader); + expectToBe(component.structureInfoHeader, expectedStructureInfoHeader); }); describe('#provideMetaData()', () => { @@ -94,25 +91,22 @@ describe('StructureInfoComponent (DONE)', () => { const headerDes = getAndExpectDebugElementByCss(compDe, 'h5#awg-structure-info-header', 1, 1); const headerEl = headerDes[0].nativeElement; - expect(headerEl).toBeDefined(); - expect(headerEl.textContent).toBeFalsy(); + expectToBe(headerEl.textContent, ''); }); it('... should not render author information yet', () => { const authorDes = getAndExpectDebugElementByCss(compDe, 'span.awg-structure-info-author a', 1, 1); const authorEl = authorDes[0].nativeElement; - expect(authorEl).toBeDefined(); - expect(authorEl.href).toBeFalsy(); - expect(authorEl.innerHTML).toBeFalsy(); + expectToBe(authorEl.href, ''); + expectToBe(authorEl.innerHTML, ''); }); it('... should not render last modification date yet', () => { const dateDes = getAndExpectDebugElementByCss(compDe, 'span#awg-structure-info-lastmodified', 1, 1); const dateEl = dateDes[0].nativeElement; - expect(dateEl).toBeDefined(); - expect(dateEl.textContent).toBeFalsy(); + expectToBe(dateEl.textContent, ''); }); }); }); @@ -132,10 +126,7 @@ describe('StructureInfoComponent (DONE)', () => { }); it('... should return structureMetaData', () => { - expect(component.structureMetaData).toBeDefined(); - expect(component.structureMetaData) - .withContext(`should be ${expectedStructureMetaData}`) - .toBe(expectedStructureMetaData); + expectToEqual(component.structureMetaData, expectedStructureMetaData); }); }); @@ -144,10 +135,7 @@ describe('StructureInfoComponent (DONE)', () => { const headerDes = getAndExpectDebugElementByCss(compDe, 'h5#awg-structure-info-header', 1, 1); const headerEl = headerDes[0].nativeElement; - expect(headerEl).toBeDefined(); - expect(headerEl.textContent) - .withContext(`should be ${expectedStructureInfoHeader}`) - .toBe(expectedStructureInfoHeader); + expectToBe(headerEl.textContent, expectedStructureInfoHeader); }); it('... should render author information', () => { @@ -156,9 +144,8 @@ describe('StructureInfoComponent (DONE)', () => { const authorDes = getAndExpectDebugElementByCss(compDe, 'span.awg-structure-info-author a', 1, 1); const authorEl = authorDes[0].nativeElement; - expect(authorEl).toBeDefined(); - expect(authorEl.href).withContext(`should be ${expectedAuthor.homepage}`).toBe(expectedAuthor.homepage); - expect(authorEl.innerHTML).withContext(`should be ${expectedAuthor.name}`).toBe(expectedAuthor.name); + expectToBe(authorEl.href, expectedAuthor.homepage); + expectToBe(authorEl.innerHTML, expectedAuthor.name); }); it('... should render last modification date', () => { @@ -167,10 +154,7 @@ describe('StructureInfoComponent (DONE)', () => { const lastmodDes = getAndExpectDebugElementByCss(compDe, 'span#awg-structure-info-lastmodified', 1, 1); const lastmodEl = lastmodDes[0].nativeElement; - expect(lastmodEl.textContent).toBeDefined(); - expect(lastmodEl.textContent) - .withContext(`should contain ${expectedLastModified}`) - .toContain(expectedLastModified); + expectToContain(lastmodEl.textContent, expectedLastModified); }); }); }); diff --git a/src/app/views/contact-view/contact-view.component.spec.ts b/src/app/views/contact-view/contact-view.component.spec.ts index b9beb02be..12b1cc71e 100644 --- a/src/app/views/contact-view/contact-view.component.spec.ts +++ b/src/app/views/contact-view/contact-view.component.spec.ts @@ -9,6 +9,9 @@ import Spy = jasmine.Spy; import { cleanStylesFromDOM } from '@testing/clean-up-helper'; import { expectSpyCall, + expectToBe, + expectToContain, + expectToEqual, getAndExpectDebugElementByCss, getAndExpectDebugElementByDirective, } from '@testing/expect-helper'; @@ -93,43 +96,27 @@ describe('ContactViewComponent (DONE)', () => { it('... injected service should use provided mockValue', () => { const coreService = TestBed.inject(CoreService); - expect(mockCoreService === coreService).toBe(true); + expectToBe(mockCoreService === coreService, true); }); describe('BEFORE initial data binding', () => { it('... should have imprint title and id', () => { - expect(component.imprintTitle).toBeDefined(); - expect(component.imprintTitle).withContext(`should be ${expectedImprintTitle}`).toBe(expectedImprintTitle); - - expect(component.imprintId).toBeDefined(); - expect(component.imprintId).withContext(`should be ${expectedImprintId}`).toBe(expectedImprintId); + expectToBe(component.imprintTitle, expectedImprintTitle); + expectToBe(component.imprintId, expectedImprintId); }); it('... should have citation title and id', () => { - expect(component.citationTitle).toBeDefined(); - expect(component.citationTitle) - .withContext(`should be ${expectedCitationTitle}`) - .toBe(expectedCitationTitle); - - expect(component.citationId).toBeDefined(); - expect(component.citationId).withContext(`should be ${expectedCitationId}`).toBe(expectedCitationId); + expectToBe(component.citationTitle, expectedCitationTitle); + expectToBe(component.citationId, expectedCitationId); }); it('... should have documentation title and id', () => { - expect(component.documentationTitle).toBeDefined(); - expect(component.documentationTitle) - .withContext(`should be ${expectedDocumentationTitle}`) - .toBe(expectedDocumentationTitle); - - expect(component.documentationId).toBeDefined(); - expect(component.documentationId) - .withContext(`should be ${expectedDocumentationId}`) - .toBe(expectedDocumentationId); + expectToBe(component.documentationTitle, expectedDocumentationTitle); + expectToBe(component.documentationId, expectedDocumentationId); }); it('... should have dateFormat', () => { - expect(component.dateFormat).toBeDefined(); - expect(component.dateFormat).withContext(`should be ${expectedDateFormat}`).toBe(expectedDateFormat); + expectToBe(component.dateFormat, expectedDateFormat); }); it('... should not have metadata nor `today`', () => { @@ -210,16 +197,10 @@ describe('ContactViewComponent (DONE)', () => { const dateEl1 = dateDes[1].nativeElement; // Check output - expect(versionEl).toBeDefined(); - expect(versionEl.textContent).withContext('should be empty string').toBe(''); - - expect(releaseEl).toBeDefined(); - expect(releaseEl.textContent).withContext('should be empty string').toBe(''); - - expect(dateEl0).toBeDefined(); - expect(dateEl0.textContent).withContext('should be empty string').toBe(''); - expect(dateEl1).toBeDefined(); - expect(dateEl1.textContent).withContext('should be empty string').toBe(''); + expectToBe(versionEl.textContent, ''); + expectToBe(releaseEl.textContent, ''); + expectToBe(dateEl0.textContent, ''); + expectToBe(dateEl1.textContent, ''); }); }); }); @@ -253,8 +234,8 @@ describe('ContactViewComponent (DONE)', () => { it('... should have triggered `router.navigate`', () => { expect(navigationSpy).toHaveBeenCalled(); - expect(navigationSpy.calls.any()).withContext('has any calls').toEqual(true); - expect(navigationSpy.calls.count()).withContext('has been called only once').toEqual(1); + expectToBe(navigationSpy.calls.any(), true); + expectToBe(navigationSpy.calls.count(), 1); }); it('... should tell ROUTER to navigate to `contactInfo` outlet', () => { @@ -266,8 +247,7 @@ describe('ContactViewComponent (DONE)', () => { expect(navArgs).toBeDefined(); expect(navArgs[0]).toBeDefined(); - expect(outletRoute).toBeDefined(); - expect(outletRoute).withContext(`should be: ${expectedRoute}`).toBe(expectedRoute); + expectToBe(outletRoute, expectedRoute); expect(navigationSpy).toHaveBeenCalledWith(navArgs[0], navArgs[1]); }); @@ -277,8 +257,7 @@ describe('ContactViewComponent (DONE)', () => { const navExtras = navArgs[1]; expect(navExtras).toBeDefined(); - expect(navExtras.preserveFragment).toBeDefined(); - expect(navExtras.preserveFragment).toBeTrue(); + expectToBe(navExtras.preserveFragment, true); expect(navigationSpy).toHaveBeenCalledWith(navArgs[0], navArgs[1]); }); }); @@ -289,22 +268,14 @@ describe('ContactViewComponent (DONE)', () => { }); it('... should return metadata', () => { - expect(component.pageMetaData).toBeDefined(); - expect(component.pageMetaData) - .withContext(`should be: ${expectedPageMetaData}`) - .toBe(expectedPageMetaData); - - expect(component.contactMetaData).toBeDefined(); - expect(component.contactMetaData) - .withContext(`should be: ${expectedContactMetaData}`) - .toBe(expectedContactMetaData); + expectToEqual(component.pageMetaData, expectedPageMetaData); + expectToEqual(component.contactMetaData, expectedContactMetaData); }); }); it('... should have `today`', () => { expectSpyCall(dateSpy, 1); - expect(component.today).toBeDefined(); - expect(component.today).withContext(`should be ${expectedToday}`).toBe(expectedToday); + expectToBe(component.today, expectedToday); }); describe('VIEW', () => { @@ -312,31 +283,14 @@ describe('ContactViewComponent (DONE)', () => { const headingDes = getAndExpectDebugElementByDirective(compDe, HeadingStubComponent, 3, 3); const headingCmps = headingDes.map(de => de.injector.get(HeadingStubComponent) as HeadingStubComponent); - expect(headingCmps[0].title).toBeTruthy(); - expect(headingCmps[0].title) - .withContext(`should have title: ${expectedCitationTitle}`) - .toBe(expectedCitationTitle); - - expect(headingCmps[0].id).toBeTruthy(); - expect(headingCmps[0].id).withContext(`should have id: ${expectedCitationId}`).toBe(expectedCitationId); - - expect(headingCmps[1].title).toBeTruthy(); - expect(headingCmps[1].title) - .withContext(`should have title: ${expectedDocumentationTitle}`) - .toBe(expectedDocumentationTitle); - - expect(headingCmps[1].id).toBeTruthy(); - expect(headingCmps[1].id) - .withContext(`should have id: ${expectedDocumentationId}`) - .toBe(expectedDocumentationId); + expectToBe(headingCmps[0].title, expectedCitationTitle); + expectToBe(headingCmps[0].id, expectedCitationId); - expect(headingCmps[2].title).toBeTruthy(); - expect(headingCmps[2].title) - .withContext(`should have title: ${expectedImprintTitle}`) - .toBe(expectedImprintTitle); + expectToBe(headingCmps[1].title, expectedDocumentationTitle); + expectToBe(headingCmps[1].id, expectedDocumentationId); - expect(headingCmps[2].id).toBeTruthy(); - expect(headingCmps[2].id).withContext(`should have id: ${expectedImprintId}`).toBe(expectedImprintId); + expectToBe(headingCmps[2].title, expectedImprintTitle); + expectToBe(headingCmps[2].id, expectedImprintId); }); it('... should render `version`, `versionReleaseDate` and `today`', () => { @@ -355,20 +309,10 @@ describe('ContactViewComponent (DONE)', () => { const pipedToday = datePipe.transform(expectedToday, expectedDateFormat); // Check output - expect(versionEl).toBeDefined(); - expect(versionEl.textContent) - .withContext(`should contain ${expectedPageMetaData.version}`) - .toContain(expectedPageMetaData.version); - - expect(releaseEl).toBeDefined(); - expect(releaseEl.textContent) - .withContext(`should contain ${expectedPageMetaData.versionReleaseDate}`) - .toContain(expectedPageMetaData.versionReleaseDate); - - expect(dateEl0).toBeDefined(); - expect(dateEl0.textContent).withContext(`should contain ${pipedToday}`).toContain(pipedToday); - expect(dateEl1).toBeDefined(); - expect(dateEl1.textContent).withContext(`should contain ${pipedToday}`).toContain(pipedToday); + expectToContain(versionEl.textContent, expectedPageMetaData.version); + expectToContain(releaseEl.textContent, expectedPageMetaData.versionReleaseDate); + expectToContain(dateEl0.textContent, pipedToday); + expectToContain(dateEl1.textContent, pipedToday); }); }); }); diff --git a/src/app/views/data-view/data-outlets/bibliography/bibliography-detail/bibliography-detail.component.spec.ts b/src/app/views/data-view/data-outlets/bibliography/bibliography-detail/bibliography-detail.component.spec.ts index 8c4ad9603..96b49a848 100644 --- a/src/app/views/data-view/data-outlets/bibliography/bibliography-detail/bibliography-detail.component.spec.ts +++ b/src/app/views/data-view/data-outlets/bibliography/bibliography-detail/bibliography-detail.component.spec.ts @@ -2,12 +2,14 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { Observable, of as observableOf } from 'rxjs'; +import { expectToBe } from '@testing/expect-helper'; + import { ConversionService } from '@awg-core/services'; import { ResourceFullResponseJson } from '@awg-shared/api-objects'; +import { BibliographyFormatPipe } from '@awg-views/data-view/data-outlets/bibliography//bibliography-format.pipe'; +import { BibEntry } from '@awg-views/data-view/data-outlets/bibliography/bibliography-entry.model'; import { BibliographyService } from '@awg-views/data-view/services'; -import { BibEntry } from '../bibliography-entry.model'; -import { BibliographyFormatPipe } from '../bibliography-format.pipe'; import { BibliographyDetailComponent } from './bibliography-detail.component'; describe('BibliographyDetailComponent', () => { @@ -73,8 +75,7 @@ describe('BibliographyDetailComponent', () => { }); it('... should have objId input', () => { - expect(component.objId).toBeTruthy(); - expect(component.objId).withContext(`should be ${expectedObjId}`).toBe(expectedObjId); + expectToBe(component.objId, expectedObjId); }); }); }); diff --git a/src/app/views/data-view/data-outlets/bibliography/bibliography.component.spec.ts b/src/app/views/data-view/data-outlets/bibliography/bibliography.component.spec.ts index af8f66115..989974d92 100644 --- a/src/app/views/data-view/data-outlets/bibliography/bibliography.component.spec.ts +++ b/src/app/views/data-view/data-outlets/bibliography/bibliography.component.spec.ts @@ -5,6 +5,8 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { Observable, of as observableOf } from 'rxjs'; import Spy = jasmine.Spy; +import { expectToBe } from '@testing/expect-helper'; + import { SearchResponseJson, SubjectItemJson } from '@awg-shared/api-objects'; import { BibliographyService } from '@awg-views/data-view/services'; @@ -76,6 +78,6 @@ describe('BibliographyComponent', () => { }); it('... injected bibliography service should use provided mockValue', () => { - expect(bibliographyService === mockBibliographyService).toBe(true); + expectToBe(bibliographyService === mockBibliographyService, true); }); }); diff --git a/src/app/views/data-view/data-outlets/resource-detail/resource-detail-header/resource-detail-header.component.spec.ts b/src/app/views/data-view/data-outlets/resource-detail/resource-detail-header/resource-detail-header.component.spec.ts index 4f0658a34..4a4e66097 100644 --- a/src/app/views/data-view/data-outlets/resource-detail/resource-detail-header/resource-detail-header.component.spec.ts +++ b/src/app/views/data-view/data-outlets/resource-detail/resource-detail-header/resource-detail-header.component.spec.ts @@ -4,6 +4,8 @@ import { ComponentFixture, fakeAsync, TestBed, waitForAsync } from '@angular/cor import { clickAndAwaitChanges } from '@testing/click-helper'; import { expectSpyCall, + expectToBe, + expectToContain, getAndExpectDebugElementByCss, getAndExpectDebugElementByDirective, } from '@testing/expect-helper'; @@ -84,11 +86,9 @@ describe('ResourceDetailHtmlHeaderComponent (DONE)', () => { it('... should contain span in h2.title with compile html component with no inner html yet', () => { const titleDe = getAndExpectDebugElementByCss(compDe, 'div.resource-title > h2.title', 1, 1); - // Find DebugElements with an attached CompileHtmlComponent const htmlDes = getAndExpectDebugElementByDirective(titleDe[0], CompileHtmlComponent, 1, 1); - expect(htmlDes[0].name).toBe('span'); + expectToBe(htmlDes[0].name, 'span'); - // Find anchor links of CompileHtmlComponent getAndExpectDebugElementByCss(htmlDes[0], 'a', 0, 0); }); @@ -96,8 +96,7 @@ describe('ResourceDetailHtmlHeaderComponent (DONE)', () => { const rLinkDe = getAndExpectDebugElementByCss(compDe, 'div.col-lg-8 > div.resource-link', 1, 1); const rLinkEl = rLinkDe[0].nativeElement; - expect(rLinkEl.textContent).toBeDefined(); - expect(rLinkEl.textContent).withContext(`should contain ' API-Request: '`).toContain(' API-Request: '); + expectToContain(rLinkEl.textContent, ' API-Request: '); }); it('... should contain one table.resource-header-table', () => { @@ -127,33 +126,25 @@ describe('ResourceDetailHtmlHeaderComponent (DONE)', () => { fixture.detectChanges(); }); - it('... should have `header` or `resourceUrl` inputs', () => { - expect(component.header).toBeDefined(); - expect(component.header).withContext(`should be ${expectedHeader}`).toBe(expectedHeader); - - expect(component.resourceUrl).toBeDefined(); - expect(component.resourceUrl).withContext(`should be ${expectedResourceUrl}`).toBe(expectedResourceUrl); + it('... should have `header` and `resourceUrl` inputs', () => { + expectToBe(component.header, expectedHeader); + expectToBe(component.resourceUrl, expectedResourceUrl); }); describe('VIEW', () => { it('... should render header title in compile html component span', () => { const expectedTitle = 'Op. 28: Skizzen zu einem "1. Satz" (später 2. Satz [M 330])'; - // Find DebugElements with an attached CompileHtmlComponent const htmlDes = getAndExpectDebugElementByDirective(compDe, CompileHtmlComponent, 1, 1); const htmlEl = htmlDes[0].nativeElement; - expect(htmlDes[0].name).toBeDefined(); - expect(htmlDes[0].name).withContext(`should be 'span'`).toBe('span'); - - expect(htmlEl.textContent).toBeDefined(); - expect(htmlEl.textContent).withContext(`should contain ${expectedTitle}`).toContain(expectedTitle); + expectToBe(htmlDes[0].name, 'span'); + expectToContain(htmlEl.textContent, expectedTitle); }); it('... should have 3 anchor links in compile html component span', () => { - // Find DebugElements with an attached CompileHtmlComponent const htmlDes = getAndExpectDebugElementByDirective(compDe, CompileHtmlComponent, 1, 1); - // Find anchor links of CompileHtmlComponent + getAndExpectDebugElementByCss(htmlDes[0], 'a', 3, 3); }); @@ -172,33 +163,17 @@ describe('ResourceDetailHtmlHeaderComponent (DONE)', () => { const lastModEl = lastModDes[0].nativeElement; // Check output - expect(tdEl.textContent).toBeTruthy(); - expect(tdEl.textContent) - .withContext(`should contain ${expectedHeader.objID}`) - .toContain(expectedHeader.objID); - - expect(typeEl.textContent).toBeTruthy(); - expect(typeEl.textContent) - .withContext(`should contain ${expectedHeader.type}`) - .toContain(expectedHeader.type); - - expect(imgEl.src).toBeTruthy(); - expect(imgEl.src).withContext(`should be ${expectedHeader.icon}`).toContain(expectedHeader.icon); - - expect(lastModEl.textContent).toBeTruthy(); - expect(lastModEl.textContent) - .withContext(`should contain '${expectedHeader.lastmod}'`) - .toContain(expectedHeader.lastmod); + expectToBe(tdEl.textContent, expectedHeader.objID); + expectToBe(typeEl.textContent, expectedHeader.type); + expectToContain(imgEl.src, expectedHeader.icon); + expectToBe(lastModEl.textContent, expectedHeader.lastmod); }); it('... should render resourceUrl in div.resource-link', () => { const rLinkDe = getAndExpectDebugElementByCss(compDe, 'div.resource-link', 1, 1); const rLinkEl = rLinkDe[0].nativeElement; - expect(rLinkEl.textContent).toBeTruthy(); - expect(rLinkEl.textContent) - .withContext(`should contain ' API-Request: ${expectedResourceUrl}'`) - .toContain(' API-Request: ' + expectedResourceUrl); + expectToBe(rLinkEl.textContent, ' API-Request: ' + expectedResourceUrl); }); }); diff --git a/src/app/views/data-view/data-outlets/resource-detail/resource-detail-html/resource-detail-html-content/imageobjects/imageobjects.component.spec.ts b/src/app/views/data-view/data-outlets/resource-detail/resource-detail-html/resource-detail-html-content/imageobjects/imageobjects.component.spec.ts index a36fedf8e..25e58ed63 100644 --- a/src/app/views/data-view/data-outlets/resource-detail/resource-detail-html/resource-detail-html-content/imageobjects/imageobjects.component.spec.ts +++ b/src/app/views/data-view/data-outlets/resource-detail/resource-detail-html/resource-detail-html-content/imageobjects/imageobjects.component.spec.ts @@ -5,7 +5,12 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { NgxGalleryComponent, NgxGalleryImage, NgxGalleryModule, NgxGalleryOptions } from '@kolkov/ngx-gallery'; import { JsonConvert } from 'json2typescript'; -import { getAndExpectDebugElementByCss, getAndExpectDebugElementByDirective } from '@testing/expect-helper'; +import { + expectToBe, + expectToEqual, + getAndExpectDebugElementByCss, + getAndExpectDebugElementByDirective, +} from '@testing/expect-helper'; import { mockContextJson } from '@testing/mock-data'; import { ContextJson } from '@awg-shared/api-objects'; @@ -82,10 +87,7 @@ describe('ResourceDetailHtmlContentImageobjectsComponent', () => { }); it('... should have galleryOptions', () => { - expect(component.galleryOptions).toBeDefined(); - expect(component.galleryOptions) - .withContext(`should equal expectedGalleryOptions: ${expectedGalleryOptions}`) - .toEqual(jasmine.arrayContaining(expectedGalleryOptions)); + expectToEqual(component.galleryOptions, jasmine.arrayContaining(expectedGalleryOptions)); }); describe('VIEW', () => { @@ -105,8 +107,7 @@ describe('ResourceDetailHtmlContentImageobjectsComponent', () => { }); it('... should have `images` inputs', () => { - expect(component.images).toBeDefined(); - expect(component.images).withContext(`should be expectedImages: ${expectedImages}`).toBe(expectedImages); + expectToEqual(component.images, expectedImages); }); describe('VIEW', () => { @@ -115,17 +116,12 @@ describe('ResourceDetailHtmlContentImageobjectsComponent', () => { }); it('... should contain one header showing number of images', () => { - // Header debug element const headerDes = getAndExpectDebugElementByCss(compDe, 'div.awg-image-obj > h5', 1, 1); - // Size debug element + const sizeDes = getAndExpectDebugElementByCss(headerDes[0], 'span#awg-image-number', 1, 1); const sizeEl = sizeDes[0].nativeElement; - // Check size output - expect(sizeEl.textContent).toBeDefined(); - expect(sizeEl.textContent) - .withContext(`should be ${expectedImages.length.toString()}`) - .toBe(expectedImages.length.toString()); + expectToBe(sizeEl.textContent, expectedImages.length.toString()); }); it('... should contain one div.awg-image-slider with one NgxGalleryComponent', () => { @@ -144,15 +140,8 @@ describe('ResourceDetailHtmlContentImageobjectsComponent', () => { const galleryDes = getAndExpectDebugElementByDirective(compDe, NgxGalleryComponent, 1, 1); const galleryCmp = galleryDes[0].injector.get(NgxGalleryComponent) as NgxGalleryComponent; - expect(galleryCmp.options).toBeDefined(); - expect(galleryCmp.options) - .withContext(`should equal expectedGalleryOptions: ${expectedGalleryOptions}`) - .toEqual(expectedGalleryOptions); - - expect(galleryCmp.images).toBeDefined(); - expect(galleryCmp.images) - .withContext(`should equal expectedGalleryImages: ${expectedImages}`) - .toEqual(expectedImages); + expectToEqual(galleryCmp.options, expectedGalleryOptions); + expectToEqual(galleryCmp.images, expectedImages); }); }); }); diff --git a/src/app/views/data-view/data-outlets/resource-detail/resource-detail-html/resource-detail-html-content/props/props.component.spec.ts b/src/app/views/data-view/data-outlets/resource-detail/resource-detail-html/resource-detail-html-content/props/props.component.spec.ts index d1240183d..291b92a70 100644 --- a/src/app/views/data-view/data-outlets/resource-detail/resource-detail-html/resource-detail-html-content/props/props.component.spec.ts +++ b/src/app/views/data-view/data-outlets/resource-detail/resource-detail-html/resource-detail-html-content/props/props.component.spec.ts @@ -1,5 +1,5 @@ import { DebugElement, SimpleChange } from '@angular/core'; -import { ComponentFixture, fakeAsync, TestBed, waitForAsync } from '@angular/core/testing'; +import { ComponentFixture, TestBed, fakeAsync, waitForAsync } from '@angular/core/testing'; import Spy = jasmine.Spy; @@ -7,6 +7,9 @@ import { clickAndAwaitChanges } from '@testing/click-helper'; import { detectChangesOnPush } from '@testing/detect-changes-on-push-helper'; import { expectSpyCall, + expectToBe, + expectToContain, + expectToEqual, getAndExpectDebugElementByCss, getAndExpectDebugElementByDirective, } from '@testing/expect-helper'; @@ -81,10 +84,7 @@ describe('ResourceDetailHtmlContentPropsComponent (DONE)', () => { describe('BEFORE initial data binding', () => { it('... should have `metaBreakLine`', () => { - expect(component.metaBreakLine).withContext('should be defined').toBeDefined(); - expect(component.metaBreakLine) - .withContext(`should be ${expectedMetaBreakLine}`) - .toBe(expectedMetaBreakLine); + expectToBe(component.metaBreakLine, expectedMetaBreakLine); }); it('... should not have `props` input', () => { @@ -124,8 +124,7 @@ describe('ResourceDetailHtmlContentPropsComponent (DONE)', () => { const headerEl = headerDes[0].nativeElement; // Check output - expect(headerEl.textContent).toBeTruthy(); - expect(headerEl.textContent).withContext('Objektdaten').toContain('Objektdaten'); + expectToContain(headerEl.textContent, 'Objektdaten'); }); it('... should contain no ul with props yet', () => { @@ -144,8 +143,7 @@ describe('ResourceDetailHtmlContentPropsComponent (DONE)', () => { }); it('... should have `props` input', () => { - expect(component.props).withContext('should be defined').toBeDefined(); - expect(component.props).withContext(`should be expectedProps: ${expectedProps}`).toBe(expectedProps); + expectToEqual(component.props, expectedProps); }); describe('VIEW', () => { @@ -183,16 +181,11 @@ describe('ResourceDetailHtmlContentPropsComponent (DONE)', () => { const htmlDes = getAndExpectDebugElementByDirective(compDe, CompileHtmlComponent, 6, 6); htmlDes.forEach(html => { - expect(html.name).toBeTruthy(); - expect(html.name).withContext(`should be span`).toBe('span'); + expectToBe(html.name, 'span'); // Check parent - expect(html.parent.name).toBeTruthy(); - expect(html.parent.name).withContext(`should be li`).toBe('li'); - expect(html.parent.attributes['class']).toBeTruthy(); - expect(html.parent.attributes['class']) - .withContext(`should be awg-prop-value`) - .toBe('awg-prop-value'); + expectToBe(html.parent.name, 'li'); + expectToBe(html.parent.attributes['class'], 'awg-prop-value'); }); }); }); @@ -220,7 +213,7 @@ describe('ResourceDetailHtmlContentPropsComponent (DONE)', () => { }); expectSpyCall(exposeGndSpy, 1, gndRemoveEvent); - expect(exposeGndSpy.calls.mostRecent().args[0]).toEqual(gndRemoveEvent); + expectToEqual(exposeGndSpy.calls.mostRecent().args[0], gndRemoveEvent); })); it('... a REMOVE and SET event if props input contains a GND property', fakeAsync(() => { @@ -234,8 +227,8 @@ describe('ResourceDetailHtmlContentPropsComponent (DONE)', () => { // Gets triggered 2x (remove all old GND values & set new GND value) expectSpyCall(exposeGndSpy, 2, gndSetEvent); - expect(exposeGndSpy.calls.first().args[0]).toEqual(gndRemoveEvent); - expect(exposeGndSpy.calls.mostRecent().args[0]).toEqual(gndSetEvent); + expectToEqual(exposeGndSpy.calls.first().args[0], gndRemoveEvent); + expectToEqual(exposeGndSpy.calls.mostRecent().args[0], gndSetEvent); })); }); diff --git a/src/app/views/data-view/data-outlets/resource-detail/resource-detail-html/resource-detail-html-content/resource-detail-html-content.component.spec.ts b/src/app/views/data-view/data-outlets/resource-detail/resource-detail-html/resource-detail-html-content/resource-detail-html-content.component.spec.ts index 2b90b17a7..754291b11 100644 --- a/src/app/views/data-view/data-outlets/resource-detail/resource-detail-html/resource-detail-html-content/resource-detail-html-content.component.spec.ts +++ b/src/app/views/data-view/data-outlets/resource-detail/resource-detail-html/resource-detail-html-content/resource-detail-html-content.component.spec.ts @@ -1,5 +1,5 @@ import { Component, DebugElement, EventEmitter, Input, Output } from '@angular/core'; -import { ComponentFixture, fakeAsync, TestBed, waitForAsync } from '@angular/core/testing'; +import { ComponentFixture, TestBed, fakeAsync, waitForAsync } from '@angular/core/testing'; import Spy = jasmine.Spy; import { NgxGalleryImage } from '@kolkov/ngx-gallery'; @@ -7,6 +7,7 @@ import { JsonConvert } from 'json2typescript'; import { expectSpyCall, + expectToEqual, getAndExpectDebugElementByCss, getAndExpectDebugElementByDirective, } from '@testing/expect-helper'; @@ -174,10 +175,7 @@ describe('ResourceDetailHtmlContentComponent (DONE)', () => { }); it('... should have `content` inputs', () => { - expect(component.content).withContext('should be defined').toBeDefined(); - expect(component.content) - .withContext(`should be expectedIncoming: ${expectedContent}`) - .toBe(expectedContent); + expectToEqual(component.content, expectedContent); }); describe('VIEW', () => { @@ -193,8 +191,7 @@ describe('ResourceDetailHtmlContentComponent (DONE)', () => { ResourceDetailHtmlContentPropsStubComponent ) as ResourceDetailHtmlContentPropsStubComponent; - expect(propsCmp.props).withContext('should be defined').toBeDefined(); - expect(propsCmp.props).withContext(`should be ${expectedContent.props}`).toBe(expectedContent.props); + expectToEqual(propsCmp.props, expectedContent.props); }); it('... should pass down `content.images` to ResourceDetailHtmlContentImageobjectsComponent', () => { @@ -209,10 +206,7 @@ describe('ResourceDetailHtmlContentComponent (DONE)', () => { ResourceDetailHtmlContentImageobjectsStubComponent ) as ResourceDetailHtmlContentImageobjectsStubComponent; - expect(imagesCmp.images).withContext('should be defined').toBeDefined(); - expect(imagesCmp.images) - .withContext(`should be ${expectedContent.images}`) - .toBe(expectedContent.images); + expectToEqual(imagesCmp.images, expectedContent.images); }); it('... should pass down `content.incoming` to ResourceDetailHtmlContentLinkedobjectsComponent', () => { @@ -227,10 +221,7 @@ describe('ResourceDetailHtmlContentComponent (DONE)', () => { ResourceDetailHtmlContentLinkedobjectsStubComponent ) as ResourceDetailHtmlContentLinkedobjectsStubComponent; - expect(incomingCmp.incomingGroups).withContext('should be defined').toBeDefined(); - expect(incomingCmp.incomingGroups) - .withContext(`should be ${expectedContent.incoming}`) - .toBe(expectedContent.incoming); + expectToEqual(incomingCmp.incomingGroups, expectedContent.incoming); }); }); diff --git a/src/app/views/data-view/data-outlets/resource-detail/resource-detail-html/resource-detail-html.component.spec.ts b/src/app/views/data-view/data-outlets/resource-detail/resource-detail-html/resource-detail-html.component.spec.ts index 851a88bc5..6028f9882 100644 --- a/src/app/views/data-view/data-outlets/resource-detail/resource-detail-html/resource-detail-html.component.spec.ts +++ b/src/app/views/data-view/data-outlets/resource-detail/resource-detail-html/resource-detail-html.component.spec.ts @@ -1,11 +1,11 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ import { Component, DebugElement, EventEmitter, Input, Output } from '@angular/core'; -import { ComponentFixture, fakeAsync, TestBed, waitForAsync } from '@angular/core/testing'; +import { ComponentFixture, TestBed, fakeAsync, waitForAsync } from '@angular/core/testing'; import Spy = jasmine.Spy; import { detectChangesOnPush } from '@testing/detect-changes-on-push-helper'; -import { expectSpyCall, getAndExpectDebugElementByDirective } from '@testing/expect-helper'; +import { expectSpyCall, expectToBe, expectToEqual, getAndExpectDebugElementByDirective } from '@testing/expect-helper'; import { GndEvent, GndEventType } from '@awg-core/services/gnd-service'; import { @@ -121,10 +121,7 @@ describe('ResourceDetailHtmlComponent (DONE)', () => { }); it('... should have `resourceDetailData` inputs', () => { - expect(component.resourceDetailData).withContext('should be defined').toBeDefined(); - expect(component.resourceDetailData) - .withContext(`should be ${expectedResourceDetailData}`) - .toBe(expectedResourceDetailData); + expectToEqual(component.resourceDetailData, expectedResourceDetailData); }); describe('VIEW', () => { @@ -154,10 +151,7 @@ describe('ResourceDetailHtmlComponent (DONE)', () => { ResourceDetailHtmlContentStubComponent ) as ResourceDetailHtmlContentStubComponent; - expect(htmlContentCmp.content).toBeDefined(); - expect(htmlContentCmp.content) - .withContext(`should be ${expectedResourceDetailData.content}`) - .toBe(expectedResourceDetailData.content); + expectToBe(htmlContentCmp.content, expectedResourceDetailData.content); }); }); diff --git a/src/app/views/data-view/data-outlets/resource-detail/resource-detail-json-converted/resource-detail-json-converted.component.spec.ts b/src/app/views/data-view/data-outlets/resource-detail/resource-detail-json-converted/resource-detail-json-converted.component.spec.ts index 44567af34..4125a8081 100644 --- a/src/app/views/data-view/data-outlets/resource-detail/resource-detail-json-converted/resource-detail-json-converted.component.spec.ts +++ b/src/app/views/data-view/data-outlets/resource-detail/resource-detail-json-converted/resource-detail-json-converted.component.spec.ts @@ -1,7 +1,7 @@ import { Component, DebugElement, Input } from '@angular/core'; import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { getAndExpectDebugElementByDirective } from '@testing/expect-helper'; +import { expectToBe, expectToEqual, getAndExpectDebugElementByDirective } from '@testing/expect-helper'; import { ResourceFullResponseJson } from '@awg-shared/api-objects'; import { ResourceDetail, ResourceDetailContent } from '@awg-views/data-view/models'; @@ -62,10 +62,7 @@ describe('ResourceDetailJsonConvertedComponent (DONE)', () => { const viewerDes = getAndExpectDebugElementByDirective(compDe, JsonViewerStubComponent, 1, 1); const viewerCmp = viewerDes[0].injector.get(JsonViewerStubComponent) as JsonViewerStubComponent; - expect(viewerCmp.jsonViewerHeader).toBeDefined(); - expect(viewerCmp.jsonViewerHeader) - .withContext(`should have header: ${expectedHeader}`) - .toBe(expectedHeader); + expectToBe(viewerCmp.jsonViewerHeader, expectedHeader); }); it('... should not pass down `resourceJsonConvertedData` to json viewer component', () => { @@ -87,10 +84,7 @@ describe('ResourceDetailJsonConvertedComponent (DONE)', () => { }); it('... should have `resourceJsonConvertedData`', () => { - expect(component.resourceJsonConvertedData).toBeDefined(); - expect(component.resourceJsonConvertedData) - .withContext(`should equal ${expectedData}`) - .toEqual(expectedData); + expectToEqual(component.resourceJsonConvertedData, expectedData); }); describe('VIEW', () => { @@ -98,8 +92,7 @@ describe('ResourceDetailJsonConvertedComponent (DONE)', () => { const viewerDes = getAndExpectDebugElementByDirective(compDe, JsonViewerStubComponent, 1, 1); const viewerCmp = viewerDes[0].injector.get(JsonViewerStubComponent) as JsonViewerStubComponent; - expect(viewerCmp.jsonViewerData).toBeDefined(); - expect(viewerCmp.jsonViewerData).withContext(`should equal ${expectedData}`).toEqual(expectedData); + expectToEqual(viewerCmp.jsonViewerData, expectedData); }); }); }); diff --git a/src/app/views/data-view/data-outlets/resource-detail/resource-detail-json-raw/resource-detail-json-raw.component.spec.ts b/src/app/views/data-view/data-outlets/resource-detail/resource-detail-json-raw/resource-detail-json-raw.component.spec.ts index 0bb33bd2d..db006d5c9 100644 --- a/src/app/views/data-view/data-outlets/resource-detail/resource-detail-json-raw/resource-detail-json-raw.component.spec.ts +++ b/src/app/views/data-view/data-outlets/resource-detail/resource-detail-json-raw/resource-detail-json-raw.component.spec.ts @@ -1,7 +1,7 @@ import { Component, DebugElement, Input } from '@angular/core'; import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { getAndExpectDebugElementByDirective } from '@testing/expect-helper'; +import { expectToBe, expectToEqual, getAndExpectDebugElementByDirective } from '@testing/expect-helper'; import { ResourceFullResponseJson } from '@awg-shared/api-objects'; import { ResourceDetail } from '@awg-views/data-view/models'; @@ -59,10 +59,7 @@ describe('ResourceDetailJsonRawComponent (DONE)', () => { const viewerDes = getAndExpectDebugElementByDirective(compDe, JsonViewerStubComponent, 1, 1); const viewerCmp = viewerDes[0].injector.get(JsonViewerStubComponent) as JsonViewerStubComponent; - expect(viewerCmp.jsonViewerHeader).toBeDefined(); - expect(viewerCmp.jsonViewerHeader) - .withContext(`should have header: ${expectedHeader}`) - .toBe(expectedHeader); + expectToBe(viewerCmp.jsonViewerHeader, expectedHeader); }); it('... should not pass down `resourceJsonRawData` to json viewer component', () => { @@ -84,8 +81,7 @@ describe('ResourceDetailJsonRawComponent (DONE)', () => { }); it('... should have `resourceJsonRawData`', () => { - expect(component.resourceJsonRawData).toBeDefined(); - expect(component.resourceJsonRawData).withContext(`should equal ${expectedData}`).toEqual(expectedData); + expectToEqual(component.resourceJsonRawData, expectedData); }); describe('VIEW', () => { @@ -93,8 +89,7 @@ describe('ResourceDetailJsonRawComponent (DONE)', () => { const viewerDes = getAndExpectDebugElementByDirective(compDe, JsonViewerStubComponent, 1, 1); const viewerCmp = viewerDes[0].injector.get(JsonViewerStubComponent) as JsonViewerStubComponent; - expect(viewerCmp.jsonViewerData).toBeDefined(); - expect(viewerCmp.jsonViewerData).withContext(`should have data: ${expectedData}`).toBe(expectedData); + expectToEqual(viewerCmp.jsonViewerData, expectedData); }); }); }); diff --git a/src/app/views/data-view/data-outlets/resource-detail/resource-detail.component.html b/src/app/views/data-view/data-outlets/resource-detail/resource-detail.component.html index 6019cdbeb..ff441e429 100644 --- a/src/app/views/data-view/data-outlets/resource-detail/resource-detail.component.html +++ b/src/app/views/data-view/data-outlets/resource-detail/resource-detail.component.html @@ -8,7 +8,7 @@ } @else { @if (errorMessage) { -
+

Die Anfrage "{{ errorMessage?.route }}" ist fehlgeschlagen.

Fehlermeldung: "{{ errorMessage?.statusText || errorMessage }}".

Möglicherweise gab es ein Problem mit der Internetverbindung oder dem verwendeten Suchbegriff.

diff --git a/src/app/views/data-view/data-outlets/search-overview.component.spec.ts b/src/app/views/data-view/data-outlets/search-overview.component.spec.ts index 9d6d6758a..62edd6d8b 100644 --- a/src/app/views/data-view/data-outlets/search-overview.component.spec.ts +++ b/src/app/views/data-view/data-outlets/search-overview.component.spec.ts @@ -6,7 +6,7 @@ import { ActivatedRoute, QueryParamsHandling } from '@angular/router'; import Spy = jasmine.Spy; -import { expectSpyCall, getAndExpectDebugElementByDirective } from '@testing/expect-helper'; +import { expectSpyCall, expectToBe, expectToEqual, getAndExpectDebugElementByDirective } from '@testing/expect-helper'; import { ActivatedRouteStub, RouterOutletStubComponent, UrlSegmentStub } from '@testing/router-stubs'; import { SideInfoService } from '@awg-core/services'; @@ -96,18 +96,14 @@ describe('SearchOverviewComponent (DONE)', () => { }); it('... should change urls', () => { - expect(mockActivatedRoute.snapshot.url[0].path).toBeTruthy(); - expect(mockActivatedRoute.snapshot.url[0].path) - .withContext(`should equal ${expectedPath}`) - .toEqual(expectedPath); + expectToBe(mockActivatedRoute.snapshot.url[0].path, expectedPath); const changedPath = 'other'; const changedRouteUrl: UrlSegmentStub[] = [{ path: changedPath }]; mockActivatedRoute.testUrl = changedRouteUrl; - expect(mockActivatedRoute.snapshot.url[0].path).toBeTruthy(); - expect(mockActivatedRoute.snapshot.url[0].path).withContext(`should equal ${changedPath}`).toEqual(changedPath); + expectToBe(mockActivatedRoute.snapshot.url[0].path, changedPath); }); describe('BEFORE initial data binding', () => { @@ -185,10 +181,7 @@ describe('SearchOverviewComponent (DONE)', () => { RouterLinkButtonGroupStubComponent ) as RouterLinkButtonGroupStubComponent; - expect(buttonCmp.routerLinkButtons).toBeTruthy(); - expect(buttonCmp.routerLinkButtons) - .withContext(`should equal ${expectedSearchRouterLinkButtons}`) - .toEqual(expectedSearchRouterLinkButtons); + expectToEqual(buttonCmp.routerLinkButtons, expectedSearchRouterLinkButtons); }); }); @@ -198,10 +191,7 @@ describe('SearchOverviewComponent (DONE)', () => { }); it('... should have `searchRouterLinkButtons`', () => { - expect(component.searchRouterLinkButtons).withContext('should be defined').toBeDefined(); - expect(component.searchRouterLinkButtons) - .withContext(`should equal ${expectedSearchRouterLinkButtons}`) - .toEqual(expectedSearchRouterLinkButtons); + expectToEqual(component.searchRouterLinkButtons, expectedSearchRouterLinkButtons); }); }); diff --git a/src/app/views/data-view/data-outlets/search-panel/extended-search-form/extended-search-form.component.spec.ts b/src/app/views/data-view/data-outlets/search-panel/extended-search-form/extended-search-form.component.spec.ts index 29e269426..7c3210f5d 100644 --- a/src/app/views/data-view/data-outlets/search-panel/extended-search-form/extended-search-form.component.spec.ts +++ b/src/app/views/data-view/data-outlets/search-panel/extended-search-form/extended-search-form.component.spec.ts @@ -14,19 +14,25 @@ import { faPlus, faRefresh, faSearch, faTrash } from '@fortawesome/free-solid-sv import { click, clickAndAwaitChanges } from '@testing/click-helper'; import { detectChangesOnPush } from '@testing/detect-changes-on-push-helper'; -import { expectSpyCall, expectToBe, expectToEqual, getAndExpectDebugElementByCss } from '@testing/expect-helper'; +import { + expectSpyCall, + expectToBe, + expectToContain, + expectToEqual, + getAndExpectDebugElementByCss, +} from '@testing/expect-helper'; import { mockPropertyTypesInResourceClassResponseJson, mockResourceTypesInVocabularyResponseJson, } from '@testing/mock-data'; import { mockConsole } from '@testing/mock-helper'; -import { ExtendedSearchParams, SearchCompop, SearchCompopSetsList } from '@awg-app/views/data-view/models'; import { PropertyTypesInResourceClassResponseJson, ResourceTypesInVocabularyResponseJson, } from '@awg-shared/api-objects'; import { SEARCH_COMPOP_SETS_LIST } from '@awg-views/data-view/data'; +import { ExtendedSearchParams, SearchCompop, SearchCompopSetsList } from '@awg-views/data-view/models'; import { DataApiService } from '@awg-views/data-view/services'; import { ExtendedSearchFormComponent } from './extended-search-form.component'; @@ -380,7 +386,7 @@ describe('ExtendedSearchFormComponent', () => { ); const labelEl = labelDes[0].nativeElement; - expect(labelEl.classList).toContain('text-muted'); + expectToContain(labelEl.classList, 'text-muted'); expectToBe(labelEl.textContent, 'Resource type'); }); }); @@ -509,7 +515,7 @@ describe('ExtendedSearchFormComponent', () => { ); const labelEl = labelDes[0].nativeElement; - expect(labelEl.classList).toContain('text-muted'); + expectToContain(labelEl.classList, 'text-muted'); expectToBe(labelEl.textContent, 'Property'); }); }); @@ -628,7 +634,7 @@ describe('ExtendedSearchFormComponent', () => { ); const labelEl = labelDes[0].nativeElement; - expect(labelEl.classList).toContain('text-muted'); + expectToContain(labelEl.classList, 'text-muted'); expectToBe(labelEl.textContent, 'Operator'); }); }); @@ -688,7 +694,7 @@ describe('ExtendedSearchFormComponent', () => { ); const labelEl = labelDes[0].nativeElement; - expect(labelEl.classList).toContain('text-muted'); + expectToContain(labelEl.classList, 'text-muted'); expectToBe(labelEl.textContent, 'Search value'); }); }); @@ -746,7 +752,7 @@ describe('ExtendedSearchFormComponent', () => { ); const buttonEl = buttonDes[0].nativeElement; - expect(buttonEl.classList).toContain('btn-outline-info'); + expectToContain(buttonEl.classList, 'btn-outline-info'); }); }); @@ -916,7 +922,7 @@ describe('ExtendedSearchFormComponent', () => { ); const buttonEl = buttonDes[0].nativeElement; - expect(buttonEl.classList).toContain('btn-outline-danger'); + expectToContain(buttonEl.classList, 'btn-outline-danger'); }); }); @@ -985,7 +991,7 @@ describe('ExtendedSearchFormComponent', () => { ); const buttonEl = buttonDes[0].nativeElement; - expect(buttonEl.classList).toContain('btn-outline-info'); + expectToContain(buttonEl.classList, 'btn-outline-info'); }); it('... should have the search button disabled as long as the form is not valid', () => { @@ -1067,7 +1073,7 @@ describe('ExtendedSearchFormComponent', () => { ); const buttonEl = buttonDes[0].nativeElement; - expect(buttonEl.classList).toContain('btn-outline-danger'); + expectToContain(buttonEl.classList, 'btn-outline-danger'); }); it('... should have the reset button disabled as long as the restypeControl is not valid', () => { @@ -1415,7 +1421,7 @@ describe('ExtendedSearchFormComponent', () => { }); it('... should return null if the index is out of bounds', () => { - expect(component.getCompopControlAtIndex(100)).toBeNull(); + expectToBe(component.getCompopControlAtIndex(100), null); }); }); @@ -1436,12 +1442,12 @@ describe('ExtendedSearchFormComponent', () => { for (const guieElementId of ['3', '6', '14']) { const compopSet = component.getCompopSetByValueType(valueTypeId, guieElementId); - expect(typeof compopSet).toBe('object'); - expect(Array.isArray(compopSet)).toBeTrue(); + expectToBe(typeof compopSet, 'object'); + expectToBe(Array.isArray(compopSet), true); expect(compopSet.length).toBeGreaterThanOrEqual(0); compopSet.forEach(compop => { - expect(compop instanceof SearchCompop).toBeTrue(); + expectToBe(compop instanceof SearchCompop, true); }); } } @@ -1599,7 +1605,7 @@ describe('ExtendedSearchFormComponent', () => { }); it('... should return null if the propertyIdControl does not exist', () => { - expect(component.getPropertyIdControlAtIndex(100)).toBeNull(); + expectToBe(component.getPropertyIdControlAtIndex(100), null); }); }); @@ -2765,13 +2771,13 @@ describe('ExtendedSearchFormComponent', () => { it('... the index is out of bounds', () => { const index = 100; - expect((component as any)._getFormArrayControlAtIndex('searchvalControl', index)).toBeNull(); + expectToBe((component as any)._getFormArrayControlAtIndex('searchvalControl', index), null); }); it('... the control does not exist', () => { const index = 0; - expect((component as any)._getFormArrayControlAtIndex('invalidControl', index)).toBeNull(); + expectToBe((component as any)._getFormArrayControlAtIndex('invalidControl', index), null); }); }); @@ -2815,7 +2821,7 @@ describe('ExtendedSearchFormComponent', () => { 'compopControl' ].setValue('EXISTS'); - expect((component as any)._isCompopExists(index)).toBeTrue(); + expectToBe((component as any)._isCompopExists(index), true); }); it('... should return false if the compop value is not `EXISTS`', () => { @@ -2825,7 +2831,7 @@ describe('ExtendedSearchFormComponent', () => { 'compopControl' ].setValue('EQUALS'); - expect((component as any)._isCompopExists(index)).toBeFalse(); + expectToBe((component as any)._isCompopExists(index), false); }); }); @@ -2839,7 +2845,7 @@ describe('ExtendedSearchFormComponent', () => { isFormControlValueMissingSpy.withArgs('compopControl', index).and.returnValue(true); - expect((component as any)._isCompopMissing(index)).toBeTrue(); + expectToBe((component as any)._isCompopMissing(index), true); }); it('... should return false if `_isFormControlValueMissing` returns false', () => { @@ -2847,7 +2853,7 @@ describe('ExtendedSearchFormComponent', () => { isFormControlValueMissingSpy.withArgs('compopControl', index).and.returnValue(false); - expect((component as any)._isCompopMissing(index)).toBeFalse(); + expectToBe((component as any)._isCompopMissing(index), false); }); }); @@ -2865,7 +2871,7 @@ describe('ExtendedSearchFormComponent', () => { 'searchvalControl' ].setValue(null); - expect((component as any)._isFormControlValueMissing('searchvalControl', index)).toBeTrue(); + expectToBe((component as any)._isFormControlValueMissing('searchvalControl', index), true); }); it('... undefined', () => { @@ -2876,7 +2882,7 @@ describe('ExtendedSearchFormComponent', () => { 'searchvalControl' ].setValue(undefined); - expect((component as any)._isFormControlValueMissing('searchvalControl', index)).toBeTrue(); + expectToBe((component as any)._isFormControlValueMissing('searchvalControl', index), true); }); it('... an empty string', () => { @@ -2887,7 +2893,7 @@ describe('ExtendedSearchFormComponent', () => { 'searchvalControl' ].setValue(''); - expect((component as any)._isFormControlValueMissing('searchvalControl', index)).toBeTrue(); + expectToBe((component as any)._isFormControlValueMissing('searchvalControl', index), true); }); it('... the default formString', () => { @@ -2898,7 +2904,7 @@ describe('ExtendedSearchFormComponent', () => { 'searchvalControl' ].setValue(expectedDefaultFormString); - expect((component as any)._isFormControlValueMissing('searchvalControl', index)).toBeTrue(); + expectToBe((component as any)._isFormControlValueMissing('searchvalControl', index), true); }); }); @@ -2910,7 +2916,7 @@ describe('ExtendedSearchFormComponent', () => { 'searchvalControl' ].setValue(1); - expect((component as any)._isFormControlValueMissing('searchvalControl', index)).toBeFalse(); + expectToBe((component as any)._isFormControlValueMissing('searchvalControl', index), false); }); it('... a string', () => { @@ -2920,7 +2926,7 @@ describe('ExtendedSearchFormComponent', () => { 'searchvalControl' ].setValue('test'); - expect((component as any)._isFormControlValueMissing('searchvalControl', index)).toBeFalse(); + expectToBe((component as any)._isFormControlValueMissing('searchvalControl', index), false); }); it('... an object', () => { @@ -2930,7 +2936,7 @@ describe('ExtendedSearchFormComponent', () => { 'searchvalControl' ].setValue({ id: 1 }); - expect((component as any)._isFormControlValueMissing('searchvalControl', index)).toBeFalse(); + expectToBe((component as any)._isFormControlValueMissing('searchvalControl', index), false); }); it('... an empty object', () => { @@ -2940,7 +2946,7 @@ describe('ExtendedSearchFormComponent', () => { 'searchvalControl' ].setValue({}); - expect((component as any)._isFormControlValueMissing('searchvalControl', index)).toBeFalse(); + expectToBe((component as any)._isFormControlValueMissing('searchvalControl', index), false); }); it('... an empty array', () => { @@ -2950,7 +2956,7 @@ describe('ExtendedSearchFormComponent', () => { 'searchvalControl' ].setValue([]); - expect((component as any)._isFormControlValueMissing('searchvalControl', index)).toBeFalse(); + expectToBe((component as any)._isFormControlValueMissing('searchvalControl', index), false); }); }); @@ -2964,9 +2970,9 @@ describe('ExtendedSearchFormComponent', () => { controls['compopControl'].setValue('EXISTS'); controls['searchvalControl'].setValue(null); - expect((component as any)._isFormControlValueMissing('propertyIdControl', index)).toBeFalse(); - expect((component as any)._isFormControlValueMissing('compopControl', index)).toBeFalse(); - expect((component as any)._isFormControlValueMissing('searchvalControl', index)).toBeTrue(); + expectToBe((component as any)._isFormControlValueMissing('propertyIdControl', index), false); + expectToBe((component as any)._isFormControlValueMissing('compopControl', index), false); + expectToBe((component as any)._isFormControlValueMissing('searchvalControl', index), true); }); }); @@ -2983,8 +2989,8 @@ describe('ExtendedSearchFormComponent', () => { component.addPropertiesControl(); component.addPropertiesControl(); - expect((component as any)._isNotLastProperty(index)).toBeTrue(); - expect((component as any)._isNotLastProperty(index1)).toBeTrue(); + expectToBe((component as any)._isNotLastProperty(index), true); + expectToBe((component as any)._isNotLastProperty(index1), true); }); it('... less than the length - 1 of the propertiesControls', () => { @@ -2993,7 +2999,7 @@ describe('ExtendedSearchFormComponent', () => { component.addPropertiesControl(); component.addPropertiesControl(); - expect((component as any)._isNotLastProperty(index)).toBeTrue(); + expectToBe((component as any)._isNotLastProperty(index), true); }); it('... negative', () => { @@ -3002,7 +3008,7 @@ describe('ExtendedSearchFormComponent', () => { component.addPropertiesControl(); component.addPropertiesControl(); - expect((component as any)._isNotLastProperty(index)).toBeTrue(); + expectToBe((component as any)._isNotLastProperty(index), true); }); }); @@ -3010,7 +3016,7 @@ describe('ExtendedSearchFormComponent', () => { it('... the last index position in the propertiesControls', () => { const index = 0; - expect((component as any)._isNotLastProperty(index)).toBeFalse(); + expectToBe((component as any)._isNotLastProperty(index), false); // Add tow more properties controls component.addPropertiesControl(); @@ -3018,7 +3024,7 @@ describe('ExtendedSearchFormComponent', () => { const index2 = 2; - expect((component as any)._isNotLastProperty(index2)).toBeFalse(); + expectToBe((component as any)._isNotLastProperty(index2), false); }); it('... greater than the length - 1 of the propertiesControls', () => { @@ -3027,7 +3033,7 @@ describe('ExtendedSearchFormComponent', () => { component.addPropertiesControl(); component.addPropertiesControl(); - expect((component as any)._isNotLastProperty(index)).toBeFalse(); + expectToBe((component as any)._isNotLastProperty(index), false); }); it('... equal to the length - 1 of the propertiesControls', () => { @@ -3036,7 +3042,7 @@ describe('ExtendedSearchFormComponent', () => { component.addPropertiesControl(); component.addPropertiesControl(); - expect((component as any)._isNotLastProperty(index)).toBeFalse(); + expectToBe((component as any)._isNotLastProperty(index), false); }); }); }); @@ -3051,7 +3057,7 @@ describe('ExtendedSearchFormComponent', () => { isFormControlValueMissingSpy.withArgs('propertyIdControl', index).and.returnValue(true); - expect((component as any)._isPropertyIdMissing(index)).toBeTrue(); + expectToBe((component as any)._isPropertyIdMissing(index), true); }); it('... should return false if `_isFormControlValueMissing` returns false', () => { @@ -3059,7 +3065,7 @@ describe('ExtendedSearchFormComponent', () => { isFormControlValueMissingSpy.withArgs('propertyIdControl', index).and.returnValue(false); - expect((component as any)._isPropertyIdMissing(index)).toBeFalse(); + expectToBe((component as any)._isPropertyIdMissing(index), false); }); }); @@ -3075,7 +3081,7 @@ describe('ExtendedSearchFormComponent', () => { isPropertyIdMissingSpy.withArgs(index).and.returnValue(true); isCompopMissingSpy.withArgs(index).and.returnValue(false); - expect((component as any)._isPropertyIdOrCompopMissing(index)).toBeTrue(); + expectToBe((component as any)._isPropertyIdOrCompopMissing(index), true); }); it('... `_isCompopMissing` returns true', () => { @@ -3084,7 +3090,7 @@ describe('ExtendedSearchFormComponent', () => { isPropertyIdMissingSpy.withArgs(index).and.returnValue(false); isCompopMissingSpy.withArgs(index).and.returnValue(true); - expect((component as any)._isPropertyIdOrCompopMissing(index)).toBeTrue(); + expectToBe((component as any)._isPropertyIdOrCompopMissing(index), true); }); it('... `_isPropertyIdMissing` and `_isCompopMissing` both return true', () => { @@ -3093,7 +3099,7 @@ describe('ExtendedSearchFormComponent', () => { isPropertyIdMissingSpy.withArgs(index).and.returnValue(true); isCompopMissingSpy.withArgs(index).and.returnValue(true); - expect((component as any)._isPropertyIdOrCompopMissing(index)).toBeTrue(); + expectToBe((component as any)._isPropertyIdOrCompopMissing(index), true); }); }); @@ -3103,7 +3109,7 @@ describe('ExtendedSearchFormComponent', () => { isPropertyIdMissingSpy.withArgs(index).and.returnValue(false); isCompopMissingSpy.withArgs(index).and.returnValue(false); - expect((component as any)._isPropertyIdOrCompopMissing(index)).toBeFalse(); + expectToBe((component as any)._isPropertyIdOrCompopMissing(index), false); }); }); @@ -3116,25 +3122,25 @@ describe('ExtendedSearchFormComponent', () => { it('... an empty string', () => { component.extendedSearchForm.controls['restypeControl'].setValue(''); - expect((component as any)._isResourecetypeMissing()).toBeTrue(); + expectToBe((component as any)._isResourecetypeMissing(), true); }); it('... undefined', () => { component.extendedSearchForm.controls['restypeControl'].setValue(undefined); - expect((component as any)._isResourecetypeMissing()).toBeTrue(); + expectToBe((component as any)._isResourecetypeMissing(), true); }); it('... null', () => { component.extendedSearchForm.controls['restypeControl'].setValue(null); - expect((component as any)._isResourecetypeMissing()).toBeTrue(); + expectToBe((component as any)._isResourecetypeMissing(), true); }); it('... the default formString', () => { component.extendedSearchForm.controls['restypeControl'].setValue(expectedDefaultFormString); - expect((component as any)._isResourecetypeMissing()).toBeTrue(); + expectToBe((component as any)._isResourecetypeMissing(), true); }); }); @@ -3142,31 +3148,31 @@ describe('ExtendedSearchFormComponent', () => { it('... a number', () => { component.extendedSearchForm.controls['restypeControl'].setValue(1); - expect((component as any)._isResourecetypeMissing()).toBeFalse(); + expectToBe((component as any)._isResourecetypeMissing(), false); }); it('... a string', () => { component.extendedSearchForm.controls['restypeControl'].setValue('1'); - expect((component as any)._isResourecetypeMissing()).toBeFalse(); + expectToBe((component as any)._isResourecetypeMissing(), false); }); it('... an object', () => { component.extendedSearchForm.controls['restypeControl'].setValue({ id: 1 }); - expect((component as any)._isResourecetypeMissing()).toBeFalse(); + expectToBe((component as any)._isResourecetypeMissing(), false); }); it('... an empty object', () => { component.extendedSearchForm.controls['restypeControl'].setValue({}); - expect((component as any)._isResourecetypeMissing()).toBeFalse(); + expectToBe((component as any)._isResourecetypeMissing(), false); }); it('... an empty array', () => { component.extendedSearchForm.controls['restypeControl'].setValue([]); - expect((component as any)._isResourecetypeMissing()).toBeFalse(); + expectToBe((component as any)._isResourecetypeMissing(), false); }); }); }); @@ -3181,7 +3187,7 @@ describe('ExtendedSearchFormComponent', () => { isFormControlValueMissingSpy.withArgs('searchvalControl', index).and.returnValue(true); - expect((component as any)._isSearchvalMissing(index)).toBeTrue(); + expectToBe((component as any)._isSearchvalMissing(index), true); }); it('... should return false if `_isFormControlValueMissing` returns false', () => { @@ -3189,7 +3195,7 @@ describe('ExtendedSearchFormComponent', () => { isFormControlValueMissingSpy.withArgs('searchvalControl', index).and.returnValue(false); - expect((component as any)._isSearchvalMissing(index)).toBeFalse(); + expectToBe((component as any)._isSearchvalMissing(index), false); }); }); @@ -3205,7 +3211,7 @@ describe('ExtendedSearchFormComponent', () => { isSearchvalMissingSpy.withArgs(index).and.returnValue(true); isSearchvalTooShortSpy.withArgs(index).and.returnValue(false); - expect((component as any)._isSearchvalMissingOrTooShort(index)).toBeTrue(); + expectToBe((component as any)._isSearchvalMissingOrTooShort(index), true); }); it('... `_isSearchvalTooShort` returns true', () => { @@ -3214,7 +3220,7 @@ describe('ExtendedSearchFormComponent', () => { isSearchvalMissingSpy.withArgs(index).and.returnValue(false); isSearchvalTooShortSpy.withArgs(index).and.returnValue(true); - expect((component as any)._isSearchvalMissingOrTooShort(index)).toBeTrue(); + expectToBe((component as any)._isSearchvalMissingOrTooShort(index), true); }); it('... `_isSearchvalMissing` and `_isSearchvalTooShort` both return true', () => { @@ -3223,7 +3229,7 @@ describe('ExtendedSearchFormComponent', () => { isSearchvalMissingSpy.withArgs(index).and.returnValue(true); isSearchvalTooShortSpy.withArgs(index).and.returnValue(true); - expect((component as any)._isSearchvalMissingOrTooShort(index)).toBeTrue(); + expectToBe((component as any)._isSearchvalMissingOrTooShort(index), true); }); }); @@ -3233,7 +3239,7 @@ describe('ExtendedSearchFormComponent', () => { isSearchvalMissingSpy.withArgs(index).and.returnValue(false); isSearchvalTooShortSpy.withArgs(index).and.returnValue(false); - expect((component as any)._isSearchvalMissingOrTooShort(index)).toBeFalse(); + expectToBe((component as any)._isSearchvalMissingOrTooShort(index), false); }); }); @@ -3252,9 +3258,9 @@ describe('ExtendedSearchFormComponent', () => { controls[1]['controls']['searchvalControl'].setValue('a'); controls[2]['controls']['searchvalControl'].setValue('ab'); - expect((component as any)._isSearchvalTooShort(0)).toBeTrue(); - expect((component as any)._isSearchvalTooShort(1)).toBeTrue(); - expect((component as any)._isSearchvalTooShort(2)).toBeTrue(); + expectToBe((component as any)._isSearchvalTooShort(0), true); + expectToBe((component as any)._isSearchvalTooShort(1), true); + expectToBe((component as any)._isSearchvalTooShort(2), true); }); it('... should return false if the searchval control at a given index has a value that is equal or longer than 3 characters', () => { @@ -3267,9 +3273,9 @@ describe('ExtendedSearchFormComponent', () => { controls[1]['controls']['searchvalControl'].setValue('abcd'); controls[2]['controls']['searchvalControl'].setValue('abcde'); - expect((component as any)._isSearchvalTooShort(0)).toBeFalse(); - expect((component as any)._isSearchvalTooShort(1)).toBeFalse(); - expect((component as any)._isSearchvalTooShort(2)).toBeFalse(); + expectToBe((component as any)._isSearchvalTooShort(0), false); + expectToBe((component as any)._isSearchvalTooShort(1), false); + expectToBe((component as any)._isSearchvalTooShort(2), false); }); }); @@ -3300,7 +3306,7 @@ describe('ExtendedSearchFormComponent', () => { compopControl.setValue('EXISTS'); - expect(validator(searchvalControl)).toBeNull(); + expectToBe(validator(searchvalControl), null); }); it('... should require non-null searchvalControl when compopControl has value other than `EXISTS`', () => { @@ -3349,7 +3355,7 @@ describe('ExtendedSearchFormComponent', () => { searchvalControl.setValue('abc'); - expect(validator(searchvalControl)).toBeNull(); + expectToBe(validator(searchvalControl), null); }); }); }); diff --git a/src/app/views/data-view/data-outlets/search-panel/fulltext-search-form/fulltext-search-form.component.spec.ts b/src/app/views/data-view/data-outlets/search-panel/fulltext-search-form/fulltext-search-form.component.spec.ts index 04191cce2..eeeb9e7e8 100644 --- a/src/app/views/data-view/data-outlets/search-panel/fulltext-search-form/fulltext-search-form.component.spec.ts +++ b/src/app/views/data-view/data-outlets/search-panel/fulltext-search-form/fulltext-search-form.component.spec.ts @@ -6,7 +6,13 @@ import { FontAwesomeTestingModule } from '@fortawesome/angular-fontawesome/testi import { faSearch, IconDefinition } from '@fortawesome/free-solid-svg-icons'; import Spy = jasmine.Spy; -import { expectSpyCall, expectToBe, expectToEqual, getAndExpectDebugElementByCss } from '@testing/expect-helper'; +import { + expectSpyCall, + expectToBe, + expectToContain, + expectToEqual, + getAndExpectDebugElementByCss, +} from '@testing/expect-helper'; import { FulltextSearchFormComponent } from './fulltext-search-form.component'; @@ -227,7 +233,7 @@ describe('FulltextSearchFormComponent (DONE)', () => { const inputDe = getAndExpectDebugElementByCss(formFloatingGroupDe[0], 'input.form-control', 1, 1); const inputEl = inputDe[0].nativeElement; - expect(inputEl.classList).toContain('is-invalid'); + expectToContain(inputEl.classList, 'is-invalid'); }); it('... should have class `ng-pristine`, but not `ng-dirty` in input.form-control', () => { @@ -240,16 +246,16 @@ describe('FulltextSearchFormComponent (DONE)', () => { const inputDe = getAndExpectDebugElementByCss(formFloatingGroupDe[0], 'input.form-control', 1, 1); const inputEl = inputDe[0].nativeElement; - expect(inputEl.classList).toContain('ng-pristine'); + expectToContain(inputEl.classList, 'ng-pristine'); expect(inputEl.classList).not.toContain('ng-dirty'); }); it('... should have an invalid searchval input', () => { - expect(component.searchvalControl.valid).toBeFalse(); + expectToBe(component.searchvalControl.valid, false); }); it('... should have an invalid form', () => { - expect(component.fulltextSearchForm.valid).toBeFalse(); + expectToBe(component.fulltextSearchForm.valid, false); }); it('... should not have a div.invalid-feedback', () => { @@ -303,7 +309,7 @@ describe('FulltextSearchFormComponent (DONE)', () => { inputEl.dispatchEvent(new Event('input')); fixture.detectChanges(); - expect(inputEl.classList).toContain('is-invalid'); + expectToContain(inputEl.classList, 'is-invalid'); }); it('... should not have class `ng-pristine`, but `ng-dirty` in input.form-control', () => { @@ -325,7 +331,7 @@ describe('FulltextSearchFormComponent (DONE)', () => { fixture.detectChanges(); expect(inputEl.classList).not.toContain('ng-pristine'); - expect(inputEl.classList).toContain('ng-dirty'); + expectToContain(inputEl.classList, 'ng-dirty'); }); it('... should have an invalid searchval input', () => { @@ -334,7 +340,7 @@ describe('FulltextSearchFormComponent (DONE)', () => { component.setSearchvalFromInput(); fixture.detectChanges(); - expect(component.searchvalControl.valid).toBeFalse(); + expectToBe(component.searchvalControl.valid, false); }); it('... should have an invalid form', () => { @@ -343,7 +349,7 @@ describe('FulltextSearchFormComponent (DONE)', () => { component.setSearchvalFromInput(); fixture.detectChanges(); - expect(component.fulltextSearchForm.valid).toBeFalse(); + expectToBe(component.fulltextSearchForm.valid, false); }); it('... should have a div.invalid-feedback if form is invalid after input', () => { @@ -461,7 +467,7 @@ describe('FulltextSearchFormComponent (DONE)', () => { fixture.detectChanges(); expect(inputEl.classList).not.toContain('ng-pristine'); - expect(inputEl.classList).toContain('ng-dirty'); + expectToContain(inputEl.classList, 'ng-dirty'); })); it('... should have a valid searchval input', () => { diff --git a/src/app/views/data-view/data-outlets/search-panel/search-panel.component.html b/src/app/views/data-view/data-outlets/search-panel/search-panel.component.html index 566e3d8d8..104374520 100644 --- a/src/app/views/data-view/data-outlets/search-panel/search-panel.component.html +++ b/src/app/views/data-view/data-outlets/search-panel/search-panel.component.html @@ -34,7 +34,7 @@
} @else { @if (errorMessage) { -
+

Die Anfrage "{{ errorMessage?.route }}" ist fehlgeschlagen.

Fehlermeldung: "{{ errorMessage?.statusText || errorMessage }}".

Möglicherweise gab es ein Problem mit der Internetverbindung oder der Suchanfrage.

diff --git a/src/app/views/data-view/data-outlets/search-panel/search-result-list/search-result-list.component.spec.ts b/src/app/views/data-view/data-outlets/search-panel/search-result-list/search-result-list.component.spec.ts index 39e84f7f0..a7e4cf310 100644 --- a/src/app/views/data-view/data-outlets/search-panel/search-result-list/search-result-list.component.spec.ts +++ b/src/app/views/data-view/data-outlets/search-panel/search-result-list/search-result-list.component.spec.ts @@ -10,6 +10,8 @@ import Spy = jasmine.Spy; import { FontAwesomeTestingModule } from '@fortawesome/angular-fontawesome/testing'; import { NgbPaginationModule } from '@ng-bootstrap/ng-bootstrap'; +import { expectToBe } from '@testing/expect-helper'; + import { ConversionService, DataStreamerService, SideInfoService } from '@awg-core/services'; import { SearchResponseJson } from '@awg-shared/api-objects'; import { CompileHtmlComponent } from '@awg-shared/compile-html'; @@ -105,14 +107,14 @@ describe('SearchResultListComponent', () => { }); it('... injected conversion service should use provided mockValue', () => { - expect(conversionService === mockConversionService).toBeTrue(); + expectToBe(conversionService === mockConversionService, true); }); it('... injected datastreamer service should use provided mockValue', () => { - expect(dataStreamerService === mockDataStreamerService).toBeTrue(); + expectToBe(dataStreamerService === mockDataStreamerService, true); }); it('... injected sideinfo service should use provided mockValue', () => { - expect(sideInfoService === mockSideInfoService).toBeTrue(); + expectToBe(sideInfoService === mockSideInfoService, true); }); }); diff --git a/src/app/views/data-view/data-view.component.spec.ts b/src/app/views/data-view/data-view.component.spec.ts index fde023756..da94e5d7f 100644 --- a/src/app/views/data-view/data-view.component.spec.ts +++ b/src/app/views/data-view/data-view.component.spec.ts @@ -8,6 +8,7 @@ import Spy = jasmine.Spy; import { cleanStylesFromDOM } from '@testing/clean-up-helper'; import { expectSpyCall, + expectToBe, getAndExpectDebugElementByCss, getAndExpectDebugElementByDirective, } from '@testing/expect-helper'; @@ -65,11 +66,8 @@ describe('DataViewComponent (DONE)', () => { describe('BEFORE initial data binding', () => { it('... should have title and id', () => { - expect(component.searchTitle).toBeDefined(); - expect(component.searchTitle).withContext(`should be ${expectedTitle}`).toBe(expectedTitle); - - expect(component.searchId).toBeDefined(); - expect(component.searchId).withContext(`should be ${expectedId}`).toBe(expectedId); + expectToBe(component.searchTitle, expectedTitle); + expectToBe(component.searchId, expectedId); }); describe('#routeToSidenav()', () => { @@ -137,9 +135,7 @@ describe('DataViewComponent (DONE)', () => { expect(navArgs).toBeDefined(); expect(navArgs[0]).toBeDefined(); - expect(outletRoute).toBeDefined(); - expect(outletRoute).withContext(`should be: ${expectedRoute}`).toBe(expectedRoute); - + expectToBe(outletRoute, expectedRoute); expect(navigationSpy).toHaveBeenCalledWith(navArgs[0], navArgs[1]); }); @@ -149,8 +145,7 @@ describe('DataViewComponent (DONE)', () => { const navExtras = navArgs[1]; expect(navExtras).toBeDefined(); - expect(navExtras.preserveFragment).toBeDefined(); - expect(navExtras.preserveFragment).withContext('should be `preserveFragment:true`').toBe(true); + expectToBe(navExtras.preserveFragment, true); expect(navigationSpy).toHaveBeenCalledWith(navArgs[0], navArgs[1]); }); @@ -161,11 +156,8 @@ describe('DataViewComponent (DONE)', () => { const headingDes = getAndExpectDebugElementByDirective(compDe, HeadingStubComponent, 1, 1); const headingCmp = headingDes[0].injector.get(HeadingStubComponent) as HeadingStubComponent; - expect(headingCmp.title).toBeTruthy(); - expect(headingCmp.title).withContext(`should have title: ${expectedTitle}`).toBe(expectedTitle); - - expect(headingCmp.id).toBeTruthy(); - expect(headingCmp.id).withContext(`should have id: ${expectedId}`).toBe(expectedId); + expectToBe(headingCmp.title, expectedTitle); + expectToBe(headingCmp.id, expectedId); }); }); }); diff --git a/src/app/views/data-view/services/bibliography.service.spec.ts b/src/app/views/data-view/services/bibliography.service.spec.ts index 6f4dd22eb..114b8cc77 100644 --- a/src/app/views/data-view/services/bibliography.service.spec.ts +++ b/src/app/views/data-view/services/bibliography.service.spec.ts @@ -9,7 +9,7 @@ import Spy = jasmine.Spy; import { JsonConvert } from 'json2typescript'; -import { expectSpyCall } from '@testing/expect-helper'; +import { expectSpyCall, expectToBe, expectToEqual } from '@testing/expect-helper'; import { mockResourceFullResponseJson, mockSearchResponseJson } from '@testing/mock-data'; import { AppConfig } from '@awg-app/app.config'; @@ -74,45 +74,28 @@ describe('BibliographyService (DONE)', () => { it('... should have serviceName', () => { const expectedServiceName = 'BibliographyService'; - expect(bibliographyService.serviceName).toBeDefined(); - expect(bibliographyService.serviceName) - .withContext(`should be ${expectedServiceName}`) - .toBe(expectedServiceName); + expectToBe(bibliographyService.serviceName, expectedServiceName); }); it('... should have projectId', () => { - expect(bibliographyService.projectId).toBeDefined(); - expect(bibliographyService.projectId).withContext(`should be ${expectedProjectId}`).toBe(expectedProjectId); + expectToBe(bibliographyService.projectId, expectedProjectId); }); it('... should have resTypeId', () => { - expect(bibliographyService.resTypeId).toBeDefined(); - expect(bibliographyService.resTypeId).withContext(`should be ${expectedResTypeId}`).toBe(expectedResTypeId); + expectToBe(bibliographyService.resTypeId, expectedResTypeId); }); it('... should have bibShortTitlePropertyId', () => { - expect(bibliographyService.bibShortTitlePropertyId).toBeDefined(); - expect(bibliographyService.bibShortTitlePropertyId) - .withContext(`should be ${expectedBibShortTitlePropertyId}`) - .toBe(expectedBibShortTitlePropertyId); + expectToBe(bibliographyService.bibShortTitlePropertyId, expectedBibShortTitlePropertyId); }); it('... should have routes', () => { - expect(bibliographyService.resourcesRoute).toBeDefined(); - expect(bibliographyService.resourcesRoute) - .withContext(`should be ${expectedResourcesRoute}`) - .toBe(expectedResourcesRoute); - - expect(bibliographyService.searchRoute).toBeDefined(); - expect(bibliographyService.searchRoute) - .withContext(`should be ${expectedSearchRoute}`) - .toBe(expectedSearchRoute); + expectToBe(bibliographyService.resourcesRoute, expectedResourcesRoute); + expectToBe(bibliographyService.searchRoute, expectedSearchRoute); }); it("... should have empty 'httpGetUrl' (inherited from ApiService)", () => { - expect(bibliographyService.httpGetUrl).toBeDefined(); - expect(bibliographyService.httpGetUrl).not.toBeTruthy(); - expect(bibliographyService.httpGetUrl).withContext(`should be empty string`).toBe(''); + expectToBe(bibliographyService.httpGetUrl, ''); }); }); @@ -122,8 +105,7 @@ describe('BibliographyService (DONE)', () => { httpClient.get('/foo/bar').subscribe({ next: data => { - expect(data).toBeTruthy(); - expect(data).withContext(`should equal ${testData}`).toEqual(testData); + expectToEqual(data, testData); }, }); @@ -133,7 +115,7 @@ describe('BibliographyService (DONE)', () => { }); // Check for GET request - expect(call.request.method).toEqual('GET'); + expectToEqual(call.request.method, 'GET'); // Respond with mocked data call.flush(testData); @@ -159,9 +141,9 @@ describe('BibliographyService (DONE)', () => { `GET to ${expectedUrl}` ); - expect(call.request.method).withContext('should be GET').toBe('GET'); - expect(call.request.responseType).withContext('should be json').toBe('json'); - expect(call.request.url).withContext(`should be ${expectedUrl}`).toBe(expectedUrl); + expectToBe(call.request.method, 'GET'); + expectToBe(call.request.responseType, 'json'); + expectToBe(call.request.url, expectedUrl); })); it('... should set filter params for GET request', waitForAsync(() => { @@ -177,22 +159,17 @@ describe('BibliographyService (DONE)', () => { `GET to ${expectedUrl}` ); - expect(call.request.method).withContext('should be GET').toBe('GET'); - expect(call.request.responseType).withContext('should be json').toBe('json'); - expect(call.request.url).withContext(`should be ${expectedUrl}`).toBe(expectedUrl); + expectToBe(call.request.method, 'GET'); + expectToBe(call.request.responseType, 'json'); + expectToBe(call.request.url, expectedUrl); + expect(call.request.params).toBeDefined(); - expect(call.request.params.keys().length).withContext('should be 5').toBe(5); - expect(call.request.params.get('searchtype')).withContext('should be extended').toBe('extended'); - expect(call.request.params.get('filter_by_project')) - .withContext(`should be ${expectedProjectId}`) - .toBe(expectedProjectId); - expect(call.request.params.get('filter_by_restype')) - .withContext(`should be ${expectedResTypeId}`) - .toBe(expectedResTypeId); - expect(call.request.params.get('property_id')) - .withContext(`should be ${expectedBibShortTitlePropertyId}`) - .toBe(expectedBibShortTitlePropertyId); - expect(call.request.params.get('compop')).withContext('should be EXISTS').toBe('EXISTS'); + expectToBe(call.request.params.keys().length, 5); + expectToBe(call.request.params.get('searchtype'), 'extended'); + expectToBe(call.request.params.get('filter_by_project'), expectedProjectId); + expectToBe(call.request.params.get('filter_by_restype'), expectedResTypeId); + expectToBe(call.request.params.get('property_id'), expectedBibShortTitlePropertyId); + expectToBe(call.request.params.get('compop'), 'EXISTS'); })); it('... should call getApiResponse (via ApiService) with filter params', waitForAsync(() => { @@ -225,10 +202,7 @@ describe('BibliographyService (DONE)', () => { bibliographyService.getBibliographyList().subscribe({ next: (response: SearchResponseJson) => { - expect(response).toBeTruthy(); - expect(response) - .withContext(`shoud equal ${expectedSearchResponseJson}`) - .toEqual(expectedSearchResponseJson); + expectToEqual(response, expectedSearchResponseJson); }, }); })); @@ -260,9 +234,7 @@ describe('BibliographyService (DONE)', () => { expectedQueryPath, expectedQueryHttpParams, ]); - expect(err) - .withContext(`shoud equal ${expectedApiServiceError}`) - .toEqual(expectedApiServiceError); + expectToEqual(err, expectedApiServiceError); }, }); })); @@ -286,7 +258,7 @@ describe('BibliographyService (DONE)', () => { // Expect one request to url with given settings httpTestingController.expectOne((req: HttpRequest) => { expect(req.params).toBeDefined(); - expect(req.params.keys().length).withContext('should be 0').toBe(0); + expectToBe(req.params.keys().length, 0); return req.method === 'GET' && req.responseType === 'json' && req.url === expectedUrl; }, `GET to ${expectedUrl}`); @@ -320,10 +292,7 @@ describe('BibliographyService (DONE)', () => { bibliographyService.getBibliographyItemDetail(expectedResourceId).subscribe({ next: (response: ResourceFullResponseJson) => { - expect(response).toBeTruthy(); - expect(response) - .withContext(`should equal ${expectedResourceFullResponseJson}`) - .toEqual(expectedResourceFullResponseJson); + expectToEqual(response, expectedResourceFullResponseJson); }, }); })); @@ -351,9 +320,7 @@ describe('BibliographyService (DONE)', () => { expectedQueryPath, expectedQueryHttpParams, ]); - expect(err) - .withContext(`shoud equal ${expectedApiServiceError}`) - .toEqual(expectedApiServiceError); + expectToEqual(err, expectedApiServiceError); }, }); })); diff --git a/src/app/views/data-view/services/data-api.service.spec.ts b/src/app/views/data-view/services/data-api.service.spec.ts index dedc2cf69..e584e70e8 100644 --- a/src/app/views/data-view/services/data-api.service.spec.ts +++ b/src/app/views/data-view/services/data-api.service.spec.ts @@ -8,7 +8,7 @@ import { JsonConvert } from 'json2typescript'; import { of as observableOf, throwError as observableThrowError } from 'rxjs'; import Spy = jasmine.Spy; -import { expectSpyCall } from '@testing/expect-helper'; +import { expectSpyCall, expectToBe, expectToEqual } from '@testing/expect-helper'; import { mockPropertyTypesInResourceClassResponseJson, mockResourceContextResponseJson, @@ -37,9 +37,8 @@ import { DataApiService } from './data-api.service'; // Helper function function expectParams(call: TestRequest, param: string, expectedValue: string[], length?: number) { - expect(call.request.params.getAll(param)).toBeTruthy(); - expect(call.request.params.getAll(param).length).withContext(`should be ${length}`).toBe(length); - expect(call.request.params.getAll(param)).withContext(`should equal ${expectedValue}`).toEqual(expectedValue); + expectToBe(call.request.params.getAll(param).length, length); + expectToEqual(call.request.params.getAll(param), expectedValue); } describe('DataApiService (DONE)', () => { @@ -139,55 +138,38 @@ describe('DataApiService (DONE)', () => { it('... injected service should use provided mockValue', () => { const conversionService = TestBed.inject(ConversionService); - expect(mockConversionService === conversionService) - .withContext('should be true') - .toBeTrue(); + expectToBe(mockConversionService === conversionService, true); }); describe('default values', () => { it('... should have serviceName', () => { const expectedServiceName = 'DataApiService'; - expect(dataApiService.serviceName).toBeDefined(); - expect(dataApiService.serviceName) - .withContext(`should be ${expectedServiceName}`) - .toBe(expectedServiceName); + expectToBe(dataApiService.serviceName, expectedServiceName); }); it('... should have projectId', () => { - expect(dataApiService.projectId).toBeDefined(); - expect(dataApiService.projectId).withContext(`should be ${expectedProjectId}`).toBe(expectedProjectId); + expectToBe(dataApiService.projectId, expectedProjectId); }); it('... should have vocabularyId', () => { - expect(dataApiService.vocabularyId).toBeDefined(); - expect(dataApiService.vocabularyId) - .withContext(`should be ${expectedVocabularyId}`) - .toBe(expectedVocabularyId); + expectToBe(dataApiService.vocabularyId, expectedVocabularyId); }); it('... should have defaultLanguage', () => { - expect(dataApiService.defaultLanguage).toBeDefined(); - expect(dataApiService.defaultLanguage) - .withContext(`should be ${expectedDefaultLanguage}`) - .toBe(expectedDefaultLanguage); + expectToBe(dataApiService.defaultLanguage, expectedDefaultLanguage); }); it('... should have resourceSuffix', () => { - expect(dataApiService.resourceSuffix).toBeDefined(); - expect(dataApiService.resourceSuffix) - .withContext(`should be ${expectedResourceSuffix}`) - .toBe(expectedResourceSuffix); + expectToBe(dataApiService.resourceSuffix, expectedResourceSuffix); }); it('... should have routes', () => { - expect(dataApiService.routes).toBeDefined(); - expect(dataApiService.routes).withContext(`should be ${expectedRoutes}`).toEqual(expectedRoutes); + expectToEqual(dataApiService.routes, expectedRoutes); }); it("... should have empty 'httpGetUrl' (inherited from ApiService)", () => { - expect(dataApiService.httpGetUrl).toBeDefined(); - expect(dataApiService.httpGetUrl).withContext('should be empty string').toBe(''); + expectToBe(dataApiService.httpGetUrl, ''); }); }); @@ -197,8 +179,7 @@ describe('DataApiService (DONE)', () => { httpClient.get('/foo/bar').subscribe({ next: data => { - expect(data).toBeTruthy(); - expect(data).withContext(`should equal ${testData}`).toEqual(testData); + expectToEqual(data, testData); }, }); @@ -208,7 +189,7 @@ describe('DataApiService (DONE)', () => { }); // Check for GET request - expect(call.request.method).withContext(`should be GET`).toBe('GET'); + expectToBe(call.request.method, 'GET'); // Respond with mocked data call.flush(testData); @@ -430,14 +411,9 @@ describe('DataApiService (DONE)', () => { `GET to ${expectedUrl}` ); - expect(call.request.method).toBeTruthy(); - expect(call.request.method).withContext('should be GET').toBe('GET'); - - expect(call.request.responseType).toBeTruthy(); - expect(call.request.responseType).withContext('should be json').toBe('json'); - - expect(call.request.url).toBeTruthy(); - expect(call.request.url).withContext(`should be ${expectedUrl}`).toBe(expectedUrl); + expectToBe(call.request.method, 'GET'); + expectToBe(call.request.responseType, 'json'); + expectToBe(call.request.url, expectedUrl); })); it('... for Extended search with provided object (url does not include query)', waitForAsync(() => { @@ -462,14 +438,9 @@ describe('DataApiService (DONE)', () => { `GET to ${expectedUrl}` ); - expect(call.request.method).toBeTruthy(); - expect(call.request.method).withContext('should be GET').toBe('GET'); - - expect(call.request.responseType).toBeTruthy(); - expect(call.request.responseType).withContext('should be json').toBe('json'); - - expect(call.request.url).toBeTruthy(); - expect(call.request.url).withContext(`should be ${expectedUrl}`).toBe(expectedUrl); + expectToBe(call.request.method, 'GET'); + expectToBe(call.request.responseType, 'json'); + expectToBe(call.request.url, expectedUrl); })); }); @@ -492,7 +463,7 @@ describe('DataApiService (DONE)', () => { ); expect(call.request.params).toBeDefined(); - expect(call.request.params.keys().length).withContext('should be 5').toBe(5); + expectToBe(call.request.params.keys().length, 5); expectParams(call, 'searchtype', ['fulltext'], 1); expectParams(call, 'filter_by_project', [expectedProjectId], 1); @@ -521,7 +492,7 @@ describe('DataApiService (DONE)', () => { ); expect(call.request.params).toBeDefined(); - expect(call.request.params.keys().length).withContext('should be 6').toBe(6); + expectToBe(call.request.params.keys().length, 6); expectParams(call, 'searchtype', ['extended'], 1); expectParams(call, 'filter_by_project', [expectedProjectId], 1); @@ -554,7 +525,7 @@ describe('DataApiService (DONE)', () => { ); expect(call.request.params).toBeDefined(); - expect(call.request.params.keys().length).withContext('should be 5').toBe(5); + expectToBe(call.request.params.keys().length, 5); expectParams(call, 'searchtype', ['fulltext'], 1); expectParams(call, 'filter_by_project', [expectedProjectId], 1); @@ -592,7 +563,7 @@ describe('DataApiService (DONE)', () => { ); expect(call.request.params).toBeDefined(); - expect(call.request.params.keys().length).withContext('should be 8').toBe(8); + expectToBe(call.request.params.keys().length, 8); expectParams(call, 'searchtype', ['extended'], 1); expectParams(call, 'filter_by_project', [expectedProjectId], 1); @@ -634,7 +605,7 @@ describe('DataApiService (DONE)', () => { ); expect(call.request.params).toBeDefined(); - expect(call.request.params.keys().length).withContext('should be 8').toBe(8); + expectToBe(call.request.params.keys().length, 8); expectParams(call, 'searchtype', ['extended'], 1); expectParams(call, 'filter_by_project', [expectedProjectId], 1); @@ -677,7 +648,7 @@ describe('DataApiService (DONE)', () => { ); expect(call.request.params).toBeDefined(); - expect(call.request.params.keys().length).withContext('should be 9').toBe(9); + expectToBe(call.request.params.keys().length, 9); expectParams(call, 'searchtype', ['extended'], 1); expectParams(call, 'filter_by_project', [expectedProjectId], 1); @@ -724,7 +695,7 @@ describe('DataApiService (DONE)', () => { ); expect(call.request.params).toBeDefined(); - expect(call.request.params.keys().length).withContext('should be 9').toBe(9); + expectToBe(call.request.params.keys().length, 9); expectParams(call, 'searchtype', ['extended'], 1); expectParams(call, 'filter_by_project', [expectedProjectId], 1); @@ -828,10 +799,7 @@ describe('DataApiService (DONE)', () => { dataApiService.getSearchData(expectedSearchParams).subscribe({ next: (response: SearchResponseJson) => { - expect(response).toBeTruthy(); - expect(response) - .withContext(`should equal ${expectedSearchResponseConverted}`) - .toEqual(expectedSearchResponseConverted); + expectToEqual(response, expectedSearchResponseConverted); }, }); })); @@ -866,9 +834,7 @@ describe('DataApiService (DONE)', () => { expectedQueryPath, expectedQueryHttpParams, ]); - expect(err) - .withContext(`should equal ${expectedApiServiceError}`) - .toEqual(expectedApiServiceError); + expectToEqual(err, expectedApiServiceError); }, }); })); @@ -955,7 +921,7 @@ describe('DataApiService (DONE)', () => { req => req.url.match(re) && req.method === 'GET' && req.responseType === 'json' ); - expect(calls.length).withContext('should be 2 calls').toBe(2); + expectToBe(calls.length, 2); })); it('... the first request being a ResourceFullResponse request', waitForAsync(() => { @@ -971,20 +937,15 @@ describe('DataApiService (DONE)', () => { req => req.url.match(re) && req.method === 'GET' && req.responseType === 'json' ); - expect(calls.length).withContext('should be 2 calls').toBe(2); + expectToBe(calls.length, 2); // Call to GET https://www.salsah.org/api/resources/11398_-_local (ResourceFullResponseJson) - expect(calls[0].request.method).toBeTruthy(); - expect(calls[0].request.method).withContext('should be GET').toBe('GET'); - - expect(calls[0].request.responseType).toBeTruthy(); - expect(calls[0].request.responseType).withContext('should be json').toBe('json'); - - expect(calls[0].request.url).toBeTruthy(); - expect(calls[0].request.url).withContext(`should be ${expectedUrl}`).toBe(expectedUrl); + expectToBe(calls[0].request.method, 'GET'); + expectToBe(calls[0].request.responseType, 'json'); + expectToBe(calls[0].request.url, expectedUrl); expect(calls[0].request.params).toBeDefined(); - expect(calls[0].request.params.keys().length).withContext('should be 0').toBe(0); + expectToBe(calls[0].request.params.keys().length, 0); })); it('... the second request being a ResourceContextResponse request', waitForAsync(() => { @@ -1000,20 +961,15 @@ describe('DataApiService (DONE)', () => { req => req.url.match(re) && req.method === 'GET' && req.responseType === 'json' ); - expect(calls.length).withContext('should be 2 calls').toBe(2); + expectToBe(calls.length, 2); // Call to GET https://www.salsah.org/api/resources/11398_-_local?reqtype=context (ResourceContextResponseJson) - expect(calls[1].request.method).toBeTruthy(); - expect(calls[1].request.method).withContext('should be GET').toBe('GET'); - - expect(calls[1].request.responseType).toBeTruthy(); - expect(calls[1].request.responseType).withContext('should be json').toBe('json'); - - expect(calls[1].request.url).toBeTruthy(); - expect(calls[1].request.url).withContext(`should be ${expectedUrl}`).toBe(expectedUrl); + expectToBe(calls[0].request.method, 'GET'); + expectToBe(calls[0].request.responseType, 'json'); + expectToBe(calls[0].request.url, expectedUrl); expect(calls[1].request.params).toBeDefined(); - expect(calls[1].request.params.keys().length).withContext('should be 1').toBe(1); + expectToBe(calls[1].request.params.keys().length, 1); expectParams(calls[1], 'reqtype', ['context'], 1); })); @@ -1027,7 +983,7 @@ describe('DataApiService (DONE)', () => { dataApiService.getResourceData(expectedResourceId).subscribe((response: ResourceData) => { // Two calls - expect(getApiResponseSpy.calls.all().length).withContext('should be 2 calls').toBe(2); + expectToBe(getApiResponseSpy.calls.all().length, 2); }); // Expect two requests to url with given settings @@ -1049,26 +1005,15 @@ describe('DataApiService (DONE)', () => { dataApiService.getResourceData(expectedResourceId).subscribe({ next: () => { // Two calls - expect(getApiResponseSpy.calls.all().length).withContext('should be 2 calls').toBe(2); + expectToBe(getApiResponseSpy.calls.all().length, 2); // Shortcut const firstCallArgs = getApiResponseSpy.calls.allArgs()[0]; // Check args of call - expect(firstCallArgs[0].name).toBeTruthy(); - expect(firstCallArgs[0].name) - .withContext('should be ResourceFullResponseJson') - .toBe('ResourceFullResponseJson'); - - expect(firstCallArgs[1]).toBeTruthy(); - expect(firstCallArgs[1]) - .withContext(`should be ${expectedQueryPath}`) - .toBe(expectedQueryPath); - - expect(firstCallArgs[2]).toBeTruthy(); - expect(firstCallArgs[2]) - .withContext(`should equal ${expectedQueryHttpParams}`) - .toEqual(expectedQueryHttpParams); + expectToBe(firstCallArgs[0].name, 'ResourceFullResponseJson'); + expectToBe(firstCallArgs[1], expectedQueryPath); + expectToEqual(firstCallArgs[2], expectedQueryHttpParams); }, }); @@ -1091,26 +1036,15 @@ describe('DataApiService (DONE)', () => { dataApiService.getResourceData(expectedResourceId).subscribe({ next: () => { // Two calls - expect(getApiResponseSpy.calls.all().length).withContext('should be 2 calls').toBe(2); + expectToBe(getApiResponseSpy.calls.all().length, 2); // Shortcut const secondCallArgs = getApiResponseSpy.calls.allArgs()[1]; // Check args of call - expect(secondCallArgs[0].name).toBeTruthy(); - expect(secondCallArgs[0].name) - .withContext('should be ResourceContextResponseJson') - .toBe('ResourceContextResponseJson'); - - expect(secondCallArgs[1]).toBeTruthy(); - expect(secondCallArgs[1]) - .withContext(`should be ${expectedQueryPath}`) - .toBe(expectedQueryPath); - - expect(secondCallArgs[2]).toBeTruthy(); - expect(secondCallArgs[2]) - .withContext(`should equal ${expectedQueryHttpParams}`) - .toEqual(expectedQueryHttpParams); + expectToBe(secondCallArgs[0].name, 'ResourceContextResponseJson'); + expectToBe(secondCallArgs[1], expectedQueryPath); + expectToEqual(secondCallArgs[2], expectedQueryHttpParams); }, }); @@ -1140,11 +1074,8 @@ describe('DataApiService (DONE)', () => { dataApiService.getResourceData(expectedResourceId).subscribe({ next: (resourceData: ResourceData) => { - expect(getApiResponseSpy.calls.all().length).withContext('should be 2 calls').toBe(2); - expect(resourceData).toBeTruthy(); - expect(resourceData) - .withContext(`should equal ${expectedResourceData}`) - .toEqual(expectedResourceData); + expectToBe(getApiResponseSpy.calls.all().length, 2); + expectToEqual(resourceData, expectedResourceData); }, }); })); @@ -1175,10 +1106,8 @@ describe('DataApiService (DONE)', () => { next: () => fail(expectedErrorMsg), error: (err: ApiServiceError) => { // Two calls - expect(getApiResponseSpy.calls.all().length).withContext('should be 2 calls').toBe(2); - expect(err) - .withContext(`should equal ${expectedApiServiceError}`) - .toEqual(expectedApiServiceError); + expectToBe(getApiResponseSpy.calls.all().length, 2); + expectToEqual(err, expectedApiServiceError); }, }); })); @@ -1194,10 +1123,8 @@ describe('DataApiService (DONE)', () => { next: () => fail(expectedErrorMsg), error: (err: ApiServiceError) => { // Two calls - expect(getApiResponseSpy.calls.all().length).withContext('should be 2 calls').toBe(2); - expect(err) - .withContext(`should equal ${expectedApiServiceError}`) - .toEqual(expectedApiServiceError); + expectToBe(getApiResponseSpy.calls.all().length, 2); + expectToEqual(err, expectedApiServiceError); }, }); })); @@ -1213,10 +1140,8 @@ describe('DataApiService (DONE)', () => { next: () => fail(expectedErrorMsg), error: (err: ApiServiceError) => { // Two calls - expect(getApiResponseSpy.calls.all().length).withContext('should be 2 calls').toBe(2); - expect(err) - .withContext(`should equal ${expectedApiServiceError}`) - .toEqual(expectedApiServiceError); + expectToBe(getApiResponseSpy.calls.all().length, 2); + expectToEqual(err, expectedApiServiceError); }, }); })); @@ -1244,14 +1169,9 @@ describe('DataApiService (DONE)', () => { `GET to ${expectedUrl}` ); - expect(call.request.method).toBeTruthy(); - expect(call.request.method).withContext('should be GET').toBe('GET'); - - expect(call.request.responseType).toBeTruthy(); - expect(call.request.responseType).withContext('should be json').toBe('json'); - - expect(call.request.url).toBeTruthy(); - expect(call.request.url).withContext(`should be ${expectedUrl}`).toBe(expectedUrl); + expectToBe(call.request.method, 'GET'); + expectToBe(call.request.responseType, 'json'); + expectToBe(call.request.url, expectedUrl); })); it('... should set default query params for GET request', waitForAsync(() => { @@ -1268,7 +1188,7 @@ describe('DataApiService (DONE)', () => { ); expect(call.request.params).toBeDefined(); - expect(call.request.params.keys().length).withContext('should be 2').toBe(2); + expectToBe(call.request.params.keys().length, 2); expectParams(call, 'vocabulary', [expectedVocabularyId], 1); expectParams(call, 'lang', [expectedDefaultLanguage], 1); @@ -1302,9 +1222,7 @@ describe('DataApiService (DONE)', () => { dataApiService.getResourceTypes().subscribe({ next: (restypes: ResourceTypesInVocabularyResponseJson) => { expect(restypes).toBeTruthy(); - expect(restypes) - .withContext(`should equal ${expectedResourceTypesInVocabularyResponseJson}`) - .toEqual(expectedResourceTypesInVocabularyResponseJson); + expectToEqual(restypes, expectedResourceTypesInVocabularyResponseJson); }, }); })); @@ -1333,9 +1251,7 @@ describe('DataApiService (DONE)', () => { expectedQueryPath, expectedQueryHttpParams, ]); - expect(err) - .withContext(`should equal ${expectedApiServiceError}`) - .toEqual(expectedApiServiceError); + expectToEqual(err, expectedApiServiceError); }, }); })); @@ -1422,14 +1338,9 @@ describe('DataApiService (DONE)', () => { `GET to ${expectedUrl}` ); - expect(call.request.method).toBeTruthy(); - expect(call.request.method).withContext('should be GET').toBe('GET'); - - expect(call.request.responseType).toBeTruthy(); - expect(call.request.responseType).withContext('should be json').toBe('json'); - - expect(call.request.url).toBeTruthy(); - expect(call.request.url).withContext(`should be ${expectedUrl}`).toBe(expectedUrl); + expectToBe(call.request.method, 'GET'); + expectToBe(call.request.responseType, 'json'); + expectToBe(call.request.url, expectedUrl); })); it('... should set default query params for GET request', waitForAsync(() => { @@ -1447,7 +1358,7 @@ describe('DataApiService (DONE)', () => { ); expect(call.request.params).toBeDefined(); - expect(call.request.params.keys().length).withContext('should be 1').toBe(1); + expectToBe(call.request.params.keys().length, 1); expectParams(call, 'restype', [expectedRestype], 1); })); @@ -1482,9 +1393,7 @@ describe('DataApiService (DONE)', () => { dataApiService.getPropertyListsByResourceType(expectedRestype).subscribe({ next: (propertyList: PropertyTypesInResourceClassResponseJson) => { expect(propertyList).toBeTruthy(); - expect(propertyList) - .withContext(`should equal ${expectedPropertyTypesInResourceClassResponseJson}`) - .toEqual(expectedPropertyTypesInResourceClassResponseJson); + expectToEqual(propertyList, expectedPropertyTypesInResourceClassResponseJson); }, }); })); @@ -1512,9 +1421,7 @@ describe('DataApiService (DONE)', () => { expectedQueryPath, expectedQueryHttpParams, ]); - expect(err) - .withContext(`should equal ${expectedApiServiceError}`) - .toEqual(expectedApiServiceError); + expectToEqual(err, expectedApiServiceError); }, }); })); diff --git a/src/app/views/edition-view/data/edition-assets.data.ts b/src/app/views/edition-view/data/edition-assets.data.ts index 9dd7e347a..c1619d279 100644 --- a/src/app/views/edition-view/data/edition-assets.data.ts +++ b/src/app/views/edition-view/data/edition-assets.data.ts @@ -14,9 +14,11 @@ export const EDITION_ASSETS_DATA = { * The names of the edition assets JSON files. */ FILES: { + complexesFile: 'edition-complexes.json', folioConvoluteFile: 'folio-convolute.json', graphFile: 'graph.json', introFile: 'intro.json', + prefaceFile: 'preface.json', rowTablesFile: 'row-tables.json', sourceListFile: 'source-list.json', sourceDescriptionListFile: 'source-description.json', diff --git a/src/app/views/edition-view/data/edition-complexes.data.ts b/src/app/views/edition-view/data/edition-complexes.data.ts deleted file mode 100644 index f8ed7c7b7..000000000 --- a/src/app/views/edition-view/data/edition-complexes.data.ts +++ /dev/null @@ -1,774 +0,0 @@ -import { AppConfig } from '@awg-app/app.config'; -import { - EDITION_CATALOGUE_TYPE_CONSTANTS, - EDITION_ROUTE_CONSTANTS, - EDITION_TYPE_CONSTANTS, -} from '@awg-views/edition-view/edition-route-constants'; -import { EditionComplex } from '@awg-views/edition-view/models'; - -/** - * The EditionComplexes class. - * - * It is used in the context of the edition view - * to store information about the edition complexes. - */ -export class EDITION_COMPLEXES { - /** - * An EditionComplex object for M 22. - */ - static readonly M22: EditionComplex = new EditionComplex( - { - title: 'Studienkomposition für Klavier / Streichquartett', - catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.MNR, - catalogueNumber: '22', - }, - { - editors: [ - { - name: 'Michael Matter', - homepage: AppConfig.AWG_PROJECT_URL + 'index.php?id=3', - }, - ], - lastModified: '21. März 2024', - }, - EDITION_ROUTE_CONSTANTS.SERIES_2, - EDITION_ROUTE_CONSTANTS.SECTION_2A, - EDITION_TYPE_CONSTANTS.SKETCH_EDITION - ); - - /** - * An EditionComplex object for M 30. - */ - static readonly M30: EditionComplex = new EditionComplex( - { - title: 'Studienkomposition für Klavier', - catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.MNR, - catalogueNumber: '30', - }, - { - editors: [ - { - name: 'Michael Matter', - homepage: AppConfig.AWG_PROJECT_URL + 'index.php?id=3', - }, - ], - lastModified: '19. Januar 2024', - }, - EDITION_ROUTE_CONSTANTS.SERIES_2, - EDITION_ROUTE_CONSTANTS.SECTION_2A, - EDITION_TYPE_CONSTANTS.SKETCH_EDITION - ); - - /** - * An EditionComplex object for M 31. - */ - static readonly M31: EditionComplex = new EditionComplex( - { - title: 'Studienkomposition für Klavier', - catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.MNR, - catalogueNumber: '31', - }, - { - editors: [ - { - name: 'Michael Matter', - homepage: AppConfig.AWG_PROJECT_URL + 'index.php?id=3', - }, - ], - lastModified: '19. Januar 2024', - }, - EDITION_ROUTE_CONSTANTS.SERIES_2, - EDITION_ROUTE_CONSTANTS.SECTION_2A, - EDITION_TYPE_CONSTANTS.SKETCH_EDITION - ); - - /** - * An EditionComplex object for M 34. - */ - static readonly M34: EditionComplex = new EditionComplex( - { - title: 'Studienkomposition für Klavier', - catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.MNR, - catalogueNumber: '34', - }, - { - editors: [ - { - name: 'Michael Matter', - homepage: AppConfig.AWG_PROJECT_URL + 'index.php?id=3', - }, - ], - lastModified: '6. Mai 2023', - }, - EDITION_ROUTE_CONSTANTS.SERIES_2, - EDITION_ROUTE_CONSTANTS.SECTION_2A, - EDITION_TYPE_CONSTANTS.SKETCH_EDITION - ); - - /** - * An EditionComplex object for M 35/42. - */ - static readonly M35_42: EditionComplex = new EditionComplex( - { - title: 'Studienkomposition für Klavier', - catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.MNR, - catalogueNumber: '35/42', - }, - { - editors: [ - { - name: 'Michael Matter', - homepage: AppConfig.AWG_PROJECT_URL + 'index.php?id=3', - }, - ], - lastModified: '8. Februar 2024', - }, - EDITION_ROUTE_CONSTANTS.SERIES_2, - EDITION_ROUTE_CONSTANTS.SECTION_2A, - EDITION_TYPE_CONSTANTS.SKETCH_EDITION - ); - - /** - * An EditionComplex object for M 37. - */ - static readonly M37: EditionComplex = new EditionComplex( - { - title: 'Studienkomposition für Klavier', - catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.MNR, - catalogueNumber: '37', - }, - { - editors: [ - { - name: 'Michael Matter', - homepage: AppConfig.AWG_PROJECT_URL + 'index.php?id=3', - }, - ], - lastModified: '19. Januar 2024', - }, - EDITION_ROUTE_CONSTANTS.SERIES_2, - EDITION_ROUTE_CONSTANTS.SECTION_2A, - EDITION_TYPE_CONSTANTS.SKETCH_EDITION - ); - - /** - * An EditionComplex object for M 133. - */ - static readonly M133: EditionComplex = new EditionComplex( - { - title: '„Dies ist ein Lied“', - catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.MNR, - catalogueNumber: '133', - }, - { - editors: [ - { - name: 'Thomas Ahrend', - homepage: AppConfig.AWG_PROJECT_URL + 'index.php?id=3', - }, - ], - lastModified: '6. Juni 2024', - }, - EDITION_ROUTE_CONSTANTS.SERIES_1, - EDITION_ROUTE_CONSTANTS.SECTION_5, - EDITION_TYPE_CONSTANTS.SKETCH_EDITION - ); - - /** - * An EditionComplex object for M 134. - */ - static readonly M134: EditionComplex = new EditionComplex( - { - title: '„Im Windesweben“', - catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.MNR, - catalogueNumber: '134', - }, - { - editors: [ - { - name: 'Thomas Ahrend', - homepage: AppConfig.AWG_PROJECT_URL + 'index.php?id=3', - }, - ], - lastModified: '6. Juni 2024', - }, - EDITION_ROUTE_CONSTANTS.SERIES_1, - EDITION_ROUTE_CONSTANTS.SECTION_5, - EDITION_TYPE_CONSTANTS.SKETCH_EDITION - ); - - /** - * An EditionComplex object for M 135. - */ - static readonly M135: EditionComplex = new EditionComplex( - { - title: '„An Bachesranft“', - catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.MNR, - catalogueNumber: '135', - }, - { - editors: [ - { - name: 'Thomas Ahrend', - homepage: AppConfig.AWG_PROJECT_URL + 'index.php?id=3', - }, - ], - lastModified: '6. Juni 2024', - }, - EDITION_ROUTE_CONSTANTS.SERIES_1, - EDITION_ROUTE_CONSTANTS.SECTION_5, - EDITION_TYPE_CONSTANTS.SKETCH_EDITION - ); - - /** - * An EditionComplex object for M 136. - */ - static readonly M136: EditionComplex = new EditionComplex( - { - title: '„Im Morgentaun“', - catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.MNR, - catalogueNumber: '136', - }, - { - editors: [ - { - name: 'Thomas Ahrend', - homepage: AppConfig.AWG_PROJECT_URL + 'index.php?id=3', - }, - ], - lastModified: '6. Juni 2024', - }, - EDITION_ROUTE_CONSTANTS.SERIES_1, - EDITION_ROUTE_CONSTANTS.SECTION_5, - EDITION_TYPE_CONSTANTS.SKETCH_EDITION - ); - - /** - * An EditionComplex object for M 137. - */ - static readonly M137: EditionComplex = new EditionComplex( - { - title: '„Kahl reckt der Baum“', - catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.MNR, - catalogueNumber: '137', - }, - { - editors: [ - { - name: 'Thomas Ahrend', - homepage: AppConfig.AWG_PROJECT_URL + 'index.php?id=3', - }, - ], - lastModified: '6. Juni 2024', - }, - EDITION_ROUTE_CONSTANTS.SERIES_1, - EDITION_ROUTE_CONSTANTS.SECTION_5, - EDITION_TYPE_CONSTANTS.SKETCH_EDITION - ); - - /** - * An EditionComplex object for M 138. - */ - static readonly M138: EditionComplex = new EditionComplex( - { - title: 'Eingang („Welt der Gestalten“)', - catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.MNR, - catalogueNumber: '138', - }, - { - editors: [ - { - name: 'Thomas Ahrend', - homepage: AppConfig.AWG_PROJECT_URL + 'index.php?id=3', - }, - ], - lastModified: '6. Juni 2024', - }, - EDITION_ROUTE_CONSTANTS.SERIES_1, - EDITION_ROUTE_CONSTANTS.SECTION_5, - EDITION_TYPE_CONSTANTS.SKETCH_EDITION - ); - - /** - * An EditionComplex object for M 139. - */ - static readonly M139: EditionComplex = new EditionComplex( - { - title: '„Noch zwingt mich Treue“', - catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.MNR, - catalogueNumber: '139', - }, - { - editors: [ - { - name: 'Thomas Ahrend', - homepage: AppConfig.AWG_PROJECT_URL + 'index.php?id=3', - }, - ], - lastModified: '6. Juni 2024', - }, - EDITION_ROUTE_CONSTANTS.SERIES_1, - EDITION_ROUTE_CONSTANTS.SECTION_5, - EDITION_TYPE_CONSTANTS.SKETCH_EDITION - ); - - /** - * An EditionComplex object for M 140. - */ - static readonly M140: EditionComplex = new EditionComplex( - { - title: '„Ja Heil und Dank dir“', - catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.MNR, - catalogueNumber: '140', - }, - { - editors: [ - { - name: 'Thomas Ahrend', - homepage: AppConfig.AWG_PROJECT_URL + 'index.php?id=3', - }, - ], - lastModified: '6. Juni 2024', - }, - EDITION_ROUTE_CONSTANTS.SERIES_1, - EDITION_ROUTE_CONSTANTS.SECTION_5, - EDITION_TYPE_CONSTANTS.SKETCH_EDITION - ); - - /** - * An EditionComplex object for M 141. - */ - static readonly M141: EditionComplex = new EditionComplex( - { - title: '„So ich traurig bin“', - catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.MNR, - catalogueNumber: '141', - }, - { - editors: [ - { - name: 'Thomas Ahrend', - homepage: AppConfig.AWG_PROJECT_URL + 'index.php?id=3', - }, - ], - lastModified: '6. Juni 2024', - }, - EDITION_ROUTE_CONSTANTS.SERIES_1, - EDITION_ROUTE_CONSTANTS.SECTION_5, - EDITION_TYPE_CONSTANTS.SKETCH_EDITION - ); - - /** - * An EditionComplex object for M 142. - */ - static readonly M142: EditionComplex = new EditionComplex( - { - title: '„Ihr tratet zu dem Herde“', - catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.MNR, - catalogueNumber: '142', - }, - { - editors: [ - { - name: 'Thomas Ahrend', - homepage: AppConfig.AWG_PROJECT_URL + 'index.php?id=3', - }, - ], - lastModified: '6. Juni 2024', - }, - EDITION_ROUTE_CONSTANTS.SERIES_1, - EDITION_ROUTE_CONSTANTS.SECTION_5, - EDITION_TYPE_CONSTANTS.SKETCH_EDITION - ); - - /** - * An EditionComplex object for M 143. - */ - static readonly M143: EditionComplex = new EditionComplex( - { - title: '„Erwachen aus dem tiefsten Traumesschoße“', - catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.MNR, - catalogueNumber: '143', - }, - { - editors: [ - { - name: 'Thomas Ahrend', - homepage: AppConfig.AWG_PROJECT_URL + 'index.php?id=3', - }, - ], - lastModified: '6. Juni 2024', - }, - EDITION_ROUTE_CONSTANTS.SERIES_1, - EDITION_ROUTE_CONSTANTS.SECTION_5, - EDITION_TYPE_CONSTANTS.SKETCH_EDITION - ); - - /** - * An EditionComplex object for M 144. - */ - static readonly M144: EditionComplex = new EditionComplex( - { - title: 'Kunfttag I („Dem bist du Kind“)', - catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.MNR, - catalogueNumber: '144', - }, - { - editors: [ - { - name: 'Thomas Ahrend', - homepage: AppConfig.AWG_PROJECT_URL + 'index.php?id=3', - }, - ], - lastModified: '6. Juni 2024', - }, - EDITION_ROUTE_CONSTANTS.SERIES_1, - EDITION_ROUTE_CONSTANTS.SECTION_5, - EDITION_TYPE_CONSTANTS.SKETCH_EDITION - ); - - /** - * An EditionComplex object for M 145. - */ - static readonly M145: EditionComplex = new EditionComplex( - { - title: 'Trauer I („So wart bis ich dies dir noch künde“)', - catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.MNR, - catalogueNumber: '145', - }, - { - editors: [ - { - name: 'Thomas Ahrend', - homepage: AppConfig.AWG_PROJECT_URL + 'index.php?id=3', - }, - ], - lastModified: '6. Juni 2024', - }, - EDITION_ROUTE_CONSTANTS.SERIES_1, - EDITION_ROUTE_CONSTANTS.SECTION_5, - EDITION_TYPE_CONSTANTS.SKETCH_EDITION - ); - - /** - * An EditionComplex object for M 146. - */ - static readonly M146: EditionComplex = new EditionComplex( - { - title: '„Das lockere Saatgefilde“', - catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.MNR, - catalogueNumber: '146', - }, - { - editors: [ - { - name: 'Thomas Ahrend', - homepage: AppConfig.AWG_PROJECT_URL + 'index.php?id=3', - }, - ], - lastModified: '6. Juni 2024', - }, - EDITION_ROUTE_CONSTANTS.SERIES_1, - EDITION_ROUTE_CONSTANTS.SECTION_5, - EDITION_TYPE_CONSTANTS.SKETCH_EDITION - ); - - /** - * An EditionComplex object for M 212. - */ - static readonly M212: EditionComplex = new EditionComplex( - { - title: '„Der Tag ist vergangen“', - catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.MNR, - catalogueNumber: '212', - }, - { - editors: [ - { - name: 'Thomas Ahrend', - homepage: AppConfig.AWG_PROJECT_URL + 'index.php?id=3', - }, - ], - lastModified: '---', - }, - EDITION_ROUTE_CONSTANTS.SERIES_1, - EDITION_ROUTE_CONSTANTS.SECTION_5, - EDITION_TYPE_CONSTANTS.SKETCH_EDITION - ); - - /** - * An EditionComplex object for M 213. - */ - static readonly M213: EditionComplex = new EditionComplex( - { - title: '„Schien mir’s, als ich sah die Sonne“', - catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.MNR, - catalogueNumber: '213', - }, - { - editors: [ - { - name: 'Thomas Ahrend', - homepage: AppConfig.AWG_PROJECT_URL + 'index.php?id=3', - }, - ], - lastModified: '---', - }, - EDITION_ROUTE_CONSTANTS.SERIES_1, - EDITION_ROUTE_CONSTANTS.SECTION_5, - EDITION_TYPE_CONSTANTS.SKETCH_EDITION - ); - - /** - * An EditionComplex object for M 216. - */ - static readonly M216: EditionComplex = new EditionComplex( - { - title: 'Gleich und Gleich („Ein Blumenglöckchen“)', - catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.MNR, - catalogueNumber: '216', - }, - { - editors: [ - { - name: 'Thomas Ahrend', - homepage: AppConfig.AWG_PROJECT_URL + 'index.php?id=3', - }, - ], - lastModified: '---', - }, - EDITION_ROUTE_CONSTANTS.SERIES_1, - EDITION_ROUTE_CONSTANTS.SECTION_5, - EDITION_TYPE_CONSTANTS.SKETCH_EDITION - ); - - /** - * An EditionComplex object for M 217. - */ - static readonly M217: EditionComplex = new EditionComplex( - { - title: 'Die geheimnisvolle Flöte („An einem Abend“)', - catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.MNR, - catalogueNumber: '217', - }, - { - editors: [ - { - name: 'Thomas Ahrend', - homepage: AppConfig.AWG_PROJECT_URL + 'index.php?id=3', - }, - ], - lastModified: '---', - }, - EDITION_ROUTE_CONSTANTS.SERIES_1, - EDITION_ROUTE_CONSTANTS.SECTION_5, - EDITION_TYPE_CONSTANTS.SKETCH_EDITION - ); - - /** - * An EditionComplex object for Opus 3. - */ - static readonly OP3: EditionComplex = new EditionComplex( - { - title: 'Fünf Lieder aus Der siebente Ring von Stefan George', - catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.OPUS, - catalogueNumber: '3', - }, - { - editors: [ - { - name: 'Thomas Ahrend', - homepage: AppConfig.AWG_PROJECT_URL + 'index.php?id=3', - }, - ], - lastModified: '6. Juni 2024', - }, - EDITION_ROUTE_CONSTANTS.SERIES_1, - EDITION_ROUTE_CONSTANTS.SECTION_5, - EDITION_TYPE_CONSTANTS.SKETCH_EDITION - ); - - /** - * An EditionComplex object for Opus 4. - */ - static readonly OP4: EditionComplex = new EditionComplex( - { - title: 'Fünf Lieder nach Gedichten von Stefan George', - catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.OPUS, - catalogueNumber: '4', - }, - { - editors: [ - { - name: 'Thomas Ahrend', - homepage: AppConfig.AWG_PROJECT_URL + 'index.php?id=3', - }, - ], - lastModified: '6. Juni 2024', - }, - EDITION_ROUTE_CONSTANTS.SERIES_1, - EDITION_ROUTE_CONSTANTS.SECTION_5, - EDITION_TYPE_CONSTANTS.SKETCH_EDITION - ); - - /** - * An EditionComplex object for Opus 12. - */ - static readonly OP12: EditionComplex = new EditionComplex( - { - title: 'Vier Lieder', - catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.OPUS, - catalogueNumber: '12', - }, - { - editors: [ - { - name: 'Thomas Ahrend', - homepage: AppConfig.AWG_PROJECT_URL + 'index.php?id=3', - }, - ], - lastModified: '9. April 2024', - }, - EDITION_ROUTE_CONSTANTS.SERIES_1, - EDITION_ROUTE_CONSTANTS.SECTION_5, - EDITION_TYPE_CONSTANTS.SKETCH_EDITION - ); - - /** - * An EditionComplex object for Opus 19. - */ - static readonly OP19: EditionComplex = new EditionComplex( - { - title: 'Zwei Lieder für gemischten Chor und Ensemble', - catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.OPUS, - catalogueNumber: '19', - }, - { - editors: [ - { - name: 'Thomas Ahrend', - homepage: AppConfig.AWG_PROJECT_URL + 'index.php?id=3', - }, - ], - lastModified: '6. Mai 2023', - }, - EDITION_ROUTE_CONSTANTS.SERIES_1, - EDITION_ROUTE_CONSTANTS.SECTION_3, - EDITION_TYPE_CONSTANTS.SKETCH_EDITION - ); - - /** - * An EditionComplex object for Opus 22. - */ - static readonly OP22: EditionComplex = new EditionComplex( - { - title: 'Quartett für Geige, Klarinette, Tenorsaxophon und Klavier', - catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.OPUS, - catalogueNumber: '22', - }, - { - editors: [ - { - name: 'Thomas Ahrend', - homepage: AppConfig.AWG_PROJECT_URL + 'index.php?id=3', - }, - ], - lastModified: '6. Mai 2023', - }, - EDITION_ROUTE_CONSTANTS.SERIES_1, - EDITION_ROUTE_CONSTANTS.SECTION_2, - EDITION_TYPE_CONSTANTS.SKETCH_EDITION - ); - - /** - * An EditionComplex object for Opus 23. - */ - static readonly OP23: EditionComplex = new EditionComplex( - { - title: 'Drei Gesänge aus Viae Inviae von Hildegard Jone', - catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.OPUS, - catalogueNumber: '23', - }, - { - editors: [ - { - name: 'Thomas Ahrend', - homepage: AppConfig.AWG_PROJECT_URL + 'index.php?id=3', - }, - ], - lastModified: '17. April 2024', - }, - EDITION_ROUTE_CONSTANTS.SERIES_1, - EDITION_ROUTE_CONSTANTS.SECTION_5, - EDITION_TYPE_CONSTANTS.SKETCH_EDITION - ); - - /** - * An EditionComplex object for Opus 24. - */ - static readonly OP24: EditionComplex = new EditionComplex( - { - title: 'Konzert für neun Instrumente', - catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.OPUS, - catalogueNumber: '24', - }, - { - editors: [ - { - name: 'Thomas Ahrend', - homepage: AppConfig.AWG_PROJECT_URL + 'index.php?id=3', - }, - ], - lastModified: '6. Mai 2023', - }, - EDITION_ROUTE_CONSTANTS.SERIES_1, - EDITION_ROUTE_CONSTANTS.SECTION_1, - EDITION_TYPE_CONSTANTS.SKETCH_EDITION - ); - - /** - * An EditionComplex object for Opus 25. - */ - static readonly OP25: EditionComplex = new EditionComplex( - { - title: 'Drei Lieder nach Gedichten von Hildegard Jone', - catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.OPUS, - catalogueNumber: '25', - }, - { - editors: [ - { - name: 'Thomas Ahrend', - homepage: AppConfig.AWG_PROJECT_URL + 'index.php?id=3', - }, - ], - lastModified: '17. April 2024', - }, - EDITION_ROUTE_CONSTANTS.SERIES_1, - EDITION_ROUTE_CONSTANTS.SECTION_5, - EDITION_TYPE_CONSTANTS.SKETCH_EDITION - ); - - /** - * An EditionComplex object for Opus 27. - */ - static readonly OP27: EditionComplex = new EditionComplex( - { - title: 'Variationen für Klavier', - catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.OPUS, - catalogueNumber: '27', - }, - { - editors: [ - { - name: 'Thomas Ahrend', - homepage: AppConfig.AWG_PROJECT_URL + 'index.php?id=3', - }, - ], - lastModified: '6. Mai 2023', - }, - EDITION_ROUTE_CONSTANTS.SERIES_1, - EDITION_ROUTE_CONSTANTS.SECTION_2, - EDITION_TYPE_CONSTANTS.SKETCH_EDITION - ); -} diff --git a/src/app/views/edition-view/data/edition-glyphs.data.ts b/src/app/views/edition-view/data/edition-glyphs.data.ts index 7e8a15345..1ba65657c 100644 --- a/src/app/views/edition-view/data/edition-glyphs.data.ts +++ b/src/app/views/edition-view/data/edition-glyphs.data.ts @@ -83,6 +83,33 @@ export const EDITION_GLYPHS_DATA = { hex: '\uD834\uDD91\uD834\uDD91\uD834\uDD91', }, + /** + * The glyph of a musical mezzo forte symbol. + * Cf. https://graphemica.com/%F0%9D%86%90 + */ + MEZZOFORTE: { + alt: '[mf]', + hex: '\uD834\uDD90\uD834\uDD91', + }, + + /** + * The glyph of a musical mezzo piano symbol. + * Cf. https://graphemica.com/%F0%9D%86%90 + */ + MEZZOPIANO: { + alt: '[mp]', + hex: '\uD834\uDD90\uD834\uDD8F', + }, + + /** + * The glyph of a musical pedal symbol. + * Cf. https://graphemica.com/%F0%9D%86%AE + */ + PEDAL: { + alt: '[ped]', + hex: '\uD834\uDDAE', + }, + /** * The glyph of a musical pianissimo (double piano) symbol. * Cf. https://graphemica.com/%F0%9D%86%8F diff --git a/src/app/views/edition-view/data/edition-outline.data.ts b/src/app/views/edition-view/data/edition-outline.data.ts deleted file mode 100644 index 256032cbc..000000000 --- a/src/app/views/edition-view/data/edition-outline.data.ts +++ /dev/null @@ -1,144 +0,0 @@ -import { EDITION_COMPLEXES } from '@awg-views/edition-view/data'; -import { EDITION_ROUTE_CONSTANTS } from '@awg-views/edition-view/edition-route-constants'; -import { EditionOutlineSeries } from '@awg-views/edition-view/models'; - -/** - * Object constant: EDITION_OUTLINE_DATA. - * - * It provides metadata for the outline structure of the edition. - */ -export const EDITION_OUTLINE_DATA: EditionOutlineSeries[] = [ - { - series: EDITION_ROUTE_CONSTANTS.SERIES_1, - sections: [ - { - section: EDITION_ROUTE_CONSTANTS.SECTION_1, - complexes: { opus: [], mnr: [] }, - disabled: true, - }, - { - section: EDITION_ROUTE_CONSTANTS.SECTION_2, - complexes: { opus: [], mnr: [] }, - disabled: true, - }, - { - section: EDITION_ROUTE_CONSTANTS.SECTION_3, - complexes: { opus: [], mnr: [] }, - disabled: true, - }, - { - section: EDITION_ROUTE_CONSTANTS.SECTION_4, - complexes: { opus: [], mnr: [] }, - disabled: true, - }, - { - section: EDITION_ROUTE_CONSTANTS.SECTION_5, - complexes: { - opus: [ - { complex: EDITION_COMPLEXES.OP3, disabled: false }, - { complex: EDITION_COMPLEXES.OP4, disabled: false }, - { complex: EDITION_COMPLEXES.OP12, disabled: false }, - { complex: EDITION_COMPLEXES.OP23, disabled: false }, - { complex: EDITION_COMPLEXES.OP25, disabled: false }, - ], - mnr: [ - { complex: EDITION_COMPLEXES.M133, disabled: true }, - { complex: EDITION_COMPLEXES.M134, disabled: true }, - { complex: EDITION_COMPLEXES.M135, disabled: true }, - { complex: EDITION_COMPLEXES.M136, disabled: true }, - { complex: EDITION_COMPLEXES.M137, disabled: true }, - { complex: EDITION_COMPLEXES.M138, disabled: true }, - { complex: EDITION_COMPLEXES.M139, disabled: true }, - { complex: EDITION_COMPLEXES.M140, disabled: true }, - { complex: EDITION_COMPLEXES.M141, disabled: true }, - { complex: EDITION_COMPLEXES.M142, disabled: true }, - { complex: EDITION_COMPLEXES.M143, disabled: false }, - { complex: EDITION_COMPLEXES.M144, disabled: false }, - { complex: EDITION_COMPLEXES.M145, disabled: false }, - { complex: EDITION_COMPLEXES.M146, disabled: false }, - { complex: EDITION_COMPLEXES.M213, disabled: true }, - { complex: EDITION_COMPLEXES.M212, disabled: true }, - { complex: EDITION_COMPLEXES.M216, disabled: true }, - { complex: EDITION_COMPLEXES.M217, disabled: true }, - ], - }, - disabled: false, - }, - ], - }, - { - series: EDITION_ROUTE_CONSTANTS.SERIES_2, - sections: [ - { - section: EDITION_ROUTE_CONSTANTS.SECTION_1, - complexes: { opus: [], mnr: [] }, - disabled: true, - }, - { - section: EDITION_ROUTE_CONSTANTS.SECTION_2A, - complexes: { - opus: [], - mnr: [ - { complex: EDITION_COMPLEXES.M22, disabled: false }, - { complex: EDITION_COMPLEXES.M30, disabled: false }, - { complex: EDITION_COMPLEXES.M31, disabled: false }, - { complex: EDITION_COMPLEXES.M34, disabled: false }, - { complex: EDITION_COMPLEXES.M35_42, disabled: false }, - { complex: EDITION_COMPLEXES.M37, disabled: false }, - ], - }, - disabled: false, - }, - { - section: EDITION_ROUTE_CONSTANTS.SECTION_2B, - complexes: { opus: [], mnr: [] }, - disabled: true, - }, - { - section: EDITION_ROUTE_CONSTANTS.SECTION_3, - complexes: { opus: [], mnr: [] }, - disabled: true, - }, - { - section: EDITION_ROUTE_CONSTANTS.SECTION_4, - complexes: { opus: [], mnr: [] }, - disabled: true, - }, - { - section: EDITION_ROUTE_CONSTANTS.SECTION_5, - complexes: { opus: [], mnr: [] }, - disabled: true, - }, - ], - }, - { - series: EDITION_ROUTE_CONSTANTS.SERIES_3, - sections: [ - { - section: EDITION_ROUTE_CONSTANTS.SECTION_1, - complexes: { opus: [], mnr: [] }, - disabled: true, - }, - { - section: EDITION_ROUTE_CONSTANTS.SECTION_2, - complexes: { opus: [], mnr: [] }, - disabled: true, - }, - { - section: EDITION_ROUTE_CONSTANTS.SECTION_3, - complexes: { opus: [], mnr: [] }, - disabled: true, - }, - { - section: EDITION_ROUTE_CONSTANTS.SECTION_4, - complexes: { opus: [], mnr: [] }, - disabled: true, - }, - { - section: EDITION_ROUTE_CONSTANTS.SERIES_3_SECTION_5, - complexes: { opus: [], mnr: [] }, - disabled: true, - }, - ], - }, -]; diff --git a/src/app/views/edition-view/data/index.ts b/src/app/views/edition-view/data/index.ts index e7bcf8d8b..850e7c141 100644 --- a/src/app/views/edition-view/data/index.ts +++ b/src/app/views/edition-view/data/index.ts @@ -8,17 +8,8 @@ */ import { EDITION_ASSETS_DATA } from './edition-assets.data'; -import { EDITION_COMPLEXES } from './edition-complexes.data'; import { EDITION_FIRM_SIGNS_DATA } from './edition-firm-signs.data'; import { EDITION_GLYPHS_DATA } from './edition-glyphs.data'; import { EDITION_GRAPH_IMAGES_DATA } from './edition-graph-images.data'; -import { EDITION_OUTLINE_DATA } from './edition-outline.data'; -export { - EDITION_ASSETS_DATA, - EDITION_FIRM_SIGNS_DATA, - EDITION_GLYPHS_DATA, - EDITION_GRAPH_IMAGES_DATA, - EDITION_OUTLINE_DATA, - EDITION_COMPLEXES, -}; +export { EDITION_ASSETS_DATA, EDITION_FIRM_SIGNS_DATA, EDITION_GLYPHS_DATA, EDITION_GRAPH_IMAGES_DATA }; diff --git a/src/app/views/edition-view/edition-complex-card/edition-complex-card.component.html b/src/app/views/edition-view/edition-complex-card/edition-complex-card.component.html index 6ae70d510..f56c86500 100644 --- a/src/app/views/edition-view/edition-complex-card/edition-complex-card.component.html +++ b/src/app/views/edition-view/edition-complex-card/edition-complex-card.component.html @@ -13,7 +13,7 @@
Ediert von @for ( - editor of complex.complex.responsibilityStatement.editors; + editor of complex.complex.respStatement.editors; track editor.name; let isLast = $last ) { @@ -26,7 +26,7 @@
}
Versionsdatum: - {{ complex.complex.responsibilityStatement.lastModified }} + {{ complex.complex.respStatement.lastModified }}

} diff --git a/src/app/views/edition-view/edition-complex-card/edition-complex-card.component.spec.ts b/src/app/views/edition-view/edition-complex-card/edition-complex-card.component.spec.ts index 03c111547..340b9bcd5 100644 --- a/src/app/views/edition-view/edition-complex-card/edition-complex-card.component.spec.ts +++ b/src/app/views/edition-view/edition-complex-card/edition-complex-card.component.spec.ts @@ -10,8 +10,8 @@ import { } from '@testing/expect-helper'; import { RouterLinkStubDirective } from '@testing/router-stubs'; -import { EDITION_COMPLEXES } from '@awg-views/edition-view/data'; -import { EditionOutlineComplex } from '@awg-views/edition-view/models'; +import { EditionOutlineComplexItem } from '@awg-views/edition-view/models'; +import { EditionComplexesService } from '@awg-views/edition-view/services'; import { EditionComplexCardComponent } from './edition-complex-card.component'; @@ -23,7 +23,11 @@ describe('EditionComplexCardComponent (DONE)', () => { let linkDes: DebugElement[]; let routerLinks; - let expectedComplexes: EditionOutlineComplex[]; + let expectedComplexes: EditionOutlineComplexItem[]; + + beforeAll(() => { + EditionComplexesService.initializeEditionComplexesList(); + }); beforeEach(async () => { await TestBed.configureTestingModule({ @@ -38,11 +42,11 @@ describe('EditionComplexCardComponent (DONE)', () => { // Test data expectedComplexes = [ - { complex: EDITION_COMPLEXES.OP12, disabled: false }, - { complex: EDITION_COMPLEXES.OP23, disabled: false }, - { complex: EDITION_COMPLEXES.OP25, disabled: true }, - { complex: EDITION_COMPLEXES.M212, disabled: false }, - { complex: EDITION_COMPLEXES.M213, disabled: true }, + { complex: EditionComplexesService.getEditionComplexById('OP12'), disabled: false }, + { complex: EditionComplexesService.getEditionComplexById('OP23'), disabled: false }, + { complex: EditionComplexesService.getEditionComplexById('OP25'), disabled: true }, + { complex: EditionComplexesService.getEditionComplexById('M212'), disabled: false }, + { complex: EditionComplexesService.getEditionComplexById('M213'), disabled: true }, ]; }); @@ -82,139 +86,139 @@ describe('EditionComplexCardComponent (DONE)', () => { describe('VIEW', () => { it('... should have as many inner div.col as editionComplexes in outer div.row', () => { - const rowDe = getAndExpectDebugElementByCss(compDe, 'div.row', 1, 1); - getAndExpectDebugElementByCss(rowDe[0], 'div.col', expectedComplexes.length, expectedComplexes.length); + const rowDes = getAndExpectDebugElementByCss(compDe, 'div.row', 1, 1); + getAndExpectDebugElementByCss(rowDes[0], 'div.col', expectedComplexes.length, expectedComplexes.length); }); it('... should have as many inner div.card.awg-edition-card as editionComplexes', () => { - const rowDe = getAndExpectDebugElementByCss(compDe, 'div.row', 1, 1); - const colDe = getAndExpectDebugElementByCss( - rowDe[0], + const rowDes = getAndExpectDebugElementByCss(compDe, 'div.row', 1, 1); + const colDes = getAndExpectDebugElementByCss( + rowDes[0], 'div.col', expectedComplexes.length, expectedComplexes.length ); - colDe.forEach(col => { - getAndExpectDebugElementByCss(col, 'div.card.awg-edition-card', 1, 1); + colDes.forEach(colDe => { + getAndExpectDebugElementByCss(colDe, 'div.card.awg-edition-card', 1, 1); }); }); it('... should have as many inner div.card-body as editionComplexes', () => { - const rowDe = getAndExpectDebugElementByCss(compDe, 'div.row', 1, 1); - const colDe = getAndExpectDebugElementByCss( - rowDe[0], + const rowDes = getAndExpectDebugElementByCss(compDe, 'div.row', 1, 1); + const colDes = getAndExpectDebugElementByCss( + rowDes[0], 'div.col', expectedComplexes.length, expectedComplexes.length ); - colDe.forEach(col => { - const cardDe = getAndExpectDebugElementByCss(col, 'div.card.awg-edition-card', 1, 1); - getAndExpectDebugElementByCss(cardDe[0], 'div.card-body', 1, 1); + colDes.forEach(colDe => { + const cardDes = getAndExpectDebugElementByCss(colDe, 'div.card.awg-edition-card', 1, 1); + getAndExpectDebugElementByCss(cardDes[0], 'div.card-body', 1, 1); }); }); it('... should have as many inner h5.card-title as editionComplexes', () => { - const rowDe = getAndExpectDebugElementByCss(compDe, 'div.row', 1, 1); - const colDe = getAndExpectDebugElementByCss( - rowDe[0], + const rowDes = getAndExpectDebugElementByCss(compDe, 'div.row', 1, 1); + const colDes = getAndExpectDebugElementByCss( + rowDes[0], 'div.col', expectedComplexes.length, expectedComplexes.length ); - colDe.forEach(col => { - const cardDe = getAndExpectDebugElementByCss(col, 'div.card.awg-edition-card', 1, 1); - const cardBodyDe = getAndExpectDebugElementByCss(cardDe[0], 'div.card-body', 1, 1); - getAndExpectDebugElementByCss(cardBodyDe[0], 'h5.card-title', 1, 1); + colDes.forEach(colDe => { + const cardDes = getAndExpectDebugElementByCss(colDe, 'div.card.awg-edition-card', 1, 1); + const cardBodyDes = getAndExpectDebugElementByCss(cardDes[0], 'div.card-body', 1, 1); + getAndExpectDebugElementByCss(cardBodyDes[0], 'h5.card-title', 1, 1); }); }); it('... should text-mute card titles of disabled editionComplexes', () => { - const rowDe = getAndExpectDebugElementByCss(compDe, 'div.row', 1, 1); - const colDe = getAndExpectDebugElementByCss( - rowDe[0], + const rowDes = getAndExpectDebugElementByCss(compDe, 'div.row', 1, 1); + const colDes = getAndExpectDebugElementByCss( + rowDes[0], 'div.col', expectedComplexes.length, expectedComplexes.length ); - colDe.forEach((col, index) => { - const cardTitleDe = getAndExpectDebugElementByCss(col, 'h5.card-title', 1, 1); - const cardTitleEl = cardTitleDe[0].nativeElement; + colDes.forEach((colDe, index) => { + const cardTitleDes = getAndExpectDebugElementByCss(colDe, 'h5.card-title', 1, 1); + const cardTitleEl = cardTitleDes[0].nativeElement; expectToBe(cardTitleEl.classList.contains('text-muted'), expectedComplexes[index].disabled); }); }); it('... should display complex as card title in span.awg-edition-info-header-title', () => { - const rowDe = getAndExpectDebugElementByCss(compDe, 'div.row', 1, 1); - const colDe = getAndExpectDebugElementByCss( - rowDe[0], + const rowDes = getAndExpectDebugElementByCss(compDe, 'div.row', 1, 1); + const colDes = getAndExpectDebugElementByCss( + rowDes[0], 'div.col', expectedComplexes.length, expectedComplexes.length ); - colDe.forEach((col, index) => { - const cardTitleDe = getAndExpectDebugElementByCss(col, 'h5.card-title', 1, 1); - const headerDe = getAndExpectDebugElementByCss( - cardTitleDe[0], + colDes.forEach((colDe, index) => { + const cardTitleDes = getAndExpectDebugElementByCss(colDe, 'h5.card-title', 1, 1); + const headerDes = getAndExpectDebugElementByCss( + cardTitleDes[0], 'span.awg-edition-info-header-title', 1, 1 ); - const headerEl = headerDe[0].nativeElement; + const headerEl = headerDes[0].nativeElement; expectToBe(headerEl.innerHTML, expectedComplexes[index].complex.complexId.full); }); }); it('... should have as many inner div.card-footer as editionComplexes', () => { - const rowDe = getAndExpectDebugElementByCss(compDe, 'div.row', 1, 1); - const colDe = getAndExpectDebugElementByCss( - rowDe[0], + const rowDes = getAndExpectDebugElementByCss(compDe, 'div.row', 1, 1); + const colDes = getAndExpectDebugElementByCss( + rowDes[0], 'div.col', expectedComplexes.length, expectedComplexes.length ); - colDe.forEach(col => { - const cardDe = getAndExpectDebugElementByCss(col, 'div.card.awg-edition-card', 1, 1); - getAndExpectDebugElementByCss(cardDe[0], 'div.card-footer', 1, 1); + colDes.forEach(colDe => { + const cardDes = getAndExpectDebugElementByCss(colDe, 'div.card.awg-edition-card', 1, 1); + getAndExpectDebugElementByCss(cardDes[0], 'div.card-footer', 1, 1); }); }); it('... should have edition responsibility statement in div.card-footer if complex is not disabled', () => { - const cardFooterDe = getAndExpectDebugElementByCss( + const cardFooterDes = getAndExpectDebugElementByCss( compDe, 'div.card-footer', expectedComplexes.length, expectedComplexes.length ); - cardFooterDe.forEach((cardFooter, index) => { + cardFooterDes.forEach((cardFooterDe, index) => { if (!expectedComplexes[index].disabled) { - getAndExpectDebugElementByCss(cardFooter, 'p.awg-edition-responsibility', 1, 1); + getAndExpectDebugElementByCss(cardFooterDe, 'p.awg-edition-responsibility', 1, 1); } else { - getAndExpectDebugElementByCss(cardFooter, 'p.awg-edition-responsibility', 0, 0); + getAndExpectDebugElementByCss(cardFooterDe, 'p.awg-edition-responsibility', 0, 0); } }); }); it('... should display as many editors in span.editor as there are editors', () => { - const cardFooterDe = getAndExpectDebugElementByCss( + const cardFooterDes = getAndExpectDebugElementByCss( compDe, 'div.card-footer', expectedComplexes.length, expectedComplexes.length ); - cardFooterDe.forEach((cardFooter, index) => { + cardFooterDes.forEach((cardFooterDe, index) => { if (!expectedComplexes[index].disabled) { - const pDe = getAndExpectDebugElementByCss(cardFooter, 'p.awg-edition-responsibility', 1, 1); - const editors = expectedComplexes[index].complex.responsibilityStatement.editors; - const editorDe = getAndExpectDebugElementByCss( - pDe[0], + const pDes = getAndExpectDebugElementByCss(cardFooterDe, 'p.awg-edition-responsibility', 1, 1); + const editors = expectedComplexes[index].complex.respStatement.editors; + const editorDes = getAndExpectDebugElementByCss( + pDes[0], 'span.editor', editors.length, editors.length ); - editorDe.forEach((editor, editorIndex) => { + editorDes.forEach((editor, editorIndex) => { const editorEl = editor.nativeElement; expectToBe(editorEl.textContent.trim(), editors[editorIndex].name); @@ -224,24 +228,24 @@ describe('EditionComplexCardComponent (DONE)', () => { }); it('... should link to homepage of editors in span.editor', () => { - const cardFooterDe = getAndExpectDebugElementByCss( + const cardFooterDes = getAndExpectDebugElementByCss( compDe, 'div.card-footer', expectedComplexes.length, expectedComplexes.length ); - cardFooterDe.forEach((cardFooter, index) => { + cardFooterDes.forEach((cardFooterDe, index) => { if (!expectedComplexes[index].disabled) { - const pDe = getAndExpectDebugElementByCss(cardFooter, 'p.awg-edition-responsibility', 1, 1); - const editors = expectedComplexes[index].complex.responsibilityStatement.editors; - const editorDe = getAndExpectDebugElementByCss( - pDe[0], + const pDes = getAndExpectDebugElementByCss(cardFooterDe, 'p.awg-edition-responsibility', 1, 1); + const editors = expectedComplexes[index].complex.respStatement.editors; + const editorDes = getAndExpectDebugElementByCss( + pDes[0], 'span.editor', editors.length, editors.length ); - editorDe.forEach((editor, editorIndex) => { + editorDes.forEach((editor, editorIndex) => { const anchorDe = getAndExpectDebugElementByCss(editor, 'a', 1, 1); const anchorEl = anchorDe[0].nativeElement; @@ -252,70 +256,70 @@ describe('EditionComplexCardComponent (DONE)', () => { }); it('... should display version date in span.version if complex is not disabled', () => { - const cardFooterDe = getAndExpectDebugElementByCss( + const cardFooterDes = getAndExpectDebugElementByCss( compDe, 'div.card-footer', expectedComplexes.length, expectedComplexes.length ); - cardFooterDe.forEach((cardFooter, index) => { + cardFooterDes.forEach((cardFooterDe, index) => { if (!expectedComplexes[index].disabled) { - const pDe = getAndExpectDebugElementByCss(cardFooter, 'p.awg-edition-responsibility', 1, 1); - const versionDe = getAndExpectDebugElementByCss(pDe[0], 'span.version', 1, 1); - const versionEl = versionDe[0].nativeElement; + const pDes = getAndExpectDebugElementByCss(cardFooterDe, 'p.awg-edition-responsibility', 1, 1); + const versionDes = getAndExpectDebugElementByCss(pDes[0], 'span.version', 1, 1); + const versionEl = versionDes[0].nativeElement; expectToBe( versionEl.textContent.trim(), - expectedComplexes[index].complex.responsibilityStatement.lastModified + expectedComplexes[index].complex.respStatement.lastModified ); } else { - getAndExpectDebugElementByCss(cardFooter, 'p.awg-edition-responsibility', 0, 0); - getAndExpectDebugElementByCss(cardFooter, 'span.version', 0, 0); + getAndExpectDebugElementByCss(cardFooterDe, 'p.awg-edition-responsibility', 0, 0); + getAndExpectDebugElementByCss(cardFooterDe, 'span.version', 0, 0); } }); }); it('... should have text-end paragraph in div.card-footer for each complex', () => { - const cardFooterDe = getAndExpectDebugElementByCss( + const cardFooterDes = getAndExpectDebugElementByCss( compDe, 'div.card-footer', expectedComplexes.length, expectedComplexes.length ); - cardFooterDe.forEach(cardFooter => { - getAndExpectDebugElementByCss(cardFooter, 'p.text-end', 1, 1); + cardFooterDes.forEach(cardFooterDe => { + getAndExpectDebugElementByCss(cardFooterDe, 'p.text-end', 1, 1); }); }); it('... should have a link to complex in text-end paragraph for each complex', () => { - const pDe = getAndExpectDebugElementByCss( + const pDes = getAndExpectDebugElementByCss( compDe, 'p.text-end', expectedComplexes.length, expectedComplexes.length ); - pDe.forEach(p => { - const linkDe = getAndExpectDebugElementByCss(p, 'a', 1, 1); - const linkEl = linkDe[0].nativeElement; + pDes.forEach(pDe => { + const aDes = getAndExpectDebugElementByCss(pDe, 'a', 1, 1); + const aEl = aDes[0].nativeElement; const expectedLinkText = 'Mehr ...'; - expectToBe(linkEl.textContent.trim(), expectedLinkText); + expectToBe(aEl.textContent.trim(), expectedLinkText); }); }); it('... should disable links only for disabled editionComplexes', () => { - const pDe = getAndExpectDebugElementByCss( + const pDes = getAndExpectDebugElementByCss( compDe, 'p.text-end', expectedComplexes.length, expectedComplexes.length ); - pDe.forEach((p, index) => { - const linkDe = getAndExpectDebugElementByCss(p, 'a', 1, 1); - const linkEl = linkDe[0].nativeElement; + pDes.forEach((pDe, index) => { + const aDes = getAndExpectDebugElementByCss(pDe, 'a', 1, 1); + const aEl = aDes[0].nativeElement; - expectToBe(linkEl.classList.contains('disabled'), expectedComplexes[index].disabled); + expectToBe(aEl.classList.contains('disabled'), expectedComplexes[index].disabled); }); }); }); @@ -347,7 +351,7 @@ describe('EditionComplexCardComponent (DONE)', () => { const linkDe = linkDes[index]; const expectedRouterLink = [expectedComplexes[index].complex.baseRoute]; - expect(routerLink.navigatedTo).toBeNull(); + expectToBe(routerLink.navigatedTo, null); click(linkDe); fixture.detectChanges(); diff --git a/src/app/views/edition-view/edition-complex-card/edition-complex-card.component.ts b/src/app/views/edition-view/edition-complex-card/edition-complex-card.component.ts index 9d15f4b92..7b56a002d 100644 --- a/src/app/views/edition-view/edition-complex-card/edition-complex-card.component.ts +++ b/src/app/views/edition-view/edition-complex-card/edition-complex-card.component.ts @@ -1,6 +1,6 @@ import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; -import { EditionOutlineComplex } from '@awg-views/edition-view/models'; +import { EditionOutlineComplexItem } from '@awg-views/edition-view/models'; /** * The EditionComplexCard component. @@ -16,10 +16,10 @@ import { EditionOutlineComplex } from '@awg-views/edition-view/models'; }) export class EditionComplexCardComponent { /** - * Input variable: complex. + * Input variable: complexes. * - * It keeps the complex of the card view. + * It keeps the complexes of the card view. */ @Input() - complexes: EditionOutlineComplex[]; + complexes: EditionOutlineComplexItem[]; } diff --git a/src/app/views/edition-view/edition-jumbotron/edition-jumbotron.component.html b/src/app/views/edition-view/edition-jumbotron/edition-jumbotron.component.html index b7313b06d..e5ec34a2f 100644 --- a/src/app/views/edition-view/edition-jumbotron/edition-jumbotron.component.html +++ b/src/app/views/edition-view/edition-jumbotron/edition-jumbotron.component.html @@ -1,5 +1,3 @@ -
-

{{ jumbotronTitle }}

+
+

diff --git a/src/app/views/edition-view/edition-jumbotron/edition-jumbotron.component.spec.ts b/src/app/views/edition-view/edition-jumbotron/edition-jumbotron.component.spec.ts index 01edffb64..8a4e462f8 100644 --- a/src/app/views/edition-view/edition-jumbotron/edition-jumbotron.component.spec.ts +++ b/src/app/views/edition-view/edition-jumbotron/edition-jumbotron.component.spec.ts @@ -1,7 +1,7 @@ import { DebugElement } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { getAndExpectDebugElementByCss } from '@testing/expect-helper'; +import { expectToBe, getAndExpectDebugElementByCss } from '@testing/expect-helper'; import { EditionJumbotronComponent } from './edition-jumbotron.component'; @@ -39,8 +39,8 @@ describe('EditionJumbotronComponent', () => { }); describe('VIEW', () => { - it('... should have one div.awg-jumbotron-image', () => { - getAndExpectDebugElementByCss(compDe, 'div.awg-jumbotron-image', 1, 1); + it('... should have one div.awg-jumbotron', () => { + getAndExpectDebugElementByCss(compDe, 'div.awg-jumbotron', 1, 1); }); }); }); @@ -56,31 +56,26 @@ describe('EditionJumbotronComponent', () => { }); it('... should have jumbotronId', () => { - expect(component.jumbotronId).toBeDefined(); - expect(component.jumbotronId).withContext(`should be ${expectedId}`).toBe(expectedId); + expectToBe(component.jumbotronId, expectedId); }); it('... should have jumbotronTitle', () => { - expect(component.jumbotronTitle).toBeDefined(); - expect(component.jumbotronTitle).withContext(`should be ${expectedTitle}`).toBe(expectedTitle); + expectToBe(component.jumbotronTitle, expectedTitle); }); describe('VIEW', () => { - it('... should have an h1 in jumbotron', () => { - const jumbotronDes = getAndExpectDebugElementByCss(compDe, 'div.awg-jumbotron-image', 1, 1); + it('... should have a heading (h3) in jumbotron', () => { + const jumbotronDes = getAndExpectDebugElementByCss(compDe, 'div.awg-jumbotron', 1, 1); - getAndExpectDebugElementByCss(jumbotronDes[0], 'h1', 1, 1); + getAndExpectDebugElementByCss(jumbotronDes[0], 'h3', 1, 1); }); - it('... should pass down `jumbotronId` and `jumbotronTitle`to jumbotron h1', () => { - const headingDes = getAndExpectDebugElementByCss(compDe, 'div.awg-jumbotron-image > h1', 1, 1); + it('... should pass down `jumbotronId` and `jumbotronTitle`to jumbotron heading', () => { + const headingDes = getAndExpectDebugElementByCss(compDe, 'div.awg-jumbotron > h3', 1, 1); const headingEl = headingDes[0].nativeElement; - expect(headingEl.id).toBeTruthy(); - expect(headingEl.id).withContext(`should be ${expectedId}`).toBe(expectedId); - - expect(headingEl.textContent).toBeTruthy(); - expect(headingEl.textContent.trim()).withContext(`should be ${expectedTitle}`).toBe(expectedTitle); + expectToBe(headingEl.id, expectedId); + expectToBe(headingEl.textContent.trim(), expectedTitle); }); }); }); diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-complex.component.spec.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-complex.component.spec.ts index 457a97e72..57f742f37 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-complex.component.spec.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-complex.component.spec.ts @@ -5,17 +5,12 @@ import { ActivatedRoute, RouterModule } from '@angular/router'; import { Observable, ReplaySubject } from 'rxjs'; import Spy = jasmine.Spy; -import { expectSpyCall } from '@testing/expect-helper'; +import { expectSpyCall, expectToEqual } from '@testing/expect-helper'; import { ActivatedRouteStub } from '@testing/router-stubs'; -import { EDITION_COMPLEXES } from '@awg-views/edition-view/data'; -import { - EDITION_CATALOGUE_TYPE_CONSTANTS, - EDITION_ROUTE_CONSTANTS, - EDITION_TYPE_CONSTANTS, -} from '@awg-views/edition-view/edition-route-constants'; -import { EditionComplex } from '@awg-views/edition-view/models'; -import { EditionService } from '@awg-views/edition-view/services'; +import { EDITION_ROUTE_CONSTANTS } from '@awg-views/edition-view/edition-route-constants'; +import { EditionComplex, EditionComplexesList } from '@awg-views/edition-view/models'; +import { EditionComplexesService, EditionService } from '@awg-views/edition-view/services'; import { EditionComplexComponent } from './edition-complex.component'; @@ -29,25 +24,29 @@ describe('EditionComplexComponent (DONE)', () => { let mockEditionComplexSubject: ReplaySubject; - let getEditionComplexFromRouteSpy: Spy; - let editionServiceGetEditionComplexSpy: Spy; - let editionServiceUpdateEditionComplexSpy: Spy; - let editionServiceClearEditionComplexSpy: Spy; + let updateEditionComplexFromRouteSpy: Spy; + let editionServiceGetSelectedEditionComplexSpy: Spy; + let editionServiceUpdateSelectedEditionComplexSpy: Spy; + let editionServiceClearSelectedEditionComplexSpy: Spy; - let expectedEditionComplexes: typeof EDITION_COMPLEXES; + let expectedEditionComplexes: EditionComplexesList; let expectedSelectedEditionComplex: EditionComplex; let expectedSelectedEditionComplexId: string; const expectedEditionRouteConstants: typeof EDITION_ROUTE_CONSTANTS = EDITION_ROUTE_CONSTANTS; + beforeAll(() => { + EditionComplexesService.initializeEditionComplexesList(); + }); + beforeEach(async () => { mockEditionComplexSubject = new ReplaySubject(1); // Mock edition service mockEditionService = { - getEditionComplex: (): Observable => mockEditionComplexSubject.asObservable(), - updateEditionComplex: (editionComplex: EditionComplex): void => + getSelectedEditionComplex: (): Observable => mockEditionComplexSubject.asObservable(), + updateSelectedEditionComplex: (editionComplex: EditionComplex): void => mockEditionComplexSubject.next(editionComplex), - clearEditionComplex: (): void => mockEditionComplexSubject.next(null), + clearSelectedEditionComplex: (): void => mockEditionComplexSubject.next(null), }; // Mocked activated route @@ -69,17 +68,26 @@ describe('EditionComplexComponent (DONE)', () => { compDe = fixture.debugElement; // TestData - expectedEditionComplexes = EDITION_COMPLEXES; - expectedSelectedEditionComplex = expectedEditionComplexes.OP12; + + expectedSelectedEditionComplex = EditionComplexesService.getEditionComplexById('OP12'); expectedSelectedEditionComplexId = 'OP12'; // Spies on component functions // `.and.callThrough` will track the spy down the nested describes, see // https://jasmine.github.io/2.0/introduction.html#section-Spies:_%3Ccode%3Eand.callThrough%3C/code%3E - getEditionComplexFromRouteSpy = spyOn(component, 'getEditionComplexFromRoute').and.callThrough(); - editionServiceGetEditionComplexSpy = spyOn(mockEditionService, 'getEditionComplex').and.callThrough(); - editionServiceUpdateEditionComplexSpy = spyOn(mockEditionService, 'updateEditionComplex').and.callThrough(); - editionServiceClearEditionComplexSpy = spyOn(mockEditionService, 'clearEditionComplex').and.callThrough(); + updateEditionComplexFromRouteSpy = spyOn(component, 'updateEditionComplexFromRoute').and.callThrough(); + editionServiceGetSelectedEditionComplexSpy = spyOn( + mockEditionService, + 'getSelectedEditionComplex' + ).and.callThrough(); + editionServiceUpdateSelectedEditionComplexSpy = spyOn( + mockEditionService, + 'updateSelectedEditionComplex' + ).and.callThrough(); + editionServiceClearSelectedEditionComplexSpy = spyOn( + mockEditionService, + 'clearSelectedEditionComplex' + ).and.callThrough(); }); it('... should create', () => { @@ -92,19 +100,16 @@ describe('EditionComplexComponent (DONE)', () => { }); it('... should have `editionRouteConstants`', () => { - expect(component.editionRouteConstants).toBeDefined(); - expect(component.editionRouteConstants) - .withContext(`should be ${expectedEditionRouteConstants}`) - .toBe(expectedEditionRouteConstants); + expectToEqual(component.editionRouteConstants, expectedEditionRouteConstants); }); - describe('#getEditionComplexFromRoute()', () => { - it('... should have a method `getEditionComplexFromRoute`', () => { - expect(component.getEditionComplexFromRoute).toBeDefined(); + describe('#updateEditionComplexFromRoute()', () => { + it('... should have a method `updateEditionComplexFromRoute`', () => { + expect(component.updateEditionComplexFromRoute).toBeDefined(); }); it('... should not have been called', () => { - expectSpyCall(getEditionComplexFromRouteSpy, 0); + expectSpyCall(updateEditionComplexFromRouteSpy, 0); }); }); }); @@ -119,25 +124,40 @@ describe('EditionComplexComponent (DONE)', () => { fixture.detectChanges(); }); - describe('#getEditionComplexFromRoute()', () => { + describe('#updateEditionComplexFromRoute()', () => { it('... should have been called', () => { - expectSpyCall(getEditionComplexFromRouteSpy, 1); + expectSpyCall(updateEditionComplexFromRouteSpy, 1); }); - it('... should get id from router', () => { - expectSpyCall(getEditionComplexFromRouteSpy, 1); + it('... should trigger `EditionComplexesService.getEditionComplexById`', () => { + const getEditionComplexByIdSpy = spyOn( + EditionComplexesService, + 'getEditionComplexById' + ).and.callThrough(); + + component.updateEditionComplexFromRoute(); + fixture.detectChanges(); + + expectSpyCall(getEditionComplexByIdSpy, 1); + }); + it('... should get id from router', () => { + expectSpyCall(updateEditionComplexFromRouteSpy, 1); expectSpyCall( - editionServiceUpdateEditionComplexSpy, + editionServiceUpdateSelectedEditionComplexSpy, 1, - expectedEditionComplexes[expectedSelectedEditionComplexId] + EditionComplexesService.getEditionComplexById(expectedSelectedEditionComplexId) ); }); - it('... should get correct id from router', () => { + it('... should get correct complex from router id', () => { // Call with op. 12 (default) - expectSpyCall(getEditionComplexFromRouteSpy, 1); - expectSpyCall(editionServiceUpdateEditionComplexSpy, 1, expectedEditionComplexes.OP12); + expectSpyCall(updateEditionComplexFromRouteSpy, 1); + expectSpyCall( + editionServiceUpdateSelectedEditionComplexSpy, + 1, + EditionComplexesService.getEditionComplexById('OP12') + ); // ---------------- // Change to op. 25 @@ -146,18 +166,33 @@ describe('EditionComplexComponent (DONE)', () => { // Trigger initial data binding fixture.detectChanges(); - expectSpyCall(getEditionComplexFromRouteSpy, 1); - expectSpyCall(editionServiceUpdateEditionComplexSpy, 2, expectedEditionComplexes.OP25); + expectSpyCall(updateEditionComplexFromRouteSpy, 1); + expectSpyCall( + editionServiceUpdateSelectedEditionComplexSpy, + 2, + EditionComplexesService.getEditionComplexById('OP25') + ); + }); + + it('... should only get complex from valid router id', () => { + expectSpyCall( + editionServiceUpdateSelectedEditionComplexSpy, + 1, + EditionComplexesService.getEditionComplexById('OP12') + ); - // ------------------ // Change to non-existing id mockActivatedRoute.testParamMap = { complexId: 'fail' }; // Trigger initial data binding fixture.detectChanges(); - expectSpyCall(getEditionComplexFromRouteSpy, 1); - expectSpyCall(editionServiceUpdateEditionComplexSpy, 3, expectedEditionComplexes['fail']); + expectSpyCall(updateEditionComplexFromRouteSpy, 1); + expectSpyCall( + editionServiceUpdateSelectedEditionComplexSpy, + 1, + EditionComplexesService.getEditionComplexById('OP12') + ); // ------------------ // Change to empty id @@ -166,8 +201,12 @@ describe('EditionComplexComponent (DONE)', () => { // Trigger initial data binding fixture.detectChanges(); - expectSpyCall(getEditionComplexFromRouteSpy, 1); - expectSpyCall(editionServiceUpdateEditionComplexSpy, 4, expectedEditionComplexes['']); + expectSpyCall(updateEditionComplexFromRouteSpy, 1); + expectSpyCall( + editionServiceUpdateSelectedEditionComplexSpy, + 1, + EditionComplexesService.getEditionComplexById('OP12') + ); // ---------------------- // Change to another key @@ -176,27 +215,31 @@ describe('EditionComplexComponent (DONE)', () => { // Trigger initial data binding fixture.detectChanges(); - expectSpyCall(getEditionComplexFromRouteSpy, 1); - expectSpyCall(editionServiceUpdateEditionComplexSpy, 5, expectedEditionComplexes['']); + expectSpyCall(updateEditionComplexFromRouteSpy, 1); + expectSpyCall( + editionServiceUpdateSelectedEditionComplexSpy, + 1, + EditionComplexesService.getEditionComplexById('OP12') + ); }); it('... should have updated selectedEditionComplex$ (via EditionService)', () => { - expectSpyCall(getEditionComplexFromRouteSpy, 1); + expectSpyCall(updateEditionComplexFromRouteSpy, 1); expectSpyCall( - editionServiceUpdateEditionComplexSpy, + editionServiceUpdateSelectedEditionComplexSpy, 1, - expectedEditionComplexes[expectedSelectedEditionComplexId] + EditionComplexesService.getEditionComplexById(expectedSelectedEditionComplexId) ); }); it('... should get edition complex from EditionService and set selectedEditionComplex$', () => { - expectSpyCall(getEditionComplexFromRouteSpy, 1); + expectSpyCall(updateEditionComplexFromRouteSpy, 1); expectSpyCall( - editionServiceUpdateEditionComplexSpy, + editionServiceUpdateSelectedEditionComplexSpy, 1, - expectedEditionComplexes[expectedSelectedEditionComplexId] + EditionComplexesService.getEditionComplexById(expectedSelectedEditionComplexId) ); - expectSpyCall(editionServiceGetEditionComplexSpy, 1); + expectSpyCall(editionServiceGetSelectedEditionComplexSpy, 1); expect(component.selectedEditionComplex$).toBeDefined(); }); @@ -204,13 +247,13 @@ describe('EditionComplexComponent (DONE)', () => { it('... should get correct edition complex from EditionService when complex id changes', () => { // ---------------- // Check for op. 12 - expectSpyCall(getEditionComplexFromRouteSpy, 1); + expectSpyCall(updateEditionComplexFromRouteSpy, 1); expectSpyCall( - editionServiceUpdateEditionComplexSpy, + editionServiceUpdateSelectedEditionComplexSpy, 1, - expectedEditionComplexes[expectedSelectedEditionComplexId] + EditionComplexesService.getEditionComplexById(expectedSelectedEditionComplexId) ); - expectSpyCall(editionServiceGetEditionComplexSpy, 1); + expectSpyCall(editionServiceGetSelectedEditionComplexSpy, 1); // ---------------- // Change to op. 25 @@ -220,13 +263,13 @@ describe('EditionComplexComponent (DONE)', () => { // Apply changes fixture.detectChanges(); - expectSpyCall(getEditionComplexFromRouteSpy, 1); + expectSpyCall(updateEditionComplexFromRouteSpy, 1); expectSpyCall( - editionServiceUpdateEditionComplexSpy, + editionServiceUpdateSelectedEditionComplexSpy, 2, - expectedEditionComplexes[expectedSelectedEditionComplexId] + EditionComplexesService.getEditionComplexById(expectedSelectedEditionComplexId) ); - expectSpyCall(editionServiceGetEditionComplexSpy, 2); + expectSpyCall(editionServiceGetSelectedEditionComplexSpy, 2); expect(component.selectedEditionComplex$).toBeDefined(); }); @@ -235,29 +278,33 @@ describe('EditionComplexComponent (DONE)', () => { const opusComplex = new EditionComplex( { title: 'Test Opus Complex', - catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.OPUS, + catalogueType: 'OPUS', catalogueNumber: '100', }, { editors: [], lastModified: '---', }, - EDITION_ROUTE_CONSTANTS.SERIES_1, - EDITION_ROUTE_CONSTANTS.SECTION_5, - EDITION_TYPE_CONSTANTS.SKETCH_EDITION + { series: '1', section: '5' } ); expectedSelectedEditionComplexId = 'op100'; - expectedEditionComplexes[expectedSelectedEditionComplexId.toUpperCase()] = opusComplex; + + spyOn(EditionComplexesService, 'getEditionComplexById').and.callFake((id: string) => { + if (id.toUpperCase() === expectedSelectedEditionComplexId.toUpperCase()) { + return opusComplex; + } + return null; + }); mockActivatedRoute.testParamMap = { complexId: expectedSelectedEditionComplexId }; - editionServiceUpdateEditionComplexSpy.and.callThrough(); + editionServiceUpdateSelectedEditionComplexSpy.and.callThrough(); // Apply changes fixture.detectChanges(); - expectSpyCall(getEditionComplexFromRouteSpy, 1); - expectSpyCall(editionServiceUpdateEditionComplexSpy, 2, opusComplex); - expectSpyCall(editionServiceGetEditionComplexSpy, 2); + expectSpyCall(updateEditionComplexFromRouteSpy, 1); + expectSpyCall(editionServiceUpdateSelectedEditionComplexSpy, 2, opusComplex); + expectSpyCall(editionServiceGetSelectedEditionComplexSpy, 2); expect(component.selectedEditionComplex$).toBeDefined(); }); @@ -266,29 +313,34 @@ describe('EditionComplexComponent (DONE)', () => { const mnrComplex = new EditionComplex( { title: 'Test M Complex', - catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.MNR, + catalogueType: 'MNR', catalogueNumber: '100', }, { editors: [], lastModified: '---', }, - EDITION_ROUTE_CONSTANTS.SERIES_1, - EDITION_ROUTE_CONSTANTS.SECTION_5, - EDITION_TYPE_CONSTANTS.SKETCH_EDITION + { series: '1', section: '5' } ); expectedSelectedEditionComplexId = 'm100'; - expectedEditionComplexes[expectedSelectedEditionComplexId.toUpperCase()] = mnrComplex; + + // Spy on the static method and provide a custom implementation + spyOn(EditionComplexesService, 'getEditionComplexById').and.callFake((id: string) => { + if (id.toUpperCase() === expectedSelectedEditionComplexId.toUpperCase()) { + return mnrComplex; + } + return null; + }); mockActivatedRoute.testParamMap = { complexId: expectedSelectedEditionComplexId }; - editionServiceUpdateEditionComplexSpy.and.callThrough(); + editionServiceUpdateSelectedEditionComplexSpy.and.callThrough(); // Apply changes fixture.detectChanges(); - expectSpyCall(getEditionComplexFromRouteSpy, 1); - expectSpyCall(editionServiceUpdateEditionComplexSpy, 2, mnrComplex); - expectSpyCall(editionServiceGetEditionComplexSpy, 2); + expectSpyCall(updateEditionComplexFromRouteSpy, 1); + expectSpyCall(editionServiceUpdateSelectedEditionComplexSpy, 2, mnrComplex); + expectSpyCall(editionServiceGetSelectedEditionComplexSpy, 2); expect(component.selectedEditionComplex$).toBeDefined(); }); @@ -297,29 +349,34 @@ describe('EditionComplexComponent (DONE)', () => { const mnrPlusComplex = new EditionComplex( { title: 'Test M* Complex', - catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.MNR_PLUS, + catalogueType: 'MNR_PLUS', catalogueNumber: '100', }, { editors: [], lastModified: '---', }, - EDITION_ROUTE_CONSTANTS.SERIES_1, - EDITION_ROUTE_CONSTANTS.SECTION_5, - EDITION_TYPE_CONSTANTS.SKETCH_EDITION + { series: '1', section: '5' } ); expectedSelectedEditionComplexId = 'mPlus100'; - expectedEditionComplexes[expectedSelectedEditionComplexId.toUpperCase()] = mnrPlusComplex; + + // Spy on the static method and provide a custom implementation + spyOn(EditionComplexesService, 'getEditionComplexById').and.callFake((id: string) => { + if (id.toUpperCase() === expectedSelectedEditionComplexId.toUpperCase()) { + return mnrPlusComplex; + } + return null; + }); mockActivatedRoute.testParamMap = { complexId: expectedSelectedEditionComplexId }; - editionServiceUpdateEditionComplexSpy.and.callThrough(); + editionServiceUpdateSelectedEditionComplexSpy.and.callThrough(); // Apply changes fixture.detectChanges(); - expectSpyCall(getEditionComplexFromRouteSpy, 1); - expectSpyCall(editionServiceUpdateEditionComplexSpy, 2, mnrPlusComplex); - expectSpyCall(editionServiceGetEditionComplexSpy, 2); + expectSpyCall(updateEditionComplexFromRouteSpy, 1); + expectSpyCall(editionServiceUpdateSelectedEditionComplexSpy, 2, mnrPlusComplex); + expectSpyCall(editionServiceGetSelectedEditionComplexSpy, 2); expect(component.selectedEditionComplex$).toBeDefined(); }); @@ -328,26 +385,31 @@ describe('EditionComplexComponent (DONE)', () => { const incompleteComplex = new EditionComplex( { title: 'Test Incomplete Complex', - catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.OPUS, + catalogueType: 'OPUS', catalogueNumber: '100', }, null, - null, - null, null ); expectedSelectedEditionComplexId = 'op100'; - expectedEditionComplexes[expectedSelectedEditionComplexId.toUpperCase()] = incompleteComplex; + + // Spy on the static method and provide a custom implementation + spyOn(EditionComplexesService, 'getEditionComplexById').and.callFake((id: string) => { + if (id.toUpperCase() === expectedSelectedEditionComplexId.toUpperCase()) { + return incompleteComplex; + } + return null; + }); mockActivatedRoute.testParamMap = { complexId: expectedSelectedEditionComplexId }; - editionServiceUpdateEditionComplexSpy.and.callThrough(); + editionServiceUpdateSelectedEditionComplexSpy.and.callThrough(); // Apply changes fixture.detectChanges(); - expectSpyCall(getEditionComplexFromRouteSpy, 1); - expectSpyCall(editionServiceUpdateEditionComplexSpy, 2, incompleteComplex); - expectSpyCall(editionServiceGetEditionComplexSpy, 2); + expectSpyCall(updateEditionComplexFromRouteSpy, 1); + expectSpyCall(editionServiceUpdateSelectedEditionComplexSpy, 2, incompleteComplex); + expectSpyCall(editionServiceGetSelectedEditionComplexSpy, 2); expect(component.selectedEditionComplex$).toBeDefined(); }); @@ -359,22 +421,27 @@ describe('EditionComplexComponent (DONE)', () => { editors: [], lastModified: '---', }, - EDITION_ROUTE_CONSTANTS.SERIES_1, - EDITION_ROUTE_CONSTANTS.SECTION_5, - EDITION_TYPE_CONSTANTS.SKETCH_EDITION + { series: '1', section: '5' } ); expectedSelectedEditionComplexId = 'op100'; - expectedEditionComplexes[expectedSelectedEditionComplexId.toUpperCase()] = incompleteComplex; + + // Spy on the static method and provide a custom implementation + spyOn(EditionComplexesService, 'getEditionComplexById').and.callFake((id: string) => { + if (id.toUpperCase() === expectedSelectedEditionComplexId.toUpperCase()) { + return incompleteComplex; + } + return null; + }); mockActivatedRoute.testParamMap = { complexId: expectedSelectedEditionComplexId }; - editionServiceUpdateEditionComplexSpy.and.callThrough(); + editionServiceUpdateSelectedEditionComplexSpy.and.callThrough(); // Apply changes fixture.detectChanges(); - expectSpyCall(getEditionComplexFromRouteSpy, 1); - expectSpyCall(editionServiceUpdateEditionComplexSpy, 2, incompleteComplex); - expectSpyCall(editionServiceGetEditionComplexSpy, 2); + expectSpyCall(updateEditionComplexFromRouteSpy, 1); + expectSpyCall(editionServiceUpdateSelectedEditionComplexSpy, 2, incompleteComplex); + expectSpyCall(editionServiceGetSelectedEditionComplexSpy, 2); expect(component.selectedEditionComplex$).toBeDefined(); }); @@ -384,7 +451,7 @@ describe('EditionComplexComponent (DONE)', () => { it('... should have cleared selectedEditionComplex$ on destroy (via EditionService)', () => { component.ngOnDestroy(); - expectSpyCall(editionServiceClearEditionComplexSpy, 1); + expectSpyCall(editionServiceClearSelectedEditionComplexSpy, 1); }); }); }); diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-complex.component.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-complex.component.ts index 25ad7126c..c539be565 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-complex.component.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-complex.component.ts @@ -1,13 +1,12 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { delay, Observable } from 'rxjs'; +import { delay, EMPTY, Observable } from 'rxjs'; -import { UtilityService } from '@awg-app/core/services'; -import { EDITION_COMPLEXES } from '@awg-views/edition-view/data'; +import { UtilityService } from '@awg-core/services'; import { EDITION_ROUTE_CONSTANTS } from '@awg-views/edition-view/edition-route-constants'; import { EditionComplex } from '@awg-views/edition-view/models'; -import { EditionService } from '@awg-views/edition-view/services'; +import { EditionComplexesService, EditionService } from '@awg-views/edition-view/services'; /** * The EditionComplex component. @@ -61,21 +60,27 @@ export class EditionComplexComponent implements OnDestroy, OnInit { * when initializing the component. */ ngOnInit(): void { - this.getEditionComplexFromRoute(); + this.updateEditionComplexFromRoute(); } /** - * Public method: getEditionComplexFromRoute. + * Public method: updateEditionComplexFromRoute. * - * It subscribes to the route params to get the id of the current edition complex and load it from the edition service. + * It fetches the route params to get the id of the current edition complex and updates the edition service. * - * @returns {void} Gets the current edition complex from the edition service. + * @returns {void} Updates the current edition complex from the route. */ - getEditionComplexFromRoute(): void { + updateEditionComplexFromRoute(): void { this.route.paramMap.subscribe(params => { const id: string = params.get('complexId') || ''; - this.editionService.updateEditionComplex(EDITION_COMPLEXES[id.toUpperCase()]); - this.selectedEditionComplex$ = this.editionService.getEditionComplex().pipe(delay(0)); + const complex = EditionComplexesService.getEditionComplexById(id.toUpperCase()); + + if (complex) { + this.editionService.updateSelectedEditionComplex(complex); + this.selectedEditionComplex$ = this.editionService.getSelectedEditionComplex().pipe(delay(0)); + } else { + this.selectedEditionComplex$ = EMPTY; + } }); } @@ -89,6 +94,6 @@ export class EditionComplexComponent implements OnDestroy, OnInit { */ ngOnDestroy() { // Remove selected edition complex - this.editionService.clearEditionComplex(); + this.editionService.clearSelectedEditionComplex(); } } diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-detail-nav/edition-detail-nav.component.spec.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-detail-nav/edition-detail-nav.component.spec.ts index 19af11189..a24effeac 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-detail-nav/edition-detail-nav.component.spec.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-detail-nav/edition-detail-nav.component.spec.ts @@ -7,14 +7,13 @@ import { of as observableOf } from 'rxjs'; import Spy = jasmine.Spy; import { cleanStylesFromDOM } from '@testing/clean-up-helper'; -import { expectSpyCall, getAndExpectDebugElementByDirective } from '@testing/expect-helper'; +import { expectSpyCall, expectToEqual, getAndExpectDebugElementByDirective } from '@testing/expect-helper'; import { RouterOutletStubComponent } from '@testing/router-stubs'; import { RouterLinkButton } from '@awg-shared/router-link-button-group/router-link-button.model'; -import { EDITION_COMPLEXES } from '@awg-views/edition-view/data'; import { EDITION_ROUTE_CONSTANTS } from '@awg-views/edition-view/edition-route-constants'; import { EditionComplex } from '@awg-views/edition-view/models'; -import { EditionService } from '@awg-views/edition-view/services'; +import { EditionComplexesService, EditionService } from '@awg-views/edition-view/services'; import { EditionDetailNavComponent } from './edition-detail-nav.component'; @@ -37,14 +36,14 @@ describe('EditionDetailNavComponent (DONE)', () => { let expectedEditionComplex: EditionComplex; let setButtonsSpy: Spy; - let getEditionComplexSpy: Spy; + let getSelectedEditionComplexSpy: Spy; beforeEach(waitForAsync(() => { // Create a fake service object with a `getData()` spy - const mockEditionService = jasmine.createSpyObj('EditionService', ['getEditionComplex']); + const mockEditionService = jasmine.createSpyObj('EditionService', ['getSelectedEditionComplex']); // Make the spy return a synchronous Observable with the test data - getEditionComplexSpy = mockEditionService.getEditionComplex.and.returnValue( - observableOf(EDITION_COMPLEXES.OP12) + getSelectedEditionComplexSpy = mockEditionService.getSelectedEditionComplex.and.returnValue( + observableOf(EditionComplexesService.getEditionComplexById('OP12')) ); TestBed.configureTestingModule({ @@ -59,7 +58,7 @@ describe('EditionDetailNavComponent (DONE)', () => { compDe = fixture.debugElement; // Test data - expectedEditionComplex = EDITION_COMPLEXES.OP12; + expectedEditionComplex = EditionComplexesService.getEditionComplexById('OP12'); expectedEditionRouterLinkButtons = [ new RouterLinkButton( expectedEditionComplex.baseRoute, @@ -116,7 +115,7 @@ describe('EditionDetailNavComponent (DONE)', () => { }); it('... should not have been called', () => { - expectSpyCall(getEditionComplexSpy, 0); + expectSpyCall(getSelectedEditionComplexSpy, 0); }); }); @@ -149,15 +148,12 @@ describe('EditionDetailNavComponent (DONE)', () => { describe('#getEditionComplex()', () => { it('... should have been called', () => { - expectSpyCall(getEditionComplexSpy, 1); + expectSpyCall(getSelectedEditionComplexSpy, 1); }); }); it('... should have `editionComplex`', () => { - expect(component.editionComplex).withContext('should be defined').toBeDefined(); - expect(component.editionComplex) - .withContext(`should equal ${expectedEditionComplex}`) - .toEqual(expectedEditionComplex); + expectToEqual(component.editionComplex, expectedEditionComplex); }); describe('#setButtons()', () => { @@ -166,10 +162,7 @@ describe('EditionDetailNavComponent (DONE)', () => { }); it('... should have `editionRouterLinkButtons`', () => { - expect(component.editionRouterLinkButtons).toBeDefined(); - expect(component.editionRouterLinkButtons) - .withContext(`should equal ${expectedEditionRouterLinkButtons}`) - .toEqual(expectedEditionRouterLinkButtons); + expectToEqual(component.editionRouterLinkButtons, expectedEditionRouterLinkButtons); }); }); @@ -188,10 +181,7 @@ describe('EditionDetailNavComponent (DONE)', () => { RouterLinkButtonGroupStubComponent ) as RouterLinkButtonGroupStubComponent; - expect(buttonCmp.routerLinkButtons).toBeTruthy(); - expect(buttonCmp.routerLinkButtons) - .withContext(`should equal ${expectedEditionRouterLinkButtons}`) - .toEqual(expectedEditionRouterLinkButtons); + expectToEqual(buttonCmp.routerLinkButtons, expectedEditionRouterLinkButtons); }); }); }); diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-detail-nav/edition-detail-nav.component.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-detail-nav/edition-detail-nav.component.ts index effd1337f..4b08a6d98 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-detail-nav/edition-detail-nav.component.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-detail-nav/edition-detail-nav.component.ts @@ -71,7 +71,7 @@ export class EditionDetailNavComponent implements OnInit, OnDestroy { */ getEditionComplex(): void { this.editionService - .getEditionComplex() + .getSelectedEditionComplex() .pipe(takeUntil(this._destroyed$)) .subscribe({ next: (complex: EditionComplex) => { diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/edition-graph.component.html b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/edition-graph.component.html index 2043724b5..6f275d199 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/edition-graph.component.html +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/edition-graph.component.html @@ -32,8 +32,9 @@ erscheinen im Zusammenhang der vollständigen Edition von in - {{ editionRouteConstants.EDITION.short }} {{ editionComplex.series.short }}/{{ - editionComplex.section.short + {{ editionRouteConstants.EDITION.short }} + {{ editionComplex.pubStatement.series.short }}/{{ + editionComplex.pubStatement.section.short }}.]

@@ -96,23 +97,12 @@

Statischer Graph

}
} @else { + @if (errorObject) { -
-
-
{{ errorObject | json }}
-
-
+ + } @else { + + } } - - - - @if (errorObject) { -
-
-
{{ errorObject | json }}
-
-
- } -
diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/edition-graph.component.spec.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/edition-graph.component.spec.ts index 2b69bed28..893a2e870 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/edition-graph.component.spec.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/edition-graph.component.spec.ts @@ -2,7 +2,14 @@ import { DOCUMENT, JsonPipe } from '@angular/common'; import { Component, DebugElement, Input } from '@angular/core'; import { ComponentFixture, fakeAsync, TestBed, waitForAsync } from '@angular/core/testing'; -import { EmptyError, lastValueFrom, Observable, of as observableOf, throwError as observableThrowError } from 'rxjs'; +import { + EMPTY, + EmptyError, + lastValueFrom, + Observable, + of as observableOf, + throwError as observableThrowError, +} from 'rxjs'; import Spy = jasmine.Spy; import { FontAwesomeTestingModule } from '@fortawesome/angular-fontawesome/testing'; @@ -21,14 +28,20 @@ import { import { mockEditionData } from '@testing/mock-data'; import { CompileHtmlComponent } from '@awg-shared/compile-html'; -import { EDITION_COMPLEXES, EDITION_GRAPH_IMAGES_DATA } from '@awg-views/edition-view/data'; +import { EDITION_GRAPH_IMAGES_DATA } from '@awg-views/edition-view/data'; import { EDITION_ROUTE_CONSTANTS } from '@awg-views/edition-view/edition-route-constants'; import { EditionComplex, Graph, GraphList, GraphRDFData, GraphSparqlQuery } from '@awg-views/edition-view/models'; -import { EditionDataService, EditionService } from '@awg-views/edition-view/services'; +import { EditionComplexesService, EditionDataService, EditionService } from '@awg-views/edition-view/services'; import { EditionGraphComponent } from './edition-graph.component'; // Mock components +@Component({ selector: 'awg-error-alert', template: '' }) +class ErrorAlertStubComponent { + @Input() + errorObject: any; +} + @Component({ selector: 'awg-graph-visualizer', template: '' }) class GraphVisualizerStubComponent { @Input() @@ -46,6 +59,9 @@ class ModalStubComponent { } } +@Component({ selector: 'awg-twelve-tone-spinner', template: '' }) +class TwelveToneSpinnerStubComponent {} + describe('EditionGraphComponent (DONE)', () => { let component: EditionGraphComponent; let fixture: ComponentFixture; @@ -61,9 +77,7 @@ describe('EditionGraphComponent (DONE)', () => { let modalOpenSpy: Spy; let compGetEditonGraphDataSpy: Spy; let editionDataServiceGetEditionGraphDataSpy: Spy; - let editionServiceGetEditionComplexSpy: Spy; - - const jsonPipe = new JsonPipe(); + let editionServiceGetSelectedEditionComplexSpy: Spy; let expectedEditionComplex: EditionComplex; let expectedEditionGraphDataEmpty: GraphList; @@ -72,6 +86,12 @@ describe('EditionGraphComponent (DONE)', () => { let expectedIsFullscreen: boolean; + const jsonPipe = new JsonPipe(); + + beforeAll(() => { + EditionComplexesService.initializeEditionComplexesList(); + }); + beforeEach(waitForAsync(() => { // Mocked editionDataService mockEditionDataService = { @@ -80,16 +100,18 @@ describe('EditionGraphComponent (DONE)', () => { }; // Mocked editionService mockEditionService = { - getEditionComplex: (): Observable => observableOf(expectedEditionComplex), + getSelectedEditionComplex: (): Observable => observableOf(expectedEditionComplex), }; TestBed.configureTestingModule({ imports: [FontAwesomeTestingModule], declarations: [ EditionGraphComponent, + ErrorAlertStubComponent, GraphVisualizerStubComponent, ModalStubComponent, CompileHtmlComponent, + TwelveToneSpinnerStubComponent, ], providers: [ { provide: EditionDataService, useValue: mockEditionDataService }, @@ -112,7 +134,7 @@ describe('EditionGraphComponent (DONE)', () => { // TestData (default) expectedIsFullscreen = false; - expectedEditionComplex = EDITION_COMPLEXES.OP12; + expectedEditionComplex = EditionComplexesService.getEditionComplexById('OP12'); expectedEditionGraphDataEmpty = JSON.parse(JSON.stringify(mockEditionData.mockGraphEmptyData)); @@ -125,14 +147,17 @@ describe('EditionGraphComponent (DONE)', () => { // Spies on component methods compGetEditonGraphDataSpy = spyOn(component, 'getEditionGraphData').and.callThrough(); - editionServiceGetEditionComplexSpy = spyOn(editionService, 'getEditionComplex').and.callThrough(); + editionServiceGetSelectedEditionComplexSpy = spyOn( + editionService, + 'getSelectedEditionComplex' + ).and.callThrough(); editionDataServiceGetEditionGraphDataSpy = spyOn(editionDataService, 'getEditionGraphData').and.callFake( (editionComplex: EditionComplex) => { switch (editionComplex) { - case EDITION_COMPLEXES.OP12: { + case EditionComplexesService.getEditionComplexById('OP12'): { return observableOf(expectedEditionGraphDataEmpty); } - case EDITION_COMPLEXES.OP25: { + case EditionComplexesService.getEditionComplexById('OP25'): { return observableOf(expectedEditionGraphDataOp25); } default: { @@ -152,11 +177,11 @@ describe('EditionGraphComponent (DONE)', () => { }); it('... injected editionService should use provided mockValue', () => { - expect(mockEditionService === editionService).toBe(true); + expectToBe(mockEditionService === editionService, true); }); it('... injected editionDataService should use provided mockValue', () => { - expect(mockEditionDataService === editionDataService).toBe(true); + expectToBe(mockEditionDataService === editionDataService, true); }); describe('BEFORE initial data binding', () => { @@ -172,7 +197,7 @@ describe('EditionGraphComponent (DONE)', () => { }); it('... should have `errorObject` = null', () => { - expect(component.errorObject).toBeNull(); + expectToBe(component.errorObject, null); }); it('... should have `isFullscreen`', () => { @@ -192,7 +217,7 @@ describe('EditionGraphComponent (DONE)', () => { }); describe('VIEW', () => { - it('... should have a `div`', () => { + it('... should contain a `div`', () => { getAndExpectDebugElementByCss(compDe, 'div', 1, 1); }); @@ -202,19 +227,29 @@ describe('EditionGraphComponent (DONE)', () => { getAndExpectDebugElementByDirective(divDes[0], ModalStubComponent, 1, 1); }); - it('... should not have a nested div.awg-graph-view', () => { + it('... should contain no div.awg-graph-view yet', () => { getAndExpectDebugElementByCss(compDe, 'div.awg-graph-view', 0, 0); }); - it('... should not have a nested div.errorMessage', () => { - getAndExpectDebugElementByCss(compDe, 'div.errorMessage', 0, 0); + it('... should not contain an error alert component (stubbed)', () => { + const divDes = getAndExpectDebugElementByCss(compDe, 'div', 1, 1); + + getAndExpectDebugElementByDirective(divDes[0], ErrorAlertStubComponent, 0, 0); + }); + + it('... should not contain a loading spinner component (stubbed)', () => { + const divDes = getAndExpectDebugElementByCss(compDe, 'div', 1, 1); + + getAndExpectDebugElementByDirective(divDes[0], TwelveToneSpinnerStubComponent, 0, 0); }); }); }); describe('AFTER initial data binding', () => { beforeEach(() => { - editionServiceGetEditionComplexSpy.and.returnValue(observableOf(EDITION_COMPLEXES.OP12)); + editionServiceGetSelectedEditionComplexSpy.and.returnValue( + observableOf(EditionComplexesService.getEditionComplexById('OP12')) + ); // Trigger initial data binding fixture.detectChanges(); @@ -225,11 +260,11 @@ describe('EditionGraphComponent (DONE)', () => { }); describe('VIEW', () => { - it('... should have one div.awg-graph-view', () => { + it('... should contain one div.awg-graph-view', () => { getAndExpectDebugElementByCss(compDe, 'div.awg-graph-view', 1, 1); }); - it('... should not contain a div.awg-graph-view if graph data is not provided', waitForAsync(() => { + it('... should not contain a div in div.awg-graph-view if graph data is not provided', waitForAsync(() => { const noGraphData = new GraphList(); noGraphData.graph = undefined; @@ -241,7 +276,7 @@ describe('EditionGraphComponent (DONE)', () => { getAndExpectDebugElementByCss(compDe, 'div.awg-graph-view > div', 0, 0); })); - it('... should contain a div.awg-graph-view if graph data is provided', () => { + it('... should contain a div in div.awg-graph-view if graph data is provided', () => { getAndExpectDebugElementByCss(compDe, 'div.awg-graph-view > div', 1, 1); }); @@ -301,7 +336,11 @@ describe('EditionGraphComponent (DONE)', () => { const shortComplexSpan = mockDocument.createElement('span'); shortComplexSpan.innerHTML = expectedEditionComplex.complexId.short; - const graphPlaceholder = `[Die Graph-Visualisierungen zum Editionskomplex ${fullComplexSpan.textContent} erscheinen im Zusammenhang der vollständigen Edition von ${shortComplexSpan.textContent} in ${expectedEditionRouteConstants.EDITION.short} ${expectedEditionComplex.series.short}/${expectedEditionComplex.section.short}.]`; + const awg = EDITION_ROUTE_CONSTANTS.EDITION.short; + const series = expectedEditionComplex.pubStatement.series.short; + const section = expectedEditionComplex.pubStatement.section.short; + + const graphPlaceholder = `[Die Graph-Visualisierungen zum Editionskomplex ${fullComplexSpan.textContent} erscheinen im Zusammenhang der vollständigen Edition von ${shortComplexSpan.textContent} in ${awg} ${series}/${section}.]`; expectToBe(pEl.textContent.trim(), graphPlaceholder); })); @@ -546,20 +585,56 @@ describe('EditionGraphComponent (DONE)', () => { detectChangesOnPush(fixture); })); - it('... should not have graph view, but one div.errorMessage with centered danger alert', waitForAsync(() => { + it('... should not contain graph view, but one ErrorAlertComponent (stubbed)', waitForAsync(() => { getAndExpectDebugElementByCss(compDe, 'div.awg-graph-view', 0, 0); - const errorDes = getAndExpectDebugElementByCss(compDe, 'div.errorMessage', 1, 1); - getAndExpectDebugElementByCss(errorDes[0], 'div.text-center > div.alert-danger', 1, 1); + const divDes = getAndExpectDebugElementByCss(compDe, 'div', 1, 1); + getAndExpectDebugElementByDirective(divDes[0], ErrorAlertStubComponent, 1, 1); })); - it('... should display errorMessage', waitForAsync(() => { - const alertDes = getAndExpectDebugElementByCss(compDe, 'div.alert-danger', 1, 1); - const alertEl = alertDes[0].nativeElement; + it('... should pass down error object to ErrorAlertComponent', waitForAsync(() => { + const errorAlertDes = getAndExpectDebugElementByDirective(compDe, ErrorAlertStubComponent, 1, 1); + const errorAlertCmp = errorAlertDes[0].injector.get( + ErrorAlertStubComponent + ) as ErrorAlertStubComponent; - expectToContain(alertEl.textContent, jsonPipe.transform(expectedError)); + expectToEqual(errorAlertCmp.errorObject, expectedError); })); }); + + describe('on loading', () => { + describe('... should contain only TwelveToneSpinnerComponent (stubbed) if ... ', () => { + it('... editionGraphData$ is EMPTY', () => { + // Mock empty observable + component.editionGraphData$ = EMPTY; + detectChangesOnPush(fixture); + + getAndExpectDebugElementByCss(compDe, 'div.awg-graph-view', 0, 0); + getAndExpectDebugElementByDirective(compDe, ErrorAlertStubComponent, 0, 0); + getAndExpectDebugElementByDirective(compDe, TwelveToneSpinnerStubComponent, 1, 1); + }); + + it('... editionGraphData$ is undefined', () => { + // Mock undefined response + component.editionGraphData$ = observableOf(undefined); + detectChangesOnPush(fixture); + + getAndExpectDebugElementByCss(compDe, 'div.awg-graph-view', 0, 0); + getAndExpectDebugElementByDirective(compDe, ErrorAlertStubComponent, 0, 0); + getAndExpectDebugElementByDirective(compDe, TwelveToneSpinnerStubComponent, 1, 1); + }); + + it('... editionGraphData$ is null', () => { + // Mock null response + component.editionGraphData$ = observableOf(null); + detectChangesOnPush(fixture); + + getAndExpectDebugElementByCss(compDe, 'div.awg-graph-view', 0, 0); + getAndExpectDebugElementByDirective(compDe, ErrorAlertStubComponent, 0, 0); + getAndExpectDebugElementByDirective(compDe, TwelveToneSpinnerStubComponent, 1, 1); + }); + }); + }); }); describe('#getEditionGraphData()', () => { @@ -567,12 +642,12 @@ describe('EditionGraphComponent (DONE)', () => { expect(component.getEditionGraphData).toBeDefined(); }); - it('... should trigger editionService.getEditionComplex', () => { - expectSpyCall(editionServiceGetEditionComplexSpy, 1); + it('... should trigger editionService.getSelectedEditionComplex', () => { + expectSpyCall(editionServiceGetSelectedEditionComplexSpy, 1); }); it('... should get current editionComplex from editionService', () => { - expectSpyCall(editionServiceGetEditionComplexSpy, 1); + expectSpyCall(editionServiceGetSelectedEditionComplexSpy, 1); expectToEqual(component.editionComplex, expectedEditionComplex); }); @@ -580,14 +655,16 @@ describe('EditionGraphComponent (DONE)', () => { it('... should update editionComplex when editionService emits changed value', waitForAsync(() => { // ---------------- // Change to op. 25 - editionServiceGetEditionComplexSpy.and.returnValue(observableOf(EDITION_COMPLEXES.OP25)); + editionServiceGetSelectedEditionComplexSpy.and.returnValue( + observableOf(EditionComplexesService.getEditionComplexById('OP25')) + ); component.getEditionGraphData(); detectChangesOnPush(fixture); - expectSpyCall(editionServiceGetEditionComplexSpy, 2); + expectSpyCall(editionServiceGetSelectedEditionComplexSpy, 2); - expectToEqual(component.editionComplex, EDITION_COMPLEXES.OP25); + expectToEqual(component.editionComplex, EditionComplexesService.getEditionComplexById('OP25')); })); it('... should trigger editionDataService.getEditionGraph', () => { @@ -601,14 +678,19 @@ describe('EditionGraphComponent (DONE)', () => { it('... should re-trigger editionDataService.getEditionGraph with updated editionComplex', waitForAsync(() => { // ---------------- // Change to op. 25 - // ExpectedEditionComplex = EDITION_COMPLEXES.op25; - editionServiceGetEditionComplexSpy.and.returnValue(observableOf(EDITION_COMPLEXES.OP25)); + editionServiceGetSelectedEditionComplexSpy.and.returnValue( + observableOf(EditionComplexesService.getEditionComplexById('OP25')) + ); component.getEditionGraphData(); detectChangesOnPush(fixture); - expectSpyCall(editionServiceGetEditionComplexSpy, 2); - expectSpyCall(editionDataServiceGetEditionGraphDataSpy, 2, EDITION_COMPLEXES.OP25); + expectSpyCall(editionServiceGetSelectedEditionComplexSpy, 2); + expectSpyCall( + editionDataServiceGetEditionGraphDataSpy, + 2, + EditionComplexesService.getEditionComplexById('OP25') + ); })); it('... should get editionGraphData from editionDataService and set editionGraphData$', waitForAsync(() => { @@ -618,9 +700,7 @@ describe('EditionGraphComponent (DONE)', () => { detectChangesOnPush(fixture); expectAsync(lastValueFrom(component.editionGraphData$)).toBeResolved(); - expectAsync(lastValueFrom(component.editionGraphData$)) - .withContext(`should be resolved to ${expectedEditionGraphDataEmpty}`) - .toBeResolvedTo(expectedEditionGraphDataEmpty); + expectAsync(lastValueFrom(component.editionGraphData$)).toBeResolvedTo(expectedEditionGraphDataEmpty); })); it('... should update editionGraphData$ when editionService emits changed value', waitForAsync(() => { @@ -628,19 +708,22 @@ describe('EditionGraphComponent (DONE)', () => { // ---------------- // Change to op. 25 - // ExpectedEditionComplex = EDITION_COMPLEXES.op25; - editionServiceGetEditionComplexSpy.and.returnValue(observableOf(EDITION_COMPLEXES.OP25)); + editionServiceGetSelectedEditionComplexSpy.and.returnValue( + observableOf(EditionComplexesService.getEditionComplexById('OP25')) + ); component.getEditionGraphData(); detectChangesOnPush(fixture); - expectSpyCall(editionServiceGetEditionComplexSpy, 2); - expectSpyCall(editionDataServiceGetEditionGraphDataSpy, 2, EDITION_COMPLEXES.OP25); + expectSpyCall(editionServiceGetSelectedEditionComplexSpy, 2); + expectSpyCall( + editionDataServiceGetEditionGraphDataSpy, + 2, + EditionComplexesService.getEditionComplexById('OP25') + ); expectAsync(lastValueFrom(component.editionGraphData$)).toBeResolved(); - expectAsync(lastValueFrom(component.editionGraphData$)) - .withContext(`should be resolved to ${expectedEditionGraphDataOp25}`) - .toBeResolvedTo(expectedEditionGraphDataOp25); + expectAsync(lastValueFrom(component.editionGraphData$)).toBeResolvedTo(expectedEditionGraphDataOp25); })); it('... should return empty observable and set errorObject if switchMap fails', waitForAsync(() => { diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/edition-graph.component.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/edition-graph.component.ts index 78035a336..ad9fe9e97 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/edition-graph.component.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/edition-graph.component.ts @@ -165,7 +165,7 @@ export class EditionGraphComponent implements OnInit { getEditionGraphData(): void { this.editionGraphData$ = this.editionService // Get current editionComplex from editionService - .getEditionComplex() + .getSelectedEditionComplex() .pipe( switchMap((complex: EditionComplex) => { // Set current editionComplex diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/force-graph/force-graph.component.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/force-graph/force-graph.component.ts index 2f4863702..141dc53bd 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/force-graph/force-graph.component.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/force-graph/force-graph.component.ts @@ -424,28 +424,12 @@ export class ForceGraphComponent implements OnInit, OnChanges, OnDestroy { * @returns {void} Attaches the data and sets up the simulation. */ private _attachData(): void { - // Limit result length const triples: Triple[] = this.graphVisualizerService.limitTriples(this.currentQueryResultTriples, this.limit); - // If type of triples is text/turtle (not array) - // The triples must be parsed to objects instead - if (typeof triples === 'string') { - this.graphVisualizerService.parseTripleString(triples).then((data: { triples; namespaces }) => { - const abrTriples: Triple[] = this.graphVisualizerService.abbreviateTriples( - data.triples, - data.namespaces - ); - this._simulationData = this._triplesToD3GraphData(abrTriples); - - this._setupForceSimulation(); - this._updateSVG(); - }); - } else { - this._simulationData = this._triplesToD3GraphData(triples); + this._simulationData = this._triplesToD3GraphData(triples); - this._setupForceSimulation(); - this._updateSVG(); - } + this._setupForceSimulation(); + this._updateSVG(); } /** diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/graph-visualizer.component.html b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/graph-visualizer.component.html index 0c4d0d76f..e2169e361 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/graph-visualizer.component.html +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/graph-visualizer.component.html @@ -50,10 +50,6 @@ [isFullscreen]="isFullscreen"> } } - - - -
} diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/graph-visualizer.component.spec.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/graph-visualizer.component.spec.ts index 795c430ac..ef2bb2b90 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/graph-visualizer.component.spec.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/graph-visualizer.component.spec.ts @@ -8,6 +8,8 @@ import { cleanStylesFromDOM } from '@testing/clean-up-helper'; import { detectChangesOnPush } from '@testing/detect-changes-on-push-helper'; import { expectSpyCall, + expectToBe, + expectToEqual, getAndExpectDebugElementByCss, getAndExpectDebugElementByDirective, } from '@testing/expect-helper'; @@ -226,8 +228,7 @@ describe('GraphVisualizerComponent (DONE)', () => { }); it('... should have defaultForceGraphHeight ', () => { - expect(component.defaultForceGraphHeight).toBeTruthy(); - expect(component.defaultForceGraphHeight).withContext('should be 500').toBe(500); + expectToBe(component.defaultForceGraphHeight, 500); }); it('... should not have triggered `resetTriples()`', () => { @@ -264,43 +265,30 @@ describe('GraphVisualizerComponent (DONE)', () => { }); it('... should have graphRDFInputData', () => { - expect(component.graphRDFInputData).toBeDefined(); - expect(component.graphRDFInputData) - .withContext(`should equal ${expectedGraphRDFData}`) - .toEqual(expectedGraphRDFData); + expectToEqual(component.graphRDFInputData, expectedGraphRDFData); }); it('... should have `isFullScreen` input', () => { - expect(component.isFullscreen).toBeDefined(); - expect(component.isFullscreen).withContext(`should be ${expectedIsFullscreen}`).toBe(expectedIsFullscreen); + expectToBe(component.isFullscreen, expectedIsFullscreen); }); it('... should have triples', () => { - expect(component.triples).toBeDefined(); - expect(component.triples) - .withContext(`should equal ${expectedGraphRDFData.triples}`) - .toEqual(expectedGraphRDFData.triples); + expectToEqual(component.triples, expectedGraphRDFData.triples); }); it('... should have queryList', () => { - expect(component.queryList).toBeDefined(); - expect(component.queryList) - .withContext(`should equal ${expectedGraphRDFData.triples}`) - .toEqual(expectedGraphRDFData.queryList); + expectToEqual(component.queryList, expectedGraphRDFData.queryList); }); it('... should have query', () => { - expect(component.query).toBeDefined(); - expect(component.query) - .withContext(`should equal ${expectedGraphRDFData.triples}`) - .toEqual(expectedGraphRDFData.queryList[0]); + expectToEqual(component.query, expectedGraphRDFData.queryList[0]); }); it('... should have queryResult', () => { expect(component.queryResult$).toBeDefined(); + component.queryResult$.subscribe(result => { - expect(result).toBeTruthy(); - expect(result).withContext(`should equal ${expectedResult}`).toEqual(expectedResult); + expectToEqual(result, expectedResult); }); }); @@ -338,10 +326,7 @@ describe('GraphVisualizerComponent (DONE)', () => { it('... should set initial triples', () => { expectSpyCall(resetTriplesSpy, 1, undefined); - expect(component.triples).toBeDefined(); - expect(component.triples) - .withContext(`should equal ${expectedGraphRDFData.triples}`) - .toEqual(expectedGraphRDFData.triples); + expectToEqual(component.triples, expectedGraphRDFData.triples); }); it('... should reset changed triples to initial triples', () => { @@ -354,8 +339,7 @@ describe('GraphVisualizerComponent (DONE)', () => { // Wait for fixture to be stable fixture.detectChanges(); - expect(component.triples).toBeDefined(); - expect(component.triples).withContext(`should equal ${changedTriples}`).toEqual(changedTriples); + expectToEqual(component.triples, changedTriples); // Reset triples component.resetTriples(); @@ -363,9 +347,7 @@ describe('GraphVisualizerComponent (DONE)', () => { expectSpyCall(resetTriplesSpy, 2, undefined); expect(component.triples).toBeDefined(); - expect(component.triples) - .withContext(`should equal ${expectedGraphRDFData.triples}`) - .toEqual(expectedGraphRDFData.triples); + expectToEqual(component.triples, expectedGraphRDFData.triples); }); it('... should not do anything if no triples are provided from rdf data', () => { @@ -405,19 +387,13 @@ describe('GraphVisualizerComponent (DONE)', () => { it('... should set initial queryList', () => { expectSpyCall(resetQuerySpy, 1, undefined); - expect(component.queryList).toBeDefined(); - expect(component.queryList) - .withContext(`should equal ${expectedGraphRDFData.queryList}`) - .toEqual(expectedGraphRDFData.queryList); + expectToEqual(component.queryList, expectedGraphRDFData.queryList); }); it('... should set initial query', () => { expectSpyCall(resetQuerySpy, 1, undefined); - expect(component.query).toBeDefined(); - expect(component.query) - .withContext(`should equal ${expectedGraphRDFData.queryList[0]}`) - .toEqual(expectedGraphRDFData.queryList[0]); + expectToEqual(component.query, expectedGraphRDFData.queryList[0]); }); it('... should find and reset a query from queryList if queryLabel and queryType is known', () => { @@ -432,18 +408,9 @@ describe('GraphVisualizerComponent (DONE)', () => { // Matches queryList queries by label expectSpyCall(resetQuerySpy, 2, undefined); - expect(component.query).toBeDefined(); - expect(component.query).withContext(`should equal ${changedQuery}`).toEqual(changedQuery); - - expect(component.query.queryLabel).toBeDefined(); - expect(component.query.queryLabel) - .withContext(`should equal ${changedQuery.queryLabel}`) - .toEqual(changedQuery.queryLabel); - - expect(component.query.queryType).toBeDefined(); - expect(component.query.queryType) - .withContext(`should equal ${changedQuery.queryType}`) - .toEqual(changedQuery.queryType); + expectToEqual(component.query, changedQuery); + expectToBe(component.query.queryLabel, changedQuery.queryLabel); + expectToBe(component.query.queryType, changedQuery.queryType); }); describe('... should set query as is, and not find from queryList, if', () => { @@ -463,18 +430,9 @@ describe('GraphVisualizerComponent (DONE)', () => { // Matches queryList queries only by label expectSpyCall(resetQuerySpy, 2, undefined); - expect(component.query).toBeDefined(); - expect(component.query).withContext(`should equal ${changedQuery}`).toEqual(changedQuery); - - expect(component.query.queryLabel).toBeDefined(); - expect(component.query.queryLabel) - .withContext(`should equal ${changedQuery.queryLabel}`) - .toBe(changedQuery.queryLabel); - - expect(component.query.queryType).toBeDefined(); - expect(component.query.queryType) - .withContext(`should equal ${changedQuery.queryType}`) - .toBe(changedQuery.queryType); + expectToEqual(component.query, changedQuery); + expectToBe(component.query.queryLabel, changedQuery.queryLabel); + expectToBe(component.query.queryType, changedQuery.queryType); }); it('... only queryType is known but not queryLabel', () => { @@ -490,18 +448,9 @@ describe('GraphVisualizerComponent (DONE)', () => { // Matches queryList queries only by type expectSpyCall(resetQuerySpy, 2, undefined); - expect(component.query).toBeDefined(); - expect(component.query).withContext(`should equal ${changedQuery}`).toEqual(changedQuery); - - expect(component.query.queryLabel).toBeDefined(); - expect(component.query.queryLabel) - .withContext(`should equal ${changedQuery.queryLabel}`) - .toBe(changedQuery.queryLabel); - - expect(component.query.queryType).toBeDefined(); - expect(component.query.queryType) - .withContext(`should equal ${changedQuery.queryType}`) - .toBe(changedQuery.queryType); + expectToEqual(component.query, changedQuery); + expectToBe(component.query.queryLabel, changedQuery.queryLabel); + expectToBe(component.query.queryType, changedQuery.queryType); }); it('... given query is not in queryList', () => { @@ -521,18 +470,9 @@ describe('GraphVisualizerComponent (DONE)', () => { expectSpyCall(resetQuerySpy, 2, undefined); - expect(component.query).toBeDefined(); - expect(component.query).withContext(`should equal ${changedQuery}`).toEqual(changedQuery); - - expect(component.query.queryLabel).toBeDefined(); - expect(component.query.queryLabel) - .withContext(`should equal ${changedQuery.queryLabel}`) - .toBe(changedQuery.queryLabel); - - expect(component.query.queryType).toBeDefined(); - expect(component.query.queryType) - .withContext(`should equal ${changedQuery.queryType}`) - .toBe(changedQuery.queryType); + expectToEqual(component.query, changedQuery); + expectToBe(component.query.queryLabel, changedQuery.queryLabel); + expectToBe(component.query.queryType, changedQuery.queryType); }); }); @@ -544,8 +484,7 @@ describe('GraphVisualizerComponent (DONE)', () => { component.query = changedQuery; fixture.detectChanges(); - expect(component.query).toBeDefined(); - expect(component.query).withContext(`should equal ${changedQuery}`).toEqual(changedQuery); + expectToEqual(component.query, changedQuery); // Reset triples component.resetQuery(); @@ -553,10 +492,7 @@ describe('GraphVisualizerComponent (DONE)', () => { expectSpyCall(resetQuerySpy, 2, undefined); - expect(component.query).toBeDefined(); - expect(component.query) - .withContext(`should equal ${expectedGraphRDFData.queryList[0]}`) - .toEqual(expectedGraphRDFData.queryList[0]); + expectToEqual(component.query, expectedGraphRDFData.queryList[0]); }); it('... should not do anything if no queryList is provided from RDF data', () => { @@ -645,10 +581,7 @@ describe('GraphVisualizerComponent (DONE)', () => { expectSpyCall(performQuerySpy, 2, undefined); expectSpyCall(namespaceSpy, 1, [queryStringWithoutPrefixes, expectedGraphRDFData.triples]); - expect(component.query).toBeDefined(); - expect(component.query) - .withContext(`should equal ${expectedGraphRDFData.queryList[0]}`) - .toEqual(expectedGraphRDFData.queryList[0]); + expectToEqual(component.query, expectedGraphRDFData.queryList[0]); }); it('... should get queryType from service', () => { @@ -670,8 +603,7 @@ describe('GraphVisualizerComponent (DONE)', () => { expectedGraphRDFData.queryList[0].queryString ); - expect(component.query.queryType).toBeDefined(); - expect(component.query.queryType).withContext('should equal construct').toEqual('construct'); + expectToBe(component.query.queryType, 'construct'); }); it('... should trigger `_queryLocalStore` for construct queries', () => { @@ -716,10 +648,9 @@ describe('GraphVisualizerComponent (DONE)', () => { component.performQuery(); detectChangesOnPush(fixture); + expectToBe(component.query.queryType, 'construct'); expectAsync(lastValueFrom(component.queryResult$)).toBeResolved(); - expectAsync(lastValueFrom(component.queryResult$)) - .withContext(`should be resolved to ${expectedResult}`) - .toBeResolvedTo(expectedResult); + expectAsync(lastValueFrom(component.queryResult$)).toBeResolvedTo(expectedResult); })); it('... should get queryResult for select queries', waitForAsync(() => { @@ -730,10 +661,9 @@ describe('GraphVisualizerComponent (DONE)', () => { component.performQuery(); detectChangesOnPush(fixture); + expectToBe(component.query.queryType, 'select'); expectAsync(lastValueFrom(component.queryResult$)).toBeResolved(); - expectAsync(lastValueFrom(component.queryResult$)) - .withContext(`should be resolved to ${expectedResult}`) - .toBeResolvedTo(expectedResult); + expectAsync(lastValueFrom(component.queryResult$)).toBeResolvedTo(expectedResult); })); it('... should set empty observable for update query types', waitForAsync(() => { @@ -743,7 +673,7 @@ describe('GraphVisualizerComponent (DONE)', () => { component.performQuery(); fixture.detectChanges(); - expect(component.query.queryType).withContext('should be other').toBe('update'); + expectToBe(component.query.queryType, 'update'); expectAsync(lastValueFrom(component.queryResult$)).toBeRejected(); expectAsync(lastValueFrom(component.queryResult$)).toBeRejectedWithError(EmptyError); })); @@ -755,7 +685,7 @@ describe('GraphVisualizerComponent (DONE)', () => { component.performQuery(); fixture.detectChanges(); - expect(component.query.queryType).withContext('should be other').toBe('other'); + expectToBe(component.query.queryType, 'other'); expectAsync(lastValueFrom(component.queryResult$)).toBeRejected(); expectAsync(lastValueFrom(component.queryResult$)).toBeRejectedWithError(EmptyError); })); @@ -806,14 +736,10 @@ describe('GraphVisualizerComponent (DONE)', () => { expectAsync( graphVisualizerService.doQuery(expectedCallback[0], expectedCallback[1], expectedCallback[2]) - ) - .withContext(`should be resolved to ${expectedResult}`) - .toBeResolvedTo(expectedResult); + ).toBeResolvedTo(expectedResult); expectAsync(lastValueFrom(component.queryResult$)).toBeResolved(); - expectAsync(lastValueFrom(component.queryResult$)) - .withContext(`should be resolved to ${expectedResult}`) - .toBeResolvedTo(expectedResult); + expectAsync(lastValueFrom(component.queryResult$)).toBeResolvedTo(expectedResult); })); it('... should return empty array on error', waitForAsync(() => { @@ -836,9 +762,7 @@ describe('GraphVisualizerComponent (DONE)', () => { ).toBeRejectedWith(expectedError); expectAsync(lastValueFrom(component.queryResult$)).toBeResolved(); - expectAsync(lastValueFrom(component.queryResult$)) - .withContext(`should be resolved to []`) - .toBeResolvedTo([]); + expectAsync(lastValueFrom(component.queryResult$)).toBeResolvedTo([]); })); it('... should log an error on error', async () => { @@ -885,11 +809,9 @@ describe('GraphVisualizerComponent (DONE)', () => { expectSpyCall(showErrorMessageSpy, 1); expect(showErrorMessageSpy.calls.any()).toBeTruthy(); - expect(showErrorMessageSpy.calls.count()).withContext(`should be 1`).toBe(1); - expect(showErrorMessageSpy.calls.first().args) - .withContext(`should equal ${expectedToastMessage}`) - .toEqual([expectedToastMessage]); - expect(showErrorMessageSpy.calls.allArgs()[0]).withContext(`should equal ${expectedToastMessage}`); + expectToBe(showErrorMessageSpy.calls.count(), 1); + expectToEqual(showErrorMessageSpy.calls.first().args, [expectedToastMessage]); + expectToEqual(showErrorMessageSpy.calls.allArgs()[0], [expectedToastMessage]); }); it('... should trigger `showErrorMessage` 2x if error message contains `undefined`', async () => { @@ -916,19 +838,11 @@ describe('GraphVisualizerComponent (DONE)', () => { expectSpyCall(showErrorMessageSpy, 2); expect(showErrorMessageSpy.calls.any()).toBeTruthy(); - expect(showErrorMessageSpy.calls.count()).withContext(`should be 2`).toBe(2); - expect(showErrorMessageSpy.calls.first().args) - .withContext(`should equal ${expectedToastMessage1}`) - .toEqual([expectedToastMessage1]); - expect(showErrorMessageSpy.calls.allArgs()[0]) - .withContext(`should equal ${expectedToastMessage1}`) - .toEqual([expectedToastMessage1]); - expect(showErrorMessageSpy.calls.allArgs()[1]) - .withContext(`should equal ${expectedToastMessage2}`) - .toEqual([expectedToastMessage2]); - expect(showErrorMessageSpy.calls.mostRecent().args) - .withContext(`should equal ${expectedToastMessage2}`) - .toEqual([expectedToastMessage2]); + expectToBe(showErrorMessageSpy.calls.count(), 2); + expectToEqual(showErrorMessageSpy.calls.first().args, [expectedToastMessage1]); + expectToEqual(showErrorMessageSpy.calls.allArgs()[0], [expectedToastMessage1]); + expectToEqual(showErrorMessageSpy.calls.allArgs()[1], [expectedToastMessage2]); + expectToEqual(showErrorMessageSpy.calls.mostRecent().args, [expectedToastMessage2]); }); }); @@ -1011,8 +925,8 @@ describe('GraphVisualizerComponent (DONE)', () => { expectSpyCall(toastServiceAddSpy, 1, expectedToast); expect(toastService.toasts).toBeDefined(); - expect(toastService.toasts.length).withContext(`should be 1`).toBe(1); - expect(toastService.toasts[0]).withContext(`should equal ${expectedToast}`).toEqual(expectedToast); + expectToBe(toastService.toasts.length, 1); + expectToEqual(toastService.toasts[0], expectedToast); }); it('... should set durationvValue = 3000 for the toast message if delay not given ', () => { @@ -1032,8 +946,8 @@ describe('GraphVisualizerComponent (DONE)', () => { expectSpyCall(toastServiceAddSpy, 1, expectedToast); expect(toastService.toasts).toBeDefined(); - expect(toastService.toasts.length).withContext(`should be 1`).toBe(1); - expect(toastService.toasts[0]).withContext(`should equal ${expectedToast}`).toEqual(expectedToast); + expectToBe(toastService.toasts.length, 1); + expectToEqual(toastService.toasts[0], expectedToast); }); }); @@ -1068,7 +982,7 @@ describe('GraphVisualizerComponent (DONE)', () => { it('... should not do anything if no node is provided', () => { // Check initial state expectSpyCall(performQuerySpy, 1, undefined); - expect(component.query.queryString).toEqual(component.graphRDFInputData.queryList[0].queryString); + expectToBe(component.query.queryString, component.graphRDFInputData.queryList[0].queryString); const resultsDes = getAndExpectDebugElementByDirective(compDe, ConstructResultsStubComponent, 1, 1); const resultsCmp = resultsDes[0].injector.get( @@ -1079,9 +993,7 @@ describe('GraphVisualizerComponent (DONE)', () => { resultsCmp.clickedNodeRequest.emit(undefined); expectSpyCall(onGraphNodeClickSpy, 1, undefined); - expect(component.query.queryString) - .withContext(`should equal ${component.graphRDFInputData.queryList[0].queryString}`) - .toEqual(component.graphRDFInputData.queryList[0].queryString); + expectToBe(component.query.queryString, component.graphRDFInputData.queryList[0].queryString); expectSpyCall(performQuerySpy, 1, undefined); }); @@ -1128,7 +1040,7 @@ describe('GraphVisualizerComponent (DONE)', () => { it('... should not do anything if no URI is provided', () => { // Check initial state expectSpyCall(performQuerySpy, 1, undefined); - expect(component.query.queryString).toEqual(component.graphRDFInputData.queryList[0].queryString); + expectToBe(component.query.queryString, component.graphRDFInputData.queryList[0].queryString); const resultsDes = getAndExpectDebugElementByDirective(compDe, SelectResultsStubComponent, 1, 1); const resultsCmp = resultsDes[0].injector.get(SelectResultsStubComponent) as SelectResultsStubComponent; @@ -1137,9 +1049,7 @@ describe('GraphVisualizerComponent (DONE)', () => { resultsCmp.clickedTableRequest.emit(''); expectSpyCall(onTableNodeClickSpy, 1, ''); - expect(component.query.queryString) - .withContext(`should equal ${component.graphRDFInputData.queryList[0].queryString}`) - .toEqual(component.graphRDFInputData.queryList[0].queryString); + expectToBe(component.query.queryString, component.graphRDFInputData.queryList[0].queryString); expectSpyCall(performQuerySpy, 1, undefined); }); @@ -1288,10 +1198,7 @@ describe('GraphVisualizerComponent (DONE)', () => { TriplesEditorStubComponent ) as TriplesEditorStubComponent; - expect(editorCmp.triples).toBeDefined(); - expect(editorCmp.triples) - .withContext(`should equal ${expectedGraphRDFData.triples}`) - .toEqual(expectedGraphRDFData.triples); + expectToEqual(editorCmp.triples, expectedGraphRDFData.triples); }); it('... should update `triples` with updateTriplesRequest event', () => { @@ -1305,8 +1212,7 @@ describe('GraphVisualizerComponent (DONE)', () => { '@prefix example: .\n\n example:Test2 example:has example:Success2 .'; editorCmp.updateTriplesRequest.emit(changedTriples); - expect(component.triples).toBeDefined(); - expect(component.triples).withContext(`should equal ${changedTriples}`).toEqual(changedTriples); + expectToEqual(component.triples, changedTriples); }); it('... should re-trigger `resetTriples()` with resetTriplesRequest event', () => { @@ -1341,15 +1247,8 @@ describe('GraphVisualizerComponent (DONE)', () => { const editorDes = getAndExpectDebugElementByDirective(compDe, SparqlEditorStubComponent, 1, 1); const editorCmp = editorDes[0].injector.get(SparqlEditorStubComponent) as SparqlEditorStubComponent; - expect(editorCmp.queryList).toBeDefined(); - expect(editorCmp.queryList) - .withContext(`should equal ${expectedGraphRDFData.queryList}`) - .toEqual(expectedGraphRDFData.queryList); - - expect(editorCmp.query).toBeDefined(); - expect(editorCmp.query) - .withContext(`should equal ${expectedGraphRDFData.queryList[0]}`) - .toEqual(expectedGraphRDFData.queryList[0]); + expectToEqual(editorCmp.queryList, expectedGraphRDFData.queryList); + expectToEqual(editorCmp.query, expectedGraphRDFData.queryList[0]); }); it('... should update `query.string` with updateQueryStringRequest event', () => { @@ -1361,10 +1260,7 @@ describe('GraphVisualizerComponent (DONE)', () => { 'PREFIX example: \n\n CONSTRUCT WHERE { ?test3 ?has ?success3 . }'; editorCmp.updateQueryStringRequest.emit(changedQueryString); - expect(component.query.queryString).toBeDefined(); - expect(component.query.queryString) - .withContext(`should equal ${changedQueryString}`) - .toEqual(changedQueryString); + expectToBe(component.query.queryString, changedQueryString); }); it('... should re-trigger `resetQuery()` with resetQueryRequest event', () => { @@ -1406,8 +1302,7 @@ describe('GraphVisualizerComponent (DONE)', () => { expect(resultsCmp.queryResult$).toBeDefined(); resultsCmp.queryResult$.subscribe(result => { - expect(result).toBeTruthy(); - expect(result).withContext(`should equal ${expectedResult}`).toEqual(expectedResult); + expectToEqual(result, expectedResult); }); }); @@ -1417,8 +1312,7 @@ describe('GraphVisualizerComponent (DONE)', () => { ConstructResultsStubComponent ) as ConstructResultsStubComponent; - expect(resultsCmp.defaultForceGraphHeight).toBeDefined(); - expect(resultsCmp.defaultForceGraphHeight).withContext('should be 500').toBe(500); + expectToBe(resultsCmp.defaultForceGraphHeight, 500); }); it('... should re-trigger `onGraphNodeClick()` with clickedTableRequest event', () => { @@ -1453,8 +1347,7 @@ describe('GraphVisualizerComponent (DONE)', () => { expect(resultsCmp.queryResult$).toBeDefined(); resultsCmp.queryResult$.subscribe(result => { - expect(result).toBeTruthy(); - expect(result).withContext(`should equal ${expectedResult}`).toEqual(expectedResult); + expectToEqual(result, expectedResult); }); }); @@ -1493,8 +1386,7 @@ describe('GraphVisualizerComponent (DONE)', () => { UnsupportedTypeResultsStubComponent ) as UnsupportedTypeResultsStubComponent; - expect(resultsCmp.queryType).toBeDefined(); - expect(resultsCmp.queryType).withContext('should be other').toBe('other'); + expectToBe(resultsCmp.queryType, 'other'); }); }); }); diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/graph-visualizer.component.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/graph-visualizer.component.ts index e4b01f486..2c69c7c61 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/graph-visualizer.component.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/graph-visualizer.component.ts @@ -188,7 +188,7 @@ export class GraphVisualizerComponent implements OnInit { * * @returns {void} Logs the click event. */ - onGraphNodeClick(node: D3SimulationNode) { + onGraphNodeClick(node: D3SimulationNode): void { if (!node) { return; } @@ -250,7 +250,7 @@ export class GraphVisualizerComponent implements OnInit { * @param {string} queryString The given queryString. * @param {string} triples THe given triples. * - * @returns {Promise} The result of the query as an promise of triple array. + * @returns {Promise} The result of the query as a promise of triple array. */ private async _queryLocalStore(queryType: string, queryString: string, triples: string): Promise { // Capture start time of query diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/models/index.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/models/index.ts index af31a4eed..2df44523d 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/models/index.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/models/index.ts @@ -16,7 +16,6 @@ import { D3SimulationNode, D3SimulationNodeType } from './d3-simulation-node.mod import { Namespace, NamespaceType } from './namespace.model'; import { Prefix, PrefixForm } from './prefix.model'; import { QueryResult, QueryResultBindings } from './query-result.model'; -import { QueryTypeIndex } from './query-type-index.model'; import { RDFStoreConstructResponse, RDFStoreSelectResponse } from './rdfstore-response.model'; import { RDFStoreConstructResponseTriple, @@ -38,9 +37,8 @@ export { D3SimulationNodeType, Namespace, NamespaceType, - PrefixForm, Prefix, - QueryTypeIndex, + PrefixForm, QueryResult, QueryResultBindings, RDFStoreConstructResponse, diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/models/query-type-index.model.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/models/query-type-index.model.ts deleted file mode 100644 index b40a6e0f5..000000000 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/models/query-type-index.model.ts +++ /dev/null @@ -1,16 +0,0 @@ -/** - * The QueryTypeIndex interface. - * - * It represents the index of a query type. - */ -export interface QueryTypeIndex { - /** - * The query type. - */ - queryType: string; - - /** - * The index of the query type. - */ - index: number; -} diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/prefix-pipe/prefix.pipe.spec.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/prefix-pipe/prefix.pipe.spec.ts index 7a49ab442..c5e6f60fc 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/prefix-pipe/prefix.pipe.spec.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/prefix-pipe/prefix.pipe.spec.ts @@ -1,3 +1,5 @@ +import { expectToBe } from '@testing/expect-helper'; + import { PrefixForm } from '../models'; import { PrefixPipe } from './prefix.pipe'; @@ -15,12 +17,12 @@ describe('PrefixPipe', () => { it('... should transform the short form of a known default RDF prefix into its long form', () => { const pipe = new PrefixPipe(); - const shortForm = 'rdf:'; + const shortForm = 'rdf'; const longForm = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'; const transformedValue = pipe.transform(shortForm, PrefixForm.LONG); - expect(transformedValue).toBe(longForm); + expectToBe(transformedValue, longForm); }); it('... should transform the long form of a known default RDF prefix into its short form', () => { @@ -30,7 +32,7 @@ describe('PrefixPipe', () => { const transformedValue = pipe.transform(longForm, PrefixForm.SHORT); - expect(transformedValue).toBe(shortForm); + expectToBe(transformedValue, shortForm); }); it('... should not transform a short value that is not in the list of default RDF prefixes', () => { @@ -39,7 +41,7 @@ describe('PrefixPipe', () => { const transformedValue = pipe.transform(shortForm, PrefixForm.LONG); - expect(transformedValue).toBe(shortForm); + expectToBe(transformedValue, shortForm); }); it('... should not transform a long value that is not in the list of default RDF prefixes', () => { @@ -48,7 +50,7 @@ describe('PrefixPipe', () => { const transformedValue = pipe.transform(longForm, PrefixForm.SHORT); - expect(transformedValue).toBe(longForm); + expectToBe(transformedValue, longForm); }); it('... should throw an error if the prefixForm is not equal to PrefixForm.SHORT or PrefixForm.LONG', () => { diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/prefix-pipe/prefix.pipe.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/prefix-pipe/prefix.pipe.ts index 8632fcb9e..ac420b139 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/prefix-pipe/prefix.pipe.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/prefix-pipe/prefix.pipe.ts @@ -40,7 +40,7 @@ export class PrefixPipe implements PipeTransform { case PrefixForm.LONG: { this.defaultPrefixes.forEach((p: Prefix) => { if (value.indexOf(p.prefixName) !== -1) { - transformedValue = value.replace(p.prefixName + ':', p.prefixIri); + transformedValue = value.replace(p.prefixName, p.prefixIri); } }); break; diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/select-results/select-results.component.spec.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/select-results/select-results.component.spec.ts index 3631a4ebe..dcb86f368 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/select-results/select-results.component.spec.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/select-results/select-results.component.spec.ts @@ -152,9 +152,7 @@ describe('SelectResultsComponent (DONE)', () => { it('... should have `queryResult` input', waitForAsync(() => { expectToEqual(component.queryResult$, expectedQueryResult$); expectAsync(lastValueFrom(component.queryResult$)).toBeResolved(); - expectAsync(lastValueFrom(component.queryResult$)) - .withContext(`should be resolved to ${expectedQueryResult}}`) - .toBeResolvedTo(expectedQueryResult); + expectAsync(lastValueFrom(component.queryResult$)).toBeResolvedTo(expectedQueryResult); })); it('... should have `queryTime` input', () => { diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/select-results/select-results.component.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/select-results/select-results.component.ts index 6c16ec154..3b5610130 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/select-results/select-results.component.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/select-results/select-results.component.ts @@ -2,7 +2,7 @@ import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from import { Observable } from 'rxjs'; -import { UtilityService } from '@awg-app/core/services'; +import { UtilityService } from '@awg-core/services'; import { QueryResult } from '../models'; /** diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/services/graph-visualizer.service.spec.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/services/graph-visualizer.service.spec.ts index c7767d998..324ec2c9b 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/services/graph-visualizer.service.spec.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/services/graph-visualizer.service.spec.ts @@ -1,7 +1,7 @@ import { TestBed } from '@angular/core/testing'; import Spy = jasmine.Spy; -import { expectSpyCall } from '@testing/expect-helper'; +import { expectSpyCall, expectToBe, expectToEqual } from '@testing/expect-helper'; import { mockConsole } from '@testing/mock-helper'; import { QueryResult, RDFStoreConstructResponseTriple, Triple } from '../models'; @@ -61,7 +61,7 @@ describe('GraphVisualizerService', () => { ]; // Spies on service functions - consoleSpy = spyOn(console, 'warn').and.callFake(mockConsole.log); + consoleSpy = spyOn(console, 'error').and.callFake(mockConsole.log); }); afterEach(() => { @@ -77,328 +77,6 @@ describe('GraphVisualizerService', () => { expect((graphVisualizerService as any)._store).toBeUndefined(); }); - describe('#limitTriples()', () => { - it('... should have a method `limitTriples`', () => { - expect(graphVisualizerService.limitTriples).toBeDefined(); - }); - - describe('should return an empty array', () => { - it('... if triples are undefined', () => { - const limit = 3; - - const result = graphVisualizerService.limitTriples(undefined, limit); - - expect(result).toEqual([]); - }); - - it('... if triples are null', () => { - const limit = 3; - - const result = graphVisualizerService.limitTriples(null, limit); - - expect(result).toEqual([]); - }); - - it('... if triples are empty array', () => { - const limit = 3; - - const result = graphVisualizerService.limitTriples([], limit); - - expect(result).toEqual([]); - }); - }); - - describe('should return the same Triple array', () => { - it('... if the Triple array length is smaller than the given limit', () => { - const inputWithTwoTriples: Triple[] = expectedTriples.slice(0, 2); - const limit = 3; - - const result = graphVisualizerService.limitTriples(inputWithTwoTriples, limit); - - expect(result).toEqual(inputWithTwoTriples); - }); - - it('... if the Triple array length is equal with the given limit', () => { - const inputWithThreeTriples: Triple[] = expectedTriples.splice(0, 3); - const limit = 3; - - const result = graphVisualizerService.limitTriples(inputWithThreeTriples, limit); - - expect(result).toEqual(inputWithThreeTriples); - }); - }); - - describe('should return a limited Triple array', () => { - it('... if the Triple array is larger than the limit', () => { - const inputWithFourTriples: Triple[] = expectedTriples.slice(0, 4); - const outputWithTwoTriples: Triple[] = expectedTriples.slice(0, 2); - const outputWithThreeTriples: Triple[] = expectedTriples.splice(0, 3); - - const limit = 3; - - const result = graphVisualizerService.limitTriples(inputWithFourTriples, limit); - - expect(result).toEqual(outputWithThreeTriples); - - const limit2 = 2; - const result2 = graphVisualizerService.limitTriples(inputWithFourTriples, limit2); - - expect(result2).toEqual(outputWithTwoTriples); - }); - }); - }); - - describe('#abbreviateTriples()', () => { - it('... should have a method `abbreviateTriples`', () => { - expect(graphVisualizerService.abbreviateTriples).toBeDefined(); - }); - - describe('should abbreviate the given StoreTriples', () => { - it('... according to the given namespaces', () => { - const triples: RDFStoreConstructResponseTriple[] = expectedConstructResponseTriples; - const namespaces = { - ex: 'http://example.org/', - exs: 'https://example.org/', - }; - - const result = graphVisualizerService.abbreviateTriples(triples, namespaces); - - expect(result[0].subject).toBeDefined(); - expect(result[0].predicate).toBeDefined(); - expect(result[0].object).toBeDefined(); - expect(result[0].subject).withContext(`should be 'ex:subject1'`).toBe('ex:subject1'); - expect(result[0].predicate).withContext(`should be 'ex:predicate1'`).toBe('ex:predicate1'); - expect(result[0].object).withContext(`should be 'ex:object1'`).toBe('ex:object1'); - - expect(result[1].subject).toBeDefined(); - expect(result[1].predicate).toBeDefined(); - expect(result[1].object).toBeDefined(); - expect(result[1].subject).withContext(`should be 'exs:subject2'`).toBe('exs:subject2'); - expect(result[1].predicate).withContext(`should be 'exs:predicate2'`).toBe('exs:predicate2'); - expect(result[1].object).withContext(`should be 'exs:object2'`).toBe('exs:object2'); - }); - - it('... if mimetype `text/turtle` is given', () => { - const triples: RDFStoreConstructResponseTriple[] = expectedConstructResponseTriples; - const namespaces = { - ex: 'http://example.org/', - exs: 'https://example.org/', - }; - const mimetypeTurtle = 'text/turtle'; - - const result = graphVisualizerService.abbreviateTriples(triples, namespaces, mimetypeTurtle); - - expect(result[0].subject).toBeDefined(); - expect(result[0].predicate).toBeDefined(); - expect(result[0].object).toBeDefined(); - expect(result[0].subject).withContext(`should be 'ex:subject1'`).toBe('ex:subject1'); - expect(result[0].predicate).withContext(`should be 'ex:predicate1'`).toBe('ex:predicate1'); - expect(result[0].object).withContext(`should be 'ex:object1'`).toBe('ex:object1'); - - expect(result[1].subject).toBeDefined(); - expect(result[1].predicate).toBeDefined(); - expect(result[1].object).toBeDefined(); - expect(result[1].subject).withContext(`should be 'exs:subject2'`).toBe('exs:subject2'); - expect(result[1].predicate).withContext(`should be 'exs:predicate2'`).toBe('exs:predicate2'); - expect(result[1].object).withContext(`should be 'exs:object2'`).toBe('exs:object2'); - }); - - it('... if no mimetype is given (`text/turtle` applied by default)', () => { - const triples: RDFStoreConstructResponseTriple[] = expectedConstructResponseTriples; - const namespaces = { - ex: 'http://example.org/', - exs: 'https://example.org/', - }; - const mimetypeEmpty = ''; - - const result = graphVisualizerService.abbreviateTriples(triples, namespaces, mimetypeEmpty); - - expect(result[0].subject).toBeDefined(); - expect(result[0].predicate).toBeDefined(); - expect(result[0].object).toBeDefined(); - expect(result[0].subject).withContext(`should be 'ex:subject1'`).toBe('ex:subject1'); - expect(result[0].predicate).withContext(`should be 'ex:predicate1'`).toBe('ex:predicate1'); - expect(result[0].object).withContext(`should be 'ex:object1'`).toBe('ex:object1'); - - expect(result[1].subject).toBeDefined(); - expect(result[1].predicate).toBeDefined(); - expect(result[1].object).toBeDefined(); - expect(result[1].subject).withContext(`should be 'exs:subject2'`).toBe('exs:subject2'); - expect(result[1].predicate).withContext(`should be 'exs:predicate2'`).toBe('exs:predicate2'); - expect(result[1].object).withContext(`should be 'exs:object2'`).toBe('exs:object2'); - }); - }); - - describe('should not abbreviate the given StoreTriples', () => { - it('... if the IRI uses an unknown namespace', () => { - const triples: RDFStoreConstructResponseTriple[] = expectedConstructResponseTriples; - const namespaces = {}; - - const result = graphVisualizerService.abbreviateTriples(triples, namespaces); - - expect(result[0].subject).toBeDefined(); - expect(result[0].predicate).toBeDefined(); - expect(result[0].object).toBeDefined(); - expect(result[0].subject) - .withContext(`should be 'http://example.org/subject1'`) - .toBe('http://example.org/subject1'); - expect(result[0].predicate) - .withContext(`should be 'http://example.org/predicate1'`) - .toBe('http://example.org/predicate1'); - expect(result[0].object) - .withContext(`should be 'http://example.org/object1'`) - .toBe('http://example.org/object1'); - - expect(result[1].subject).toBeDefined(); - expect(result[1].predicate).toBeDefined(); - expect(result[1].object).toBeDefined(); - expect(result[1].subject) - .withContext(`should be 'https://example.org/subject2'`) - .toBe('https://example.org/subject2'); - expect(result[1].predicate) - .withContext(`should be 'https://example.org/predicate2'`) - .toBe('https://example.org/predicate2'); - expect(result[1].object) - .withContext(`should be 'https://example.org/object2'`) - .toBe('https://example.org/object2'); - }); - - it('... if a given mimetype is not `text/turtle`', () => { - const triples: RDFStoreConstructResponseTriple[] = expectedConstructResponseTriples; - const namespaces = { - ex: 'http://example.org/', - exs: 'https://example.org/', - }; - const mimetypePlain = 'text/plain'; - - const result = graphVisualizerService.abbreviateTriples(triples, namespaces, mimetypePlain); - - expect(result[0].subject).toBeDefined(); - expect(result[0].predicate).toBeDefined(); - expect(result[0].object).toBeDefined(); - expect(result[0].subject) - .withContext(`should be 'http://example.org/subject1'`) - .toBe('http://example.org/subject1'); - expect(result[0].predicate) - .withContext(`should be 'http://example.org/predicate1'`) - .toBe('http://example.org/predicate1'); - expect(result[0].object) - .withContext(`should be 'http://example.org/object1'`) - .toBe('http://example.org/object1'); - - expect(result[1].subject).toBeDefined(); - expect(result[1].predicate).toBeDefined(); - expect(result[1].object).toBeDefined(); - expect(result[1].subject) - .withContext(`should be 'https://example.org/subject2'`) - .toBe('https://example.org/subject2'); - expect(result[1].predicate) - .withContext(`should be 'https://example.org/predicate2'`) - .toBe('https://example.org/predicate2'); - expect(result[1].object) - .withContext(`should be 'https://example.org/object2'`) - .toBe('https://example.org/object2'); - }); - }); - }); - - describe('#getQuerytype()', () => { - it('... should have a method `getQuerytype`', () => { - expect(graphVisualizerService.getQuerytype).toBeDefined(); - }); - - describe('should return correct querytpe', () => { - it('... if the query is a SELECT query (= `select`)', () => { - const query = 'SELECT * WHERE { ?s ?p ?o }'; - - const result = graphVisualizerService.getQuerytype(query); - - expect(result).toBeDefined(); - expect(result).withContext('should be `select`').toBe('select'); - }); - - it('... if the query is a CONSTRUCT query (= `construct`)', () => { - const query = 'CONSTRUCT { ?s ?p ?o } WHERE { ?s ?p ?o }'; - - const result = graphVisualizerService.getQuerytype(query); - - expect(result).toBeDefined(); - expect(result).withContext('should be `construct`').toBe('construct'); - }); - - it('... if the query is an ASK query (= `ask`)', () => { - const query = 'ASK WHERE { ?s ?p ?o }'; - - const result = graphVisualizerService.getQuerytype(query); - - expect(result).toBeDefined(); - expect(result).withContext('should be `ask`').toBe('ask'); - }); - - it('... if the query is a DESCRIBE query (= `describe`)', () => { - const query = 'DESCRIBE ?s WHERE { ?s ?p ?o }'; - - const result = graphVisualizerService.getQuerytype(query); - - expect(result).toBeDefined(); - expect(result).withContext('should be `describe`').toBe('describe'); - }); - - it('... if the query is a COUNT query (= `count`)', () => { - const query = 'COUNT ?s WHERE { ?s ?p ?o }'; - - const result = graphVisualizerService.getQuerytype(query); - - expect(result).toBeDefined(); - expect(result).withContext('should be `count`').toBe('count'); - }); - - it('... if the query is a DELETE query (= `update`)', () => { - const query = 'DELETE {?s ?p ?o } WHERE { ?s ?p ?o }'; - - const result = graphVisualizerService.getQuerytype(query); - - expect(result).toBeDefined(); - expect(result).withContext('should be `update`').toBe('update'); - }); - - it('... if the query is an INSERT query (= `update`)', () => { - const query = 'INSERT { ?s ?p ?o } WHERE { ?s ?p ?o} '; - - const result = graphVisualizerService.getQuerytype(query); - - expect(result).toBeDefined(); - expect(result).withContext('should be `update`').toBe('update'); - }); - - it('... if the query starts with prefixes', () => { - const query = 'PREFIX ex: SELECT * WHERE { ?s ?p ?o }'; - - const result = graphVisualizerService.getQuerytype(query); - - expect(result).toBeDefined(); - expect(result).withContext('should be `select`').toBe('select'); - }); - }); - - it('... should return the first query type if the query uses multiple query types', () => { - const query = 'CONSTRUCT { ?s ?p ?y } WHERE { SELECT ?s ?p ( bnode() AS ?y ) WHERE { ?s ?p ?o } }'; - - const result = graphVisualizerService.getQuerytype(query); - - expect(result).toBeDefined(); - expect(result).withContext('should be `construct`').toBe('construct'); - }); - - it('... should return `null` if the query is not a SELECT, CONSTRUCT, ASK, COUNT, DESCRIBE, INSERT or DELETE query', () => { - const query = 'LOAD '; - - const result = graphVisualizerService.getQuerytype(query); - - expect(result).toBe(null); - }); - }); - describe('#checkNamespacesInQuery()', () => { it('... should have a method `checkNamespacesInQuery`', () => { expect(graphVisualizerService.checkNamespacesInQuery).toBeDefined(); @@ -410,7 +88,7 @@ describe('GraphVisualizerService', () => { '@prefix ex: '; const result = graphVisualizerService.checkNamespacesInQuery(undefined, tripleStr); - expect(result).toBe(undefined); + expect(result).toBeUndefined(); }); it('... if no tripleString is given', () => { @@ -418,13 +96,13 @@ describe('GraphVisualizerService', () => { const result = graphVisualizerService.checkNamespacesInQuery(queryStr, undefined); - expect(result).toBe(undefined); + expect(result).toBeUndefined(); }); it('... if no queryString and tripleString is given', () => { const result = graphVisualizerService.checkNamespacesInQuery(undefined, undefined); - expect(result).toBe(undefined); + expect(result).toBeUndefined(); }); }); @@ -436,32 +114,20 @@ describe('GraphVisualizerService', () => { const result = graphVisualizerService.checkNamespacesInQuery(queryStr, tripleStr); - expect(result).toBeDefined(); - expect(result).withContext(`should be ${expectedResult}`).toBe(expectedResult); + expectToBe(result, expectedResult); }); describe('should check qNames from the query if a qName is not referenced in the list of namespaces and ...', () => { describe('if the qName is not in the list of default namespaces', () => { - it('... warn in the console ', () => { + it('... error in the console ', () => { const tripleStr = '@prefix ex: . '; const queryStr = 'SELECT * WHERE { ?s xyz:composer ?o }'; - const expectedFirstWarning = `Prefix 'xyz:' not declared in SPARQL and/or Turtle header. Searching in default namespaces...`; - const expectedSecondWarning = `'xyz:' is unknown. Please provide a declaration.`; + const expectedError = `Prefix 'xyz' is unknown. Please provide a declaration.`; graphVisualizerService.checkNamespacesInQuery(queryStr, tripleStr); - expectSpyCall(consoleSpy, 2); - - expect(consoleSpy.calls.argsFor(0)).toBeDefined(); - expect(consoleSpy.calls.argsFor(0)) - .withContext(`should equal ${expectedFirstWarning}`) - .toEqual([expectedFirstWarning]); - - expect(consoleSpy.calls.argsFor(1)).toBeDefined(); - expect(consoleSpy.calls.argsFor(1)) - .withContext(`should equal ${expectedSecondWarning}`) - .toEqual([expectedSecondWarning]); + expectSpyCall(consoleSpy, 1, [expectedError]); }); }); @@ -474,30 +140,7 @@ describe('GraphVisualizerService', () => { const result = graphVisualizerService.checkNamespacesInQuery(queryStr, tripleStr); - expect(result).toBeDefined(); - expect(result.trim()).withContext(`should be ${expectedResult}`).toBe(expectedResult); - }); - - it('... warn in the console ', () => { - const tripleStr = - '@prefix ex: .\n .'; - const queryStr = 'PREFIX ex: \nSELECT * WHERE { ?s foaf:age ?o }'; - const expectedFirstWarning = `Prefix 'foaf:' not declared in SPARQL and/or Turtle header. Searching in default namespaces...`; - const expectedSecondWarning = `Added 'PREFIX foaf: \n' to SPARQL prefixes from list of default namespaces.`; - - graphVisualizerService.checkNamespacesInQuery(queryStr, tripleStr); - - expectSpyCall(consoleSpy, 2); - - expect(consoleSpy.calls.argsFor(0)).toBeDefined(); - expect(consoleSpy.calls.argsFor(0)) - .withContext(`should equal ${expectedFirstWarning}`) - .toEqual([expectedFirstWarning]); - - expect(consoleSpy.calls.argsFor(1)).toBeDefined(); - expect(consoleSpy.calls.argsFor(1)) - .withContext(`should equal ${expectedSecondWarning}`) - .toEqual([expectedSecondWarning]); + expectToBe(result, expectedResult); }); }); }); @@ -507,9 +150,9 @@ describe('GraphVisualizerService', () => { '@prefix ex: . '; const expectedError = 'The type must be TURTLE or SPARQL, but was: undefined.'; - expect(() => (graphVisualizerService as any)._extractNamespacesFromString(undefined, tripleStr)) - .withContext('should throw an error') - .toThrowError(expectedError); + expect(() => + (graphVisualizerService as any)._extractNamespacesFromString(undefined, tripleStr) + ).toThrowError(expectedError); }); }); @@ -527,6 +170,7 @@ describe('GraphVisualizerService', () => { await graphVisualizerService.doQuery(queryType, queryStr, tripleStr); expect((graphVisualizerService as any)._store).toBeDefined(); + expectToEqual((graphVisualizerService as any)._store.constructor.name, 'Store'); }); describe('should perform a given query with a given turtle string against the rdfstore', () => { @@ -545,8 +189,7 @@ describe('GraphVisualizerService', () => { const result = await graphVisualizerService.doQuery(queryType, queryStr, tripleStr); - expect(result).toBeDefined(); - expect(result).withContext(`should equal ${expectedConstructResult}`).toEqual(expectedConstructResult); + expectToEqual(result, expectedConstructResult); }); it('... and return QueryResult with SELECT query', async () => { @@ -583,8 +226,7 @@ describe('GraphVisualizerService', () => { const result = await graphVisualizerService.doQuery(queryType, queryStr, tripleStr); - expect(result).toBeDefined(); - expect(result).withContext(`should equal ${expectedSelectResult}`).toEqual(expectedSelectResult); + expectToEqual(result, expectedSelectResult); }); it('... and transform integer literals to number labels in a SELECT response', async () => { @@ -643,8 +285,7 @@ describe('GraphVisualizerService', () => { const result = await graphVisualizerService.doQuery(queryType, queryStr, tripleStr); - expect(result).toBeDefined(); - expect(result).withContext(`should equal ${expectedSelectResult}`).toEqual(expectedSelectResult); + expectToEqual(result, expectedSelectResult); }); describe('... and return `undefined`', () => { @@ -684,27 +325,1387 @@ describe('GraphVisualizerService', () => { const result = await graphVisualizerService.doQuery(queryType, queryStr, tripleStr); - expect(result).toBeDefined(); - expect(result).withContext(`should equal ${expectedResponse}`).toEqual(expectedResponse); + expectToEqual(result, expectedResponse); }); }); }); - describe('#parseTripleString()', () => { - it('... should have a method `parseTripleString`', () => { - expect(graphVisualizerService.parseTripleString).toBeDefined(); + describe('#getQuerytype()', () => { + it('... should have a method `getQuerytype`', () => { + expect(graphVisualizerService.getQuerytype).toBeDefined(); }); - it('... should return a Promise of triples and namespaces', async () => { - const triples = - '@prefix ex: . .'; + describe('should return correct querytpe', () => { + it('... if the query is a SELECT query (= `select`)', () => { + const query = 'SELECT * WHERE { ?s ?p ?o }'; - const result = graphVisualizerService.parseTripleString(triples); + const result = graphVisualizerService.getQuerytype(query); - expect(result).toBeDefined(); - await expectAsync(result).toBeResolved(); + expectToBe(result, 'select'); + }); + + it('... if the query is a CONSTRUCT query (= `construct`)', () => { + const query = 'CONSTRUCT { ?s ?p ?o } WHERE { ?s ?p ?o }'; + + const result = graphVisualizerService.getQuerytype(query); + + expectToBe(result, 'construct'); + }); + + it('... if the query is an ASK query (= `ask`)', () => { + const query = 'ASK WHERE { ?s ?p ?o }'; + + const result = graphVisualizerService.getQuerytype(query); + + expectToBe(result, 'ask'); + }); + + it('... if the query is a DESCRIBE query (= `describe`)', () => { + const query = 'DESCRIBE ?s WHERE { ?s ?p ?o }'; + + const result = graphVisualizerService.getQuerytype(query); + + expectToBe(result, 'describe'); + }); + + it('... if the query is a COUNT query (= `count`)', () => { + const query = 'COUNT ?s WHERE { ?s ?p ?o }'; + + const result = graphVisualizerService.getQuerytype(query); + + expectToBe(result, 'count'); + }); + + it('... if the query is a DELETE query (= `update`)', () => { + const query = 'DELETE {?s ?p ?o } WHERE { ?s ?p ?o }'; + + const result = graphVisualizerService.getQuerytype(query); + + expectToBe(result, 'update'); + }); + + it('... if the query is an INSERT query (= `update`)', () => { + const query = 'INSERT { ?s ?p ?o } WHERE { ?s ?p ?o} '; + + const result = graphVisualizerService.getQuerytype(query); + + expectToBe(result, 'update'); + }); + + it('... if the query starts with prefixes', () => { + const query = 'PREFIX ex: SELECT * WHERE { ?s ?p ?o }'; + + const result = graphVisualizerService.getQuerytype(query); + + expectToBe(result, 'select'); + }); + }); + + it('... should return the first query type if the query uses multiple query types', () => { + const query = 'CONSTRUCT { ?s ?p ?y } WHERE { SELECT ?s ?p ( bnode() AS ?y ) WHERE { ?s ?p ?o } }'; + + const result = graphVisualizerService.getQuerytype(query); + + expectToBe(result, 'construct'); + }); + + it('... should return `null` if the query is not a SELECT, CONSTRUCT, ASK, COUNT, DESCRIBE, INSERT or DELETE query', () => { + const query = 'LOAD '; + + const result = graphVisualizerService.getQuerytype(query); + + expectToBe(result, null); + }); + }); + + describe('#limitTriples()', () => { + it('... should have a method `limitTriples`', () => { + expect(graphVisualizerService.limitTriples).toBeDefined(); + }); + + describe('should return an empty array', () => { + it('... if triples are undefined', () => { + const limit = 3; + + const result = graphVisualizerService.limitTriples(undefined, limit); + + expectToEqual(result, []); + }); + + it('... if triples are null', () => { + const limit = 3; + + const result = graphVisualizerService.limitTriples(null, limit); + + expectToEqual(result, []); + }); + + it('... if triples are empty array', () => { + const limit = 3; + + const result = graphVisualizerService.limitTriples([], limit); + + expectToEqual(result, []); + }); + }); + + describe('should return the original Triple array', () => { + it('... if the Triple array length is smaller than the given limit', () => { + const inputWithTwoTriples: Triple[] = expectedTriples.slice(0, 2); + const limit = 3; + + const result = graphVisualizerService.limitTriples(inputWithTwoTriples, limit); + + expectToEqual(result, inputWithTwoTriples); + }); + + it('... if the Triple array length is equal with the given limit', () => { + const inputWithThreeTriples: Triple[] = expectedTriples.splice(0, 3); + const limit = 3; + + const result = graphVisualizerService.limitTriples(inputWithThreeTriples, limit); + + expectToEqual(result, inputWithThreeTriples); + }); + }); + + describe('should return a limited Triple array', () => { + it('... if the Triple array is larger than the limit', () => { + const inputWithFourTriples: Triple[] = expectedTriples.slice(0, 4); + const outputWithTwoTriples: Triple[] = expectedTriples.slice(0, 2); + const outputWithThreeTriples: Triple[] = expectedTriples.splice(0, 3); + + const limit = 3; + + const result = graphVisualizerService.limitTriples(inputWithFourTriples, limit); + + expectToEqual(result, outputWithThreeTriples); + + const limit2 = 2; + const result2 = graphVisualizerService.limitTriples(inputWithFourTriples, limit2); + + expectToEqual(result2, outputWithTwoTriples); + }); + }); + }); + + describe('#parseTripleString()', () => { + it('... should have a method `parseTripleString`', () => { + expect(graphVisualizerService.parseTripleString).toBeDefined(); + }); + + it('... should return a Promise of triples and namespaces for a given triple string', async () => { + const triples = + '@prefix ex: . @prefix ex2: . .'; + + await expectAsync(graphVisualizerService.parseTripleString(triples)).toBeResolved(); + + const result = await graphVisualizerService.parseTripleString(triples); + + expect(result).toBeDefined(); + expectToEqual(result.namespaces, { ex: 'http://example.org/', ex2: 'http://example2.org/' }); + expectToBe(Array.isArray(result.quads), true); + expectToBe(result.quads.length, 1); + expectToBe(result.quads[0].subject.id, 'http://example.org/subject'); + expectToBe(result.quads[0].predicate.id, 'http://example.org/predicate'); + expectToBe(result.quads[0].object.id, 'http://example.org/object'); + }); + + it('... should return a Promise of empty triples and namespaces for an empty triple string', async () => { + const triples = ''; + + await expectAsync(graphVisualizerService.parseTripleString(triples)).toBeResolved(); + + const result = await graphVisualizerService.parseTripleString(triples); + + expect(result).toBeDefined(); + expectToEqual(result.namespaces, {}); + expectToBe(Array.isArray(result.quads), true); + expectToBe(result.quads.length, 0); + }); + + describe('... should throw an error', () => { + it('... for missing dots', async () => { + const triplesWithSyntaxError = + '@prefix ex: @prefix ex2: . .'; + + await expectAsync( + graphVisualizerService.parseTripleString(triplesWithSyntaxError) + ).toBeRejectedWithError('Expected declaration to end with a dot on line 1.'); + }); + + it('... for missing @', async () => { + const triplesWithSyntaxError = + 'prefix ex: . @prefix ex2: . .'; + + await expectAsync( + graphVisualizerService.parseTripleString(triplesWithSyntaxError) + ).toBeRejectedWithError('Expected entity but got . on line 1.'); + }); + + it('... for missing prefix marker', async () => { + const triplesWithSyntaxError = + '@prefix ex: . ex2: . .'; + + await expectAsync( + graphVisualizerService.parseTripleString(triplesWithSyntaxError) + ).toBeRejectedWithError('Undefined prefix "ex2:" on line 1.'); + }); + }); + }); + + describe('#_abbreviate()', () => { + it('... should have a method `_abbreviate`', () => { + expect((graphVisualizerService as any)._abbreviate).toBeDefined(); + }); + + describe('... should return an abbreviated IRI if', () => { + it('... the given IRI matches a given namespace', () => { + const iri = 'http://example.org/subject'; + const namespaces = { ex: 'http://example.org/' }; + const expectedAbbreviation = 'ex:subject'; + + const result = (graphVisualizerService as any)._abbreviate(iri, namespaces); + + expectToBe(result, expectedAbbreviation); + }); + + it('... the given IRI matches one of the provided namespaces', () => { + const iri = 'http://example2.org/subject'; + const namespaces = { + ex: 'http://example.org/', + ex2: 'http://example2.org/', + ex3: 'http://example3.org/', + }; + const expectedAbbreviation = 'ex2:subject'; + + const result = (graphVisualizerService as any)._abbreviate(iri, namespaces); + + expectToBe(result, expectedAbbreviation); + }); + + it('... the given IRI matches multiple namespaces (using the first matching namespace)', () => { + const iri = 'http://example.com/subject'; + const namespaces = { + other: 'http://other.org/subject', + ex1: 'http://example.com/', + ex2: 'http://example.com/', + ex3: 'http://example.com/', + }; + const expectedAbbreviation = 'ex1:subject'; + + const result = (graphVisualizerService as any)._abbreviate(iri, namespaces); + + expect(result).toBe(expectedAbbreviation); + }); + }); + + describe('... should return a partially (incorrect) abbreviated IRI if', () => { + it('... the namespace does not have a trailing slash', () => { + const iri = 'http://example.org/subject'; + const namespaces = { ex: 'http://example.org' }; + const expectedAbbreviation = 'ex:/subject'; + + const result = (graphVisualizerService as any)._abbreviate(iri, namespaces); + + expectToBe(result, expectedAbbreviation); + }); + + it('... the namespace does not have a trailing hash', () => { + const iri = 'http://example.org#subject'; + const namespaces = { ex: 'http://example.org' }; + const expectedAbbreviation = 'ex:#subject'; + + const result = (graphVisualizerService as any)._abbreviate(iri, namespaces); + + expectToBe(result, expectedAbbreviation); + }); + + it('... the namespace matches the IRI exactly', () => { + const iri = 'http://example.org/'; + const namespaces = { ex: 'http://example.org/' }; + const expectedAbbreviation = 'ex:'; + + const result = (graphVisualizerService as any)._abbreviate(iri, namespaces); + + expectToBe(result, expectedAbbreviation); + }); + }); + + describe('... should return the original IRI if', () => { + it('... the given IRI does not start with http', () => { + const notFullIri = 'ex:subject'; + const namespaces = { ex: 'http://example.org/' }; + const expectedAbbreviation = 'ex:subject'; + + const result = (graphVisualizerService as any)._abbreviate(notFullIri, namespaces); + + expectToBe(result, expectedAbbreviation); + }); + + it('... no namespaces are provided', () => { + const iri = 'http://example.org/subject'; + const namespaces = {}; + const expectedAbbreviation = 'http://example.org/subject'; + + const result = (graphVisualizerService as any)._abbreviate(iri, namespaces); + + expectToBe(result, expectedAbbreviation); + }); + + it('... the given namespaces are undefined or null', () => { + const iri = 'http://example.org/subject'; + const namespaces = undefined; + const expectedAbbreviation = 'http://example.org/subject'; + + const result = (graphVisualizerService as any)._abbreviate(iri, namespaces); + + expectToBe(result, expectedAbbreviation); + + const namespaces2 = null; + + const result2 = (graphVisualizerService as any)._abbreviate(iri, namespaces2); + + expectToBe(result2, expectedAbbreviation); + }); + + it('... the given IRI does not match a given namespace', () => { + const notMatchingIri = 'http://other.org/subject'; + const namespaces = { ex: 'http://example.org/' }; + const expectedAbbreviation = 'http://other.org/subject'; + + const result = (graphVisualizerService as any)._abbreviate(notMatchingIri, namespaces); + + expectToBe(result, expectedAbbreviation); + }); + + it('... the given IRI does not match any of the provided namespaces', () => { + const notMatchingIri = 'http://other.org/subject'; + const namespaces = { + ex: 'http://example.org/', + ex2: 'http://example2.org/', + ex3: 'http://example3.org/', + }; + const expectedAbbreviation = 'http://other.org/subject'; + + const result = (graphVisualizerService as any)._abbreviate(notMatchingIri, namespaces); + + expectToBe(result, expectedAbbreviation); + }); + + it('... the given IRI does not match a given namespace respecting case sensitivity', () => { + const iri = 'http://example.org/subject'; + const namespaces = { ex: 'http://EXAMPLE.org/' }; + const expectedAbbreviation = 'http://example.org/subject'; + + const result = (graphVisualizerService as any)._abbreviate(iri, namespaces); + + expectToBe(result, expectedAbbreviation); + }); + + it('... the given IRI only partially matches a given namespace', () => { + const iri = 'http://example.org#subject'; + const namespaces = { ex: 'http://example.org/' }; + const expectedAbbreviation = 'http://example.org#subject'; + + const result = (graphVisualizerService as any)._abbreviate(iri, namespaces); + + expectToBe(result, expectedAbbreviation); + }); + }); + + it('... should return `undefined` if the given IRI is undefined', () => { + const iri = undefined; + const namespaces = { ex: 'http://example.org/' }; + + const result = (graphVisualizerService as any)._abbreviate(iri, namespaces); + + expect(result).toBeUndefined(); + }); + + it('... should return `null` if the given IRI is null', () => { + const iri = null; + const namespaces = { ex: 'http://example.org/' }; + + const result = (graphVisualizerService as any)._abbreviate(iri, namespaces); + + expectToBe(result, null); + }); + }); + + describe('#_createStore()', () => { + it('... should have a method `_createStore`', () => { + expect((graphVisualizerService as any)._createStore).toBeDefined(); + }); + + it('... should return a Promise of an rdfstore instance', async () => { + await expectAsync((graphVisualizerService as any)._createStore(global.rdfstore)).toBeResolved(); + }); + + it('... should return a Promise of an rdfstore instance with load and execute methods', async () => { + const result = await (graphVisualizerService as any)._createStore(global.rdfstore); + + expect(result).toBeDefined(); + expectToBe(result.constructor.name, 'Store'); + expect(result.load).toBeDefined(); + expect(result.execute).toBeDefined(); + }); + + it('... should reject if store.create encounters an error', async () => { + const expectedError = new Error('Test error'); + const mockStore = { + create: callback => { + callback(expectedError, null); + }, + }; + + const storeSpy = spyOn(mockStore, 'create').and.callThrough(); + + await expectAsync((graphVisualizerService as any)._createStore(mockStore)).toBeRejectedWith(expectedError); + + expectSpyCall(storeSpy, 1, [jasmine.any(Function)]); + }); + }); + + describe('#_executeQuery()', () => { + let store; + + beforeEach(async () => { + store = await (graphVisualizerService as any)._createStore(global.rdfstore); + + let tripleStr = + '@prefix ex: . @prefix ex1: . @prefix ex2: .'; + + for (let i = 1; i <= 2; i++) { + tripleStr += ` . `; + } + + await (graphVisualizerService as any)._loadTriplesInStore(store, tripleStr); + }); + + it('... should have a method `_executeQuery`', () => { + expect((graphVisualizerService as any)._executeQuery).toBeDefined(); + }); + + it('... should resolve a construct response for a CONSTRUCT query', async () => { + const query = 'CONSTRUCT WHERE { ?s ?p ?o . }'; + const expectedQueryResult = [ + ' .', + ' .', + ]; + + const result = await (graphVisualizerService as any)._executeQuery(store, query); + + expectToBe(result.triples.length, 2); + result.triples.forEach((triple, index: number) => { + expectToBe(triple.toString().trim(), expectedQueryResult[index]); + }); + }); + + it('... should resolve a select response for a SELECT query', async () => { + const query = 'SELECT * WHERE { ?s ?p ?o . }'; + const expectedQueryResult = [ + { + s: { token: 'uri', value: 'http://example.org/subject1' }, + p: { token: 'uri', value: 'http://example.org/predicate1' }, + o: { token: 'uri', value: 'http://example.org/object1' }, + }, + { + s: { token: 'uri', value: 'http://example.org/subject2' }, + p: { token: 'uri', value: 'http://example.org/predicate2' }, + o: { token: 'uri', value: 'http://example.org/object2' }, + }, + ]; + + const result = await (graphVisualizerService as any)._executeQuery(store, query); + + expectToBe(result.length, 2); + result.forEach((triple, index: number) => { + expectToEqual(triple, expectedQueryResult[index]); + }); + }); + + it('... should reject if query is empty', async () => { + const emptyQuery = ''; + + await expectAsync((graphVisualizerService as any)._executeQuery(store, emptyQuery)).toBeRejected(); + }); + + it('... should reject and throw/log an error if store.execute encounters an error', async () => { + const expectedError = new Error('Test error'); + const mockStore = { + execute: (query, callback) => { + callback(expectedError, null); + }, + }; + + const storeSpy = spyOn(mockStore, 'execute').and.callThrough(); + + const testQuery = 'SELECT * WHERE { ?s ?p ?o }'; + + await expectAsync((graphVisualizerService as any)._executeQuery(mockStore, testQuery)).toBeRejectedWith( + expectedError + ); + + expectSpyCall(storeSpy, 1, [testQuery, jasmine.any(Function)]); + expectSpyCall(consoleSpy, 1, ['_executeQuery# got ERROR', expectedError]); + }); + }); + + describe('#_extractNamespacesFromString()', () => { + it('... should have a method `_extractNamespacesFromString`', () => { + expect((graphVisualizerService as any)._extractNamespacesFromString).toBeDefined(); + }); + + it('... should return an object with namespaces from a given turtle string', () => { + const turtleStr = + '@prefix ex: . @prefix ex2: . .'; + const expectedNamespaces = { ex: 'http://example.org/', ex2: 'http://example2.org' }; + + const result = (graphVisualizerService as any)._extractNamespacesFromString('TURTLE', turtleStr); + + expectToEqual(result, expectedNamespaces); + }); + + it('... should return an object with namespaces from a given SPARQL string', () => { + const sparqlStr = + 'PREFIX ex: . PREFIX ex2: . SELECT * WHERE { ?s ?p ?o }'; + const expectedNamespaces = { ex: 'http://example.org/', ex2: 'http://example2.org' }; + + const result = (graphVisualizerService as any)._extractNamespacesFromString('SPARQL', sparqlStr); + + expectToEqual(result, expectedNamespaces); + }); + + describe('... should return an empty object if', () => { + it('... the given string is empty', () => { + const emptyStr = ''; + const expectedNamespaces = {}; + + const result = (graphVisualizerService as any)._extractNamespacesFromString('TURTLE', emptyStr); + + expectToEqual(result, expectedNamespaces); + + const result2 = (graphVisualizerService as any)._extractNamespacesFromString('SPARQL', emptyStr); + + expectToEqual(result2, expectedNamespaces); + }); + + it('... the given string has no prefixes in TURTLE', () => { + const noPrefixTurtleStr = + ' .'; + const expectedNamespaces = {}; + + const result = (graphVisualizerService as any)._extractNamespacesFromString( + 'TURTLE', + noPrefixTurtleStr + ); + + expectToEqual(result, expectedNamespaces); + }); + + it('... the given string has no prefixes in SPARQL', () => { + const noPrefixSparqlStr = 'SELECT * WHERE { ?s ?p ?o }'; + const expectedNamespaces = {}; + + const result = (graphVisualizerService as any)._extractNamespacesFromString( + 'SPARQL', + noPrefixSparqlStr + ); + + expectToEqual(result, expectedNamespaces); + }); + }); + + it('... should throw an error if called with another type than TURTLE or SPARQL', () => { + const tripleStr = + '@prefix ex: . '; + const expectedError = 'The type must be TURTLE or SPARQL, but was: OTHER.'; + + expect(() => (graphVisualizerService as any)._extractNamespacesFromString('OTHER', tripleStr)).toThrowError( + expectedError + ); + }); + }); + + describe('#_extractQNamePrefixesFromSPARQLWhereClause()', () => { + it('... should have a method `_extractQNamePrefixesFromSPARQLWhereClause`', () => { + expect((graphVisualizerService as any)._extractQNamePrefixesFromSPARQLWhereClause).toBeDefined(); + }); + + it('... should return an empty array if no prefixes are in the where clause', () => { + const query = 'SELECT * WHERE { ?s ?p ?o . }'; + const expectedPrefixes = []; + + const result = (graphVisualizerService as any)._extractQNamePrefixesFromSPARQLWhereClause(query); + + expectToEqual(result, expectedPrefixes); + }); + + it('... should return an array of prefixes from the where clause', () => { + const query = 'SELECT * WHERE { ex:s ex1:p ex2:o .}'; + const expectedPrefixes = ['ex', 'ex1', 'ex2']; + + const result = (graphVisualizerService as any)._extractQNamePrefixesFromSPARQLWhereClause(query); + + expectToEqual(result, expectedPrefixes); + }); + + it('... should return an array of unique prefixes from the where clause', () => { + const query = 'SELECT * WHERE { ex:s ex1:p ex2:o . ex:s1 ex1:p1 ex2:o1 .}'; + const expectedPrefixes = ['ex', 'ex1', 'ex2']; + + const result = (graphVisualizerService as any)._extractQNamePrefixesFromSPARQLWhereClause(query); + + expectToEqual(result, expectedPrefixes); + }); + + it('... should return an array of unique prefixes from the where clause respecting case sensitivity', () => { + const query = + 'SELECT * WHERE { ex:s ex1:p ex2:o . Ex:s1 Ex1:p1 Ex2:o1 . EX:s2 EX1:p2 EX2:o2 . eX:s3 eX1:p3 eX2:o3 .}'; + const expectedPrefixes = ['ex', 'ex1', 'ex2', 'Ex', 'Ex1', 'Ex2', 'EX', 'EX1', 'EX2', 'eX', 'eX1', 'eX2']; + + const result = (graphVisualizerService as any)._extractQNamePrefixesFromSPARQLWhereClause(query); + + expectToEqual(result, expectedPrefixes); + }); + + it('... should find prefixes when no where keyword is given', () => { + const query = 'SELECT * { ex:s ex1:p ex2:o . ex:s1 ex1:p1 ex2:o1 .}'; + const expectedPrefixes = ['ex', 'ex1', 'ex2']; + + const result = (graphVisualizerService as any)._extractQNamePrefixesFromSPARQLWhereClause(query); + + expectToEqual(result, expectedPrefixes); + }); + + it('... should find prefixes starting with underscore, small letter or capital letter', () => { + const query = 'SELECT * WHERE { _:s Ex1:p EX2:o . ex:s1 ex1:p1 ex2:o1 .}'; + const expectedPrefixes = ['_', 'Ex1', 'EX2', 'ex', 'ex1', 'ex2']; + + const result = (graphVisualizerService as any)._extractQNamePrefixesFromSPARQLWhereClause(query); + + expectToEqual(result, expectedPrefixes); + }); + }); + + describe('#_loadTriplesInStore()', () => { + let store; + + beforeEach(async () => { + store = await (graphVisualizerService as any)._createStore(global.rdfstore); + }); + + it('... should have a method `_loadTriplesInStore`', () => { + expect((graphVisualizerService as any)._loadTriplesInStore).toBeDefined(); + }); + + it('... should load a single triple into the rdfstore', async () => { + const tripleStr = + '@prefix ex: . .'; + const expectedSize = 1; + + const size = await (graphVisualizerService as any)._loadTriplesInStore(store, tripleStr); + + expectToBe(size, expectedSize); + }); + + it('... should load multiple triples into the rdfstore', async () => { + const tripleStr = + '@prefix ex: . . ' + + ' ;' + + ' .'; + const expectedSize = 3; + + const size = await (graphVisualizerService as any)._loadTriplesInStore(store, tripleStr); + + expectToBe(size, expectedSize); + }); + + it('... should load a huge number of triples into the rdfstore', async () => { + let tripleStr = '@prefix ex: . '; + const expectedSize = 1000; + + for (let i = 0; i < expectedSize; i++) { + tripleStr += ` . `; + } + + const size = await (graphVisualizerService as any)._loadTriplesInStore(store, tripleStr); + + expectToBe(size, expectedSize); + }); + + it('... should load prefixed triples into the rdfstore', async () => { + const tripleStr = + '@prefix ex: . ' + + 'ex:subject ex:predicate ex:object. ' + + 'ex:subject2 ex:predicate2 ex:object2.'; + const expectedSize = 2; + + const size = await (graphVisualizerService as any)._loadTriplesInStore(store, tripleStr); + + expectToBe(size, expectedSize); + }); + + it('... should load triples without prefixes or URIs into the rdfstore', async () => { + const tripleStr = ' .'; + const expectedSize = 1; + + const size = await (graphVisualizerService as any)._loadTriplesInStore(store, tripleStr); + + expectToBe(size, expectedSize); + }); + + it('... should load triples with mimetype `text/turtle` by default (no mimetype given)', async () => { + const tripleStr = '@prefix ex: . ex:subject ex:predicate ex:object.'; + const expectedSize = 1; + + const size = await (graphVisualizerService as any)._loadTriplesInStore(store, tripleStr); + + expectToBe(size, expectedSize); + }); + + it('... should load triples with mimetype `text/turtle` if given', async () => { + const tripleStr = '@prefix ex: . ex:subject ex:predicate ex:object.'; + const mimeType = 'text/turtle'; + const expectedSize = 1; + + const size = await (graphVisualizerService as any)._loadTriplesInStore(store, tripleStr, mimeType); + + expectToBe(size, expectedSize); + }); + + it('... should load triples with mimetype `application/ld+json` if given', async () => { + const tripleStr = + '[{"@id":"http://example.org/object"},{"@id":"http://example.org/subject","http://example.org/predicate":[{"@id":"http://example.org/object"}]}]'; + const mimeType = 'application/ld+json'; + const expectedSize = 1; + + const size = await (graphVisualizerService as any)._loadTriplesInStore(store, tripleStr, mimeType); + + expectToBe(size, expectedSize); + }); + + it('... should reject and throw/log an error if no parser is found for the provided mimeType', async () => { + const tripleStr = '@prefix ex: . ex:subject ex:predicate ex:object.'; + const mimeType = 'application/rdf+xml'; + const expectedErrorMessage = `Cannot find parser for the provided media type:${mimeType}`; + const expectedError = new Error(expectedErrorMessage); + + await expectAsync( + (graphVisualizerService as any)._loadTriplesInStore(store, tripleStr, mimeType) + ).toBeRejectedWithError(expectedErrorMessage); + + expectSpyCall(consoleSpy, 1, ['_loadTriplesInStore# got ERROR', expectedError]); + }); + }); + + describe('_mapKeys', () => { + it('... should have a method `_mapKeys`', () => { + expect((graphVisualizerService as any)._mapKeys).toBeDefined(); + }); + + describe('... should return an empty object if', () => { + it('... the input object is empty', () => { + const inputObj = {}; + const keyMap = { + token: 'type', + type: 'datatype', + lang: 'xml:lang', + }; + + const result = (graphVisualizerService as any)._mapKeys(inputObj, keyMap); + + expectToEqual(result, {}); + }); + + it('... the input object is null', () => { + const inputObj = null; + const keyMap = { + token: 'type', + type: 'datatype', + lang: 'xml:lang', + }; + + const result = (graphVisualizerService as any)._mapKeys(inputObj, keyMap); + + expectToEqual(result, {}); + }); + + it('... the input object is undefined', () => { + const inputObj = undefined; + const keyMap = { + token: 'type', + type: 'datatype', + lang: 'xml:lang', + }; + + const result = (graphVisualizerService as any)._mapKeys(inputObj, keyMap); + + expectToEqual(result, {}); + }); + }); + + describe('... should return the original object if', () => { + it('... the new keys object is empty', () => { + const inputObj = { + key1: 'value1', + key2: 'value2', + }; + const keyMap = {}; + + const result = (graphVisualizerService as any)._mapKeys(inputObj, keyMap); + + expectToEqual(result, inputObj); + }); + + it('... the new keys object is null', () => { + const inputObj = { + key1: 'value1', + key2: 'value2', + }; + const keyMap = null; + + const result = (graphVisualizerService as any)._mapKeys(inputObj, keyMap); + + expectToEqual(result, inputObj); + }); + + it('... the new keys object is undefined', () => { + const inputObj = { + key1: 'value1', + key2: 'value2', + }; + const keyMap = undefined; + + const result = (graphVisualizerService as any)._mapKeys(inputObj, keyMap); + + expectToEqual(result, inputObj); + }); + }); + + it('... should return an object with mapped keys', () => { + const inputObj = { + key1: 'value1', + key2: 'value2', + }; + const keyMap = { + key1: 'key1Mapped', + key2: 'key2Mapped', + }; + const outputObj = { + key1Mapped: 'value1', + key2Mapped: 'value2', + }; + + const result = (graphVisualizerService as any)._mapKeys(inputObj, keyMap); + + expectToEqual(result, outputObj); + }); + + it('... should map token, type and lang keys in a given object', () => { + const inputObj = { + token: 'literal', + type: 'http://www.w3.org/2001/XMLSchema#string', + lang: 'en', + }; + const keyMap = { + token: 'type', + type: 'datatype', + lang: 'xml:lang', + }; + const outputObj = { + type: 'literal', + datatype: 'http://www.w3.org/2001/XMLSchema#string', + }; + outputObj['xml:lang'] = 'en'; + + const result = (graphVisualizerService as any)._mapKeys(inputObj, keyMap); + + expectToEqual(result, outputObj); + }); + }); + + describe('_prepareMappedBindings', () => { + it('... should have a method `_prepareMappedBindings`', () => { + expect((graphVisualizerService as any)._prepareMappedBindings).toBeDefined(); + }); + + it('... should return an array with mapped bindings and label', () => { + const selectResponse = [ + { + key1: { + token: 'uri', + value: 'https://edition.anton-webern.ch/webern-onto#Op25_1', + }, + key2: { + token: 'literal', + type: 'http://www.w3.org/2001/XMLSchema#integer', + value: '1', + }, + }, + ]; + const expectedMappedBindings = [ + { + key1: { + label: 'awg:Op25_1', + type: 'uri', + value: 'https://edition.anton-webern.ch/webern-onto#Op25_1', + }, + key2: { + datatype: 'http://www.w3.org/2001/XMLSchema#integer', + label: 1, + type: 'literal', + value: '1', + }, + }, + ]; + + const result = (graphVisualizerService as any)._prepareMappedBindings(selectResponse); + + expectToEqual(result, expectedMappedBindings); + }); + + it('... should return a prefixed label for a URI value', () => { + const selectResponse = [ + { + key1: { + token: 'uri', + value: 'https://edition.anton-webern.ch/webern-onto#Op25_1', + }, + }, + { + key1: { + token: 'uri', + value: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', + }, + }, + ]; + const expectedMappedBindings = [ + { + key1: { + label: 'awg:Op25_1', + type: 'uri', + value: 'https://edition.anton-webern.ch/webern-onto#Op25_1', + }, + }, + { + key1: { + label: 'rdf:type', + type: 'uri', + value: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', + }, + }, + ]; + + const result = (graphVisualizerService as any)._prepareMappedBindings(selectResponse); + + expectToEqual(result, expectedMappedBindings); + }); + + describe('... should return a number label for', () => { + it('... literal integer values', () => { + const selectResponse = [ + { + key1: { + token: 'literal', + type: 'http://www.w3.org/2001/XMLSchema#integer', + value: '1', + }, + }, + ]; + const expectedMappedBindings = [ + { + key1: { + datatype: 'http://www.w3.org/2001/XMLSchema#integer', + label: 1, + type: 'literal', + value: '1', + }, + }, + ]; + + const result = (graphVisualizerService as any)._prepareMappedBindings(selectResponse); + + expectToEqual(result, expectedMappedBindings); + }); + + it('... literal non-negative integer values', () => { + const selectResponse = [ + { + key1: { + token: 'literal', + type: 'http://www.w3.org/2001/XMLSchema#nonNegativeInteger', + value: '1', + }, + }, + ]; + const expectedMappedBindings = [ + { + key1: { + datatype: 'http://www.w3.org/2001/XMLSchema#nonNegativeInteger', + label: 1, + type: 'literal', + value: '1', + }, + }, + ]; + + const result = (graphVisualizerService as any)._prepareMappedBindings(selectResponse); + + expectToEqual(result, expectedMappedBindings); + }); + }); + + it('... should trigger `_mapKeys` method for each key', () => { + const selectResponse = [ + { + key1: { + token: 'uri', + value: 'https://edition.anton-webern.ch/webern-onto#Op25_1', + }, + key2: { + token: 'literal', + type: 'http://www.w3.org/2001/XMLSchema#integer', + value: '1', + }, + }, + ]; + const mapKeysSpy = spyOn(graphVisualizerService as any, '_mapKeys').and.callThrough(); + + (graphVisualizerService as any)._prepareMappedBindings(selectResponse); + + expectSpyCall(mapKeysSpy, 2); + }); + }); + + describe('#_prepareConstructResponse()', () => { + it('... should have a method `_prepareConstructResponse`', () => { + expect((graphVisualizerService as any)._prepareConstructResponse).toBeDefined(); + }); + + describe('should flatten and abbreviate the given StoreTriples', () => { + it('... according to the given namespaces', () => { + const triples: RDFStoreConstructResponseTriple[] = expectedConstructResponseTriples; + const namespaces = { + ex: 'http://example.org/', + exs: 'https://example.org/', + }; + + const result = (graphVisualizerService as any)._prepareConstructResponse(triples, namespaces); + + expectToBe(result[0].subject, 'ex:subject1'); + expectToBe(result[0].predicate, 'ex:predicate1'); + expectToBe(result[0].object, 'ex:object1'); + + expectToBe(result[1].subject, 'exs:subject2'); + expectToBe(result[1].predicate, 'exs:predicate2'); + expectToBe(result[1].object, 'exs:object2'); + + expectToEqual(result, [ + { + subject: 'ex:subject1', + predicate: 'ex:predicate1', + object: 'ex:object1', + }, + { + subject: 'exs:subject2', + predicate: 'exs:predicate2', + object: 'exs:object2', + }, + ]); + }); + + it('... if mimetype `text/turtle` is given', () => { + const triples: RDFStoreConstructResponseTriple[] = expectedConstructResponseTriples; + const namespaces = { + ex: 'http://example.org/', + exs: 'https://example.org/', + }; + const mimetypeTurtle = 'text/turtle'; + + const result = (graphVisualizerService as any)._prepareConstructResponse( + triples, + namespaces, + mimetypeTurtle + ); + + expectToBe(result[0].subject, 'ex:subject1'); + expectToBe(result[0].predicate, 'ex:predicate1'); + expectToBe(result[0].object, 'ex:object1'); + + expectToBe(result[1].subject, 'exs:subject2'); + expectToBe(result[1].predicate, 'exs:predicate2'); + expectToBe(result[1].object, 'exs:object2'); + + expectToEqual(result, [ + { + subject: 'ex:subject1', + predicate: 'ex:predicate1', + object: 'ex:object1', + }, + { + subject: 'exs:subject2', + predicate: 'exs:predicate2', + object: 'exs:object2', + }, + ]); + }); + + it('... if no mimetype is given (`text/turtle` applied by default)', () => { + const triples: RDFStoreConstructResponseTriple[] = expectedConstructResponseTriples; + const namespaces = { + ex: 'http://example.org/', + exs: 'https://example.org/', + }; + const mimetypeEmpty = ''; + + const result = (graphVisualizerService as any)._prepareConstructResponse( + triples, + namespaces, + mimetypeEmpty + ); + + expectToBe(result[0].subject, 'ex:subject1'); + expectToBe(result[0].predicate, 'ex:predicate1'); + expectToBe(result[0].object, 'ex:object1'); + + expectToBe(result[1].subject, 'exs:subject2'); + expectToBe(result[1].predicate, 'exs:predicate2'); + expectToBe(result[1].object, 'exs:object2'); + + expectToEqual(result, [ + { + subject: 'ex:subject1', + predicate: 'ex:predicate1', + object: 'ex:object1', + }, + { + subject: 'exs:subject2', + predicate: 'exs:predicate2', + object: 'exs:object2', + }, + ]); + }); + + it('... should trigger `_abbreviate` method for each part of a triple', () => { + const triples: RDFStoreConstructResponseTriple[] = expectedConstructResponseTriples; + const namespaces = { + ex: 'http://example.org/', + exs: 'https://example.org/', + }; + const abbreviateSpy = spyOn(graphVisualizerService as any, '_abbreviate').and.callThrough(); + + (graphVisualizerService as any)._prepareConstructResponse(triples, namespaces); + + const tripleLength = triples.length; + const tripleKeysLength = Object.keys(triples[0]).length; + const expectedCalls = tripleLength * tripleKeysLength; + + expectSpyCall(abbreviateSpy, expectedCalls); + }); + }); + + describe('should flatten, but not abbreviate the given StoreTriples', () => { + it('... if no namespaces are provided', () => { + const triples: RDFStoreConstructResponseTriple[] = expectedConstructResponseTriples; + const namespaces = {}; + + const result = (graphVisualizerService as any)._prepareConstructResponse(triples, namespaces); + + expectToBe(result[0].subject, 'http://example.org/subject1'); + expectToBe(result[0].predicate, 'http://example.org/predicate1'); + expectToBe(result[0].object, 'http://example.org/object1'); + + expectToBe(result[1].subject, 'https://example.org/subject2'); + expectToBe(result[1].predicate, 'https://example.org/predicate2'); + expectToBe(result[1].object, 'https://example.org/object2'); + + expectToEqual(result, [ + { + subject: 'http://example.org/subject1', + predicate: 'http://example.org/predicate1', + object: 'http://example.org/object1', + }, + { + subject: 'https://example.org/subject2', + predicate: 'https://example.org/predicate2', + object: 'https://example.org/object2', + }, + ]); + }); + + it('... if namespaces do not match the IRIs', () => { + const triples: RDFStoreConstructResponseTriple[] = expectedConstructResponseTriples; + const namespaces = { + ot: 'http://other.org/', + }; + + const result = (graphVisualizerService as any)._prepareConstructResponse(triples, namespaces); + + expectToBe(result[0].subject, 'http://example.org/subject1'); + expectToBe(result[0].predicate, 'http://example.org/predicate1'); + expectToBe(result[0].object, 'http://example.org/object1'); + + expectToBe(result[1].subject, 'https://example.org/subject2'); + expectToBe(result[1].predicate, 'https://example.org/predicate2'); + expectToBe(result[1].object, 'https://example.org/object2'); + + expectToEqual(result, [ + { + subject: 'http://example.org/subject1', + predicate: 'http://example.org/predicate1', + object: 'http://example.org/object1', + }, + { + subject: 'https://example.org/subject2', + predicate: 'https://example.org/predicate2', + object: 'https://example.org/object2', + }, + ]); + }); + + it('... if a given mimetype is not `text/turtle`', () => { + const triples: RDFStoreConstructResponseTriple[] = expectedConstructResponseTriples; + const namespaces = { + ex: 'http://example.org/', + exs: 'https://example.org/', + }; + const mimetypePlain = 'text/plain'; + + const result = (graphVisualizerService as any)._prepareConstructResponse( + triples, + namespaces, + mimetypePlain + ); + + expectToBe(result[0].subject, 'http://example.org/subject1'); + expectToBe(result[0].predicate, 'http://example.org/predicate1'); + expectToBe(result[0].object, 'http://example.org/object1'); + + expectToBe(result[1].subject, 'https://example.org/subject2'); + expectToBe(result[1].predicate, 'https://example.org/predicate2'); + expectToBe(result[1].object, 'https://example.org/object2'); + + expectToEqual(result, [ + { + subject: 'http://example.org/subject1', + predicate: 'http://example.org/predicate1', + object: 'http://example.org/object1', + }, + { + subject: 'https://example.org/subject2', + predicate: 'https://example.org/predicate2', + object: 'https://example.org/object2', + }, + ]); + }); + }); + }); + + describe('_prepareSelectResponse', () => { + it('... should have a method `_prepareSelectResponse`', () => { + expect((graphVisualizerService as any)._prepareSelectResponse).toBeDefined(); + }); + + it('... should return a QueryResult object with mapped bindings and vars', () => { + const selectResponse = [ + { + key1: { + token: 'uri', + value: 'https://edition.anton-webern.ch/webern-onto#Op25_1', + }, + key2: { + token: 'literal', + type: 'http://www.w3.org/2001/XMLSchema#integer', + value: '1', + }, + }, + ]; + const expectedQueryResult = { + status: 200, + data: { + head: { + vars: ['key1', 'key2'], + }, + body: { + bindings: [ + { + key1: { + label: 'awg:Op25_1', + type: 'uri', + value: 'https://edition.anton-webern.ch/webern-onto#Op25_1', + }, + key2: { + datatype: 'http://www.w3.org/2001/XMLSchema#integer', + label: 1, + type: 'literal', + value: '1', + }, + }, + ], + }, + }, + }; + + const result = (graphVisualizerService as any)._prepareSelectResponse(selectResponse); + + expectToEqual(result, expectedQueryResult); + }); + + it('... should return status=400 and `Query returned no results` if selectRespone is empty', () => { + const selectResponse = []; + const expectedResponse = { + status: 400, + data: 'Query returned no results', + }; + + const result = (graphVisualizerService as any)._prepareSelectResponse(selectResponse); + + expectToEqual(result, expectedResponse); + }); + + it('... should return status=404 and undefined if selectRespone is undefined or null', () => { + const selectResponse = undefined; + const expectedResponse = { + status: 404, + data: undefined, + }; + + const result = (graphVisualizerService as any)._prepareSelectResponse(selectResponse); + + expectToEqual(result, expectedResponse); + + const selectResponse2 = null; + + const result2 = (graphVisualizerService as any)._prepareSelectResponse(selectResponse2); + + expectToEqual(result2, expectedResponse); + }); + + it('... should trigger `_prepareMappedBindings` method', () => { + const selectResponse = [ + { + key1: { + token: 'uri', + value: 'https://edition.anton-webern.ch/webern-onto#Op25_1', + }, + key2: { + token: 'literal', + type: 'http://www.w3.org/2001/XMLSchema#integer', + value: '1', + }, + }, + ]; + + const prepareMappedBindingsSpy = spyOn( + graphVisualizerService as any, + '_prepareMappedBindings' + ).and.callThrough(); + + (graphVisualizerService as any)._prepareSelectResponse(selectResponse); - // TODO: check if the result is a Promise of Triple[] and Namespace[] + expectSpyCall(prepareMappedBindingsSpy, 1, [selectResponse]); }); }); }); diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/services/graph-visualizer.service.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/services/graph-visualizer.service.ts index fa996a066..f2aa25be1 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/services/graph-visualizer.service.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/services/graph-visualizer.service.ts @@ -12,7 +12,7 @@ import { NamespaceType, PrefixForm, QueryResult, - QueryTypeIndex, + QueryResultBindings, RDFStoreConstructResponse, RDFStoreConstructResponseTriple, RDFStoreSelectResponse, @@ -50,98 +50,10 @@ export class GraphVisualizerService { */ constructor(private prefixPipe: PrefixPipe) {} - /** - * Public method: parseTripleString. - * - * It parses the triples from a given triple string. - * - * @param {string} triples The given triple string. - * - * @returns {Promise<{triples; namespaces}>} A promise of the parsed triples. - */ - parseTripleString(triples: string): Promise<{ triples; namespaces } | unknown> { - const parser = new N3.Parser(); - const jsonTriples = []; - - return new Promise((resolve, reject) => { - parser.parse(triples, (err, triple, namespaceValues) => { - if (triple) { - jsonTriples.push(triple); - } else { - resolve({ triples: jsonTriples, namespaces: namespaceValues }); - } - if (err) { - reject(err); - } - }); - }); - } - - /** - * Public method: limitTriples. - * - * It limits a given array of triples by a given limit. - * - * @param {Triple[]} triples The given triples array. - * @param {number} limit The given limit. - * - * @returns {Triple[]} The array of limited triples. - */ - limitTriples(triples: Triple[], limit: number): Triple[] { - if (!triples) { - return []; - } - if (triples.length > limit) { - return triples.slice(0, limit); - } else { - return triples; - } - } - - /** - * Public method: abbreviateTriples. - * - * It abbreviates the given triples according to the given namespaces. - * - * @param {RDFStoreConstructResponseTriple[]} storeTriples The given triples from the rdf construct response. - * @param {string} namespaces The given namespaces. - * @param {string} [mimeType] The given optional mimeType. - * - * @returns {Triple[]} The array of abbreviated triples. - */ - abbreviateTriples( - storeTriples: RDFStoreConstructResponseTriple[], - namespaces: Namespace, - mimeType?: string - ): Triple[] { - if (!mimeType) { - mimeType = 'text/turtle'; - } - return storeTriples.map((storeTriple: RDFStoreConstructResponseTriple) => { - let s: string = storeTriple.subject.nominalValue; - let p: string = storeTriple.predicate.nominalValue; - let o: string = storeTriple.object.nominalValue; - - // Abbreviate turtle format - if (mimeType === 'text/turtle') { - if (this._abbreviate(s, namespaces) != null) { - s = this._abbreviate(s, namespaces); - } - if (this._abbreviate(p, namespaces) != null) { - p = this._abbreviate(p, namespaces); - } - if (this._abbreviate(o, namespaces) != null) { - o = this._abbreviate(o, namespaces); - } - } - return { subject: s, predicate: p, object: o }; - }); - } - /** * Public method: checkNamespacesInQuery. * - * It checks the existing namespaces and qNames in a SPARQL query + * It checks the existing namespaces and prefixes in a SPARQL query * and appends missing prefix declarations, if possible, from the Turtle string. * * @param {string} queryStr The given SPARQL query string. @@ -153,53 +65,27 @@ export class GraphVisualizerService { if (!queryStr || !turtleStr) { return undefined; } - // Get namespaces from Turtle triples const turtleNamespaces: Namespace = this._extractNamespacesFromString(NamespaceType.TURTLE, turtleStr); - // Get namespaces from SPARQL query const sparqlNamespaces: Namespace = this._extractNamespacesFromString(NamespaceType.SPARQL, queryStr); - // Get qNames used in the SPARQL query WHERE clause - const qNames: string[] = this._extractQNamesFromSPARQLWhereClause(queryStr); + const sparqlPrefixes: string[] = this._extractQNamePrefixesFromSPARQLWhereClause(queryStr); + const sparqlNamespaceKeys = new Set(Object.keys(sparqlNamespaces)); - // Get keys of namespace objects - const turtleNamespaceKeys = Object.keys(turtleNamespaces); - const sparqlNamespaceKeys = Object.keys(sparqlNamespaces); let missingNamespacesStr = ''; - // Loop over namespaces from Turtle prefix clause - turtleNamespaceKeys.forEach(key => { - // If namespace is missing in SPARQL header, add them from Turtle - if (sparqlNamespaceKeys.indexOf(key) === -1) { - missingNamespacesStr += `PREFIX ${key} ${turtleNamespaces[key]}\n`; + // Merge turtle namespaces with those from SPARQL WHERE clause (expanded if any) + // And add missing prefixes to the SPARQL query + [ + ...Object.entries(turtleNamespaces), + ...sparqlPrefixes.map(prefix => [prefix, this.prefixPipe.transform(prefix, PrefixForm.LONG)]), + ].forEach(([key, value]) => { + if (!sparqlNamespaceKeys.has(key) && key !== value) { + missingNamespacesStr += `PREFIX ${key}: <${value}>\n`; + } else if (key === value) { + console.error(`Prefix '${key}' is unknown. Please provide a declaration.`); } }); - // Loop over existing qNames from SPARQL query - if (qNames.length > 0) { - qNames.forEach(qName => { - // If prefix is not in the list... - if (sparqlNamespaceKeys.indexOf(qName) === -1) { - // TODO: Warnings should go into error messages - console.warn( - `Prefix '${qName}' not declared in SPARQL and/or Turtle header. Searching in default namespaces...` - ); - - const defaultNamespace = this.prefixPipe.transform(qName, PrefixForm.LONG); - if (defaultNamespace !== qName) { - const missingPrefix = `PREFIX ${qName} <${defaultNamespace}>\n`; - missingNamespacesStr += missingPrefix; - console.warn(`Added '${missingPrefix}' to SPARQL prefixes from list of default namespaces.`); - } else { - console.warn(`'${qName}' is unknown. Please provide a declaration.`); - } - } - }); - } - - if (missingNamespacesStr !== '') { - queryStr = missingNamespacesStr + queryStr; - } - - return queryStr; + return missingNamespacesStr + queryStr; } /** @@ -224,7 +110,7 @@ export class GraphVisualizerService { mimeType = 'text/turtle'; } - return this._createStore() + return this._createStore(rdfstore) .then(store => { this._store = store; @@ -242,12 +128,11 @@ export class GraphVisualizerService { // Reformat data if construct query if (queryType === 'construct') { const response = res as RDFStoreConstructResponse; - // Get namespaces - return this._getNamespaces(ttlString).then((namespaces: Namespace) => - // Process triples - this.abbreviateTriples(response.triples, namespaces, mimeType) - ); + const namespaces = this._extractNamespacesFromString(NamespaceType.TURTLE, ttlString); + const constructResponse = this._prepareConstructResponse(response.triples, namespaces, mimeType); + return constructResponse; } + return undefined; }); } @@ -261,47 +146,70 @@ export class GraphVisualizerService { * * @returns {string} The query type. */ - getQuerytype(query: string): string { - let keyWords: QueryTypeIndex[] = [ - { queryType: 'select', index: -1 }, - { queryType: 'construct', index: -1 }, - { queryType: 'ask', index: -1 }, - { queryType: 'count', index: -1 }, - { queryType: 'describe', index: -1 }, - { queryType: 'insert', index: -1 }, - { queryType: 'delete', index: -1 }, - ]; - - // Get indexes and set a variable if at least one matches + store lowest index - let match = false; // Set to true if some keyword match is found - let low = Infinity; - - keyWords = keyWords.map(item => { - item.index = query.toLowerCase().indexOf(item.queryType); - if (item.index !== -1) { - match = true; - if (item.index < low) { - low = item.index; - } + getQuerytype(query: string): string | null { + const queryTypes = ['select', 'construct', 'ask', 'count', 'describe', 'insert', 'delete']; + + let lowestIndex = Infinity; + let foundType: string | null = null; + + queryTypes.forEach(type => { + const index = query.toLowerCase().indexOf(type); + if (index !== -1 && index < lowestIndex) { + lowestIndex = index; + foundType = type; } - return item; }); - // If none of the keywords match, return null - if (!match) { + if (foundType === null) { return null; } - // If more keywords exist in one query, take the one with the lowest index (first in string) - const lowest: QueryTypeIndex = keyWords.find(item => item.index === low); - - let type: string = lowest.queryType; + return foundType === 'insert' || foundType === 'delete' ? 'update' : foundType; + } - if (type === 'insert' || type === 'delete') { - type = 'update'; + /** + * Public method: limitTriples. + * + * It limits a given array of triples by a given limit. + * + * @param {Triple[]} triples The given triples array. + * @param {number} limit The given limit. + * + * @returns {Triple[]} The array of limited triples. + */ + limitTriples(triples: Triple[], limit: number): Triple[] { + if (!triples) { + return []; } + return triples.length > limit ? triples.slice(0, limit) : triples; + } - return type; + /** + * Public method: parseTripleString. + * + * It parses the triples from a given triple string. + * + * @param {string} triples The given triple string. + * + * @returns {Promise<{triples; namespaces}>} A promise of the parsed triples. + */ + parseTripleString(triples: string): Promise<{ quads: N3.DataFactory.quad[]; namespaces: N3.DataFactory.prefixes }> { + const parser = new N3.Parser(); + const jsonTriples = []; + + return new Promise((resolve, reject) => { + parser.parse(triples, (error, quad, prefixes) => { + if (error) { + reject(error); + return; + } + if (quad) { + jsonTriples.push(quad); + } else { + resolve({ quads: jsonTriples, namespaces: prefixes }); + } + }); + }); } /** @@ -315,34 +223,35 @@ export class GraphVisualizerService { * @returns {string} The abbreviated or original iri string. */ private _abbreviate(iri: string, namespaces: Namespace): string { - let newVal: string = iri; - // If IRI has 'http' or 'https in its name, continue - if (iri.indexOf('http') !== -1) { - // Loop over namespaces - Object.entries(namespaces).forEach(([key, value]) => { - // If the IRI has the prefixed namespace in its name, return it - if (iri.indexOf(value) !== -1) { - newVal = iri.replace(value, key + ':'); - } - }); + if (!iri?.startsWith('http') || !namespaces) { + return iri; } - return newVal; + + for (const [namespaceKey, namespaceValue] of Object.entries(namespaces)) { + if (iri.includes(namespaceValue)) { + return iri.replace(namespaceValue, namespaceKey + ':'); + } + } + + return iri; } /** * Private method: _createStore. * - * It creates an instance of the triple store. + * It creates an instance of the rdfstore. + * + * @param {typeof rdfstore} store The given rdfstore. * - * @returns {Promise} A promise of the triple store instance. + * @returns {Promise} A promise of the rdfstore instance. */ - private _createStore(): Promise { + private _createStore(store: typeof rdfstore): Promise { return new Promise((resolve, reject) => { - rdfstore.create((err, store) => { + store.create((err, createdStore) => { if (err) { reject(err); } - resolve(store); + resolve(createdStore); }); }); } @@ -375,127 +284,57 @@ export class GraphVisualizerService { * It extracts the namespaces (qname: ) of a given type (SPARQL, TURTLE) * from a given string. * - * @param {string} str The given string. * @param {NamespaceType} type The given namespace type. + * @param {string} str The given string. * - * @returns {Promise} A promise of the namespaces. + * @returns {Namespace} A namespace object. */ - private _extractNamespacesFromString(type: NamespaceType, str: string) { - // Replace all whitespace characters with a single space and split by space - // Remove empty values - const arr = str - .toLowerCase() - .replace(/\s/g, ' ') - .split(' ') - .filter(el => el !== ''); - - let prefixStr; - + private _extractNamespacesFromString(type: NamespaceType, str: string): Namespace { + let regex: RegExp; switch (type) { - case NamespaceType.TURTLE: { - prefixStr = '@prefix'.toLowerCase(); + case NamespaceType.TURTLE: + regex = /@prefix\s+(\w+):\s+<([^>]+)>/g; break; - } - case NamespaceType.SPARQL: { - prefixStr = 'PREFIX'.toLowerCase(); + case NamespaceType.SPARQL: + regex = /PREFIX\s+(\w+):\s+<([^>]+)>/g; break; - } - default: { - // This branch should not be reached + default: const exhaustiveCheck: never = type; throw new Error(`The type must be TURTLE or SPARQL, but was: ${exhaustiveCheck}.`); - } } - // Get index of all occurrences of prefix string - const prefixIndexArray = arr.reduce((a, e, i) => { - if (e === prefixStr) { - a.push(i); - } - return a; - }, []); - - // Create object of qNames and namespaceNames - const obj = {}; - prefixIndexArray.forEach(prefixIndex => { - const qName = arr[prefixIndex + 1]; - let namespaceName = arr[prefixIndex + 2]; - // Remove final dot if there is no space between namespace and dot - if (namespaceName.at(-1) === '.') { - namespaceName = namespaceName.slice(0, -1); - } - obj[qName] = namespaceName; - }); + const namespaces: Namespace = {}; + for (const match of str.matchAll(regex)) { + const [_, prefix, namespaceName] = match; + namespaces[prefix] = namespaceName; + } - return obj; + return namespaces; } /** - * Private method: _extractQNamesFromSPARQLWhereClause. + * Private method: _extractQNamePrefixesFromSPARQLWhereClause. * - * It identifies the qNames that are used in the WHERE clause of a SPARQL query. + * It identifies the qname prefixes that are used in the WHERE clause of a SPARQL query. * * @param {string} query The given query string. * - * @returns {string[]} A string array of the used qNames. + * @returns {string[]} A string array of the used qname prefixes. */ - private _extractQNamesFromSPARQLWhereClause(query: string): string[] { - let m; - let queryStr = query.toLowerCase(); - let start = 0; - const qNames: string[] = []; - const regex = /\b[a-zA-Z]{2,15}:/g; - const where = 'WHERE {'.toLowerCase(); + private _extractQNamePrefixesFromSPARQLWhereClause(query: string): string[] { + const where = 'WHERE {'; + const regex = /\b([a-zA-Z_][a-zA-Z0-9._-]{0,15}):/g; // Find WHERE clause - if (queryStr.includes(where)) { - start = queryStr.indexOf(where) + where.length; - } - - // Remove everything before WHERE clause from query string - queryStr = queryStr.slice(start); - - // Find prefixes in query - // eslint-disable-next-line no-cond-assign - while ((m = regex.exec(queryStr)) !== null) { - // This is necessary to avoid infinite loops with zero-width matches - if (m.index === regex.lastIndex) { - regex.lastIndex++; - } + const start = query.toLowerCase().indexOf(where.toLowerCase()); + const queryStr = start !== -1 ? query.slice(start) : query; - // The result can be accessed through the `m`-variable. - m.forEach(match => { - if (qNames.indexOf(match) === -1) { - qNames.push(match); - } - }); - } - return qNames; - } - - /** - * Private method: _getNamespaces. - * - * It extracts the namespaces from a given triple string. - * - * @param {string} triples The given triple string. - * - * @returns {Promise} A promise of the namespaces. - */ - private _getNamespaces(triples: string): Promise { - // Parse triples - const parser = new N3.Parser(); + // Find prefixes in query using matchAll + const matches = queryStr.matchAll(regex); + // Use captured group (index 1) to return prefixes without the colon + const prefixes = new Set(Array.from(matches, match => match[1])); - return new Promise((resolve, reject) => { - parser.parse(triples, (err, triple, prefixes) => { - if (!triple) { - resolve(prefixes); - } - if (err) { - reject(err); - } - }); - }); + return Array.from(prefixes); } /** @@ -515,9 +354,9 @@ export class GraphVisualizerService { } return new Promise((resolve, reject) => { - store.load(mimeType, triples, (err, size) => { + store.load(mimeType, triples, (err, size: number) => { if (err) { - console.error('_loadTriplesInStore# got error', err); + console.error('_loadTriplesInStore# got ERROR', err); reject(err); } resolve(size); @@ -530,17 +369,100 @@ export class GraphVisualizerService { * * It maps the keys of a given key-value paired object to given newKeys. * - * @param {[key:string]: string} obj The given obj. - * @param {[key:string]: string} newKeys The given new keys. + * @param {Record} obj The given object. + * @param {Record} newKeysObj The given new keys object. * - * @returns {[key:string]: string} An object with the new keys. + * @returns {Record} An object with the new keys. */ - private _mapKeys(obj: { [key: string]: string }, newKeys: { [key: string]: string }): { [key: string]: string } { - const keyValues = Object.keys(obj).map(key => { - const newKey = newKeys[key] || key; - return { [newKey]: obj[key] }; + private _mapKeys(obj: Record, keyMap: Record): Record { + if (!obj) { + return {}; + } + if (!keyMap) { + return obj; + } + return Object.entries(obj).reduce( + (acc, [key, value]) => { + const newKey = keyMap[key] || key; + acc[newKey] = value; + return acc; + }, + {} as { [key: string]: string } + ); + } + + /** + * Private method: _prepareMappedBindings. + * + * It prepares the bindings with mapped keys and label of a given select response. + * + * @param {RDFStoreSelectResponse} selectResponse The given select response. + * + * @returns {QueryResultBindings[]} The array of bindings. + */ + private _prepareMappedBindings(selectResponse: RDFStoreSelectResponse): QueryResultBindings[] { + const xmlsInteger = 'http://www.w3.org/2001/XMLSchema#integer'; + const xmlsNonNegativeInteger = 'http://www.w3.org/2001/XMLSchema#nonNegativeInteger'; + const keyMap = { + token: 'type', + type: 'datatype', + lang: 'xml:lang', + }; + + return selectResponse.map(item => { + const newItem: Record = {}; + + Object.entries(item).forEach(([itemEntryKey, itemEntryValue]) => { + // Map keys + newItem[itemEntryKey] = this._mapKeys(itemEntryValue, keyMap); + + // Set label + const { value, type, datatype = '' } = newItem[itemEntryKey]; + newItem[itemEntryKey]['label'] = + type === 'literal' && (datatype === xmlsInteger || datatype === xmlsNonNegativeInteger) + ? +value + : this.prefixPipe.transform(value, PrefixForm.SHORT); + }); + return newItem; + }); + } + + /** + * Private method: _prepareConstructResponse. + * + * It prepares the triples of the construct response. + * + * @param {RDFStoreConstructResponseTriple[]} storeTriples The given triples from the rdf construct response. + * @param {string} namespaces The given namespaces. + * @param {string} [mimeType] The given optional mimeType. + * + * @returns {Triple[]} The array of abbreviated triples. + */ + private _prepareConstructResponse( + storeTriples: RDFStoreConstructResponseTriple[], + namespaces: Namespace, + mimeType?: string + ): Triple[] { + const shouldAbbreviate = !mimeType || mimeType === 'text/turtle'; + + return storeTriples.map((storeTriple: RDFStoreConstructResponseTriple) => { + let { + subject: s, + predicate: p, + object: o, + } = { + subject: storeTriple.subject.nominalValue, + predicate: storeTriple.predicate.nominalValue, + object: storeTriple.object.nominalValue, + }; + + if (shouldAbbreviate) { + s = this._abbreviate(s, namespaces); + p = this._abbreviate(p, namespaces); + o = this._abbreviate(o, namespaces); + } + return { subject: s, predicate: p, object: o }; }); - return Object.assign({}, ...keyValues); } /** @@ -560,59 +482,19 @@ export class GraphVisualizerService { return { status: 404, data: undefined }; } - // Check that it didn't return null results - if (selectResponse[0] == null) { + if (selectResponse.length === 0) { return { status: 400, data: 'Query returned no results' }; } - // Get variable keys - const varKeys = Object.keys(selectResponse[0]); - - // Get object array - const b = selectResponse; - - // Rename keys according to below mapping table - const map = { - token: 'type', - type: 'datatype', - lang: 'xml:lang', - }; - - // Loop over data to rename the keys - for (const i in b) { - if (b.hasOwnProperty(i)) { - for (const key in varKeys) { - if (varKeys.hasOwnProperty(key)) { - // Map keys - b[i][varKeys[key]] = this._mapKeys(b[i][varKeys[key]], map); - - // Add label with short prefix - b[i][varKeys[key]]['label'] = ''; - if (b[i][varKeys[key]]['value']) { - b[i][varKeys[key]]['label'] = this.prefixPipe.transform( - b[i][varKeys[key]]['value'], - PrefixForm.SHORT - ); - - // Transform integer values to numbers - const xmlsInteger = 'http://www.w3.org/2001/XMLSchema#integer'; - const xmlsNonNegativeInteger = 'http://www.w3.org/2001/XMLSchema#nonNegativeInteger'; - const type = b[i][varKeys[key]]['type']; - const datatype = b[i][varKeys[key]]['datatype'] || ''; - if ( - type === 'literal' && - (datatype === xmlsInteger || datatype === xmlsNonNegativeInteger) - ) { - b[i][varKeys[key]]['label'] = +b[i][varKeys[key]]['value']; - } - } - } - } - } - } + // Get variable keys and bindings + const selectResponseKeys = Object.keys(selectResponse[0]); + const selectResponseBindings = this._prepareMappedBindings(selectResponse); // Re-format data - const reformatted: QueryResult = { head: { vars: varKeys }, body: { bindings: b } }; + const reformatted: QueryResult = { + head: { vars: selectResponseKeys }, + body: { bindings: selectResponseBindings }, + }; return { status: 200, data: reformatted }; } diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/sparql-editor/sparql-editor.component.spec.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/sparql-editor/sparql-editor.component.spec.ts index 99a505c89..09f1a2bab 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/sparql-editor/sparql-editor.component.spec.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/sparql-editor/sparql-editor.component.spec.ts @@ -1218,7 +1218,7 @@ describe('SparqlEditorComponent (DONE)', () => { }); it('... should return true if queryList = true and query is a valid query (has queryType, queryLabel, queryString)', () => { - expect(component.isExampleQueriesEnabled()).toBeTrue(); + expectToBe(component.isExampleQueriesEnabled(), true); }); it('... should return false if query is falsy', async () => { @@ -1227,7 +1227,7 @@ describe('SparqlEditorComponent (DONE)', () => { // Change detection await detectChangesOnPush(fixture); - expect(component.isExampleQueriesEnabled()).toBeFalse(); + expectToBe(component.isExampleQueriesEnabled(), false); }); it('... should return false if query.queryType is falsy', async () => { @@ -1236,7 +1236,7 @@ describe('SparqlEditorComponent (DONE)', () => { // Change detection await detectChangesOnPush(fixture); - expect(component.isExampleQueriesEnabled()).toBeFalse(); + expectToBe(component.isExampleQueriesEnabled(), false); }); it('... should return false if query.queryLabel is falsy', async () => { @@ -1245,7 +1245,7 @@ describe('SparqlEditorComponent (DONE)', () => { // Change detection await detectChangesOnPush(fixture); - expect(component.isExampleQueriesEnabled()).toBeFalse(); + expectToBe(component.isExampleQueriesEnabled(), false); }); it('... should return false if query.queryString is falsy', async () => { @@ -1254,7 +1254,7 @@ describe('SparqlEditorComponent (DONE)', () => { // Change detection await detectChangesOnPush(fixture); - expect(component.isExampleQueriesEnabled()).toBeFalse(); + expectToBe(component.isExampleQueriesEnabled(), false); }); it('... should return false if queryList is falsy', async () => { @@ -1263,7 +1263,7 @@ describe('SparqlEditorComponent (DONE)', () => { // Change detection await detectChangesOnPush(fixture); - expect(component.isExampleQueriesEnabled()).toBeFalse(); + expectToBe(component.isExampleQueriesEnabled(), false); }); it('... should return false if query (incl. type, label & string) and queryList not exist', async () => { @@ -1273,7 +1273,7 @@ describe('SparqlEditorComponent (DONE)', () => { // Change detection await detectChangesOnPush(fixture); - expect(component.isExampleQueriesEnabled()).toBeFalse(); + expectToBe(component.isExampleQueriesEnabled(), false); }); }); @@ -1698,24 +1698,24 @@ describe('SparqlEditorComponent (DONE)', () => { component.query = expectedConstructQuery1; component.setViewType(); - expect(component.selectedViewType).toBe(ViewHandleTypes.GRAPH); + expectToBe(component.selectedViewType, ViewHandleTypes.GRAPH); component.query = expectedConstructQuery2; component.setViewType(); - expect(component.selectedViewType).toBe(ViewHandleTypes.GRAPH); + expectToBe(component.selectedViewType, ViewHandleTypes.GRAPH); }); it('... should return ViewHandleTypes.TABLE if querytype is `select`', () => { component.query = expectedSelectQuery1; component.setViewType(); - expect(component.selectedViewType).toBe(ViewHandleTypes.TABLE); + expectToBe(component.selectedViewType, ViewHandleTypes.TABLE); component.query = expectedSelectQuery2; component.setViewType(); - expect(component.selectedViewType).toBe(ViewHandleTypes.TABLE); + expectToBe(component.selectedViewType, ViewHandleTypes.TABLE); }); }); diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/sparql-no-results/sparql-no-results.component.spec.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/sparql-no-results/sparql-no-results.component.spec.ts index acbc61673..0702f6491 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/sparql-no-results/sparql-no-results.component.spec.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/sparql-no-results/sparql-no-results.component.spec.ts @@ -1,7 +1,7 @@ import { DebugElement } from '@angular/core'; import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { getAndExpectDebugElementByCss } from '@testing/expect-helper'; +import { expectToBe, expectToContain, expectToEqual, getAndExpectDebugElementByCss } from '@testing/expect-helper'; import { LOGOSDATA } from '@awg-core/core-data'; import { Logos } from '@awg-core/core-models'; @@ -50,7 +50,7 @@ describe('SparqlNoResultsComponent (DONE)', () => { it('... injected service should use provided mockValue', () => { const coreService = TestBed.inject(CoreService); - expect(mockCoreService === coreService).toBe(true); + expectToBe(mockCoreService === coreService, true); }); describe('BEFORE initial data binding', () => { @@ -75,42 +75,25 @@ describe('SparqlNoResultsComponent (DONE)', () => { }); it('... should contain plain text in 1st and 2nd paragraph', () => { - const divDes = getAndExpectDebugElementByCss(compDe, 'div.text-center', 1, 1); - const pDes = getAndExpectDebugElementByCss(compDe, 'div.text-center > p', 4, 1); + const pDes = getAndExpectDebugElementByCss(compDe, 'div.text-center > p', 4, 4); - const divEl = divDes[0].nativeElement; const p1El = pDes[0].nativeElement; const p2El = pDes[1].nativeElement; - expect(divEl.id).toBeDefined(); - - expect(p1El.textContent).toBeDefined(); - expect(p1El.textContent) - .withContext( - 'should contain: Entschuldigung, Ihre SPARQL-Anfrage führte leider zu keinem Ergebnis.' - ) - .toContain('Entschuldigung, Ihre SPARQL-Anfrage führte leider zu keinem Ergebnis.'); - - expect(p2El.textContent).toBeDefined(); - expect(p2El.textContent) - .withContext('should contain: Möglicherweise können Sie Ihre Anfrage anpassen.') - .toContain('Möglicherweise können Sie Ihre Anfrage anpassen.'); + expectToBe(p1El.textContent, 'Entschuldigung, Ihre SPARQL-Anfrage führte leider zu keinem Ergebnis.'); + expectToBe(p2El.textContent, 'Möglicherweise können Sie Ihre Anfrage anpassen.'); }); it('... should contain one empty link in 3rd and 4th paragraph', () => { - getAndExpectDebugElementByCss(compDe, 'div.text-center', 1, 1); - const pDes = getAndExpectDebugElementByCss(compDe, 'div.text-center > p', 4, 1); + const pDes = getAndExpectDebugElementByCss(compDe, 'div.text-center > p', 4, 4); const p3aDes = getAndExpectDebugElementByCss(pDes[2], 'p > a', 1, 1); const p4aDes = getAndExpectDebugElementByCss(pDes[3], 'p > a', 1, 1); const p3aEl = p3aDes[0].nativeElement; const p4aEl = p4aDes[0].nativeElement; - expect(p3aEl.href).toBeDefined(); - expect(p3aEl.href).withContext('should be empty string').not.toBeTruthy(); // JASMINE: empty string ==> not truthy - - expect(p4aEl.href).toBeDefined(); - expect(p4aEl.href).withContext('should be empty string').not.toBeTruthy(); + expectToBe(p3aEl.href, ''); + expectToBe(p4aEl.href, ''); }); it('... should contain one empty image in 4th paragraph link', () => { @@ -121,8 +104,7 @@ describe('SparqlNoResultsComponent (DONE)', () => { const imgEl = imgDes[0].nativeElement; - expect(imgEl.src).toBeDefined(); - expect(imgEl.src).withContext('should be empty string').not.toBeTruthy(); + expectToBe(imgEl.src, ''); }); }); }); @@ -142,8 +124,7 @@ describe('SparqlNoResultsComponent (DONE)', () => { }); it('... should return logos', () => { - expect(component.logos).toBeDefined(); - expect(component.logos).withContext(`should be ${expectedLogos}`).toBe(expectedLogos); + expectToEqual(component.logos, expectedLogos); }); }); @@ -157,22 +138,9 @@ describe('SparqlNoResultsComponent (DONE)', () => { const p3aEl = p3aDes[0].nativeElement; const p4aEl = p4aDes[0].nativeElement; - expect(p3aEl.href).toBeDefined(); - expect(p3aEl.href).withContext('should be empty string').toBeTruthy(); - expect(p3aEl.href) - .withContext(`should contain ${expectedLogos['sparql'].href}`) - .toContain(expectedLogos['sparql'].href); - - expect(p3aEl.textContent).toBeDefined(); - expect(p3aEl.textContent) - .withContext(`should contain: ${expectedLogos['sparql'].href}`) - .toContain(expectedLogos['sparql'].href); - - expect(p4aEl.href).toBeDefined(); - expect(p4aEl.href).withContext('should be empty string').toBeTruthy(); - expect(p4aEl.href) - .withContext(`should contain ${expectedLogos['sparql'].href}`) - .toContain(expectedLogos['sparql'].href); + expectToBe(p3aEl.href, expectedLogos['sparql'].href); + expectToBe(p3aEl.textContent, expectedLogos['sparql'].href); + expectToBe(p4aEl.href, expectedLogos['sparql'].href); }); it('... should contain correct image in 4th paragraph link', () => { @@ -183,10 +151,7 @@ describe('SparqlNoResultsComponent (DONE)', () => { const imgEl = imgDes[0].nativeElement; - expect(imgEl.src).toBeDefined(); - expect(imgEl.src) - .withContext(`should contain ${expectedLogos['sparql'].src}`) - .toContain(expectedLogos['sparql'].src); + expectToContain(imgEl.src, expectedLogos['sparql'].src); }); }); }); diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/sparql-table/sparql-table.component.spec.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/sparql-table/sparql-table.component.spec.ts index bf7c39efa..4a75d1636 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/sparql-table/sparql-table.component.spec.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/sparql-table/sparql-table.component.spec.ts @@ -4,7 +4,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { NgbPaginationModule } from '@ng-bootstrap/ng-bootstrap'; import Spy = jasmine.Spy; -import { expectSpyCall, getAndExpectDebugElementByDirective } from '@testing/expect-helper'; +import { expectSpyCall, expectToBe, expectToEqual, getAndExpectDebugElementByDirective } from '@testing/expect-helper'; import { QueryResult } from '../models'; import { SparqlTableComponent } from './sparql-table.component'; @@ -94,15 +94,11 @@ describe('SparqlTableComponent (DONE)', () => { }); it('... should have `queryResult` input', () => { - expect(component.queryResult).withContext('should be defined').toBeDefined(); - expect(component.queryResult) - .withContext(`should equal ${expectedQueryResult}`) - .toEqual(expectedQueryResult); + expectToEqual(component.queryResult, expectedQueryResult); }); it('... should have `queryTime` input', () => { - expect(component.queryTime).withContext('should be defined').toBeDefined(); - expect(component.queryTime).withContext(`should equal ${expectedQueryTime}`).toEqual(expectedQueryTime); + expectToBe(component.queryTime, expectedQueryTime); }); describe('VIEW', () => { @@ -114,30 +110,21 @@ describe('SparqlTableComponent (DONE)', () => { const tableDes = getAndExpectDebugElementByDirective(compDe, TableStubComponent, 1, 1); const tableCmp = tableDes[0].injector.get(TableStubComponent) as TableStubComponent; - expect(tableCmp.tableTitle).toBeDefined(); - expect(tableCmp.tableTitle) - .withContext(`should equal ${expectedTableTitle}`) - .toEqual(expectedTableTitle); + expectToBe(tableCmp.tableTitle, expectedTableTitle); }); it('... should pass down `headerInputData` to table component', () => { const tableDes = getAndExpectDebugElementByDirective(compDe, TableStubComponent, 1, 1); const tableCmp = tableDes[0].injector.get(TableStubComponent) as TableStubComponent; - expect(tableCmp.headerInputData).toBeDefined(); - expect(tableCmp.headerInputData) - .withContext(`should equal ${expectedQueryResult.head.vars}`) - .toEqual(expectedQueryResult.head.vars); + expectToEqual(tableCmp.headerInputData, expectedQueryResult.head.vars); }); it('... should pass down `rowInputData` to table component', () => { const tableDes = getAndExpectDebugElementByDirective(compDe, TableStubComponent, 1, 1); const tableCmp = tableDes[0].injector.get(TableStubComponent) as TableStubComponent; - expect(tableCmp.rowInputData).toBeDefined(); - expect(tableCmp.rowInputData) - .withContext(`should equal ${expectedQueryResult.body.bindings}`) - .toEqual(expectedQueryResult.body.bindings); + expectToEqual(tableCmp.rowInputData, expectedQueryResult.body.bindings); }); }); diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/unsupported-type-results/unsupported-type-results.component.spec.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/unsupported-type-results/unsupported-type-results.component.spec.ts index f876966d7..b1d8e0445 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/unsupported-type-results/unsupported-type-results.component.spec.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-graph/graph-visualizer/unsupported-type-results/unsupported-type-results.component.spec.ts @@ -188,7 +188,7 @@ describe('UnsupportedTypeResultsComponent (DONE)', () => { ); let itemBodyEl = itemBodyDes[0].nativeElement; - expect(itemBodyEl.classList).toContain('show'); + expectToContain(itemBodyEl.classList, 'show'); // Click header button click(btnEl as HTMLElement); @@ -217,7 +217,7 @@ describe('UnsupportedTypeResultsComponent (DONE)', () => { ); itemBodyEl = itemBodyDes[0].nativeElement; - expect(itemBodyEl.classList).toContain('show'); + expectToContain(itemBodyEl.classList, 'show'); }); it('... should contain item body with two centered paragraphs', () => { @@ -381,7 +381,7 @@ describe('UnsupportedTypeResultsComponent (DONE)', () => { ); let itemBodyEl = itemBodyDes[0].nativeElement; - expect(itemBodyEl.classList).toContain('show'); + expectToContain(itemBodyEl.classList, 'show'); // Click header button click(btnEl as HTMLElement); @@ -396,7 +396,7 @@ describe('UnsupportedTypeResultsComponent (DONE)', () => { ); itemBodyEl = itemBodyDes[0].nativeElement; - expect(itemBodyEl.classList).toContain('show'); + expectToContain(itemBodyEl.classList, 'show'); }); it('... should contain item body with two centered paragraphs', () => { diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-intro/edition-intro.component.html b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-intro/edition-intro.component.html index 8ac91e099..2049632f4 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-intro/edition-intro.component.html +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-intro/edition-intro.component.html @@ -8,7 +8,7 @@
@if (utils.isNotEmptyArray(editionIntroData.intro[0].content)) { @for (introParagraph of editionIntroData.intro[0].content; track introParagraph) { -

+

} } @else {

@@ -16,8 +16,8 @@ >[Die Einleitung zum Editionskomplex erscheint im Zusammenhang der vollständigen Edition von in - {{ editionRouteConstants.EDITION.short }} {{ editionComplex.series.short }}/{{ - editionComplex.section.short + {{ editionRouteConstants.EDITION.short }} {{ editionComplex.pubStatement.series.short }}/{{ + editionComplex.pubStatement.section.short }}.]

@@ -35,13 +35,10 @@
Anmerkungen
} @else { @if (errorObject) { -
-
-
- {{ errorObject }} -
-
-
+ + } @else { + + } }
diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-intro/edition-intro.component.scss b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-intro/edition-intro.component.scss index cac7160e3..4ac6662f2 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-intro/edition-intro.component.scss +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-intro/edition-intro.component.scss @@ -1,4 +1,4 @@ -p.awg-intro-paragraph { +.awg-intro-para { margin: 0; text-indent: 25px; diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-intro/edition-intro.component.spec.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-intro/edition-intro.component.spec.ts index c622064f4..4c76eafe3 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-intro/edition-intro.component.spec.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-intro/edition-intro.component.spec.ts @@ -1,10 +1,17 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ -import { DOCUMENT } from '@angular/common'; -import { Component, DebugElement } from '@angular/core'; +import { DOCUMENT, JsonPipe } from '@angular/common'; +import { Component, DebugElement, Input } from '@angular/core'; import { ComponentFixture, fakeAsync, TestBed, waitForAsync } from '@angular/core/testing'; import { Router, RouterModule } from '@angular/router'; -import { EmptyError, lastValueFrom, Observable, of as observableOf, throwError as observableThrowError } from 'rxjs'; +import { + EMPTY, + EmptyError, + lastValueFrom, + Observable, + of as observableOf, + throwError as observableThrowError, +} from 'rxjs'; import Spy = jasmine.Spy; import { NgbModalModule } from '@ng-bootstrap/ng-bootstrap'; @@ -23,19 +30,27 @@ import { mockEditionData } from '@testing/mock-data'; import { RouterLinkStubDirective } from '@testing/router-stubs'; import { CompileHtmlComponent } from '@awg-shared/compile-html'; -import { EDITION_COMPLEXES } from '@awg-views/edition-view/data'; import { EDITION_ROUTE_CONSTANTS } from '@awg-views/edition-view/edition-route-constants'; import { EditionComplex, EditionSvgSheet, IntroList } from '@awg-views/edition-view/models'; -import { EditionDataService, EditionService } from '@awg-views/edition-view/services'; +import { EditionComplexesService, EditionDataService, EditionService } from '@awg-views/edition-view/services'; import { EditionIntroComponent } from './edition-intro.component'; // Mock components +@Component({ selector: 'awg-error-alert', template: '' }) +class ErrorAlertStubComponent { + @Input() + errorObject: any; +} + @Component({ selector: 'awg-modal', template: '' }) class ModalStubComponent { open(modalContentSnippetKey: string): void {} } +@Component({ selector: 'awg-twelve-tone-spinner', template: '' }) +class TwelveToneSpinnerStubComponent {} + describe('IntroComponent (DONE)', () => { let component: EditionIntroComponent; let fixture: ComponentFixture; @@ -64,7 +79,7 @@ describe('IntroComponent (DONE)', () => { let editionDataServiceGetEditionIntroDataSpy: Spy; let getEditionIntroDataSpy: Spy; - let getEditionComplexSpy: Spy; + let editionServiceGetSelectedEditionComplexSpy: Spy; let navigateWithComplexIdSpy: Spy; let navigateToIntroFragmentSpy: Spy; let navigateToReportFragmentSpy: Spy; @@ -73,6 +88,12 @@ describe('IntroComponent (DONE)', () => { let componentOpenModalSpy: Spy; let selectSvgSheetSpy: Spy; + const jsonPipe = new JsonPipe(); + + beforeAll(() => { + EditionComplexesService.initializeEditionComplexesList(); + }); + beforeEach(waitForAsync(() => { // Mock router with spy object mockRouter = jasmine.createSpyObj('Router', ['navigate']); @@ -83,12 +104,19 @@ describe('IntroComponent (DONE)', () => { observableOf(expectedEditionIntroData), }; mockEditionService = { - getEditionComplex: (): Observable => observableOf(expectedEditionComplex), + getSelectedEditionComplex: (): Observable => observableOf(expectedEditionComplex), }; TestBed.configureTestingModule({ imports: [NgbModalModule, RouterModule], - declarations: [CompileHtmlComponent, EditionIntroComponent, ModalStubComponent, RouterLinkStubDirective], + declarations: [ + CompileHtmlComponent, + EditionIntroComponent, + ErrorAlertStubComponent, + ModalStubComponent, + RouterLinkStubDirective, + TwelveToneSpinnerStubComponent, + ], providers: [ { provide: EditionDataService, useValue: mockEditionDataService }, { provide: EditionService, useValue: mockEditionService }, @@ -109,7 +137,7 @@ describe('IntroComponent (DONE)', () => { editionService = TestBed.inject(EditionService); // Test data - expectedEditionComplex = EDITION_COMPLEXES.OP12; + expectedEditionComplex = EditionComplexesService.getEditionComplexById('OP12'); expectedEditionComplexBaseRoute = '/edition/complex/op12/'; expectedComplexId = 'testComplex1'; expectedNextComplexId = 'testComplex2'; @@ -125,7 +153,7 @@ describe('IntroComponent (DONE)', () => { editionDataServiceGetEditionIntroDataSpy = spyOn(editionDataService, 'getEditionIntroData').and.returnValue( observableOf(expectedEditionIntroData) ); - getEditionComplexSpy = spyOn(editionService, 'getEditionComplex').and.returnValue( + editionServiceGetSelectedEditionComplexSpy = spyOn(editionService, 'getSelectedEditionComplex').and.returnValue( observableOf(expectedEditionComplex) ); getEditionIntroDataSpy = spyOn(component, 'getEditionIntroData').and.callThrough(); @@ -160,18 +188,28 @@ describe('IntroComponent (DONE)', () => { }); describe('VIEW', () => { + it('... should contain a `div`', () => { + getAndExpectDebugElementByCss(compDe, 'div', 1, 1); + }); + it('... should contain one modal component (stubbed)', () => { getAndExpectDebugElementByDirective(compDe, ModalStubComponent, 1, 1); }); it('... should contain no div.awg-intro-view yet', () => { - // Div debug element getAndExpectDebugElementByCss(compDe, 'div.awg-intro-view', 0, 0); }); - it('... should contain no div.errorMessage yet', () => { - // Div debug element - getAndExpectDebugElementByCss(compDe, 'div.errorMessage', 0, 0); + it('... should not contain an error alert component (stubbed)', () => { + const divDes = getAndExpectDebugElementByCss(compDe, 'div', 1, 1); + + getAndExpectDebugElementByDirective(divDes[0], ErrorAlertStubComponent, 0, 0); + }); + + it('... should not contain a loading spinner component (stubbed)', () => { + const divDes = getAndExpectDebugElementByCss(compDe, 'div', 1, 1); + + getAndExpectDebugElementByDirective(divDes[0], TwelveToneSpinnerStubComponent, 0, 0); }); }); }); @@ -186,16 +224,14 @@ describe('IntroComponent (DONE)', () => { fixture.detectChanges(); }); - it('... should have called `getEditionComplex()`', () => { - // `getEditionReportData()` called immediately after init - expectSpyCall(getEditionComplexSpy, 1); - }); - it('... should have called `getEditionIntroData()`', () => { - // `getEditionIntroData()` called immediately after init expectSpyCall(getEditionIntroDataSpy, 1); }); + it('... should have triggered `getSelectedEditionComplex()` method from EditionService', () => { + expectSpyCall(editionServiceGetSelectedEditionComplexSpy, 1); + }); + it('... should have editionComplex', () => { expectToEqual(component.editionComplex, expectedEditionComplex); }); @@ -217,7 +253,7 @@ describe('IntroComponent (DONE)', () => { getAndExpectDebugElementByCss( divDes[0], - 'p.awg-intro-paragraph', + 'p.awg-intro-para', expectedEditionIntroData.intro[0].content.length, expectedEditionIntroData.intro[0].content.length ); @@ -229,7 +265,7 @@ describe('IntroComponent (DONE)', () => { const pDes = getAndExpectDebugElementByCss( divDes[0], - 'p.awg-intro-paragraph', + 'p.awg-intro-para', expectedEditionIntroData.intro[0].content.length, expectedEditionIntroData.intro[0].content.length ); @@ -313,10 +349,76 @@ describe('IntroComponent (DONE)', () => { const shortComplexSpan = mockDocument.createElement('span'); shortComplexSpan.innerHTML = expectedEditionComplex.complexId.short; - const introPlaceholder = `[Die Einleitung zum Editionskomplex ${fullComplexSpan.textContent} erscheint im Zusammenhang der vollständigen Edition von ${shortComplexSpan.textContent} in ${expectedEditionRouteConstants.EDITION.short} ${expectedEditionComplex.series.short}/${expectedEditionComplex.section.short}.]`; + const awg = EDITION_ROUTE_CONSTANTS.EDITION.short; + const series = expectedEditionComplex.pubStatement.series.short; + const section = expectedEditionComplex.pubStatement.section.short; + + const introPlaceholder = `[Die Einleitung zum Editionskomplex ${fullComplexSpan.textContent} erscheint im Zusammenhang der vollständigen Edition von ${shortComplexSpan.textContent} in ${awg} ${series}/${section}.]`; expectToBe(pEl.textContent.trim(), introPlaceholder); })); + + describe('on error', () => { + const expectedError = { status: 404, statusText: 'got Error' }; + + beforeEach(waitForAsync(() => { + // Spy on editionDataService to return an error + editionDataServiceGetEditionIntroDataSpy.and.returnValue(observableThrowError(() => expectedError)); + + component.getEditionIntroData(); + detectChangesOnPush(fixture); + })); + + it('... should not contain intro view, but one ErrorAlertComponent (stubbed)', waitForAsync(() => { + getAndExpectDebugElementByCss(compDe, 'div.awg-intro-view', 0, 0); + + const divDes = getAndExpectDebugElementByCss(compDe, 'div', 1, 1); + getAndExpectDebugElementByDirective(divDes[0], ErrorAlertStubComponent, 1, 1); + })); + + it('... should pass down error object to ErrorAlertComponent', waitForAsync(() => { + const errorAlertDes = getAndExpectDebugElementByDirective(compDe, ErrorAlertStubComponent, 1, 1); + const errorAlertCmp = errorAlertDes[0].injector.get( + ErrorAlertStubComponent + ) as ErrorAlertStubComponent; + + expectToEqual(errorAlertCmp.errorObject, expectedError); + })); + }); + + describe('on loading', () => { + describe('... should contain only TwelveToneSpinnerComponent (stubbed) if ... ', () => { + it('... editionIntroData$ is EMPTY', () => { + // Mock empty observable + component.editionIntroData$ = EMPTY; + detectChangesOnPush(fixture); + + getAndExpectDebugElementByCss(compDe, 'div.awg-intro-view', 0, 0); + getAndExpectDebugElementByDirective(compDe, ErrorAlertStubComponent, 0, 0); + getAndExpectDebugElementByDirective(compDe, TwelveToneSpinnerStubComponent, 1, 1); + }); + + it('... editionIntroData$ is undefined', () => { + // Mock undefined response + component.editionIntroData$ = observableOf(undefined); + detectChangesOnPush(fixture); + + getAndExpectDebugElementByCss(compDe, 'div.awg-intro-view', 0, 0); + getAndExpectDebugElementByDirective(compDe, ErrorAlertStubComponent, 0, 0); + getAndExpectDebugElementByDirective(compDe, TwelveToneSpinnerStubComponent, 1, 1); + }); + + it('... editionIntroData$ is null', () => { + // Mock null response + component.editionIntroData$ = observableOf(null); + detectChangesOnPush(fixture); + + getAndExpectDebugElementByCss(compDe, 'div.awg-intro-view', 0, 0); + getAndExpectDebugElementByDirective(compDe, ErrorAlertStubComponent, 0, 0); + getAndExpectDebugElementByDirective(compDe, TwelveToneSpinnerStubComponent, 1, 1); + }); + }); + }); }); describe('#getEditionIntroData()', () => { @@ -329,7 +431,7 @@ describe('IntroComponent (DONE)', () => { }); it('... should have got `editionComplex` from editionService', () => { - expectSpyCall(getEditionComplexSpy, 1); + expectSpyCall(editionServiceGetSelectedEditionComplexSpy, 1); expectToEqual(component.editionComplex, expectedEditionComplex); }); @@ -345,12 +447,12 @@ describe('IntroComponent (DONE)', () => { // Init new switchMap component.getEditionIntroData(); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectAsync(lastValueFrom(component.editionIntroData$)).toBeRejected(); expectAsync(lastValueFrom(component.editionIntroData$)).toBeRejectedWithError(EmptyError); - expect(component.errorObject).toEqual(expectedError); + expectToEqual(component.errorObject, expectedError); })); }); @@ -365,7 +467,7 @@ describe('IntroComponent (DONE)', () => { // Find paragraphs const pDes = getAndExpectDebugElementByCss( divDes[0], - 'p.awg-intro-paragraph', + 'p.awg-intro-para', expectedEditionIntroData.intro[0].content.length, expectedEditionIntroData.intro[0].content.length ); @@ -392,7 +494,7 @@ describe('IntroComponent (DONE)', () => { }; component.navigateToIntroFragment(expectedIntroIds); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedIntroIds.complexId, @@ -412,7 +514,7 @@ describe('IntroComponent (DONE)', () => { }; component.navigateToIntroFragment(expectedIntroIds); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedIntroIds.complexId, @@ -431,7 +533,7 @@ describe('IntroComponent (DONE)', () => { }; component.navigateToIntroFragment(expectedIntroIds); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedIntroIds.complexId, @@ -450,7 +552,7 @@ describe('IntroComponent (DONE)', () => { }; component.navigateToIntroFragment(expectedIntroIds); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedIntroIds.complexId, @@ -470,7 +572,7 @@ describe('IntroComponent (DONE)', () => { }; component.navigateToIntroFragment(expectedIntroIds); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ undefined, @@ -488,7 +590,7 @@ describe('IntroComponent (DONE)', () => { }; component.navigateToIntroFragment(expectedIntroIds); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ undefined, @@ -507,7 +609,7 @@ describe('IntroComponent (DONE)', () => { }; component.navigateToIntroFragment(expectedIntroIds); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedIntroIds.complexId, @@ -529,7 +631,7 @@ describe('IntroComponent (DONE)', () => { // Find paragraphs const pDes = getAndExpectDebugElementByCss( divDes[0], - 'p.awg-intro-paragraph', + 'p.awg-intro-para', expectedEditionIntroData.intro[0].content.length, expectedEditionIntroData.intro[0].content.length ); @@ -556,7 +658,7 @@ describe('IntroComponent (DONE)', () => { }; component.navigateToReportFragment(expectedReportIds); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedReportIds.complexId, @@ -576,7 +678,7 @@ describe('IntroComponent (DONE)', () => { }; component.navigateToReportFragment(expectedReportIds); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedReportIds.complexId, @@ -595,7 +697,7 @@ describe('IntroComponent (DONE)', () => { }; component.navigateToReportFragment(expectedReportIds); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedReportIds.complexId, @@ -614,7 +716,7 @@ describe('IntroComponent (DONE)', () => { }; component.navigateToReportFragment(expectedReportIds); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedReportIds.complexId, @@ -634,7 +736,7 @@ describe('IntroComponent (DONE)', () => { }; component.navigateToReportFragment(expectedReportIds); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ undefined, @@ -652,7 +754,7 @@ describe('IntroComponent (DONE)', () => { }; component.navigateToReportFragment(expectedReportIds); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ undefined, @@ -671,7 +773,7 @@ describe('IntroComponent (DONE)', () => { }; component.navigateToReportFragment(expectedReportIds); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedReportIds.complexId, @@ -693,7 +795,7 @@ describe('IntroComponent (DONE)', () => { // Find paragraphs const pDes = getAndExpectDebugElementByCss( divDes[0], - 'p.awg-intro-paragraph', + 'p.awg-intro-para', expectedEditionIntroData.intro[0].content.length, expectedEditionIntroData.intro[0].content.length ); @@ -709,14 +811,14 @@ describe('IntroComponent (DONE)', () => { it('... should open modal with given id', () => { component.openModal(expectedModalSnippet); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(componentOpenModalSpy, 1, expectedModalSnippet); expectSpyCall(modalOpenSpy, 1, expectedModalSnippet); const otherSnippet = 'otherSnippet'; component.openModal(otherSnippet); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(componentOpenModalSpy, 2, otherSnippet); expectSpyCall(modalOpenSpy, 2, otherSnippet); @@ -757,7 +859,7 @@ describe('IntroComponent (DONE)', () => { // Find paragraphs const pDes = getAndExpectDebugElementByCss( divDes[0], - 'p.awg-intro-paragraph', + 'p.awg-intro-para', expectedEditionIntroData.intro[0].content.length, expectedEditionIntroData.intro[0].content.length ); @@ -781,7 +883,7 @@ describe('IntroComponent (DONE)', () => { }; component.selectSvgSheet(expectedSheetIds); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedSheetIds.complexId, @@ -801,7 +903,7 @@ describe('IntroComponent (DONE)', () => { }; component.selectSvgSheet(expectedSheetIds); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedSheetIds.complexId, @@ -820,7 +922,7 @@ describe('IntroComponent (DONE)', () => { }; component.selectSvgSheet(expectedSheetIds); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedSheetIds.complexId, @@ -839,7 +941,7 @@ describe('IntroComponent (DONE)', () => { }; component.selectSvgSheet(expectedSheetIds); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedSheetIds.complexId, @@ -859,7 +961,7 @@ describe('IntroComponent (DONE)', () => { }; component.selectSvgSheet(expectedSheetIds); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ undefined, @@ -877,7 +979,7 @@ describe('IntroComponent (DONE)', () => { }; component.selectSvgSheet(expectedSheetIds); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ undefined, @@ -896,7 +998,7 @@ describe('IntroComponent (DONE)', () => { }; component.selectSvgSheet(expectedSheetIds); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedSheetIds.complexId, @@ -919,7 +1021,7 @@ describe('IntroComponent (DONE)', () => { const expectedNavigationExtras = { fragment: '' }; (component as any)._navigateWithComplexId(undefined, expectedTargetRoute, expectedNavigationExtras); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ undefined, @@ -938,7 +1040,7 @@ describe('IntroComponent (DONE)', () => { const expectedNavigationExtras = { fragment: '' }; (component as any)._navigateWithComplexId(null, expectedTargetRoute, expectedNavigationExtras); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [null, expectedTargetRoute, expectedNavigationExtras]); expectSpyCall(navigationSpy, 1, [ @@ -953,7 +1055,7 @@ describe('IntroComponent (DONE)', () => { const expectedNavigationExtras = { fragment: '' }; (component as any)._navigateWithComplexId('', expectedTargetRoute, expectedNavigationExtras); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, ['', expectedTargetRoute, expectedNavigationExtras]); expectSpyCall(navigationSpy, 1, [ @@ -972,7 +1074,7 @@ describe('IntroComponent (DONE)', () => { expectedTargetRoute, expectedNavigationExtras ); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedEditionComplex.complexId.route.replace('/', ''), @@ -997,7 +1099,7 @@ describe('IntroComponent (DONE)', () => { expectedTargetRoute, expectedNavigationExtras ); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedNextComplexId, @@ -1023,7 +1125,7 @@ describe('IntroComponent (DONE)', () => { expectedTargetRoute, expectedNavigationExtras ); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ undefined, @@ -1046,7 +1148,7 @@ describe('IntroComponent (DONE)', () => { expectedTargetRoute, expectedNavigationExtras ); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ undefined, @@ -1071,7 +1173,7 @@ describe('IntroComponent (DONE)', () => { expectedTargetRoute, expectedNavigationExtras ); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ undefined, @@ -1094,7 +1196,7 @@ describe('IntroComponent (DONE)', () => { expectedTargetRoute, expectedNavigationExtras ); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ undefined, @@ -1119,7 +1221,7 @@ describe('IntroComponent (DONE)', () => { expectedTargetRoute, expectedNavigationExtras ); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ undefined, @@ -1142,7 +1244,7 @@ describe('IntroComponent (DONE)', () => { expectedTargetRoute, expectedNavigationExtras ); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ undefined, @@ -1170,7 +1272,7 @@ describe('IntroComponent (DONE)', () => { expectedTargetRoute, expectedNavigationExtras ); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedComplexId, @@ -1194,7 +1296,7 @@ describe('IntroComponent (DONE)', () => { expectedTargetRoute, expectedNavigationExtras ); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedComplexId, @@ -1220,7 +1322,7 @@ describe('IntroComponent (DONE)', () => { expectedTargetRoute, expectedNavigationExtras ); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedComplexId, @@ -1244,7 +1346,7 @@ describe('IntroComponent (DONE)', () => { expectedTargetRoute, expectedNavigationExtras ); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedComplexId, @@ -1270,7 +1372,7 @@ describe('IntroComponent (DONE)', () => { expectedTargetRoute, expectedNavigationExtras ); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedComplexId, @@ -1294,7 +1396,7 @@ describe('IntroComponent (DONE)', () => { expectedTargetRoute, expectedNavigationExtras ); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedComplexId, @@ -1321,7 +1423,7 @@ describe('IntroComponent (DONE)', () => { expectedTargetRoute, expectedNavigationExtras ); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedNextComplexId, @@ -1344,7 +1446,7 @@ describe('IntroComponent (DONE)', () => { expectedTargetRoute, expectedNavigationExtras ); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedNextComplexId, @@ -1369,7 +1471,7 @@ describe('IntroComponent (DONE)', () => { expectedTargetRoute, expectedNavigationExtras ); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedNextComplexId, @@ -1392,7 +1494,7 @@ describe('IntroComponent (DONE)', () => { expectedTargetRoute, expectedNavigationExtras ); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedNextComplexId, @@ -1417,7 +1519,7 @@ describe('IntroComponent (DONE)', () => { expectedTargetRoute, expectedNavigationExtras ); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedNextComplexId, @@ -1440,7 +1542,7 @@ describe('IntroComponent (DONE)', () => { expectedTargetRoute, expectedNavigationExtras ); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedNextComplexId, diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-intro/edition-intro.component.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-intro/edition-intro.component.ts index b71bc39f1..194810197 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-intro/edition-intro.component.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-intro/edition-intro.component.ts @@ -107,7 +107,7 @@ export class EditionIntroComponent implements OnInit { getEditionIntroData(): void { this.editionIntroData$ = this.editionService // Get current editionComplex from editionService - .getEditionComplex() + .getSelectedEditionComplex() .pipe( switchMap((complex: EditionComplex) => { // Set current editionComplex diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/edition-report.component.html b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/edition-report.component.html index 7161bd1cf..6592bfec5 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/edition-report.component.html +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/edition-report.component.html @@ -3,6 +3,7 @@ + @if (editionReportData$ | async; as editionReportData) {
@@ -86,5 +87,13 @@
+ } @else { + + @if (errorObject) { + + } @else { + + + } } diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/edition-report.component.spec.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/edition-report.component.spec.ts index d782da193..f6617758d 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/edition-report.component.spec.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/edition-report.component.spec.ts @@ -1,14 +1,23 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ +import { JsonPipe } from '@angular/common'; import { Component, DebugElement, EventEmitter, Input, NgModule, Output } from '@angular/core'; import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { Router } from '@angular/router'; -import { EmptyError, lastValueFrom, Observable, of as observableOf, throwError as observableThrowError } from 'rxjs'; +import { + EMPTY, + EmptyError, + lastValueFrom, + Observable, + of as observableOf, + throwError as observableThrowError, +} from 'rxjs'; import Spy = jasmine.Spy; import { NgbAccordionModule, NgbConfig, NgbModalModule } from '@ng-bootstrap/ng-bootstrap'; import { cleanStylesFromDOM } from '@testing/clean-up-helper'; +import { detectChangesOnPush } from '@testing/detect-changes-on-push-helper'; import { expectSpyCall, expectToBe, @@ -20,7 +29,6 @@ import { mockEditionData } from '@testing/mock-data'; import { RouterOutletStubComponent } from '@testing/router-stubs'; import { CompileHtmlComponent } from '@awg-shared/compile-html'; -import { EDITION_COMPLEXES } from '@awg-views/edition-view/data'; import { EDITION_ROUTE_CONSTANTS } from '@awg-views/edition-view/edition-route-constants'; import { EditionComplex, @@ -30,11 +38,17 @@ import { SourceList, TextcriticsList, } from '@awg-views/edition-view/models'; -import { EditionDataService, EditionService } from '@awg-views/edition-view/services'; +import { EditionComplexesService, EditionDataService, EditionService } from '@awg-views/edition-view/services'; import { EditionReportComponent } from './edition-report.component'; // Mock components +@Component({ selector: 'awg-error-alert', template: '' }) +class ErrorAlertStubComponent { + @Input() + errorObject: any; +} + @Component({ selector: 'awg-modal', template: '' }) class ModalStubComponent { open(_modalContentSnippetKey: string): void {} @@ -86,6 +100,9 @@ export class TextcriticsListStubComponent { selectSvgSheetRequest: EventEmitter<{ complexId: string; sheetId: string }> = new EventEmitter(); } +@Component({ selector: 'awg-twelve-tone-spinner', template: '' }) +class TwelveToneSpinnerStubComponent {} + describe('EditionReportComponent', () => { let component: EditionReportComponent; let fixture: ComponentFixture; @@ -116,7 +133,7 @@ describe('EditionReportComponent', () => { let editionDataServiceGetEditionReportDataSpy: Spy; let getEditionReportDataSpy: Spy; - let getEditionComplexSpy: Spy; + let editionServiceGetSelectedEditionComplexSpy: Spy; let navigateToReportFragmentSpy: Spy; let navigateWithComplexIdSpy: Spy; let navigationSpy: Spy; @@ -124,6 +141,8 @@ describe('EditionReportComponent', () => { let onModalOpenSpy: Spy; let selectSvgSheetSpy: Spy; + const jsonPipe = new JsonPipe(); + // Global NgbConfigModule @NgModule({ imports: [NgbAccordionModule], exports: [NgbAccordionModule] }) class NgbAccordionWithConfigModule { @@ -133,6 +152,10 @@ describe('EditionReportComponent', () => { } } + beforeAll(() => { + EditionComplexesService.initializeEditionComplexesList(); + }); + beforeEach(waitForAsync(() => { // Mock router with spy object mockRouter = jasmine.createSpyObj('Router', ['navigate']); @@ -145,7 +168,7 @@ describe('EditionReportComponent', () => { observableOf(expectedEditionReportData), }; mockEditionService = { - getEditionComplex: (): Observable => observableOf(expectedEditionComplex), + getSelectedEditionComplex: (): Observable => observableOf(expectedEditionComplex), }; TestBed.configureTestingModule({ @@ -153,12 +176,14 @@ describe('EditionReportComponent', () => { declarations: [ CompileHtmlComponent, EditionReportComponent, + ErrorAlertStubComponent, ModalStubComponent, SourceListStubComponent, SourceDescriptionStubComponent, SourceEvaluationStubComponent, TextcriticsListStubComponent, RouterOutletStubComponent, + TwelveToneSpinnerStubComponent, ], providers: [ { provide: EditionDataService, useValue: mockEditionDataService }, @@ -180,7 +205,7 @@ describe('EditionReportComponent', () => { // Test data expectedPanelId = 'awg-sources-panel'; expectedReportFragment = 'source_A'; - expectedEditionComplex = EDITION_COMPLEXES.OP12; + expectedEditionComplex = EditionComplexesService.getEditionComplexById('OP12'); expectedEditionComplexBaseRoute = '/edition/complex/op12/'; expectedComplexId = 'testComplex1'; expectedNextComplexId = 'testComplex2'; @@ -204,7 +229,7 @@ describe('EditionReportComponent', () => { editionDataServiceGetEditionReportDataSpy = spyOn(editionDataService, 'getEditionReportData').and.returnValue( observableOf(expectedEditionReportData) ); - getEditionComplexSpy = spyOn(editionService, 'getEditionComplex').and.returnValue( + editionServiceGetSelectedEditionComplexSpy = spyOn(editionService, 'getSelectedEditionComplex').and.returnValue( observableOf(expectedEditionComplex) ); getEditionReportDataSpy = spyOn(component, 'getEditionReportData').and.callThrough(); @@ -238,6 +263,16 @@ describe('EditionReportComponent', () => { }); describe('VIEW', () => { + it('... should contain a `div`', () => { + getAndExpectDebugElementByCss(compDe, 'div', 1, 1); + }); + + it('... should contain one modal component (stubbed)', () => { + const divDes = getAndExpectDebugElementByCss(compDe, 'div', 1, 1); + + getAndExpectDebugElementByDirective(divDes[0], ModalStubComponent, 1, 1); + }); + it('... should contain no div.accordion yet', () => { // Div.accordion debug element getAndExpectDebugElementByCss(compDe, 'div.accordion', 0, 0); @@ -258,6 +293,18 @@ describe('EditionReportComponent', () => { it('... should not contain textcritics list component (stubbed) yet', () => { getAndExpectDebugElementByDirective(compDe, TextcriticsListStubComponent, 0, 0); }); + + it('... should not contain an error alert component (stubbed)', () => { + const divDes = getAndExpectDebugElementByCss(compDe, 'div', 1, 1); + + getAndExpectDebugElementByDirective(divDes[0], ErrorAlertStubComponent, 0, 0); + }); + + it('... should not contain a loading spinner component (stubbed)', () => { + const divDes = getAndExpectDebugElementByCss(compDe, 'div', 1, 1); + + getAndExpectDebugElementByDirective(divDes[0], TwelveToneSpinnerStubComponent, 0, 0); + }); }); }); @@ -271,30 +318,25 @@ describe('EditionReportComponent', () => { fixture.detectChanges(); }); - it('... should have called `getEditionComplex()`', () => { - // `getEditionReportData()` called immediately after init - expectSpyCall(getEditionComplexSpy, 1); - }); - it('... should have called `getEditionReportData()`', () => { - // `getEditionReportData()` called immediately after init expectSpyCall(getEditionReportDataSpy, 1); }); + it('... should have triggered `getSelectedEditionComplex()` method from EditionService', () => { + expectSpyCall(editionServiceGetSelectedEditionComplexSpy, 1); + }); + it('... should have editionComplex', () => { expectToEqual(component.editionComplex, expectedEditionComplex); }); it('... should have editionReportData$', waitForAsync(() => { expectAsync(lastValueFrom(component.editionReportData$)).toBeResolved(); - expectAsync(lastValueFrom(component.editionReportData$)) - .withContext(`should be resolved to ${expectedEditionReportData}`) - .toBeResolvedTo(expectedEditionReportData); + expectAsync(lastValueFrom(component.editionReportData$)).toBeResolvedTo(expectedEditionReportData); })); describe('VIEW', () => { it('... should contain one div.accordion', () => { - // NgbAccordion debug element getAndExpectDebugElementByCss(compDe, 'div.accordion', 1, 1); }); @@ -352,6 +394,70 @@ describe('EditionReportComponent', () => { expectToEqual(textcriticsCmp.textcriticsData, expectedTextcriticsData); }); + + describe('on error', () => { + const expectedError = { status: 404, statusText: 'got Error' }; + + beforeEach(waitForAsync(() => { + // Spy on editionDataService to return an error + editionDataServiceGetEditionReportDataSpy.and.returnValue( + observableThrowError(() => expectedError) + ); + + component.getEditionReportData(); + detectChangesOnPush(fixture); + })); + + it('... should not contain report view, but one ErrorAlertComponent (stubbed)', waitForAsync(() => { + getAndExpectDebugElementByCss(compDe, 'div.accordion', 0, 0); + + const divDes = getAndExpectDebugElementByCss(compDe, 'div', 1, 1); + getAndExpectDebugElementByDirective(divDes[0], ErrorAlertStubComponent, 1, 1); + })); + + it('... should pass down error object to ErrorAlertComponent', waitForAsync(() => { + const errorAlertDes = getAndExpectDebugElementByDirective(compDe, ErrorAlertStubComponent, 1, 1); + const errorAlertCmp = errorAlertDes[0].injector.get( + ErrorAlertStubComponent + ) as ErrorAlertStubComponent; + + expectToEqual(errorAlertCmp.errorObject, expectedError); + })); + }); + + describe('on loading', () => { + describe('... should contain only TwelveToneSpinnerComponent (stubbed) if ... ', () => { + it('... editionReportData$ is EMPTY', () => { + // Mock empty observable + component.editionReportData$ = EMPTY; + detectChangesOnPush(fixture); + + getAndExpectDebugElementByCss(compDe, 'div.awg-report-view', 0, 0); + getAndExpectDebugElementByDirective(compDe, ErrorAlertStubComponent, 0, 0); + getAndExpectDebugElementByDirective(compDe, TwelveToneSpinnerStubComponent, 1, 1); + }); + + it('... editionReportData$ is undefined', () => { + // Mock undefined response + component.editionReportData$ = observableOf(undefined); + detectChangesOnPush(fixture); + + getAndExpectDebugElementByCss(compDe, 'div.awg-report-view', 0, 0); + getAndExpectDebugElementByDirective(compDe, ErrorAlertStubComponent, 0, 0); + getAndExpectDebugElementByDirective(compDe, TwelveToneSpinnerStubComponent, 1, 1); + }); + + it('... editionReportData$ is null', () => { + // Mock null response + component.editionReportData$ = observableOf(null); + detectChangesOnPush(fixture); + + getAndExpectDebugElementByCss(compDe, 'div.awg-report-view', 0, 0); + getAndExpectDebugElementByDirective(compDe, ErrorAlertStubComponent, 0, 0); + getAndExpectDebugElementByDirective(compDe, TwelveToneSpinnerStubComponent, 1, 1); + }); + }); + }); }); describe('#getEditionReportData()', () => { @@ -364,7 +470,7 @@ describe('EditionReportComponent', () => { }); it('... should have got `editionComplex` from editionService', () => { - expectSpyCall(getEditionComplexSpy, 1); + expectSpyCall(editionServiceGetSelectedEditionComplexSpy, 1); expectToEqual(component.editionComplex, expectedEditionComplex); }); @@ -380,12 +486,12 @@ describe('EditionReportComponent', () => { // Init new switchMap component.getEditionReportData(); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectAsync(lastValueFrom(component.editionReportData$)).toBeRejected(); expectAsync(lastValueFrom(component.editionReportData$)).toBeRejectedWithError(EmptyError); - expect(component.errorObject).toEqual(expectedError); + expectToEqual(component.errorObject, expectedError); })); }); @@ -534,14 +640,14 @@ describe('EditionReportComponent', () => { it('... should open modal with given id', () => { component.onModalOpen(expectedModalSnippet); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(onModalOpenSpy, 1, expectedModalSnippet); expectSpyCall(modalOpenSpy, 1, expectedModalSnippet); const otherSnippet = 'otherSnippet'; component.onModalOpen(otherSnippet); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(onModalOpenSpy, 2, otherSnippet); expectSpyCall(modalOpenSpy, 2, otherSnippet); @@ -682,7 +788,7 @@ describe('EditionReportComponent', () => { }; component.onReportFragmentNavigate(expectedReportIds); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedReportIds.complexId, @@ -702,7 +808,7 @@ describe('EditionReportComponent', () => { }; component.onReportFragmentNavigate(expectedReportIds); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedReportIds.complexId, @@ -721,7 +827,7 @@ describe('EditionReportComponent', () => { }; component.onReportFragmentNavigate(expectedReportIds); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedReportIds.complexId, @@ -740,7 +846,7 @@ describe('EditionReportComponent', () => { }; component.onReportFragmentNavigate(expectedReportIds); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedReportIds.complexId, @@ -976,7 +1082,7 @@ describe('EditionReportComponent', () => { }; component.onSvgSheetSelect(expectedSheetIds); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedSheetIds.complexId, @@ -996,7 +1102,7 @@ describe('EditionReportComponent', () => { }; component.onSvgSheetSelect(expectedSheetIds); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedSheetIds.complexId, @@ -1015,7 +1121,7 @@ describe('EditionReportComponent', () => { }; component.onSvgSheetSelect(expectedSheetIds); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedSheetIds.complexId, @@ -1034,7 +1140,7 @@ describe('EditionReportComponent', () => { }; component.onSvgSheetSelect(expectedSheetIds); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedSheetIds.complexId, @@ -1054,7 +1160,7 @@ describe('EditionReportComponent', () => { }; component.onSvgSheetSelect(expectedSheetIds); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ undefined, @@ -1072,7 +1178,7 @@ describe('EditionReportComponent', () => { }; component.onSvgSheetSelect(expectedSheetIds); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ undefined, @@ -1091,7 +1197,7 @@ describe('EditionReportComponent', () => { }; component.onSvgSheetSelect(expectedSheetIds); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedSheetIds.complexId, @@ -1114,7 +1220,7 @@ describe('EditionReportComponent', () => { const expectedNavigationExtras = { fragment: '' }; (component as any)._navigateWithComplexId(undefined, expectedTargetRoute, expectedNavigationExtras); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ undefined, @@ -1133,7 +1239,7 @@ describe('EditionReportComponent', () => { const expectedNavigationExtras = { fragment: '' }; (component as any)._navigateWithComplexId(null, expectedTargetRoute, expectedNavigationExtras); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [null, expectedTargetRoute, expectedNavigationExtras]); expectSpyCall(navigationSpy, 1, [ @@ -1148,7 +1254,7 @@ describe('EditionReportComponent', () => { const expectedNavigationExtras = { fragment: '' }; (component as any)._navigateWithComplexId('', expectedTargetRoute, expectedNavigationExtras); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, ['', expectedTargetRoute, expectedNavigationExtras]); expectSpyCall(navigationSpy, 1, [ @@ -1167,7 +1273,7 @@ describe('EditionReportComponent', () => { expectedTargetRoute, expectedNavigationExtras ); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedEditionComplex.complexId.route.replace('/', ''), @@ -1192,7 +1298,7 @@ describe('EditionReportComponent', () => { expectedTargetRoute, expectedNavigationExtras ); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedNextComplexId, @@ -1218,7 +1324,7 @@ describe('EditionReportComponent', () => { expectedTargetRoute, expectedNavigationExtras ); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ undefined, @@ -1241,7 +1347,7 @@ describe('EditionReportComponent', () => { expectedTargetRoute, expectedNavigationExtras ); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ undefined, @@ -1266,7 +1372,7 @@ describe('EditionReportComponent', () => { expectedTargetRoute, expectedNavigationExtras ); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ undefined, @@ -1289,7 +1395,7 @@ describe('EditionReportComponent', () => { expectedTargetRoute, expectedNavigationExtras ); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ undefined, @@ -1317,7 +1423,7 @@ describe('EditionReportComponent', () => { expectedTargetRoute, expectedNavigationExtras ); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedComplexId, @@ -1341,7 +1447,7 @@ describe('EditionReportComponent', () => { expectedTargetRoute, expectedNavigationExtras ); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedComplexId, @@ -1367,7 +1473,7 @@ describe('EditionReportComponent', () => { expectedTargetRoute, expectedNavigationExtras ); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedComplexId, @@ -1391,7 +1497,7 @@ describe('EditionReportComponent', () => { expectedTargetRoute, expectedNavigationExtras ); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedComplexId, @@ -1418,7 +1524,7 @@ describe('EditionReportComponent', () => { expectedTargetRoute, expectedNavigationExtras ); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedNextComplexId, @@ -1441,7 +1547,7 @@ describe('EditionReportComponent', () => { expectedTargetRoute, expectedNavigationExtras ); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedNextComplexId, @@ -1466,7 +1572,7 @@ describe('EditionReportComponent', () => { expectedTargetRoute, expectedNavigationExtras ); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedNextComplexId, @@ -1489,7 +1595,7 @@ describe('EditionReportComponent', () => { expectedTargetRoute, expectedNavigationExtras ); - fixture.detectChanges(); + detectChangesOnPush(fixture); expectSpyCall(navigateWithComplexIdSpy, 1, [ expectedNextComplexId, diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/edition-report.component.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/edition-report.component.ts index d466aa58b..17a66a7f4 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/edition-report.component.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/edition-report.component.ts @@ -115,7 +115,7 @@ export class EditionReportComponent implements OnInit { getEditionReportData(): void { this.editionReportData$ = this.editionService // Get current editionComplex from editionService - .getEditionComplex() + .getSelectedEditionComplex() .pipe( switchMap((complex: EditionComplex) => { // Set current editionComplex diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/source-description/source-description-corrections/source-description-corrections.component.html b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/source-description/source-description-corrections/source-description-corrections.component.html index 8f4850969..ef750b4ec 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/source-description/source-description-corrections/source-description-corrections.component.html +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/source-description/source-description-corrections/source-description-corrections.component.html @@ -13,7 +13,7 @@ [compile-html-ref]="ref">

} { EditionTkaTableStubComponent ) as EditionTkaTableStubComponent; - expectToEqual(editionTkaTableCmp.textcriticalComments, expectedCorrections[index].comments); + expectToEqual(editionTkaTableCmp.textcriticalCommentBlocks, expectedCorrections[index].comments); }); }); @@ -277,7 +277,11 @@ describe('SourceDescriptionCorrectionsComponent (DONE)', () => { EditionTkaTableStubComponent ) as EditionTkaTableStubComponent; - expect(editionTkaTableCmp.isRowTable).toBe(expectedCorrections[index].rowtable); + if (expectedCorrections[index].rowtable) { + expectToBe(editionTkaTableCmp.isRowTable, expectedCorrections[index].rowtable); + } else { + expect(editionTkaTableCmp.isRowTable).toBeUndefined(); + } }); }); diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/source-description/source-description-corrections/source-description-corrections.component.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/source-description/source-description-corrections/source-description-corrections.component.ts index fee336a59..0bc51b235 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/source-description/source-description-corrections/source-description-corrections.component.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/source-description/source-description-corrections/source-description-corrections.component.ts @@ -2,6 +2,13 @@ import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from import { Textcritics } from '@awg-views/edition-view/models'; +/** + * The SourceDescriptionCorrections component. + * + * It contains the source description corrections section + * of the critical report + * of the edition view of the app. + */ @Component({ selector: 'awg-source-description-corrections', templateUrl: './source-description-corrections.component.html', diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/source-description/source-description-details/source-description-details.component.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/source-description/source-description-details/source-description-details.component.ts index 7395bf040..a00514f00 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/source-description/source-description-details/source-description-details.component.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/source-description/source-description-details/source-description-details.component.ts @@ -1,5 +1,12 @@ import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core'; +/** + * The SourceDescriptionDetails component. + * + * It contains the source description details section + * of the critical report + * of the edition view of the app. + */ @Component({ selector: 'awg-source-description-details', templateUrl: './source-description-details.component.html', diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/source-description/source-description.component.spec.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/source-description/source-description.component.spec.ts index 8164453de..0e08a1b12 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/source-description/source-description.component.spec.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/source-description/source-description.component.spec.ts @@ -1683,13 +1683,13 @@ describe('SourceDescriptionComponent (DONE)', () => { const result1 = component.getWritingMaterialFirmSign(variant); - expect(result1).toEqual({ route: '', full: 'Not a known firm sign.', short: 'unknown' }); + expectToEqual(result1, { route: '', full: 'Not a known firm sign.', short: 'unknown' }); variant = undefined; const result2 = component.getWritingMaterialFirmSign(variant); - expect(result2).toEqual({ route: '', full: 'Not a known firm sign.', short: 'unknown' }); + expectToEqual(result2, { route: '', full: 'Not a known firm sign.', short: 'unknown' }); }); }); diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/source-evaluation/source-evaluation.component.html b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/source-evaluation/source-evaluation.component.html index 202cc8ce2..8915a091c 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/source-evaluation/source-evaluation.component.html +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/source-evaluation/source-evaluation.component.html @@ -11,8 +11,8 @@ >[Die Quellenbewertung zum Editionskomplex erscheint im Zusammenhang der vollständigen Edition von in - {{ editionRouteConstants.EDITION.short }} {{ editionComplex.series.short }}/{{ - editionComplex.section.short + {{ editionRouteConstants.EDITION.short }} {{ editionComplex.pubStatement.series.short }}/{{ + editionComplex.pubStatement.section.short }}.]

diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/source-evaluation/source-evaluation.component.spec.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/source-evaluation/source-evaluation.component.spec.ts index 992e29740..0c6fc0020 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/source-evaluation/source-evaluation.component.spec.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/source-evaluation/source-evaluation.component.spec.ts @@ -17,9 +17,9 @@ import { mockEditionData } from '@testing/mock-data'; import { RouterLinkStubDirective } from '@testing/router-stubs'; import { CompileHtmlComponent } from '@awg-shared/compile-html'; -import { EDITION_COMPLEXES } from '@awg-views/edition-view/data'; import { EDITION_ROUTE_CONSTANTS } from '@awg-views/edition-view/edition-route-constants'; -import { EditionComplex, EditionSvgSheet, SourceEvaluationList } from '@awg-views/edition-view/models'; +import { EditionComplex, SourceEvaluationList } from '@awg-views/edition-view/models'; +import { EditionComplexesService } from '@awg-views/edition-view/services'; import { SourceEvaluationComponent } from './source-evaluation.component'; @@ -60,7 +60,7 @@ describe('SourceEvaluationComponent (DONE)', () => { compDe = fixture.debugElement; // Test data - expectedEditionComplex = EDITION_COMPLEXES.OP25; + expectedEditionComplex = EditionComplexesService.getEditionComplexById('OP25'); expectedComplexId = 'testComplex1'; expectedNextComplexId = 'testComplex2'; expectedReportFragment = 'source_A'; @@ -223,7 +223,11 @@ describe('SourceEvaluationComponent (DONE)', () => { const shortComplexSpan = mockDocument.createElement('span'); shortComplexSpan.innerHTML = expectedEditionComplex.complexId.short; - const evaluationPlaceholder = `[Die Quellenbewertung zum Editionskomplex ${fullComplexSpan.textContent} erscheint im Zusammenhang der vollständigen Edition von ${shortComplexSpan.textContent} in ${expectedEditionRouteConstants.EDITION.short} ${expectedEditionComplex.series.short}/${expectedEditionComplex.section.short}.]`; + const awg = EDITION_ROUTE_CONSTANTS.EDITION.short; + const series = expectedEditionComplex.pubStatement.series.short; + const section = expectedEditionComplex.pubStatement.section.short; + + const evaluationPlaceholder = `[Die Quellenbewertung zum Editionskomplex ${fullComplexSpan.textContent} erscheint im Zusammenhang der vollständigen Edition von ${shortComplexSpan.textContent} in ${awg} ${series}/${section}.]`; expectToBe(pEl.textContent.trim(), evaluationPlaceholder); })); diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/source-list/source-list.component.html b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/source-list/source-list.component.html index 5b4266215..15e9df778 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/source-list/source-list.component.html +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/source-list/source-list.component.html @@ -1,50 +1,56 @@
- - - @for (source of sourceListData.sources; track $index; let sourceIndex = $index) { - - + + + } + +
- @if (source.hasDescription === true) { - - @if (source.missing) { - [ - } - {{ source.siglum }} - @if (source.siglumAddendum) { - - {{ source.siglumAddendum }} - - } - @if (source.missing) { - ] - } - - } @else { - - @if (source.missing) { - [ - } - {{ source.siglum }} - @if (source.siglumAddendum) { - - {{ source.siglumAddendum }} - - } - @if (source.missing) { - ] + @if (utils.isNotEmptyArray(sourceListData.sources)) { + + + @for (source of sourceListData.sources; track $index; let sourceIndex = $index) { + + - - - } - -
+ + + {{ source.siglum }} + @if (source.siglumAddendum) { + + {{ source.siglumAddendum }} + + } + + + @if (source.missing) { + [ + } + + @if (source.missing) { + ] + } + + + @if (source.hasDescription || source.linkTo) { + + + + } @else { + } - - } - -
- -
+ +
+
+ +
+ } @if (utils.isNotEmptyArray(sourceListData.textSources)) { { }); describe('VIEW', () => { - it('... should contain one table with table body (no text sources), but no rows (tr) yet', () => { - const tableBodyDes = getAndExpectDebugElementByCss(compDe, 'table > tbody', 1, 1); + it('... should contain one div.card with with div.card-body, but no tables yet', () => { + const divCardBodyDes = getAndExpectDebugElementByCss(compDe, 'div.card > div.card-body', 1, 1); - getAndExpectDebugElementByCss(tableBodyDes[0], 'tr', 0, 0); + getAndExpectDebugElementByCss(divCardBodyDes[0], 'table', 0, 0); }); }); }); @@ -92,15 +92,24 @@ describe('SourceListComponent (DONE)', () => { }); describe('VIEW', () => { - it('... should contain one div.card', () => { - getAndExpectDebugElementByCss(compDe, 'div.card', 1, 1); - }); + describe('... without any sources', () => { + beforeEach(() => { + expectedSourceListData = { + sources: [], + textSources: [], + }; + component.sourceListData = expectedSourceListData; + detectChangesOnPush(fixture); + }); - it('... should contain one div.card-body in div.card', () => { - getAndExpectDebugElementByCss(compDe, 'div.card > div.card-body', 1, 1); + it('... should contain no tables with in div.card-body', () => { + const divCardBodyDes = getAndExpectDebugElementByCss(compDe, 'div.card > div.card-body', 1, 1); + + getAndExpectDebugElementByCss(divCardBodyDes[0], 'table', 0, 0); + }); }); - describe('... if text sources are not present', () => { + describe('... with only musical sources', () => { it('... should contain one table with table body in div.card-body', () => { getAndExpectDebugElementByCss(compDe, 'div.card-body > table > tbody', 1, 1); }); @@ -127,7 +136,41 @@ describe('SourceListComponent (DONE)', () => { }); }); - it('... should contain siglum link in header column (th)', () => { + it('... should contain siglum container span in header column (th)', () => { + const expectedSourcesLength = expectedSourceListData.sources.length; + const tableBodyDes = getAndExpectDebugElementByCss(compDe, 'table > tbody', 1, 1); + + const rowDes = getAndExpectDebugElementByCss( + tableBodyDes[0], + 'tr', + expectedSourcesLength, + expectedSourcesLength + ); + + rowDes.forEach((rowDe, index) => { + const columnDes = getAndExpectDebugElementByCss(rowDe, 'th', 1, 1); + + const containerDes = getAndExpectDebugElementByCss( + columnDes[0], + 'span.awg-source-list-siglum-container', + 1, + 1 + ); + const containerEl = containerDes[0].nativeElement; + + const expectedSiglum = + expectedSourceListData.sources[index].siglum + + expectedSourceListData.sources[index].siglumAddendum; + + if (expectedSourceListData.sources[index].missing) { + expectToBe(containerEl.textContent.trim(), `[${expectedSiglum}]`); + } else { + expectToBe(containerEl.textContent.trim(), expectedSiglum.trim()); + } + }); + }); + + it('... should contain siglum link as link text in header column (th)', () => { expectedSourceListData.sources[2].missing = false; component.sourceListData = expectedSourceListData; @@ -143,8 +186,14 @@ describe('SourceListComponent (DONE)', () => { rowDes.forEach((rowDe, index) => { const columnDes = getAndExpectDebugElementByCss(rowDe, 'th', 1, 1); + const containerDes = getAndExpectDebugElementByCss( + columnDes[0], + 'span.awg-source-list-siglum-container', + 1, + 1 + ); - const anchorDes = getAndExpectDebugElementByCss(columnDes[0], 'a', 1, 1); + const anchorDes = getAndExpectDebugElementByCss(containerDes[0], 'a', 1, 1); const anchorEl = anchorDes[0].nativeElement; const spanDes = getAndExpectDebugElementByCss(anchorDes[0], 'span', 1, 1); @@ -160,7 +209,7 @@ describe('SourceListComponent (DONE)', () => { }); }); - it('... should display siglum addendum if present in header column (th)', () => { + it('... should display siglum addendum as link text if present in header column (th)', () => { expectedSourceListData.sources[0].siglumAddendum = 'a'; expectedSourceListData.sources[1].siglumAddendum = 'b'; expectedSourceListData.sources[2].siglumAddendum = 'H'; @@ -179,8 +228,14 @@ describe('SourceListComponent (DONE)', () => { rowDes.forEach((rowDe, index) => { const columnDes = getAndExpectDebugElementByCss(rowDe, 'th', 1, 1); + const containerDes = getAndExpectDebugElementByCss( + columnDes[0], + 'span.awg-source-list-siglum-container', + 1, + 1 + ); - const anchorDes = getAndExpectDebugElementByCss(columnDes[0], 'a', 1, 1); + const anchorDes = getAndExpectDebugElementByCss(containerDes[0], 'a', 1, 1); const anchorEl = anchorDes[0].nativeElement; const spanDes = getAndExpectDebugElementByCss(anchorDes[0], 'span', 2, 2); @@ -204,7 +259,7 @@ describe('SourceListComponent (DONE)', () => { }); }); - it('... should display missing sources in brackets in header column (th)', () => { + it('... should display missing sources in brackets as link text in header column (th)', () => { expectedSourceListData.sources[0].missing = true; expectedSourceListData.sources[1].missing = true; expectedSourceListData.sources[2].missing = true; @@ -222,30 +277,42 @@ describe('SourceListComponent (DONE)', () => { rowDes.forEach((rowDe, index) => { const columnDes = getAndExpectDebugElementByCss(rowDe, 'th', 1, 1); + const containerDes = getAndExpectDebugElementByCss( + columnDes[0], + 'span.awg-source-list-siglum-container', + 1, + 1 + ); - const anchorDes = getAndExpectDebugElementByCss(columnDes[0], 'a', 1, 1); + const anchorDes = getAndExpectDebugElementByCss(containerDes[0], 'a', 1, 1); const anchorEl = anchorDes[0].nativeElement; const spanDes = getAndExpectDebugElementByCss(anchorDes[0], 'span', 3, 3); - // First span is opening bracket - // Last span is closing bracket + const openingBracketDes = spanDes[0]; const siglumDes = spanDes[1]; + const closingBracketDes = spanDes[2]; + + const openingBracketEl = openingBracketDes.nativeElement; const siglumEl = siglumDes.nativeElement; + const closingBracketEl = closingBracketDes.nativeElement; const expectedSiglum = expectedSourceListData.sources[index].siglum; expectToBe(anchorEl.textContent.trim(), `[${expectedSiglum}]`); + expectToBe(openingBracketEl.textContent.trim(), '['); + expectToBe(closingBracketEl.textContent.trim(), ']'); + expectToBe(siglumEl.textContent.trim(), expectedSiglum.trim()); expect(siglumEl).toHaveClass('awg-source-list-siglum'); }); }); - it('... should display missing sources with addendum in brackets in header column (th)', () => { + it('... should display missing sources with addendum in brackets as link text in header column (th)', () => { expectedSourceListData.sources[0].siglumAddendum = 'a'; expectedSourceListData.sources[1].siglumAddendum = 'H'; - expectedSourceListData.sources[2].siglumAddendum = 'F1-2'; + expectedSourceListData.sources[2].siglumAddendum = 'F1-F2'; expectedSourceListData.sources[0].missing = true; expectedSourceListData.sources[1].missing = true; @@ -264,25 +331,36 @@ describe('SourceListComponent (DONE)', () => { rowDes.forEach((rowDe, index) => { const columnDes = getAndExpectDebugElementByCss(rowDe, 'th', 1, 1); + const containerDes = getAndExpectDebugElementByCss( + columnDes[0], + 'span.awg-source-list-siglum-container', + 1, + 1 + ); - const anchorDes = getAndExpectDebugElementByCss(columnDes[0], 'a', 1, 1); + const anchorDes = getAndExpectDebugElementByCss(containerDes[0], 'a', 1, 1); const anchorEl = anchorDes[0].nativeElement; const spanDes = getAndExpectDebugElementByCss(anchorDes[0], 'span', 4, 4); - // First span is opening bracket - // Last span is closing bracket + const openingBracketDes = spanDes[0]; const siglumDes = spanDes[1]; - const siglumEl = siglumDes.nativeElement; - const siglumAddendumDes = spanDes[2]; + const closingBracketDes = spanDes[3]; + + const openingBracketEl = openingBracketDes.nativeElement; + const siglumEl = siglumDes.nativeElement; const siglumAddendumEl = siglumAddendumDes.nativeElement; + const closingBracketEl = closingBracketDes.nativeElement; const expectedSiglum = expectedSourceListData.sources[index].siglum; const expectedAddendum = expectedSourceListData.sources[index].siglumAddendum; expectToBe(anchorEl.textContent.trim(), `[${expectedSiglum}${expectedAddendum}]`); + expectToBe(openingBracketEl.textContent.trim(), '['); + expectToBe(closingBracketEl.textContent.trim(), ']'); + expectToBe(siglumEl.textContent.trim(), expectedSiglum.trim()); expect(siglumEl).toHaveClass('awg-source-list-siglum'); @@ -291,6 +369,124 @@ describe('SourceListComponent (DONE)', () => { }); }); + it('... should contain link to report fragment for sources with description and linkTo value', fakeAsync(() => { + expectedSourceListData = { + sources: [ + { + siglum: 'A', + siglumAddendum: '', + type: 'Test type 3', + location: 'Test location 3.', + hasDescription: true, + linkTo: 'source_A', + }, + ], + }; + component.sourceListData = expectedSourceListData; + detectChangesOnPush(fixture); + + const expectedSourcesLength = expectedSourceListData.sources.length; + const tableBodyDes = getAndExpectDebugElementByCss(compDe, 'table > tbody', 1, 1); + + const anchorDes = getAndExpectDebugElementByCss( + tableBodyDes[0], + 'tr > th > span.awg-source-list-siglum-container > a', + expectedSourcesLength, + expectedSourcesLength + ); + + clickAndAwaitChanges(anchorDes[0], fixture); + + expectSpyCall(navigateToReportFragmentSpy, 1, { complexId: '', fragmentId: 'source_A' }); + })); + + it('... should contain link to openModal for sources without description but linkTo value', fakeAsync(() => { + expectedSourceListData = { + sources: [ + { + siglum: 'B', + siglumAddendum: '', + type: 'Test type 3', + location: 'Test location 3.', + hasDescription: false, + linkTo: 'MODAL_TEXT', + }, + ], + }; + component.sourceListData = expectedSourceListData; + detectChangesOnPush(fixture); + + const expectedSourcesLength = expectedSourceListData.sources.length; + const tableBodyDes = getAndExpectDebugElementByCss(compDe, 'table > tbody', 1, 1); + + const anchorDes = getAndExpectDebugElementByCss( + tableBodyDes[0], + 'tr > th > span.awg-source-list-siglum-container > a', + expectedSourcesLength, + expectedSourcesLength + ); + + clickAndAwaitChanges(anchorDes[0], fixture); + + expectSpyCall(openModalSpy, 1, 'MODAL_TEXT'); + })); + + it('... should contain no link for missing sources without description and linkTo value', () => { + expectedSourceListData = { + sources: [ + { + siglum: 'C', + siglumAddendum: '', + missing: true, + type: 'Test type 3', + location: 'Test location 3.', + hasDescription: false, + linkTo: '', + }, + ], + }; + component.sourceListData = expectedSourceListData; + detectChangesOnPush(fixture); + + const expectedSourcesLength = expectedSourceListData.sources.length; + const rowDes = getAndExpectDebugElementByCss( + compDe, + 'table > tbody > tr', + expectedSourcesLength, + expectedSourcesLength + ); + + rowDes.forEach((rowDe, index) => { + const columnDes = getAndExpectDebugElementByCss(rowDe, 'th', 1, 1); + const containerDes = getAndExpectDebugElementByCss( + columnDes[0], + 'span.awg-source-list-siglum-container', + 1, + 1 + ); + + getAndExpectDebugElementByCss(containerDes[0], 'a', 0, 0); + + const spanDes = getAndExpectDebugElementByCss(containerDes[0], 'span', 3, 3); + + const openingBracketDes = spanDes[0]; + const siglumDes = spanDes[1]; + const closingBracketDes = spanDes[2]; + + const openingBracketEl = openingBracketDes.nativeElement; + const siglumEl = siglumDes.nativeElement; + const closingBracketEl = closingBracketDes.nativeElement; + + const expectedSiglum = expectedSourceListData.sources[index].siglum; + + expectToBe(openingBracketEl.textContent.trim(), '['); + expectToBe(closingBracketEl.textContent.trim(), ']'); + + expectToBe(siglumEl.textContent.trim(), expectedSiglum.trim()); + expect(siglumEl).toHaveClass('awg-source-list-siglum'); + }); + }); + it('... should contain source type and source location in second table column (td)', () => { const expectedSourcesLength = expectedSourceListData.sources.length; const rowDes = getAndExpectDebugElementByCss( @@ -313,7 +509,7 @@ describe('SourceListComponent (DONE)', () => { }); }); - describe('... if text sources are present', () => { + describe('... with musical and text sources', () => { beforeEach(() => { expectedSourceListData = JSON.parse(JSON.stringify(mockEditionData.mockSourceListDataWithTexts)); component.sourceListData = expectedSourceListData; @@ -507,8 +703,15 @@ describe('SourceListComponent (DONE)', () => { }); it('... should trigger on click', fakeAsync(() => { - // Get anhors in description - const anchorDes = getAndExpectDebugElementByCss(compDe, 'table tr > th > a', 3, 3); + const expectedSourcesLength = expectedSourceListData.sources.length; + const tableBodyDes = getAndExpectDebugElementByCss(compDe, 'table > tbody', 1, 1); + + const anchorDes = getAndExpectDebugElementByCss( + tableBodyDes[0], + 'tr > th > span.awg-source-list-siglum-container > a', + expectedSourcesLength, + expectedSourcesLength + ); // Everything but first anchor uses modal // Click on first anchor @@ -578,8 +781,15 @@ describe('SourceListComponent (DONE)', () => { }); it('... should trigger on click', fakeAsync(() => { - // Get anhors in th column - const anchorDes = getAndExpectDebugElementByCss(compDe, 'table tr > th > a', 3, 3); + const expectedSourcesLength = expectedSourceListData.sources.length; + const tableBodyDes = getAndExpectDebugElementByCss(compDe, 'table > tbody', 1, 1); + + const anchorDes = getAndExpectDebugElementByCss( + tableBodyDes[0], + 'tr > th > span.awg-source-list-siglum-container > a', + expectedSourcesLength, + expectedSourcesLength + ); // Everything but first anchor uses modal // Click on second anchor diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/source-list/source-list.component.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/source-list/source-list.component.ts index a9846e430..b68edce74 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/source-list/source-list.component.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/source-list/source-list.component.ts @@ -1,6 +1,6 @@ import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core'; -import { UtilityService } from '@awg-app/core/services'; +import { UtilityService } from '@awg-core/services'; import { SourceList } from '@awg-views/edition-view/models'; /** diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/textcritics-list/textcritics-list.component.html b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/textcritics-list/textcritics-list.component.html index dcb8e2a07..a32792765 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/textcritics-list/textcritics-list.component.html +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/textcritics-list/textcritics-list.component.html @@ -16,39 +16,48 @@
- @if (utils.isNotEmptyArray(textcritics.description)) { -
-

- : -

+
+

+ : +

+ @if (utils.isNotEmptyArray(textcritics.description)) { -
- } - @if (utils.isNotEmptyArray(textcritics.comments)) { -
-

- : -

+ } @else { + + } +
+
+

+ : +

+ @if (utils.isNotEmptyArray(textcritics.comments)) { -
- } + } @else { + + } +
+ +

+ [Nicht vorhanden.] +

+
diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/textcritics-list/textcritics-list.component.spec.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/textcritics-list/textcritics-list.component.spec.ts index 8da113b90..635cccaf5 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/textcritics-list/textcritics-list.component.spec.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-report/textcritics-list/textcritics-list.component.spec.ts @@ -16,9 +16,9 @@ import { } from '@testing/expect-helper'; import { mockEditionData } from '@testing/mock-data'; -import { UtilityService } from '@awg-app/core/services'; +import { UtilityService } from '@awg-core/services'; import { CompileHtmlComponent } from '@awg-shared/compile-html'; -import { TextcriticalComment, TextcriticsList } from '@awg-views/edition-view/models'; +import { TextcriticalCommentBlock, TextcriticsList } from '@awg-views/edition-view/models'; import { TextcriticsListComponent } from './textcritics-list.component'; @@ -45,7 +45,7 @@ class EditionTkaLabelStubComponent { @Component({ selector: 'awg-edition-tka-table', template: '' }) class EditionTkaTableStubComponent { @Input() - textcriticalComments: TextcriticalComment[]; + textcriticalCommentBlocks: TextcriticalCommentBlock[]; @Input() isCorrections = false; @Input() @@ -435,191 +435,284 @@ describe('TextcriticsListComponent (DONE)', () => { detectChangesOnPush(fixture); }); - it('... should contain no item body with div and paragraphs if description and comment arrays are empty', () => { - const textcritics = expectedTextcriticsData.textcritics[0]; - const bodyDes = getAndExpectDebugElementByCss( - compDe, - `div#${textcritics.id} > div.accordion-collapse > div.accordion-body`, - 1, - 1, - 'open' - ); - - getAndExpectDebugElementByCss(bodyDes[0], 'div', 0, 0); - }); - - it('... should contain item body with div, small caps paragraph, first EditionTkaLabelComponent and EditionTkaDescriptionComponent if description array is not empty', () => { - const textcritics = expectedTextcriticsData.textcritics[1]; - - const bodyDes = getAndExpectDebugElementByCss( - compDe, - `div#${textcritics.id} > div.accordion-collapse > div.accordion-body`, - 1, - 1, - 'open' - ); - const divDes = getAndExpectDebugElementByCss(bodyDes[0], 'div:first-child', 1, 1); - const pDes = getAndExpectDebugElementByCss(divDes[0], 'p.smallcaps', 1, 1); - - getAndExpectDebugElementByDirective(pDes[0], EditionTkaLabelStubComponent, 1, 1); - - getAndExpectDebugElementByDirective(divDes[0], EditionTkaDescriptionStubComponent, 1, 1); - }); - - it('... should pass down `id` data to first EditionTkaLabelComponent (stubbed)', () => { - const bodyDes = getAndExpectDebugElementByCss( - compDe, - `div#${expectedTextcriticsData.textcritics[1].id} > div.accordion-collapse > div.accordion-body`, - 1, - 1, - 'open' - ); - const divDes = getAndExpectDebugElementByCss(bodyDes[0], 'div:first-child', 1, 1); - const pDes = getAndExpectDebugElementByCss(divDes[0], 'p.smallcaps', 1, 1); - - const labelDes = getAndExpectDebugElementByDirective(pDes[0], EditionTkaLabelStubComponent, 1, 1); - const labelCmp = labelDes[0].injector.get( - EditionTkaLabelStubComponent - ) as EditionTkaLabelStubComponent; - - expectToBe(labelCmp.id, expectedTextcriticsData.textcritics[1].id); - }); - - it('... should pass down `labelType` data to first EditionTkaLabelComponent (stubbed)', () => { - const bodyDes = getAndExpectDebugElementByCss( - compDe, - `div#${expectedTextcriticsData.textcritics[1].id} > div.accordion-collapse > div.accordion-body`, - 1, - 1, - 'open' - ); - const divDes = getAndExpectDebugElementByCss(bodyDes[0], 'div:first-child', 1, 1); - const pDes = getAndExpectDebugElementByCss(divDes[0], 'p.smallcaps', 1, 1); - - const labelDes = getAndExpectDebugElementByDirective(pDes[0], EditionTkaLabelStubComponent, 1, 1); - const labelCmp = labelDes[0].injector.get( - EditionTkaLabelStubComponent - ) as EditionTkaLabelStubComponent; - - expectToBe(labelCmp.labelType, 'evaluation'); + describe('... if description array is empty', () => { + it('... should contain item body with div, small caps paragraph, EditionTkaLabelComponent, but no EditionTkaDescriptionComponent', () => { + const textcritics = expectedTextcriticsData.textcritics[0]; + + const bodyDes = getAndExpectDebugElementByCss( + compDe, + `div#${textcritics.id} > div.accordion-collapse > div.accordion-body`, + 1, + 1, + 'open' + ); + const divDes = getAndExpectDebugElementByCss(bodyDes[0], 'div:first-child', 1, 1); + const pDes = getAndExpectDebugElementByCss(divDes[0], 'p.smallcaps', 1, 1); + + getAndExpectDebugElementByDirective(pDes[0], EditionTkaLabelStubComponent, 1, 1); + + getAndExpectDebugElementByDirective(divDes[0], EditionTkaDescriptionStubComponent, 0, 0); + }); + + it('... should display a no content message (small.text-muted) in another paragraph within item body div', () => { + const textcritics = expectedTextcriticsData.textcritics[0]; + + const bodyDes = getAndExpectDebugElementByCss( + compDe, + `div#${textcritics.id} > div.accordion-collapse > div.accordion-body`, + 1, + 1, + 'open' + ); + const divDes = getAndExpectDebugElementByCss(bodyDes[0], 'div:first-child', 1, 1); + const pDes = getAndExpectDebugElementByCss(divDes[0], 'p', 2, 2); + + // Get small element of second paragraph + const smallDes = getAndExpectDebugElementByCss(pDes[1], 'small', 1, 1); + const smallEl = smallDes[0].nativeElement; + + expectToContain(smallEl.textContent, '[Nicht vorhanden.]'); + expect(smallEl).toHaveClass('text-muted'); + }); }); - it('... should pass down `description` data to EditionTkaDescriptionComponent (stubbed)', () => { - const editionTkaDescriptionDes = getAndExpectDebugElementByDirective( - compDe, - EditionTkaDescriptionStubComponent, - 1, - 1 - ); - const editionTkaDescriptionCmp = editionTkaDescriptionDes[0].injector.get( - EditionTkaDescriptionStubComponent - ) as EditionTkaDescriptionStubComponent; - - expectToEqual( - editionTkaDescriptionCmp.textcriticalDescriptions, - expectedTextcriticsData.textcritics[1].description - ); + describe('... if description array is not empty', () => { + it('... should contain item body with div, small caps paragraph, first EditionTkaLabelComponent and EditionTkaDescriptionComponent', () => { + const textcritics = expectedTextcriticsData.textcritics[1]; + + const bodyDes = getAndExpectDebugElementByCss( + compDe, + `div#${textcritics.id} > div.accordion-collapse > div.accordion-body`, + 1, + 1, + 'open' + ); + const divDes = getAndExpectDebugElementByCss(bodyDes[0], 'div:first-child', 1, 1); + const pDes = getAndExpectDebugElementByCss(divDes[0], 'p.smallcaps', 1, 1); + + getAndExpectDebugElementByDirective(pDes[0], EditionTkaLabelStubComponent, 1, 1); + + getAndExpectDebugElementByDirective(divDes[0], EditionTkaDescriptionStubComponent, 1, 1); + }); + + it('... should pass down `id` data to first EditionTkaLabelComponent (stubbed)', () => { + const bodyDes = getAndExpectDebugElementByCss( + compDe, + `div#${expectedTextcriticsData.textcritics[1].id} > div.accordion-collapse > div.accordion-body`, + 1, + 1, + 'open' + ); + const divDes = getAndExpectDebugElementByCss(bodyDes[0], 'div:first-child', 1, 1); + const pDes = getAndExpectDebugElementByCss(divDes[0], 'p.smallcaps', 1, 1); + + const labelDes = getAndExpectDebugElementByDirective( + pDes[0], + EditionTkaLabelStubComponent, + 1, + 1 + ); + const labelCmp = labelDes[0].injector.get( + EditionTkaLabelStubComponent + ) as EditionTkaLabelStubComponent; + + expectToBe(labelCmp.id, expectedTextcriticsData.textcritics[1].id); + }); + + it('... should pass down `labelType` data to first EditionTkaLabelComponent (stubbed)', () => { + const bodyDes = getAndExpectDebugElementByCss( + compDe, + `div#${expectedTextcriticsData.textcritics[1].id} > div.accordion-collapse > div.accordion-body`, + 1, + 1, + 'open' + ); + const divDes = getAndExpectDebugElementByCss(bodyDes[0], 'div:first-child', 1, 1); + const pDes = getAndExpectDebugElementByCss(divDes[0], 'p.smallcaps', 1, 1); + + const labelDes = getAndExpectDebugElementByDirective( + pDes[0], + EditionTkaLabelStubComponent, + 1, + 1 + ); + const labelCmp = labelDes[0].injector.get( + EditionTkaLabelStubComponent + ) as EditionTkaLabelStubComponent; + + expectToBe(labelCmp.labelType, 'evaluation'); + }); + + it('... should pass down `description` data to EditionTkaDescriptionComponent (stubbed)', () => { + const editionTkaDescriptionDes = getAndExpectDebugElementByDirective( + compDe, + EditionTkaDescriptionStubComponent, + 1, + 1 + ); + const editionTkaDescriptionCmp = editionTkaDescriptionDes[0].injector.get( + EditionTkaDescriptionStubComponent + ) as EditionTkaDescriptionStubComponent; + + expectToEqual( + editionTkaDescriptionCmp.textcriticalDescriptions, + expectedTextcriticsData.textcritics[1].description + ); + }); }); - it('... should contain item body with div, small caps paragraph, second EditionTkaLabelComponent and EditionTkaTableComponent if comments array is not empty', () => { - const textcritics = expectedTextcriticsData.textcritics[1]; - - const bodyDes = getAndExpectDebugElementByCss( - compDe, - `div#${textcritics.id} > div.accordion-collapse > div.accordion-body`, - 1, - 1, - 'open' - ); - const divDes = getAndExpectDebugElementByCss(bodyDes[0], 'div:not(:first-child)', 1, 1); - const pDes = getAndExpectDebugElementByCss(divDes[0], 'p.smallcaps', 1, 1); - - getAndExpectDebugElementByDirective(pDes[0], EditionTkaLabelStubComponent, 1, 1); - - getAndExpectDebugElementByDirective(divDes[0], EditionTkaTableStubComponent, 1, 1); + describe('... if commments array is empty', () => { + it('... should contain item body with div, small caps paragraph, EditionTkaLabelComponent, but no EditionTkaTableComponent', () => { + const textcritics = expectedTextcriticsData.textcritics[0]; + + const bodyDes = getAndExpectDebugElementByCss( + compDe, + `div#${textcritics.id} > div.accordion-collapse > div.accordion-body`, + 1, + 1, + 'open' + ); + const divDes = getAndExpectDebugElementByCss(bodyDes[0], 'div:not(:first-child)', 1, 1); + const pDes = getAndExpectDebugElementByCss(divDes[0], 'p.smallcaps', 1, 1); + + getAndExpectDebugElementByDirective(pDes[0], EditionTkaLabelStubComponent, 1, 1); + + getAndExpectDebugElementByDirective(divDes[0], EditionTkaTableStubComponent, 0, 0); + }); + + it('... should display a no content message (small.text-muted) in another paragraph within item body div', () => { + const textcritics = expectedTextcriticsData.textcritics[0]; + + const bodyDes = getAndExpectDebugElementByCss( + compDe, + `div#${textcritics.id} > div.accordion-collapse > div.accordion-body`, + 1, + 1, + 'open' + ); + const divDes = getAndExpectDebugElementByCss(bodyDes[0], 'div:not(:first-child)', 1, 1); + const pDes = getAndExpectDebugElementByCss(divDes[0], 'p', 2, 2); + + // Get small element of second paragraph + const smallDes = getAndExpectDebugElementByCss(pDes[1], 'small', 1, 1); + const smallEl = smallDes[0].nativeElement; + + expectToContain(smallEl.textContent, '[Nicht vorhanden.]'); + expect(smallEl).toHaveClass('text-muted'); + }); }); - it('... should pass down `id` data to second EditionTkaLabelComponent (stubbed)', () => { - const bodyDes = getAndExpectDebugElementByCss( - compDe, - `div#${expectedTextcriticsData.textcritics[1].id} > div.accordion-collapse > div.accordion-body`, - 1, - 1, - 'open' - ); - const divDes = getAndExpectDebugElementByCss(bodyDes[0], 'div:not(:first-child)', 1, 1); - const pDes = getAndExpectDebugElementByCss(divDes[0], 'p.smallcaps', 1, 1); - - const labelDes = getAndExpectDebugElementByDirective(pDes[0], EditionTkaLabelStubComponent, 1, 1); - const labelCmp = labelDes[0].injector.get( - EditionTkaLabelStubComponent - ) as EditionTkaLabelStubComponent; - - expectToBe(labelCmp.id, expectedTextcriticsData.textcritics[1].id); - }); - - it('... should pass down `labelType` data to second EditionTkaLabelComponent (stubbed)', () => { - const bodyDes = getAndExpectDebugElementByCss( - compDe, - `div#${expectedTextcriticsData.textcritics[1].id} > div.accordion-collapse > div.accordion-body`, - 1, - 1, - 'open' - ); - const divDes = getAndExpectDebugElementByCss(bodyDes[0], 'div:not(:first-child)', 1, 1); - const pDes = getAndExpectDebugElementByCss(divDes[0], 'p.smallcaps', 1, 1); - - const labelDes = getAndExpectDebugElementByDirective(pDes[0], EditionTkaLabelStubComponent, 1, 1); - const labelCmp = labelDes[0].injector.get( - EditionTkaLabelStubComponent - ) as EditionTkaLabelStubComponent; - - expectToBe(labelCmp.labelType, 'comment'); - }); - - it('... should pass down `comments` to EditionTkaTableComponent (stubbed)', () => { - const editionTkaTableDes = getAndExpectDebugElementByDirective( - compDe, - EditionTkaTableStubComponent, - 1, - 1 - ); - const editionTkaTableCmp = editionTkaTableDes[0].injector.get( - EditionTkaTableStubComponent - ) as EditionTkaTableStubComponent; - - expectToEqual( - editionTkaTableCmp.textcriticalComments, - expectedTextcriticsData.textcritics[1].comments - ); - }); - - it('... should pass down `isRowTable` to EditionTkaTableComponent (stubbed)', () => { - const editionTkaTableDes = getAndExpectDebugElementByDirective( - compDe, - EditionTkaTableStubComponent, - 1, - 1 - ); - const editionTkaTableCmp = editionTkaTableDes[0].injector.get( - EditionTkaTableStubComponent - ) as EditionTkaTableStubComponent; - - expectToEqual(editionTkaTableCmp.isRowTable, expectedTextcriticsData.textcritics[1].rowtable); - }); - - it('... should pass down `isSketchId` to EditionTkaTableComponent (stubbed)', () => { - const editionTkaTableDes = getAndExpectDebugElementByDirective( - compDe, - EditionTkaTableStubComponent, - 1, - 1 - ); - const editionTkaTableCmp = editionTkaTableDes[0].injector.get( - EditionTkaTableStubComponent - ) as EditionTkaTableStubComponent; - - expectToEqual(editionTkaTableCmp.isSketchId, false); + describe('... if comments array is not empty', () => { + it('... should contain item body with div, small caps paragraph, second EditionTkaLabelComponent and EditionTkaTableComponent', () => { + const textcritics = expectedTextcriticsData.textcritics[1]; + + const bodyDes = getAndExpectDebugElementByCss( + compDe, + `div#${textcritics.id} > div.accordion-collapse > div.accordion-body`, + 1, + 1, + 'open' + ); + const divDes = getAndExpectDebugElementByCss(bodyDes[0], 'div:not(:first-child)', 1, 1); + const pDes = getAndExpectDebugElementByCss(divDes[0], 'p.smallcaps', 1, 1); + + getAndExpectDebugElementByDirective(pDes[0], EditionTkaLabelStubComponent, 1, 1); + + getAndExpectDebugElementByDirective(divDes[0], EditionTkaTableStubComponent, 1, 1); + }); + + it('... should pass down `id` data to second EditionTkaLabelComponent (stubbed)', () => { + const bodyDes = getAndExpectDebugElementByCss( + compDe, + `div#${expectedTextcriticsData.textcritics[1].id} > div.accordion-collapse > div.accordion-body`, + 1, + 1, + 'open' + ); + const divDes = getAndExpectDebugElementByCss(bodyDes[0], 'div:not(:first-child)', 1, 1); + const pDes = getAndExpectDebugElementByCss(divDes[0], 'p.smallcaps', 1, 1); + + const labelDes = getAndExpectDebugElementByDirective( + pDes[0], + EditionTkaLabelStubComponent, + 1, + 1 + ); + const labelCmp = labelDes[0].injector.get( + EditionTkaLabelStubComponent + ) as EditionTkaLabelStubComponent; + + expectToBe(labelCmp.id, expectedTextcriticsData.textcritics[1].id); + }); + + it('... should pass down `labelType` data to second EditionTkaLabelComponent (stubbed)', () => { + const bodyDes = getAndExpectDebugElementByCss( + compDe, + `div#${expectedTextcriticsData.textcritics[1].id} > div.accordion-collapse > div.accordion-body`, + 1, + 1, + 'open' + ); + const divDes = getAndExpectDebugElementByCss(bodyDes[0], 'div:not(:first-child)', 1, 1); + const pDes = getAndExpectDebugElementByCss(divDes[0], 'p.smallcaps', 1, 1); + + const labelDes = getAndExpectDebugElementByDirective( + pDes[0], + EditionTkaLabelStubComponent, + 1, + 1 + ); + const labelCmp = labelDes[0].injector.get( + EditionTkaLabelStubComponent + ) as EditionTkaLabelStubComponent; + + expectToBe(labelCmp.labelType, 'comment'); + }); + + it('... should pass down `comments` to EditionTkaTableComponent (stubbed)', () => { + const editionTkaTableDes = getAndExpectDebugElementByDirective( + compDe, + EditionTkaTableStubComponent, + 1, + 1 + ); + const editionTkaTableCmp = editionTkaTableDes[0].injector.get( + EditionTkaTableStubComponent + ) as EditionTkaTableStubComponent; + + expectToEqual( + editionTkaTableCmp.textcriticalCommentBlocks, + expectedTextcriticsData.textcritics[1].comments + ); + }); + + it('... should pass down `isRowTable` to EditionTkaTableComponent (stubbed)', () => { + const editionTkaTableDes = getAndExpectDebugElementByDirective( + compDe, + EditionTkaTableStubComponent, + 1, + 1 + ); + const editionTkaTableCmp = editionTkaTableDes[0].injector.get( + EditionTkaTableStubComponent + ) as EditionTkaTableStubComponent; + + expectToEqual(editionTkaTableCmp.isRowTable, expectedTextcriticsData.textcritics[1].rowtable); + }); + + it('... should pass down `isSketchId` to EditionTkaTableComponent (stubbed)', () => { + const editionTkaTableDes = getAndExpectDebugElementByDirective( + compDe, + EditionTkaTableStubComponent, + 1, + 1 + ); + const editionTkaTableCmp = editionTkaTableDes[0].injector.get( + EditionTkaTableStubComponent + ) as EditionTkaTableStubComponent; + + expectToEqual(editionTkaTableCmp.isSketchId, false); + }); }); }); }); diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-accolade/edition-accolade.component.html b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-accolade/edition-accolade.component.html index 4f2a72a56..b050e9b16 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-accolade/edition-accolade.component.html +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-accolade/edition-accolade.component.html @@ -33,7 +33,7 @@ @if (selectedSvgSheet && selectedTextcritics) { { let expectedOverlays: EditionSvgOverlay[]; let expectedSvgSheet: EditionSvgSheet; let expectedNextSvgSheet: EditionSvgSheet; - let expectedSelectedTextcriticalComments: TextcriticalComment[]; + let expectedSelectedTextcriticalCommentBlocks: TextcriticalCommentBlock[]; let expectedSelectedTextcritics: Textcritics; let expectedShowTkA: boolean; let expectedModalSnippet: string; @@ -138,7 +138,7 @@ describe('EditionAccoladeComponent (DONE)', () => { sheets: { workEditions: [], textEditions: [], sketchEditions: [expectedSvgSheet, expectedNextSvgSheet] }, }; expectedSelectedTextcritics = mockEditionData.mockTextcriticsData.textcritics.at(1); - expectedSelectedTextcriticalComments = expectedSelectedTextcritics.comments; + expectedSelectedTextcriticalCommentBlocks = expectedSelectedTextcritics.comments; const type = EditionSvgOverlayTypes.tka; const id = 'tka-1'; @@ -184,8 +184,8 @@ describe('EditionAccoladeComponent (DONE)', () => { expect(component.selectedSvgSheet).toBeUndefined(); }); - it('... should not have `selectedTextcriticalComments`', () => { - expect(component.selectedTextcriticalComments).toBeUndefined(); + it('... should not have `selectedTextcriticalCommentBlocks`', () => { + expect(component.selectedTextcriticalCommentBlocks).toBeUndefined(); }); it('... should not have `selectedTextcritics`', () => { @@ -225,7 +225,7 @@ describe('EditionAccoladeComponent (DONE)', () => { // Simulate the parent setting the input properties component.svgSheetsData = expectedSvgSheetsData; component.selectedSvgSheet = expectedSvgSheet; - component.selectedTextcriticalComments = expectedSelectedTextcriticalComments; + component.selectedTextcriticalCommentBlocks = expectedSelectedTextcriticalCommentBlocks; component.selectedTextcritics = expectedSelectedTextcritics; component.showTkA = expectedShowTkA; @@ -241,8 +241,8 @@ describe('EditionAccoladeComponent (DONE)', () => { expectToEqual(component.selectedSvgSheet, expectedSvgSheet); }); - it('... should have `selectedTextcriticalComments` input', () => { - expectToEqual(component.selectedTextcriticalComments, expectedSelectedTextcriticalComments); + it('... should have `selectedTextcriticalCommentBlocks` input', () => { + expectToEqual(component.selectedTextcriticalCommentBlocks, expectedSelectedTextcriticalCommentBlocks); }); it('... should have `selectedTextcritics` input', () => { @@ -447,7 +447,7 @@ describe('EditionAccoladeComponent (DONE)', () => { expectToEqual(footerCmp.selectedTextcritics, expectedSelectedTextcritics); }); - it('... should pass down selectedTextcriticalComments to the EditionSvgSheetFooterComponent', () => { + it('... should pass down selectedTextcriticalCommentBlocks to the EditionSvgSheetFooterComponent', () => { const footerDes = getAndExpectDebugElementByDirective( compDe, EditionSvgSheetFooterStubComponent, @@ -458,7 +458,10 @@ describe('EditionAccoladeComponent (DONE)', () => { EditionSvgSheetFooterStubComponent ) as EditionSvgSheetFooterStubComponent; - expectToEqual(footerCmp.selectedTextcriticalComments, expectedSelectedTextcriticalComments); + expectToEqual( + footerCmp.selectedTextcriticalCommentBlocks, + expectedSelectedTextcriticalCommentBlocks + ); }); it('... should pass down showTkA to the EditionSvgSheetFooterComponent', () => { diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-accolade/edition-accolade.component.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-accolade/edition-accolade.component.ts index 7bc514e92..843fa62c3 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-accolade/edition-accolade.component.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-accolade/edition-accolade.component.ts @@ -4,7 +4,7 @@ import { EditionSvgOverlay, EditionSvgSheet, EditionSvgSheetList, - TextcriticalComment, + TextcriticalCommentBlock, Textcritics, } from '@awg-views/edition-view/models'; @@ -41,12 +41,12 @@ export class EditionAccoladeComponent { selectedSvgSheet: EditionSvgSheet; /** - * Input variable: selectedTextcriticalComments. + * Input variable: selectedTextcriticalCommentBlocks. * - * It keeps the selected textcritical comments. + * It keeps the selected textcritical comment blocks. */ @Input() - selectedTextcriticalComments: TextcriticalComment[]; + selectedTextcriticalCommentBlocks: TextcriticalCommentBlock[]; /** * Input variable: selectedTextcritics. diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-accolade/edition-svg-sheet-footer/edition-svg-sheet-footer.component.html b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-accolade/edition-svg-sheet-footer/edition-svg-sheet-footer.component.html index e22b10cb5..af969f842 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-accolade/edition-svg-sheet-footer/edition-svg-sheet-footer.component.html +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-accolade/edition-svg-sheet-footer/edition-svg-sheet-footer.component.html @@ -38,7 +38,7 @@ >:

{ let expectedSvgSheet: EditionSvgSheet; let expectedNextSvgSheet: EditionSvgSheet; let expectedSelectedTextcritics: Textcritics; - let expectedSelectedTextcriticalComments: TextcriticalComment[]; + let expectedSelectedTextcriticalCommentBlocks: TextcriticalCommentBlock[]; let expectedShowTka: boolean; let expectedModalSnippet: string; @@ -114,7 +114,7 @@ describe('EditionSvgSheetFooterComponent (DONE)', () => { expectedSvgSheet = JSON.parse(JSON.stringify(mockEditionData.mockSvgSheet_Sk1)); expectedNextSvgSheet = JSON.parse(JSON.stringify(mockEditionData.mockSvgSheet_Sk2)); expectedSelectedTextcritics = JSON.parse(JSON.stringify(mockEditionData.mockTextcriticsData.textcritics.at(1))); - expectedSelectedTextcriticalComments = expectedSelectedTextcritics.comments; + expectedSelectedTextcriticalCommentBlocks = expectedSelectedTextcritics.comments; expectedShowTka = true; expectedChevronDownIcon = faChevronDown; @@ -139,8 +139,8 @@ describe('EditionSvgSheetFooterComponent (DONE)', () => { }); describe('BEFORE initial data binding', () => { - it('... should not have `selectedTextcriticalComments`', () => { - expect(component.selectedTextcriticalComments).toBeUndefined(); + it('... should not have `selectedTextcriticalCommentBlocks`', () => { + expect(component.selectedTextcriticalCommentBlocks).toBeUndefined(); }); it('... should not have `selectedTextcritics`', () => { @@ -182,7 +182,7 @@ describe('EditionSvgSheetFooterComponent (DONE)', () => { beforeEach(() => { // Simulate the parent setting the input properties component.selectedTextcritics = expectedSelectedTextcritics; - component.selectedTextcriticalComments = expectedSelectedTextcriticalComments; + component.selectedTextcriticalCommentBlocks = expectedSelectedTextcriticalCommentBlocks; component.showTkA = expectedShowTka; // Trigger initial data binding @@ -193,8 +193,8 @@ describe('EditionSvgSheetFooterComponent (DONE)', () => { expectToEqual(component.selectedTextcritics, expectedSelectedTextcritics); }); - it('... should have `selectedTextcriticalComments` input', () => { - expectToEqual(component.selectedTextcriticalComments, expectedSelectedTextcriticalComments); + it('... should have `selectedTextcriticalCommentBlocks` input', () => { + expectToEqual(component.selectedTextcriticalCommentBlocks, expectedSelectedTextcriticalCommentBlocks); }); it('... should have `showTkA` input', () => { @@ -240,7 +240,7 @@ describe('EditionSvgSheetFooterComponent (DONE)', () => { expect(iconDe[0].children[0]).toBeTruthy(); expect(iconDe[0].children[0].classes).toBeTruthy(); - expect(iconDe[0].children[0].classes['fa-chevron-right']).toBeTrue(); + expectToBe(iconDe[0].children[0].classes['fa-chevron-right'], true); }); it('... should contain fa-icon with chevronDown in evaluation paragraph if showTextcritics = true', () => { @@ -257,7 +257,7 @@ describe('EditionSvgSheetFooterComponent (DONE)', () => { expect(iconDe[0].children[0]).toBeTruthy(); expect(iconDe[0].children[0].classes).toBeTruthy(); - expect(iconDe[0].children[0].classes['fa-chevron-down']).toBeTrue(); + expectToBe(iconDe[0].children[0].classes['fa-chevron-down'], true); }); it('... should contain a span.smallcaps in evaluation paragraph with first EditionTkaLabelComponent', () => { @@ -449,11 +449,11 @@ describe('EditionSvgSheetFooterComponent (DONE)', () => { expectToBe(labelCmp.labelType, 'comment'); }); - it('... should pass down `selectedTextcriticalComments` to the EditionTkaTableComponent', () => { + it('... should pass down `selectedTextcriticalCommentBlocks` to the EditionTkaTableComponent', () => { const tableDes = getAndExpectDebugElementByDirective(compDe, EditionTkaTableStubComponent, 1, 1); const tableCmp = tableDes[0].injector.get(EditionTkaTableStubComponent) as EditionTkaTableStubComponent; - expectToEqual(tableCmp.textcriticalComments, expectedSelectedTextcriticalComments); + expectToEqual(tableCmp.textcriticalCommentBlocks, expectedSelectedTextcriticalCommentBlocks); }); it('... should pass down `isRowTable` to the EditionTkaTableComponent', () => { @@ -714,17 +714,17 @@ describe('EditionSvgSheetFooterComponent (DONE)', () => { }); it('... should toggle `showTextcritics`', () => { - expect(component.showTextcritics).toBe(false); + expectToBe(component.showTextcritics, false); component.toggleTextcritics(); detectChangesOnPush(fixture); - expect(component.showTextcritics).toBe(true); + expectToBe(component.showTextcritics, true); component.toggleTextcritics(); detectChangesOnPush(fixture); - expect(component.showTextcritics).toBe(false); + expectToBe(component.showTextcritics, false); }); }); }); diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-accolade/edition-svg-sheet-footer/edition-svg-sheet-footer.component.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-accolade/edition-svg-sheet-footer/edition-svg-sheet-footer.component.ts index 2afb49e6d..ce49418c9 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-accolade/edition-svg-sheet-footer/edition-svg-sheet-footer.component.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-accolade/edition-svg-sheet-footer/edition-svg-sheet-footer.component.ts @@ -2,8 +2,8 @@ import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from import { faChevronDown, faChevronRight } from '@fortawesome/free-solid-svg-icons'; -import { UtilityService } from '@awg-app/core/services'; -import { TextcriticalComment, Textcritics } from '@awg-app/views/edition-view/models'; +import { UtilityService } from '@awg-core/services'; +import { TextcriticalCommentBlock, Textcritics } from '@awg-views/edition-view/models'; /** * The EditionSvgSheetFooter component. @@ -20,12 +20,12 @@ import { TextcriticalComment, Textcritics } from '@awg-app/views/edition-view/mo }) export class EditionSvgSheetFooterComponent { /** - * Input variable: selectedTextcriticalComments. + * Input variable: selectedTextcriticalCommentBlocks. * - * It keeps the selected textcritical comments. + * It keeps the selected textcritical comment blocks. */ @Input() - selectedTextcriticalComments: TextcriticalComment[]; + selectedTextcriticalCommentBlocks: TextcriticalCommentBlock[]; /** * Input variable: selectedTextcritics. diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-accolade/edition-svg-sheet-nav/edition-svg-sheet-nav-item/edition-svg-sheet-nav-item.component.spec.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-accolade/edition-svg-sheet-nav/edition-svg-sheet-nav-item/edition-svg-sheet-nav-item.component.spec.ts index d2ca7d2a6..bffafe91b 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-accolade/edition-svg-sheet-nav/edition-svg-sheet-nav-item/edition-svg-sheet-nav-item.component.spec.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-accolade/edition-svg-sheet-nav/edition-svg-sheet-nav-item/edition-svg-sheet-nav-item.component.spec.ts @@ -13,7 +13,7 @@ import { } from '@testing/expect-helper'; import { mockEditionData } from '@testing/mock-data'; -import { EditionSvgSheet } from '@awg-app/views/edition-view/models'; +import { EditionSvgSheet } from '@awg-views/edition-view/models'; import { EditionSvgSheetNavItemComponent } from './edition-svg-sheet-nav-item.component'; @@ -176,10 +176,10 @@ describe('EditionSvgSheetNavItemComponent (DONE)', () => { const anchorEl1 = anchorDes[1].nativeElement; expectToContain(anchorEl0.classList, 'active'); - expect(anchorEl0.classList).withContext(`should not contain 'text-muted'`).not.toContain('text-muted'); + expect(anchorEl0.classList).not.toContain('text-muted'); expectToContain(anchorEl1.classList, 'text-muted'); - expect(anchorEl1.classList).withContext(`should not contain 'active'`).not.toContain('active'); + expect(anchorEl1.classList).not.toContain('active'); }); it('... should display sheet label in direct anchors (no partials)', () => { @@ -289,7 +289,7 @@ describe('EditionSvgSheetNavItemComponent (DONE)', () => { const anchorEl = anchorDe.nativeElement; expectToContain(anchorEl.classList, 'text-muted'); - expect(anchorEl.classList).withContext(`should not contain 'active'`).not.toContain('active'); + expect(anchorEl.classList).not.toContain('active'); }); }); @@ -307,10 +307,10 @@ describe('EditionSvgSheetNavItemComponent (DONE)', () => { let anchorEl1 = anchorDes[1].nativeElement; expectToContain(anchorEl0.classList, 'active'); - expect(anchorEl0.classList).withContext(`should not contain 'text-muted'`).not.toContain('text-muted'); + expect(anchorEl0.classList).not.toContain('text-muted'); expectToContain(anchorEl1.classList, 'text-muted'); - expect(anchorEl1.classList).withContext(`should not contain 'active'`).not.toContain('active'); + expect(anchorEl1.classList).not.toContain('active'); component.selectedSvgSheet = JSON.parse(JSON.stringify(mockEditionData.mockSvgSheet_Sk3b)); detectChangesOnPush(fixture); @@ -325,10 +325,10 @@ describe('EditionSvgSheetNavItemComponent (DONE)', () => { anchorEl1 = anchorDes[1].nativeElement; expectToContain(anchorEl0.classList, 'text-muted'); - expect(anchorEl0.classList).withContext(`should not contain 'active'`).not.toContain('active'); + expect(anchorEl0.classList).not.toContain('active'); expectToContain(anchorEl1.classList, 'active'); - expect(anchorEl1.classList).withContext(`should not contain 'text-muted'`).not.toContain('text-muted'); + expect(anchorEl1.classList).not.toContain('text-muted'); }); it('... should have as many item anchors (.dropdown-item) in dropdown as partials in sheet content', () => { @@ -364,12 +364,10 @@ describe('EditionSvgSheetNavItemComponent (DONE)', () => { const anchorEl1 = anchorDes[1].nativeElement; expectToContain(anchorEl0.classList, 'active'); - expect(anchorEl0.classList) - .withContext(`should not have class 'text-muted'`) - .not.toContain('text-muted'); + expect(anchorEl0.classList).not.toContain('text-muted'); expectToContain(anchorEl1.classList, 'text-muted'); - expect(anchorEl1.classList).withContext(`should not have class 'active'`).not.toContain('active'); + expect(anchorEl1.classList).not.toContain('active'); }); it('... should display sheet labels in dropdown item anchors (with numbered partials)', () => { @@ -408,13 +406,13 @@ describe('EditionSvgSheetNavItemComponent (DONE)', () => { it('... should return false if given id does not equal id of selected svg sheet', () => { const comparison = component.isSelectedSvgSheet(expectedNextSvgSheet.id); - expect(comparison).toBeFalse(); + expectToBe(comparison, false); }); it('... should return true if given id does equal id of selected svg sheet', () => { const comparison = component.isSelectedSvgSheet(expectedSvgSheet.id); - expect(comparison).toBeTrue(); + expectToBe(comparison, true); }); }); @@ -425,7 +423,7 @@ describe('EditionSvgSheetNavItemComponent (DONE)', () => { const comparison = component.isSelectedSvgSheet(expectedSvgSheetWithPartials.id, 'XXX'); - expect(comparison).toBeFalse(); + expectToBe(comparison, false); }); it('... should return true if given id does equal id with partial of selected svg sheet', () => { @@ -434,7 +432,7 @@ describe('EditionSvgSheetNavItemComponent (DONE)', () => { const comparison = component.isSelectedSvgSheet(expectedSvgSheetWithPartials.id, 'a'); - expect(comparison).toBeTrue(); + expectToBe(comparison, true); }); }); }); diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-accolade/edition-svg-sheet-nav/edition-svg-sheet-nav-item/edition-svg-sheet-nav-item.component.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-accolade/edition-svg-sheet-nav/edition-svg-sheet-nav-item/edition-svg-sheet-nav-item.component.ts index 32317529d..73fee9a71 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-accolade/edition-svg-sheet-nav/edition-svg-sheet-nav-item/edition-svg-sheet-nav-item.component.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-accolade/edition-svg-sheet-nav/edition-svg-sheet-nav-item/edition-svg-sheet-nav-item.component.ts @@ -1,6 +1,7 @@ import { Component, EventEmitter, Input, Output } from '@angular/core'; -import { UtilityService } from '@awg-app/core/services'; -import { EditionSvgSheet } from '@awg-app/views/edition-view/models'; + +import { UtilityService } from '@awg-core/services'; +import { EditionSvgSheet } from '@awg-views/edition-view/models'; /** * The EditionSvgSheetNavItem component. diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-accolade/edition-svg-sheet-viewer/edition-svg-sheet-viewer.component.spec.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-accolade/edition-svg-sheet-viewer/edition-svg-sheet-viewer.component.spec.ts index 091a75efd..74495ab91 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-accolade/edition-svg-sheet-viewer/edition-svg-sheet-viewer.component.spec.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-accolade/edition-svg-sheet-viewer/edition-svg-sheet-viewer.component.spec.ts @@ -12,6 +12,7 @@ import { clickAndAwaitChanges } from '@testing/click-helper'; import { expectSpyCall, expectToBe, + expectToContain, expectToEqual, getAndExpectDebugElementByCss, getAndExpectDebugElementByDirective, @@ -216,7 +217,7 @@ describe('EditionSvgSheetViewerComponent', () => { it('... injected service should use provided mockValue', () => { const svgDrawingService = TestBed.inject(EditionSvgDrawingService); - expect(svgDrawingService === mockEditionSvgDrawingService).toBe(true); + expectToBe(svgDrawingService === mockEditionSvgDrawingService, true); }); describe('BEFORE initial data binding', () => { @@ -414,9 +415,9 @@ describe('EditionSvgSheetViewerComponent', () => { expectToBe(buttonEl.getAttribute('title'), 'Reset zoom'); expectToBe(buttonEl.getAttribute('type'), 'submit'); - expect(buttonEl.classList).toContain('btn'); - expect(buttonEl.classList).toContain('btn-sm'); - expect(buttonEl.classList).toContain('btn-outline-info'); + expectToContain(buttonEl.classList, 'btn'); + expectToContain(buttonEl.classList, 'btn-sm'); + expectToContain(buttonEl.classList, 'btn-outline-info'); }); it('... should display compress icon in button', () => { @@ -739,11 +740,13 @@ describe('EditionSvgSheetViewerComponent', () => { const overlayGroupRectSelection = expectedOverlayGroups.select( `#${overlay.id} rect.${expectedOverlayType}` ); - expect(serviceUpdateTkkOverlayColorSpy.calls.all()[index].args[0]).toEqual(overlay); - expect(serviceUpdateTkkOverlayColorSpy.calls.all()[index].args[1]).toEqual( + expectToEqual(serviceUpdateTkkOverlayColorSpy.calls.all()[index].args[0], overlay); + expectToEqual( + serviceUpdateTkkOverlayColorSpy.calls.all()[index].args[1], overlayGroupRectSelection ); - expect(serviceUpdateTkkOverlayColorSpy.calls.all()[index].args[2]).toEqual( + expectToBe( + serviceUpdateTkkOverlayColorSpy.calls.all()[index].args[2], EditionSvgOverlayActionTypes.fill ); }); @@ -758,7 +761,8 @@ describe('EditionSvgSheetViewerComponent', () => { expect(serviceUpdateTkkOverlayColorSpy).toHaveBeenCalledTimes(expectedOverlayGroups.nodes().length); expectedOverlayGroups.nodes().forEach((_node, index) => { - expect(serviceUpdateTkkOverlayColorSpy.calls.all()[index].args[2]).toEqual( + expectToBe( + serviceUpdateTkkOverlayColorSpy.calls.all()[index].args[2], EditionSvgOverlayActionTypes.fill ); }); @@ -773,7 +777,8 @@ describe('EditionSvgSheetViewerComponent', () => { expect(serviceUpdateTkkOverlayColorSpy).toHaveBeenCalledTimes(expectedOverlayGroups.nodes().length); expectedOverlayGroups.nodes().forEach((_node, index) => { - expect(serviceUpdateTkkOverlayColorSpy.calls.all()[index].args[2]).toEqual( + expectToBe( + serviceUpdateTkkOverlayColorSpy.calls.all()[index].args[2], EditionSvgOverlayActionTypes.transparent ); }); @@ -815,17 +820,17 @@ describe('EditionSvgSheetViewerComponent', () => { let expectedZoom = null; component.onZoomChange(expectedZoom); - expect(component.sliderConfig.value).toBe(expectedZoom); + expectToBe(component.sliderConfig.value, expectedZoom); expectedZoom = 5; component.onZoomChange(expectedZoom); - expect(component.sliderConfig.value).toBe(expectedZoom); + expectToBe(component.sliderConfig.value, expectedZoom); expectedZoom = expectedSliderConfig.initial; component.onZoomChange(expectedZoom); - expect(component.sliderConfig.value).toBe(expectedSliderConfig.initial); + expectToBe(component.sliderConfig.value, expectedSliderConfig.initial); }); it('... should trigger `_rescaleZoom` function', () => { @@ -1363,7 +1368,7 @@ describe('EditionSvgSheetViewerComponent', () => { it(`... for stepSize ${stepSize} and given value ${givenValue} returns ${expectedNearestStep}`, () => { component.sliderConfig.stepSize = stepSize; const result = (component as any)._roundToScaleStepDecimalPrecision(givenValue); - expect(result).toBe(expectedNearestStep); + expectToBe(result, expectedNearestStep); }); } } diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-convolute/edition-convolute.component.spec.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-convolute/edition-convolute.component.spec.ts index d74623d07..ca247b37a 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-convolute/edition-convolute.component.spec.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-convolute/edition-convolute.component.spec.ts @@ -127,7 +127,7 @@ describe('EditionConvoluteComponent (DONE)', () => { }); it('... should have faSquare', () => { - expectToBe(component.faSquare, faSquare); + expectToEqual(component.faSquare, faSquare); }); it('... should have folioLegends', () => { @@ -402,7 +402,7 @@ describe('EditionConvoluteComponent (DONE)', () => { const reportLinkDe = linkDes[0]; // Contact link DebugElement const reportLink = routerLinks[0]; // Contact link directive - expect(reportLink.navigatedTo).toBeNull(); + expectToBe(reportLink.navigatedTo, null); click(reportLinkDe); fixture.detectChanges(); @@ -414,7 +414,7 @@ describe('EditionConvoluteComponent (DONE)', () => { const reportLinkDe = linkDes[0]; // Contact link DebugElement const reportLink = routerLinks[0]; // Contact link directive - expect(reportLink.navigatedTo).toBeNull(); + expectToBe(reportLink.navigatedTo, null); click(reportLinkDe); fixture.detectChanges(); diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-convolute/edition-folio-viewer/edition-folio-viewer.component.spec.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-convolute/edition-folio-viewer/edition-folio-viewer.component.spec.ts index f8312f815..9d0b9ab81 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-convolute/edition-folio-viewer/edition-folio-viewer.component.spec.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-convolute/edition-folio-viewer/edition-folio-viewer.component.spec.ts @@ -7,7 +7,13 @@ import Spy = jasmine.Spy; import { cleanStylesFromDOM } from '@testing/clean-up-helper'; import { clickAndAwaitChanges } from '@testing/click-helper'; -import { expectSpyCall, expectToBe, expectToEqual, getAndExpectDebugElementByCss } from '@testing/expect-helper'; +import { + expectSpyCall, + expectToBe, + expectToContain, + expectToEqual, + getAndExpectDebugElementByCss, +} from '@testing/expect-helper'; import { mockEditionData } from '@testing/mock-data'; import { @@ -141,7 +147,7 @@ describe('EditionFolioViewerComponent (DONE)', () => { it('... injected service should use provided mockValue', () => { const folioService = TestBed.inject(FolioService); - expect(mockFolioService === folioService).toBeTrue(); + expectToBe(mockFolioService === folioService, true); }); describe('BEFORE initial data binding', () => { @@ -236,8 +242,8 @@ describe('EditionFolioViewerComponent (DONE)', () => { const expectedLgColClass = 'col-lg-' + Math.floor(12 / expectedFolioSvgDataArray.length); - expect(colEl.classList.contains('col-sm-6')).toBeTrue(); - expect(colEl.classList.contains(expectedLgColClass)).toBeTrue(); + expectToContain(colEl.classList, 'col-sm-6'); + expectToContain(colEl.classList, expectedLgColClass); }); }); @@ -377,8 +383,10 @@ describe('EditionFolioViewerComponent (DONE)', () => { component.createSVGCanvas(); expect(component.viewBoxArray.length).not.toEqual(component.folioSvgDataArray.length); - expectToEqual(component.canvasArray, []); expectToBe(component.canvasArray.length, 0); + expectToBe(component.viewBoxArray.length, 2); + + expectToEqual(component.canvasArray, []); }); it('... svgCanvas is empty', () => { @@ -387,7 +395,7 @@ describe('EditionFolioViewerComponent (DONE)', () => { component.prepareFolioSvgOutput(); component.createSVGCanvas(); - expect(component.canvasArray).toEqual([]); + expectToEqual(component.canvasArray, []); }); }); @@ -451,13 +459,13 @@ describe('EditionFolioViewerComponent (DONE)', () => { it('... the given id matches the selectedSvgSheet id', () => { component.selectedSvgSheet = expectedSvgSheet; - expect(component.isSelectedSvgSheet('test-1')).toBeTrue(); + expectToBe(component.isSelectedSvgSheet('test-1'), true); }); it('... the given id matches the selectedSvgSheet id with partial', () => { component.selectedSvgSheet = expectedSvgSheetWithPartialA; - expect(component.isSelectedSvgSheet('test-2a')).toBeTrue(); + expectToBe(component.isSelectedSvgSheet('test-2a'), true); }); }); @@ -465,19 +473,19 @@ describe('EditionFolioViewerComponent (DONE)', () => { it('... the given id does not match the selectedSvgSheet id', () => { component.selectedSvgSheet = expectedSvgSheet; - expect(component.isSelectedSvgSheet('other-test')).toBeFalse(); + expectToBe(component.isSelectedSvgSheet('other-test'), false); }); it('... given the id does not match the selectedSvgSheet id with partial', () => { component.selectedSvgSheet = expectedSvgSheetWithPartialA; - expect(component.isSelectedSvgSheet('test-2b')).toBeFalse(); + expectToBe(component.isSelectedSvgSheet('test-2b'), false); }); it('... selectedSvgSheet is undefined', () => { component.selectedSvgSheet = undefined; - expect(component.isSelectedSvgSheet('test-1')).toBeFalse(); + expectToBe(component.isSelectedSvgSheet('test-1'), false); }); }); }); @@ -730,15 +738,15 @@ describe('EditionFolioViewerComponent (DONE)', () => { component.toggleActiveClass(); - expect(svgGroupSelection1.classed('active')).toBe(true); - expect(svgGroupSelection2.classed('active')).toBe(false); + expectToBe(svgGroupSelection1.classed('active'), true); + expectToBe(svgGroupSelection2.classed('active'), false); isSelectedSvgSheetSpy.and.callFake(contentSegmentId => contentSegmentId === 'another-id'); component.toggleActiveClass(); - expect(svgGroupSelection1.classed('active')).toBe(false); - expect(svgGroupSelection2.classed('active')).toBe(true); + expectToBe(svgGroupSelection1.classed('active'), false); + expectToBe(svgGroupSelection2.classed('active'), true); }); }); diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-convolute/edition-folio-viewer/folio.service.spec.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-convolute/edition-folio-viewer/folio.service.spec.ts index db422fb40..c51296e71 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-convolute/edition-folio-viewer/folio.service.spec.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-convolute/edition-folio-viewer/folio.service.spec.ts @@ -17,7 +17,7 @@ import { FolioSvgContentSegment, FolioSvgData, ViewBox, -} from '@awg-app/views/edition-view/models'; +} from '@awg-views/edition-view/models'; import { mockConsole } from '@testing/mock-helper'; import { FolioService } from './folio.service'; @@ -48,6 +48,7 @@ describe('FolioService (DONE)', () => { let expectedConvolutes: FolioConvolute[]; let expectedFolioSettings: FolioSettings; let expectedFolioSvgData: FolioSvgData; + let expectedDefaultFolio: Folio; let expectedReversedFolio: Folio; let expectedUpperLeftCorner: FolioCalculationPoint; @@ -81,6 +82,7 @@ describe('FolioService (DONE)', () => { // Test data expectedConvolutes = JSON.parse(JSON.stringify(mockEditionData.mockFolioConvoluteData.convolutes)); + expectedDefaultFolio = expectedConvolutes[0].folios[0]; expectedReversedFolio = JSON.parse(JSON.stringify(mockEditionData.mockReversedFolio)); expectedFolioSettings = { factor: 1.5, @@ -109,11 +111,7 @@ describe('FolioService (DONE)', () => { expectedLowerRightCorner = new FolioCalculationPoint(30, 40); expectedFolioSvgData = new FolioSvgData( - new FolioCalculation( - expectedFolioSettings, - expectedConvolutes[0].folios[0], - expectedContentSegmentOffsetCorrection - ) + new FolioCalculation(expectedFolioSettings, expectedDefaultFolio, expectedContentSegmentOffsetCorrection) ); // Spies on service functions @@ -181,7 +179,7 @@ describe('FolioService (DONE)', () => { it('... should use mock console', () => { console.error('Test'); - expect(mockConsole.get(0)).toBe('Test'); + expectToBe(mockConsole.get(0), 'Test'); }); it('... should clear mock console after each run', () => { @@ -257,7 +255,7 @@ describe('FolioService (DONE)', () => { it('... should return an instance of FolioSvgData object', () => { // Create mock FolioSettings and Folio objects const folioSettings: FolioSettings = expectedFolioSettings; - const folio: Folio = expectedConvolutes[0].folios[0]; + const folio: Folio = expectedDefaultFolio; // Call the method with the mock objects const result = folioService.getFolioSvgData(folioSettings, folio); @@ -269,8 +267,7 @@ describe('FolioService (DONE)', () => { it('... should create a new FolioCalculation object with the correct parameters', () => { // Create mock FolioSettings and Folio objects const folioSettings: FolioSettings = expectedFolioSettings; - const folio: Folio = expectedConvolutes[0].folios[0]; - + const folio: Folio = expectedDefaultFolio; const result = folioService.getFolioSvgData(folioSettings, folio); expectToEqual(result, expectedFolioSvgData); @@ -279,7 +276,7 @@ describe('FolioService (DONE)', () => { it('... should create a new FolioCalculation object when contentSegmentOffsetCorrection is undefined', () => { // Create mock FolioSettings and Folio objects const folioSettings: FolioSettings = expectedFolioSettings; - const folio: Folio = expectedConvolutes[0].folios[0]; + const folio: Folio = expectedDefaultFolio; const expectedFolioSvgDataWithoutOffset = new FolioSvgData(new FolioCalculation(folioSettings, folio, 0)); @@ -373,7 +370,7 @@ describe('FolioService (DONE)', () => { }); it('should set the ref variable', () => { - expect(folioService.ref).toBe(ref); + expectToEqual(folioService.ref, ref); }); it('... should trigger `_appendCanvasSheetGroup` method', () => { @@ -382,7 +379,7 @@ describe('FolioService (DONE)', () => { it('should append one SVG sheet group to the svg canvas', () => { expect(svgSheetGroup).toBeDefined(); - expect(svgSheetGroup.size()).toBe(1); + expectToBe(svgSheetGroup.size(), 1); }); it('... should trigger `_addFolioSheetToSvgCanvas` method', () => { @@ -859,7 +856,7 @@ describe('FolioService (DONE)', () => { const sheetGroup = svgCanvas.select('g.sheet-group'); expect(sheetGroup).toBeDefined(); - expect(sheetGroup.size()).toBe(1); + expectToBe(sheetGroup.size(), 1); }); it('... should set the `sheetGroupId` attribute of the sheet group', () => { @@ -1372,8 +1369,8 @@ describe('FolioService (DONE)', () => { const callArgs = appendSvgElementWithAttrsSpy.calls.argsFor(i); const expectedArgs = [...commonArgs, i === 0 ? {} : additionalAttributes]; - expect(callArgs.length).toBe(expectedArgs.length); - expect(callArgs).toEqual(expectedArgs); + expectToBe(callArgs.length, expectedArgs.length); + expectToEqual(callArgs, expectedArgs); }); }); diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-sheets.component.html b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-sheets.component.html index 607023861..b08deaa0b 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-sheets.component.html +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-sheets.component.html @@ -3,30 +3,40 @@ - - + + @if (isLoading) { + + } @else { + + @if (errorObject) { + + } @else { +
+ + + - - - - - @if (selectedConvolute && selectedSvgSheet) { - - + + @if (selectedConvolute && selectedSvgSheet) { + + + } +
+ } } diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-sheets.component.spec.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-sheets.component.spec.ts index 50f2cdae1..2b1957a68 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-sheets.component.spec.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-sheets.component.spec.ts @@ -1,20 +1,23 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ +import { JsonPipe } from '@angular/common'; import { Component, DebugElement, EventEmitter, Input, Output } from '@angular/core'; import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { ActivatedRoute, NavigationEnd, Router } from '@angular/router'; -import { Observable, of as observableOf } from 'rxjs'; +import { Observable, of as observableOf, throwError as observableThrowError } from 'rxjs'; import Spy = jasmine.Spy; -import { NgbModalModule } from '@ng-bootstrap/ng-bootstrap'; - -import { expectSpyCall, expectToEqual, getAndExpectDebugElementByDirective } from '@testing/expect-helper'; +import { + expectSpyCall, + expectToBe, + expectToEqual, + getAndExpectDebugElementByCss, + getAndExpectDebugElementByDirective, +} from '@testing/expect-helper'; import { mockEditionData } from '@testing/mock-data'; import { ActivatedRouteStub, UrlSegmentStub } from '@testing/router-stubs'; import { CompileHtmlComponent } from '@awg-shared/compile-html'; -import { ModalComponent } from '@awg-shared/modal/modal.component'; -import { EDITION_COMPLEXES } from '@awg-views/edition-view/data'; import { EDITION_ROUTE_CONSTANTS } from '@awg-views/edition-view/edition-route-constants'; import { EditionComplex, @@ -23,12 +26,18 @@ import { EditionSvgSheetList, FolioConvolute, FolioConvoluteList, - TextcriticalComment, + TextcriticalCommentBlock, Textcritics, TextcriticsList, } from '@awg-views/edition-view/models'; -import { EditionDataService, EditionService, EditionSheetsService } from '@awg-views/edition-view/services'; +import { + EditionComplexesService, + EditionDataService, + EditionService, + EditionSheetsService, +} from '@awg-views/edition-view/services'; +import { detectChangesOnPush } from '@testing/detect-changes-on-push-helper'; import { EditionSheetsComponent } from './edition-sheets.component'; @Component({ selector: 'awg-edition-accolade', template: '' }) @@ -38,7 +47,7 @@ class EditionAccoladeStubComponent { @Input() selectedSvgSheet: EditionSvgSheet; @Input() - selectedTextcriticalComments: TextcriticalComment[]; + selectedTextcriticalCommentBlocks: TextcriticalCommentBlock[]; @Input() selectedTextcritics: Textcritics; @Input() @@ -69,6 +78,22 @@ class EditionConvoluteStubComponent { selectSvgSheetRequest: EventEmitter<{ complexId: string; sheetId: string }> = new EventEmitter(); } +@Component({ selector: 'awg-error-alert', template: '' }) +class ErrorAlertStubComponent { + @Input() + errorObject: any; +} + +@Component({ selector: 'awg-modal', template: '' }) +class ModalStubComponent { + modalContent: string; + open(modalContentSnippetKey: string): void { + this.modalContent = modalContentSnippetKey; + } +} +@Component({ selector: 'awg-twelve-tone-spinner', template: '' }) +class TwelveToneSpinnerStubComponent {} + describe('EditionSheetsComponent', () => { let component: EditionSheetsComponent; let fixture: ComponentFixture; @@ -84,7 +109,7 @@ describe('EditionSheetsComponent', () => { let mockEditionSheetsService: Partial; let editionDataServiceGetEditionSheetsDataSpy: Spy; - let editionServiceGetEditionComplexSpy: Spy; + let editionServiceGetSelectedEditionComplexSpy: Spy; let editionSheetsServiceSelectSvgSheetByIdSpy: Spy; let editionSheetsServiceSelectConvoluteSpy: Spy; let getEditionSheetsDataSpy: Spy; @@ -92,6 +117,7 @@ describe('EditionSheetsComponent', () => { let navigateWithComplexIdSpy: Spy; let navigationSpy: Spy; let onSvgSheetSelectSpy: Spy; + let selectSvgSheetSpy: Spy; let expectedEditionComplex: EditionComplex; let expectedFolioConvoluteData: FolioConvoluteList; @@ -106,6 +132,12 @@ describe('EditionSheetsComponent', () => { let expectedReportFragment: string; const expectedEditionRouteConstants: typeof EDITION_ROUTE_CONSTANTS = EDITION_ROUTE_CONSTANTS; + const jsonPipe = new JsonPipe(); + + beforeAll(() => { + EditionComplexesService.initializeEditionComplexesList(); + }); + beforeEach(waitForAsync(() => { // Mock router with spy object // Router spy object @@ -131,7 +163,7 @@ describe('EditionSheetsComponent', () => { ): Observable<(FolioConvoluteList | EditionSvgSheetList | TextcriticsList)[]> => observableOf([]), }; mockEditionService = { - getEditionComplex: (): Observable => observableOf(), + getSelectedEditionComplex: (): Observable => observableOf(), }; mockEditionSheetsService = { selectSvgSheetById: (sheets: EditionSvgSheetList['sheets'], id: string): EditionSvgSheet => @@ -144,13 +176,14 @@ describe('EditionSheetsComponent', () => { }; TestBed.configureTestingModule({ - imports: [NgbModalModule], declarations: [ CompileHtmlComponent, EditionSheetsComponent, EditionConvoluteStubComponent, EditionAccoladeStubComponent, - ModalComponent, + ErrorAlertStubComponent, + ModalStubComponent, + TwelveToneSpinnerStubComponent, ], providers: [ { provide: EditionDataService, useValue: mockEditionDataService }, @@ -172,7 +205,7 @@ describe('EditionSheetsComponent', () => { mockActivatedRoute.testQueryParamMap = { id: '' }; // Test data - expectedEditionComplex = EDITION_COMPLEXES.OP12; + expectedEditionComplex = EditionComplexesService.getEditionComplexById('OP12'); expectedComplexId = 'op12'; expectedNextComplexId = 'testComplex2'; expectedEditionComplexBaseRoute = `/edition/complex/${expectedComplexId}/`; @@ -192,9 +225,10 @@ describe('EditionSheetsComponent', () => { mockEditionDataService, 'getEditionSheetsData' ).and.returnValue(observableOf([expectedFolioConvoluteData, expectedSvgSheetsData, expectedTextcriticsData])); - editionServiceGetEditionComplexSpy = spyOn(mockEditionService, 'getEditionComplex').and.returnValue( - observableOf(expectedEditionComplex) - ); + editionServiceGetSelectedEditionComplexSpy = spyOn( + mockEditionService, + 'getSelectedEditionComplex' + ).and.returnValue(observableOf(expectedEditionComplex)); editionSheetsServiceSelectSvgSheetByIdSpy = spyOn( mockEditionSheetsService, 'selectSvgSheetById' @@ -202,11 +236,15 @@ describe('EditionSheetsComponent', () => { editionSheetsServiceSelectConvoluteSpy = spyOn(mockEditionSheetsService, 'selectConvolute').and.returnValue( expectedFolioConvoluteData[0] ); + + navigationSpy = mockRouter.navigate as jasmine.Spy; + getEditionSheetsDataSpy = spyOn(component, 'getEditionSheetsData').and.callThrough(); navigateToReportFragmentSpy = spyOn(component, 'onReportFragmentNavigate').and.callThrough(); - navigateWithComplexIdSpy = spyOn(component as any, '_navigateWithComplexId').and.callThrough(); - navigationSpy = mockRouter.navigate as jasmine.Spy; onSvgSheetSelectSpy = spyOn(component, 'onSvgSheetSelect').and.callThrough(); + + navigateWithComplexIdSpy = spyOn(component as any, '_navigateWithComplexId').and.callThrough(); + selectSvgSheetSpy = spyOn(component as any, '_selectSvgSheet').and.callThrough(); }); it('... should create', () => { @@ -218,8 +256,12 @@ describe('EditionSheetsComponent', () => { expect(component.editionComplex).toBeUndefined(); }); - it('... should not have `errorMessage`', () => { - expect(component.errorMessage).toBeUndefined(); + it('... should have `errorObject` = null', () => { + expectToBe(component.errorObject, null); + }); + + it('... should have `isLoading===true`', () => { + expectToBe(component.isLoading, true); }); it('... should not have `folioConvoluteData`', () => { @@ -234,8 +276,8 @@ describe('EditionSheetsComponent', () => { expect(component.selectedSvgSheet).toBeUndefined(); }); - it('... should not have `selectedTextcriticalComments`', () => { - expect(component.selectedTextcriticalComments).toBeUndefined(); + it('... should not have `selectedTextcriticalCommentBlocks`', () => { + expect(component.selectedTextcriticalCommentBlocks).toBeUndefined(); }); it('... should not have `selectedTextcritics`', () => { @@ -243,7 +285,7 @@ describe('EditionSheetsComponent', () => { }); it('... should have `showTkA===false`', () => { - expect(component.showTkA).toBeFalse(); + expectToBe(component.showTkA, false); }); it('... should not have `snapshotQueryParamsId`', () => { @@ -259,12 +301,44 @@ describe('EditionSheetsComponent', () => { }); it('... should have `_isFirstPageLoad===true`', () => { - expect((component as any)._isFirstPageLoad).toBeTrue(); + expectToBe((component as any)._isFirstPageLoad, true); }); it('... should have `editionRouteConstants` getter', () => { expectToEqual(component.editionRouteConstants, expectedEditionRouteConstants); }); + + describe('VIEW', () => { + it('... should contain a `div`', () => { + getAndExpectDebugElementByCss(compDe, 'div', 1, 1); + }); + + it('... should contain one modal component (stubbed)', () => { + const divDes = getAndExpectDebugElementByCss(compDe, 'div', 1, 1); + + getAndExpectDebugElementByDirective(divDes[0], ModalStubComponent, 1, 1); + }); + + it('... should not contain an error alert component (stubbed)', () => { + const divDes = getAndExpectDebugElementByCss(compDe, 'div', 1, 1); + + getAndExpectDebugElementByDirective(divDes[0], ErrorAlertStubComponent, 0, 0); + }); + + it('... should not contain a loading spinner component (stubbed)', () => { + const divDes = getAndExpectDebugElementByCss(compDe, 'div', 1, 1); + + getAndExpectDebugElementByDirective(divDes[0], TwelveToneSpinnerStubComponent, 0, 0); + }); + + it('... should not contain an AccoladeComponent (stubbed)', () => { + getAndExpectDebugElementByDirective(compDe, EditionAccoladeStubComponent, 0, 0); + }); + + it('... should not contain a ConvoluteComponent (stubbed)', () => { + getAndExpectDebugElementByDirective(compDe, EditionConvoluteStubComponent, 0, 0); + }); + }); }); describe('AFTER initial data binding', () => { @@ -289,6 +363,64 @@ describe('EditionSheetsComponent', () => { expectToEqual(mockActivatedRoute.snapshot.url[0].path, changedPath); }); + describe('VIEW', () => { + it('... should contain one div.awg-sheets-view', () => { + getAndExpectDebugElementByCss(compDe, 'div.awg-sheets-view', 1, 1); + }); + + it('... should contain one AccoladeComponent (stubbed)', () => { + getAndExpectDebugElementByDirective(compDe, EditionAccoladeStubComponent, 1, 1); + }); + + it('... should contain no ConvoluteComponent (stubbed) if no convolute is provided', () => { + getAndExpectDebugElementByDirective(compDe, EditionConvoluteStubComponent, 0, 0); + }); + + describe('on error', () => { + const expectedError = { status: 404, statusText: 'got Error' }; + + beforeEach(waitForAsync(() => { + // Spy on editionDataService to return an error + editionDataServiceGetEditionSheetsDataSpy.and.returnValue( + observableThrowError(() => expectedError) + ); + + component.getEditionSheetsData(); + detectChangesOnPush(fixture); + })); + + it('... should not contain sheets view, but one ErrorAlertComponent (stubbed)', waitForAsync(() => { + getAndExpectDebugElementByCss(compDe, 'div.awg-sheets-view', 0, 0); + + const divDes = getAndExpectDebugElementByCss(compDe, 'div', 1, 1); + getAndExpectDebugElementByDirective(divDes[0], ErrorAlertStubComponent, 1, 1); + })); + + it('... should pass down error object to ErrorAlertComponent', waitForAsync(() => { + const errorAlertDes = getAndExpectDebugElementByDirective(compDe, ErrorAlertStubComponent, 1, 1); + const errorAlertCmp = errorAlertDes[0].injector.get( + ErrorAlertStubComponent + ) as ErrorAlertStubComponent; + + expectToEqual(errorAlertCmp.errorObject, expectedError); + })); + }); + + describe('on loading', () => { + describe('... should contain only TwelveToneSpinnerComponent (stubbed) if ... ', () => { + it('... isLoading is true', () => { + component.isLoading = true; + detectChangesOnPush(fixture); + + getAndExpectDebugElementByCss(compDe, 'div.awg-sheets-view', 0, 0); + getAndExpectDebugElementByDirective(compDe, ErrorAlertStubComponent, 0, 0); + + getAndExpectDebugElementByDirective(compDe, TwelveToneSpinnerStubComponent, 1, 1); + }); + }); + }); + }); + describe('#onReportFragmentNavigate()', () => { it('... should have a method `onReportFragmentNavigate`', () => { expect(component.onReportFragmentNavigate).toBeDefined(); @@ -523,6 +655,232 @@ describe('EditionSheetsComponent', () => { }); }); + describe('#_assignData()', () => { + it('... should have a method `_assignData`', () => { + expect((component as any)._assignData).toBeDefined(); + }); + + it('... should assign data from the service to the component', () => { + component.folioConvoluteData = undefined; + component.svgSheetsData = undefined; + component.textcriticsData = undefined; + detectChangesOnPush(fixture); + + const expectedData = [expectedFolioConvoluteData, expectedSvgSheetsData, expectedTextcriticsData]; + + (component as any)._assignData(expectedData); + + expectToEqual(component.folioConvoluteData, expectedFolioConvoluteData); + expectToEqual(component.svgSheetsData, expectedSvgSheetsData); + expectToEqual(component.textcriticsData, expectedTextcriticsData); + }); + }); + + describe('#_getDefaultSheetId()', () => { + it('... should have a method `_getDefaultSheetId`', () => { + expect((component as any)._getDefaultSheetId).toBeDefined(); + }); + + describe('... should return an empty string if', () => { + it('... should return an empty string if svgSheetsData is undefined', () => { + component.svgSheetsData = undefined; + detectChangesOnPush(fixture); + + const result = (component as any)._getDefaultSheetId(); + + expectToBe(result, ''); + }); + + it('... should return an empty string if svgSheetsData.sheets.sketchEditions is an empty array', () => { + component.svgSheetsData = { sheets: { sketchEditions: [] } } as EditionSvgSheetList; + detectChangesOnPush(fixture); + + const result = (component as any)._getDefaultSheetId(); + + expectToBe(result, ''); + }); + }); + + it('... should return the id of the first sketch sheet by default (no partials)', () => { + const mockSheet1 = { id: 'sheet1', content: [] } as EditionSvgSheet; + + component.svgSheetsData = { + sheets: { sketchEditions: [mockSheet1] }, + } as EditionSvgSheetList; + detectChangesOnPush(fixture); + + const result = (component as any)._getDefaultSheetId(); + + expectToBe(result, mockSheet1.id); + }); + + it('... should return the id and first partial of the first sketch sheet by default if partials are present', () => { + const mockSheet1 = { + id: 'sheet1', + content: [ + { svg: '', image: '', partial: 'a' }, + { svg: '', image: '', partial: 'b' }, + ], + } as EditionSvgSheet; + component.svgSheetsData = { + sheets: { sketchEditions: [mockSheet1] }, + } as EditionSvgSheetList; + detectChangesOnPush(fixture); + + const result = (component as any)._getDefaultSheetId(); + + expectToBe(result, 'sheet1a'); + }); + + it('... should return the first id and partial of the first sketch sheet from a list of multiple sheets', () => { + const mockSheet1 = { + id: 'sheet1', + content: [ + { svg: '', image: '', partial: 'a' }, + { svg: '', image: '', partial: 'b' }, + ], + } as EditionSvgSheet; + const mockSheet2 = { + id: 'sheet2', + content: [ + { svg: '', image: '', partial: 'c' }, + { svg: '', image: '', partial: 'd' }, + ], + } as EditionSvgSheet; + component.svgSheetsData = { + sheets: { sketchEditions: [mockSheet1, mockSheet2] }, + } as EditionSvgSheetList; + + const result = (component as any)._getDefaultSheetId(); + + expectToBe(result, 'sheet1a'); + }); + + it('... should return the first id and partial of the first sketch sheet from a list of multiple edition types', () => { + const mockSheet1 = { + id: 'sheet1', + content: [ + { svg: '', image: '', partial: 'a' }, + { svg: '', image: '', partial: 'b' }, + ], + } as EditionSvgSheet; + const mockSheet2 = { id: 'sheet2', content: [] } as EditionSvgSheet; + const mockSheet3 = { + id: 'sheet3', + content: [ + { svg: '', image: '', partial: 'c' }, + { svg: '', image: '', partial: 'd' }, + ], + } as EditionSvgSheet; + component.svgSheetsData = { + sheets: { + workEditions: [mockSheet1], + textEditions: [mockSheet2], + sketchEditions: [mockSheet3], + }, + } as EditionSvgSheetList; + + const result = (component as any)._getDefaultSheetId(); + + expectToBe(result, 'sheet3c'); + }); + }); + + describe('#_handleQueryParams()', () => { + it('... should have a method `_handleQueryParams`', () => { + expect((component as any)._handleQueryParams).toBeDefined(); + }); + + describe('... with svgSheetsData available and id given from query params', () => { + it('... should trigger `_selectSvgSheet` with the correct sheet id', () => { + const sheetId = 'test-TF1'; + mockActivatedRoute.testQueryParamMap = { id: sheetId }; + detectChangesOnPush(fixture); + + (component as any)._handleQueryParams(mockActivatedRoute.testQueryParamMap); + + expectSpyCall(selectSvgSheetSpy, 2, sheetId); + }); + }); + + describe('... with svgSheetsData available and id not given from query params', () => { + it('... should trigger `onSvgSheetSelect` with snapshotQueryParamsId on first page load', () => { + mockActivatedRoute.testQueryParamMap = { id: '' }; + (component as any)._isFirstPageLoad = true; + + const snapShotSheetId = 'test-TF1'; + component.snapshotQueryParamsId = snapShotSheetId; + detectChangesOnPush(fixture); + + (component as any)._handleQueryParams(mockActivatedRoute.testQueryParamMap); + + expectSpyCall(onSvgSheetSelectSpy, 3, { + complexId: '', + sheetId: snapShotSheetId, + }); + }); + + it('... should trigger `onSvgSheetSelect` with default id on subsequent page loads', () => { + mockActivatedRoute.testQueryParamMap = { id: '' }; + (component as any)._isFirstPageLoad = false; + + const defaultSheetId = 'test-1'; + const snapShotSheetId = 'test-TF1'; + component.snapshotQueryParamsId = snapShotSheetId; + detectChangesOnPush(fixture); + + (component as any)._handleQueryParams(mockActivatedRoute.testQueryParamMap); + + expectSpyCall(onSvgSheetSelectSpy, 3, { + complexId: '', + sheetId: defaultSheetId, + }); + }); + }); + + describe('... with svgSheetsData not available and id not given from query params', () => { + it('... should trigger `onSvgSheetSelect` with no id', () => { + mockActivatedRoute.testQueryParamMap = { id: '' }; + (component as any)._isFirstPageLoad = true; + + component.svgSheetsData = undefined; + component.snapshotQueryParamsId = ''; + detectChangesOnPush(fixture); + + (component as any)._handleQueryParams(mockActivatedRoute.testQueryParamMap); + + expectSpyCall(onSvgSheetSelectSpy, 3, { + complexId: '', + sheetId: '', + }); + }); + it('... should reset selectedSvgSheet to undefined', () => { + mockActivatedRoute.testQueryParamMap = { id: '' }; + (component as any)._isFirstPageLoad = true; + + component.svgSheetsData = undefined; + component.snapshotQueryParamsId = ''; + detectChangesOnPush(fixture); + + (component as any)._handleQueryParams(mockActivatedRoute.testQueryParamMap); + + expect(component.selectedSvgSheet).toBeUndefined(); + }); + }); + + it('... should set _isFirstPageLoad and isLoading to false after handling query params', () => { + component.isLoading = true; + (component as any)._isFirstPageLoad = true; + mockActivatedRoute.testQueryParamMap = { id: 'sheetId' }; + detectChangesOnPush(fixture); + + (component as any)._handleQueryParams(mockActivatedRoute.testQueryParamMap); + + expectToBe((component as any)._isFirstPageLoad, false); + expectToBe(component.isLoading, false); + }); + }); + describe('#_navigateWithComplexId()', () => { it('... should have a method `_navigateWithComplexId`', () => { expect((component as any)._navigateWithComplexId).toBeDefined(); diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-sheets.component.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-sheets.component.ts index e4057d299..8d12768c0 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-sheets.component.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-sheets/edition-sheets.component.ts @@ -1,8 +1,8 @@ import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core'; import { ActivatedRoute, NavigationExtras, ParamMap, Router } from '@angular/router'; -import { Observable, Subject, combineLatest } from 'rxjs'; -import { switchMap, takeUntil, tap } from 'rxjs/operators'; +import { EMPTY, Observable, Subject, combineLatest } from 'rxjs'; +import { catchError, switchMap, takeUntil, tap } from 'rxjs/operators'; import { UtilityService } from '@awg-core/services'; import { ModalComponent } from '@awg-shared/modal/modal.component'; @@ -14,7 +14,7 @@ import { EditionSvgSheetList, FolioConvolute, FolioConvoluteList, - TextcriticalComment, + TextcriticalCommentBlock, Textcritics, TextcriticsList, } from '@awg-views/edition-view/models'; @@ -50,11 +50,18 @@ export class EditionSheetsComponent implements OnInit, OnDestroy { editionComplex: EditionComplex; /** - * Public variable: errorMessage. + * Public variable: errorObject. * - * It keeps an errorMessage for the service calls. + * It keeps an errorObject for the service calls. */ - errorMessage: string = undefined; + errorObject = null; + + /** + * Public variable: isLoading. + * + * It keeps the loading status of the edition sheets. + */ + isLoading = true; /** * Public variable: folioConvoluteData. @@ -78,11 +85,11 @@ export class EditionSheetsComponent implements OnInit, OnDestroy { selectedSvgSheet: EditionSvgSheet; /** - * Public variable: selectedTextcriticalComments. + * Public variable: selectedTextcriticalCommentBlocks. * - * It keeps the selected textcritical comments. + * It keeps the selected textcritical comment blocks. */ - selectedTextcriticalComments: TextcriticalComment[]; + selectedTextcriticalCommentBlocks: TextcriticalCommentBlock[]; /** * Public variable: selectedTextcritics. @@ -183,18 +190,28 @@ export class EditionSheetsComponent implements OnInit, OnDestroy { * @returns {void} Gets the current edition complex and all necessary edition data. */ getEditionSheetsData(): void { + this.errorObject = null; + this.snapshotQueryParamsId = this.route.snapshot.queryParamMap.get('id'); combineLatest([this.route.paramMap, this.route.queryParamMap]) .pipe( switchMap(([_params, queryParams]) => this._fetchEditionComplexData(queryParams)), + // Error handling + catchError(err => { + this.errorObject = err; + this.isLoading = false; + return EMPTY; + }), takeUntil(this._destroyed$) ) .subscribe({ - next: () => {}, + next: () => { + this.isLoading = false; + }, error: err => { - console.error(err); - this.errorMessage = err; + this.errorObject = err; + this.isLoading = false; }, }); } @@ -247,12 +264,12 @@ export class EditionSheetsComponent implements OnInit, OnDestroy { * @returns {void} Sets the selectedTextcriticalComments and showTka variable. */ onOverlaySelect(overlays: EditionSvgOverlay[]): void { - this.selectedTextcriticalComments = this.editionSheetsService.getTextcriticalCommentsForOverlays( + this.selectedTextcriticalCommentBlocks = this.editionSheetsService.getTextcriticalCommentsForOverlays( this.selectedTextcritics.comments, overlays ); - this.showTkA = this.utils.isNotEmptyArray(this.selectedTextcriticalComments); + this.showTkA = this.utils.isNotEmptyArray(this.selectedTextcriticalCommentBlocks); } /** @@ -343,7 +360,8 @@ export class EditionSheetsComponent implements OnInit, OnDestroy { private _fetchEditionComplexData( queryParams: ParamMap ): Observable { - return this.editionService.getEditionComplex().pipe( + this.isLoading = true; + return this.editionService.getSelectedEditionComplex().pipe( // Set editionComplex tap((complex: EditionComplex) => (this.editionComplex = complex)), // Get editionSheetsData @@ -388,6 +406,12 @@ export class EditionSheetsComponent implements OnInit, OnDestroy { ? this.snapshotQueryParamsId : this._getDefaultSheetId(); + // Reset selectedSvgSheet if no sheetId is provided + if (sheetIdFromQueryParams === '') { + this.selectedSvgSheet = undefined; + } + + // Navigate once more to the selected sheet this.onSvgSheetSelect({ complexId: '', sheetId: sheetIdFromQueryParams, @@ -395,6 +419,7 @@ export class EditionSheetsComponent implements OnInit, OnDestroy { } this._isFirstPageLoad = false; + this.isLoading = false; } /** @@ -444,7 +469,7 @@ export class EditionSheetsComponent implements OnInit, OnDestroy { this.utils.isNotEmptyObject(this.selectedTextcritics) && this.utils.isNotEmptyArray(this.selectedTextcritics.comments) ) { - this.selectedTextcriticalComments = this.selectedTextcritics.comments; + this.selectedTextcriticalCommentBlocks = this.selectedTextcritics.comments; } } } diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-tka/edition-tka-description/edition-tka-description.component.spec.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-tka/edition-tka-description/edition-tka-description.component.spec.ts index 41f3c24a2..06a6483d4 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-tka/edition-tka-description/edition-tka-description.component.spec.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-tka/edition-tka-description/edition-tka-description.component.spec.ts @@ -12,7 +12,7 @@ import { } from '@testing/expect-helper'; import { mockEditionData } from '@testing/mock-data'; -import { CompileHtmlComponent } from '@awg-app/shared/compile-html'; +import { CompileHtmlComponent } from '@awg-shared/compile-html'; import { EditionSvgSheet } from '@awg-views/edition-view/models'; import { DOCUMENT } from '@angular/common'; diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-tka/edition-tka-table/edition-tka-table.component.html b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-tka/edition-tka-table/edition-tka-table.component.html index 99a3f9a9b..b1d6a69a5 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-tka/edition-tka-table/edition-tka-table.component.html +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-tka/edition-tka-table/edition-tka-table.component.html @@ -8,15 +8,24 @@ } - @if (textcriticalComments) { + @if (textcriticalCommentBlocks) {
- @for (textcriticalComment of textcriticalComments; track $index) { - - - - - - + @for (textcriticalCommentBlock of textcriticalCommentBlocks; track $index) { + @if (textcriticalCommentBlock.blockHeader) { + + + + } + @for (textcriticalComment of textcriticalCommentBlock.blockComments; track $index) { + + + + + + + } } } diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-tka/edition-tka-table/edition-tka-table.component.spec.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-tka/edition-tka-table/edition-tka-table.component.spec.ts index c93c56283..f777ee1e9 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-tka/edition-tka-table/edition-tka-table.component.spec.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-tka/edition-tka-table/edition-tka-table.component.spec.ts @@ -8,6 +8,7 @@ import { detectChangesOnPush } from '@testing/detect-changes-on-push-helper'; import { expectSpyCall, expectToBe, + expectToContain, expectToEqual, getAndExpectDebugElementByCss, getAndExpectDebugElementByDirective, @@ -16,7 +17,7 @@ import { mockEditionData } from '@testing/mock-data'; import { CompileHtmlComponent } from '@awg-shared/compile-html'; import { EDITION_GLYPHS_DATA } from '@awg-views/edition-view/data'; -import { EditionSvgSheet, TextcriticalComment, TkaTableHeaderColumn } from '@awg-views/edition-view/models'; +import { EditionSvgSheet, TextcriticalCommentBlock, TkaTableHeaderColumn } from '@awg-views/edition-view/models'; import { EditionTkaTableComponent } from './edition-tka-table.component'; @@ -44,8 +45,9 @@ describe('EditionTkaTableComponent (DONE)', () => { let expectedNextComplexId: string; let expectedSvgSheet: EditionSvgSheet; let expectedNextSvgSheet: EditionSvgSheet; - let expectedTextcriticalComments: TextcriticalComment[]; + let expectedTextcriticalCommentBlocks: TextcriticalCommentBlock[]; let expectedTableHeaderStrings: { [key: string]: TkaTableHeaderColumn[] }; + let expectedTotalRows: number; beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ @@ -68,7 +70,14 @@ describe('EditionTkaTableComponent (DONE)', () => { expectedModalSnippet = JSON.parse(JSON.stringify(mockEditionData.mockModalSnippet)); expectedSvgSheet = JSON.parse(JSON.stringify(mockEditionData.mockSvgSheet_Sk1)); expectedNextSvgSheet = JSON.parse(JSON.stringify(mockEditionData.mockSvgSheet_Sk2)); - expectedTextcriticalComments = mockEditionData.mockTextcriticsData.textcritics.at(1).comments; + expectedTextcriticalCommentBlocks = mockEditionData.mockTextcriticsData.textcritics.at(1).comments; + + const totalBlockHeaders = expectedTextcriticalCommentBlocks.filter(block => block.blockHeader).length; + const totalBlockComments = expectedTextcriticalCommentBlocks.reduce( + (acc, block) => acc + block.blockComments.length, + 0 + ); + expectedTotalRows = totalBlockHeaders + totalBlockComments; expectedIsRowTable = false; expectedTableHeaderStrings = { @@ -113,8 +122,8 @@ describe('EditionTkaTableComponent (DONE)', () => { }); describe('BEFORE initial data binding', () => { - it('... should not have textcriticalComments', () => { - expect(component.textcriticalComments).toBeUndefined(); + it('... should not have textcriticalCommentBlocks', () => { + expect(component.textcriticalCommentBlocks).toBeUndefined(); }); it('... should have isRowTable = false', () => { @@ -151,152 +160,200 @@ describe('EditionTkaTableComponent (DONE)', () => { describe('AFTER initial data binding', () => { beforeEach(() => { // Simulate the parent setting the input properties - component.textcriticalComments = expectedTextcriticalComments; + component.textcriticalCommentBlocks = expectedTextcriticalCommentBlocks; component.isRowTable = expectedIsRowTable; // Trigger initial data binding fixture.detectChanges(); }); - it('... should have textcriticalComments', () => { - expectToBe(component.textcriticalComments, expectedTextcriticalComments); + it('... should have textcriticalCommentBlocks', () => { + expectToBe(component.textcriticalCommentBlocks, expectedTextcriticalCommentBlocks); }); describe('VIEW', () => { - it('... should contain one row (tr) with four columns (th) in table head', () => { - const tableHeadDes = getAndExpectDebugElementByCss(compDe, 'table > thead > tr', 1, 1); - getAndExpectDebugElementByCss(tableHeadDes[0], 'th', 4, 4); - }); + describe('... table header', () => { + it('... should contain one row (tr) with four columns (th) in table head', () => { + const tableHeadDes = getAndExpectDebugElementByCss(compDe, 'table > thead > tr', 1, 1); + getAndExpectDebugElementByCss(tableHeadDes[0], 'th', 4, 4); + }); - it('... should display rowTable table header if `isRowTable` flag is given', () => { - component.isRowTable = true; - detectChangesOnPush(fixture); + it('... should display rowTable table header if `isRowTable` flag is given', () => { + component.isRowTable = true; + detectChangesOnPush(fixture); - const tableHeadDes = getAndExpectDebugElementByCss(compDe, 'table > thead > tr', 1, 1); - const columnDes = getAndExpectDebugElementByCss(tableHeadDes[0], 'th', 4, 4); + const tableHeadDes = getAndExpectDebugElementByCss(compDe, 'table > thead > tr', 1, 1); + const columnDes = getAndExpectDebugElementByCss(tableHeadDes[0], 'th', 4, 4); - columnDes.forEach((columnDe, index) => { - const columnEl = columnDe.nativeElement; - expectToBe(columnEl.textContent.trim(), expectedTableHeaderStrings['rowTable'][index].label); + columnDes.forEach((columnDe, index) => { + const columnEl = columnDe.nativeElement; + expectToBe(columnEl.textContent.trim(), expectedTableHeaderStrings['rowTable'][index].label); + }); }); - }); - it('... should display corrections table header if `isCorrections` flag is given', () => { - component.isCorrections = true; - detectChangesOnPush(fixture); + it('... should display corrections table header if `isCorrections` flag is given', () => { + component.isCorrections = true; + detectChangesOnPush(fixture); - const tableHeadDes = getAndExpectDebugElementByCss(compDe, 'table > thead > tr', 1, 1); - const columnDes = getAndExpectDebugElementByCss(tableHeadDes[0], 'th', 4, 4); + const tableHeadDes = getAndExpectDebugElementByCss(compDe, 'table > thead > tr', 1, 1); + const columnDes = getAndExpectDebugElementByCss(tableHeadDes[0], 'th', 4, 4); - columnDes.forEach((columnDe, index) => { - const columnEl = columnDe.nativeElement; - expectToBe(columnEl.textContent.trim(), expectedTableHeaderStrings['corrections'][index].label); + columnDes.forEach((columnDe, index) => { + const columnEl = columnDe.nativeElement; + expectToBe(columnEl.textContent.trim(), expectedTableHeaderStrings['corrections'][index].label); + }); }); - }); - it('... should display default table header if `isRowTable` or `isCorrections` flags are not given', () => { - const tableHeadDes = getAndExpectDebugElementByCss(compDe, 'table > thead > tr', 1, 1); - const columnDes = getAndExpectDebugElementByCss(tableHeadDes[0], 'th', 4, 4); + it('... should display default table header if `isRowTable` or `isCorrections` flags are not given', () => { + const tableHeadDes = getAndExpectDebugElementByCss(compDe, 'table > thead > tr', 1, 1); + const columnDes = getAndExpectDebugElementByCss(tableHeadDes[0], 'th', 4, 4); - columnDes.forEach((columnDe, index) => { - const columnEl = columnDe.nativeElement; - expectToBe(columnEl.textContent.trim(), expectedTableHeaderStrings['default'][index].label); + columnDes.forEach((columnDe, index) => { + const columnEl = columnDe.nativeElement; + expectToBe(columnEl.textContent.trim(), expectedTableHeaderStrings['default'][index].label); + }); }); - }); - it('... should display default table header with adjusted comment colum if `isSketchId` flag is true', () => { - component.isSketchId = true; - detectChangesOnPush(fixture); + it('... should display default table header with adjusted comment colum if `isSketchId` flag is true', () => { + component.isSketchId = true; + detectChangesOnPush(fixture); - const expected = expectedTableHeaderStrings['default']; - expected[3].label = 'Kommentar'; + const expected = expectedTableHeaderStrings['default']; + expected[3].label = 'Kommentar'; - const tableHeadDes = getAndExpectDebugElementByCss(compDe, 'table > thead > tr', 1, 1); - const columnDes = getAndExpectDebugElementByCss(tableHeadDes[0], 'th', 4, 4); + const tableHeadDes = getAndExpectDebugElementByCss(compDe, 'table > thead > tr', 1, 1); + const columnDes = getAndExpectDebugElementByCss(tableHeadDes[0], 'th', 4, 4); - columnDes.forEach((columnDe, index) => { - const columnEl = columnDe.nativeElement; - expectToBe(columnEl.textContent.trim(), expected[index].label); + columnDes.forEach((columnDe, index) => { + const columnEl = columnDe.nativeElement; + expectToBe(columnEl.textContent.trim(), expected[index].label); + }); }); }); - it('... should contain one table body', () => { - const tableDes = getAndExpectDebugElementByCss(compDe, 'table', 1, 1); + describe('... table body', () => { + it('... should contain no table body if textcritical comment blocks are not provided', () => { + component.textcriticalCommentBlocks = undefined; + detectChangesOnPush(fixture); - getAndExpectDebugElementByCss(tableDes[0], 'thead', 1, 1); - getAndExpectDebugElementByCss(tableDes[0], 'tbody', 1, 1); - }); + const tableDes = getAndExpectDebugElementByCss(compDe, 'table', 1, 1); - it('... should contain as many rows (tr) in table body as entries in textcritical comments', () => { - getAndExpectDebugElementByCss( - compDe, - 'table > tbody > tr', - expectedTextcriticalComments.length, - expectedTextcriticalComments.length - ); - }); + getAndExpectDebugElementByCss(tableDes[0], 'thead', 1, 1); + getAndExpectDebugElementByCss(tableDes[0], 'tbody', 0, 0); + }); - it('... should contain four cells (td) in each row (tr) in table body', () => { - const rows = getAndExpectDebugElementByCss( - compDe, - 'table > tbody > tr', - expectedTextcriticalComments.length, - expectedTextcriticalComments.length - ); + it('... should contain one table body if textcritical comment blocks are provided ', () => { + const tableDes = getAndExpectDebugElementByCss(compDe, 'table', 1, 1); - rows.forEach(row => { - getAndExpectDebugElementByCss(row, 'td', 4, 4); + getAndExpectDebugElementByCss(tableDes[0], 'thead', 1, 1); + getAndExpectDebugElementByCss(tableDes[0], 'tbody', 1, 1); }); - }); - it('... should contain correct data in all row cells (tr/td)', () => { - const rows = getAndExpectDebugElementByCss( - compDe, - 'table > tbody > tr', - expectedTextcriticalComments.length, - expectedTextcriticalComments.length - ); - rows.forEach((row, index) => { - const rowCells = getAndExpectDebugElementByCss(row, 'td', 4, 4); - - const measureCell = rowCells[0].nativeElement; - const systemCell = rowCells[1].nativeElement; - const positionCell = rowCells[2].nativeElement; - const commentCell = rowCells[3].nativeElement; - - const measureCellHtmlSnippet = mockDocument.createElement('span'); - measureCellHtmlSnippet.innerHTML = expectedTextcriticalComments[index].measure; - if (index === 2) { - measureCellHtmlSnippet.innerHTML = '{13}'; - } - - const commentCellHtmlSnippet = mockDocument.createElement('span'); - commentCellHtmlSnippet.innerHTML = expectedTextcriticalComments[index].comment; - if (index === 2) { - commentCellHtmlSnippet.innerHTML = '♮ überschreibt ♭.'; - } - - expectToBe(measureCell.textContent, measureCellHtmlSnippet.textContent); - expectToBe(systemCell.textContent, expectedTextcriticalComments[index].system); - expectToBe(positionCell.textContent, expectedTextcriticalComments[index].position); - expectToBe(commentCell.textContent, commentCellHtmlSnippet.textContent); + it('... should contain rows (tr) for each textcritical comment and block header in table body', () => { + getAndExpectDebugElementByCss(compDe, 'table > tbody > tr', expectedTotalRows, expectedTotalRows); }); - }); - it('... should contain CompileHtmlComponent only in fourth cell (td) of each row (tr)', () => { - const rows = getAndExpectDebugElementByCss( - compDe, - 'table > tbody > tr', - expectedTextcriticalComments.length, - expectedTextcriticalComments.length - ); - rows.forEach(row => { - const rowCells = getAndExpectDebugElementByCss(row, 'td', 4, 4); + it('... should contain one cell (td colspan=4) for block headers and four cells (td) for block comments in each row (tr) in table body', () => { + const rows = getAndExpectDebugElementByCss( + compDe, + 'table > tbody > tr', + expectedTotalRows, + expectedTotalRows + ); + + let rowIndex = 0; + expectedTextcriticalCommentBlocks.forEach(block => { + if (block.blockHeader) { + const tdDes = getAndExpectDebugElementByCss(rows[rowIndex], 'td', 1, 1); + const tdEl = tdDes[0].nativeElement; + expectToBe(tdEl.getAttribute('colspan'), '4'); + expectToContain(tdEl.classList, 'awg-edition-tka-table-block-header'); + + rowIndex++; + } + block.blockComments.forEach(() => { + getAndExpectDebugElementByCss(rows[rowIndex], 'td', 4, 4); + + rowIndex++; + }); + }); + }); + + it('... should contain correct data in all row cells (tr/td)', () => { + const rows = getAndExpectDebugElementByCss( + compDe, + 'table > tbody > tr', + expectedTotalRows, + expectedTotalRows + ); + + let rowIndex = 0; + expectedTextcriticalCommentBlocks.forEach(block => { + if (block.blockHeader) { + const tdDes = getAndExpectDebugElementByCss( + rows[rowIndex], + 'td.awg-edition-tka-table-block-header', + 1, + 1 + ); + const tdEl = tdDes[0].nativeElement; + + expectToBe(tdEl.textContent, block.blockHeader); + + rowIndex++; + } + block.blockComments.forEach((comment, index) => { + const rowCells = getAndExpectDebugElementByCss(rows[rowIndex], 'td', 4, 4); + + const measureCell = rowCells[0].nativeElement; + const systemCell = rowCells[1].nativeElement; + const positionCell = rowCells[2].nativeElement; + const commentCell = rowCells[3].nativeElement; + + const measureCellHtmlSnippet = mockDocument.createElement('span'); + measureCellHtmlSnippet.innerHTML = index === 2 ? '{13}' : comment.measure; + + const commentCellHtmlSnippet = mockDocument.createElement('span'); + commentCellHtmlSnippet.innerHTML = index === 2 ? '♮ überschreibt ♭.' : comment.comment; + + expectToBe(measureCell.textContent, measureCellHtmlSnippet.textContent); + expectToBe(systemCell.textContent, comment.system); + expectToBe(positionCell.textContent, comment.position); + expectToBe(commentCell.textContent, commentCellHtmlSnippet.textContent); + + rowIndex++; + }); + }); + }); - getAndExpectDebugElementByDirective(rowCells[0], CompileHtmlComponent, 0, 0); - getAndExpectDebugElementByDirective(rowCells[1], CompileHtmlComponent, 0, 0); - getAndExpectDebugElementByDirective(rowCells[2], CompileHtmlComponent, 0, 0); - getAndExpectDebugElementByDirective(rowCells[3], CompileHtmlComponent, 1, 1); + it('... should contain CompileHtmlComponent in each header cell or fourth cell (td) of a block comment', () => { + const rows = getAndExpectDebugElementByCss( + compDe, + 'table > tbody > tr', + expectedTotalRows, + expectedTotalRows + ); + + let rowIndex = 0; + expectedTextcriticalCommentBlocks.forEach(block => { + if (block.blockHeader) { + const tdDes = getAndExpectDebugElementByCss(rows[rowIndex], 'td', 1, 1); + + getAndExpectDebugElementByDirective(tdDes[0], CompileHtmlComponent, 1, 1); + + rowIndex++; + } + block.blockComments.forEach(() => { + const tdDes = getAndExpectDebugElementByCss(rows[rowIndex], 'td', 4, 4); + + getAndExpectDebugElementByDirective(tdDes[0], CompileHtmlComponent, 0, 0); + getAndExpectDebugElementByDirective(tdDes[1], CompileHtmlComponent, 0, 0); + getAndExpectDebugElementByDirective(tdDes[2], CompileHtmlComponent, 0, 0); + getAndExpectDebugElementByDirective(tdDes[3], CompileHtmlComponent, 1, 1); + + rowIndex++; + }); + }); }); }); }); @@ -322,12 +379,13 @@ describe('EditionTkaTableComponent (DONE)', () => { expectToBe(component.getGlyph('[#]'), '\u266F'); // SHARP expectToBe(component.getGlyph('[a]'), '\u266E'); // NATURAL expectToBe(component.getGlyph('[f]'), '\uD834\uDD91'); // FORTE + expectToBe(component.getGlyph('[ped]'), '\uD834\uDDAE'); // PEDAL }); it('... should return an empty string for an invalid glyph alt value', () => { - expect(component.getGlyph('')).toBe(''); - expect(component.getGlyph('[invalid]')).toBe(''); - expect(component.getGlyph('[not found]')).toBe(''); + expectToBe(component.getGlyph(''), ''); + expectToBe(component.getGlyph('[invalid]'), ''); + expectToBe(component.getGlyph('[not found]'), ''); }); }); @@ -428,14 +486,14 @@ describe('EditionTkaTableComponent (DONE)', () => { const rows = getAndExpectDebugElementByCss( compDe, 'table > tbody > tr', - expectedTextcriticalComments.length, - expectedTextcriticalComments.length + expectedTotalRows, + expectedTotalRows ); - // Find spans of second row - const spanDes = getAndExpectDebugElementByCss(rows[1], 'td > span', 1, 1); + // Find spans of third row + const spanDes = getAndExpectDebugElementByCss(rows[2], 'td > span', 1, 1); - // Find anchors in second span + // Find anchors in span const anchorDes = getAndExpectDebugElementByCss(spanDes[0], 'a', 3, 3); // Trigger click with click helper & wait for changes @@ -509,14 +567,14 @@ describe('EditionTkaTableComponent (DONE)', () => { const rows = getAndExpectDebugElementByCss( compDe, 'table > tbody > tr', - expectedTextcriticalComments.length, - expectedTextcriticalComments.length + expectedTotalRows, + expectedTotalRows ); - // Find spans of second row - const spanDes = getAndExpectDebugElementByCss(rows[1], 'td > span', 1, 1); + // Find spans of third row + const spanDes = getAndExpectDebugElementByCss(rows[2], 'td > span', 1, 1); - // Find anchors in second span + // Find anchors in span const anchorDes = getAndExpectDebugElementByCss(spanDes[0], 'a', 3, 3); // Click on first anchor with modal call @@ -547,14 +605,14 @@ describe('EditionTkaTableComponent (DONE)', () => { const rows = getAndExpectDebugElementByCss( compDe, 'table > tbody > tr', - expectedTextcriticalComments.length, - expectedTextcriticalComments.length + expectedTotalRows, + expectedTotalRows ); - // Find spans of second row - const spanDes = getAndExpectDebugElementByCss(rows[1], 'td > span', 1, 1); + // Find spans of third row + const spanDes = getAndExpectDebugElementByCss(rows[2], 'td > span', 1, 1); - // Find anchors in second span + // Find anchors in span const anchorDes = getAndExpectDebugElementByCss(spanDes[0], 'a', 3, 3); // Trigger click with click helper & wait for changes diff --git a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-tka/edition-tka-table/edition-tka-table.component.ts b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-tka/edition-tka-table/edition-tka-table.component.ts index e974724ee..db4d92896 100644 --- a/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-tka/edition-tka-table/edition-tka-table.component.ts +++ b/src/app/views/edition-view/edition-outlets/edition-complex/edition-detail/edition-tka/edition-tka-table/edition-tka-table.component.ts @@ -1,7 +1,7 @@ import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core'; -import { EDITION_GLYPHS_DATA } from '@awg-app/views/edition-view/data'; -import { TextcriticalComment, TkaTableHeaderColumn } from '@awg-views/edition-view/models'; +import { EDITION_GLYPHS_DATA } from '@awg-views/edition-view/data'; +import { TextcriticalCommentBlock, TkaTableHeaderColumn } from '@awg-views/edition-view/models'; /** * The EditionTkaTable component. @@ -17,12 +17,12 @@ import { TextcriticalComment, TkaTableHeaderColumn } from '@awg-views/edition-vi }) export class EditionTkaTableComponent { /** - * Input variable: textcriticalComments. + * Input variable: textcriticalCommentBlocks. * - * It keeps the textcritical comments. + * It keeps the textcritical comment blocks. */ @Input() - textcriticalComments: TextcriticalComment[]; + textcriticalCommentBlocks: TextcriticalCommentBlock[]; /** * Input variable: isCorrections. diff --git a/src/app/views/edition-view/edition-outlets/edition-preface/edition-preface-routing.module.ts b/src/app/views/edition-view/edition-outlets/edition-preface/edition-preface-routing.module.ts new file mode 100644 index 000000000..cf58b80d7 --- /dev/null +++ b/src/app/views/edition-view/edition-outlets/edition-preface/edition-preface-routing.module.ts @@ -0,0 +1,30 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; + +import { EditionPrefaceComponent } from './edition-preface.component'; + +/* Routes of the EditionPrefaceModule */ +const EDITION_PREFACE_ROUTES: Routes = [ + { + path: '', + component: EditionPrefaceComponent, + data: { title: 'AWG Online Edition – Preface' }, + }, +]; + +/** + * Routed components of the {@link EditionPrefaceModule}: + * {@link EditionPrefaceComponent}. + */ +export const routedEditionPrefaceComponents = [EditionPrefaceComponent]; + +/** + * EditionPreface module routing. + * + * It activates the EDITION_PREFACE_ROUTES. + */ +@NgModule({ + imports: [RouterModule.forChild(EDITION_PREFACE_ROUTES)], + exports: [RouterModule], +}) +export class EditionPrefaceRoutingModule {} diff --git a/src/app/views/edition-view/edition-outlets/edition-preface/edition-preface.component.html b/src/app/views/edition-view/edition-outlets/edition-preface/edition-preface.component.html new file mode 100644 index 000000000..b3f868dec --- /dev/null +++ b/src/app/views/edition-view/edition-outlets/edition-preface/edition-preface.component.html @@ -0,0 +1,12 @@ +@if (prefaceData$ | async; as prefaceData) { +
+

+ DE + | + EN +

+ @for (prefaceParagraph of prefaceData.preface[currentLanguage].content; track $index) { +

+ } +
+} diff --git a/src/app/views/edition-view/edition-outlets/edition-preface/edition-preface.component.scss b/src/app/views/edition-view/edition-outlets/edition-preface/edition-preface.component.scss new file mode 100644 index 000000000..6e7b96721 --- /dev/null +++ b/src/app/views/edition-view/edition-outlets/edition-preface/edition-preface.component.scss @@ -0,0 +1,56 @@ +@import '/src/assets/themes/scss/shared'; + +.awg-language-switcher { + font-family: 'Montserrat', sans-serif; + font-size: small; + text-align: end; + + a { + cursor: pointer; + text-decoration: none; + color: inherit; + // disable the active link style + &.active, + &.active:hover { + cursor: default; + color: inherit; + } + &:not(.active) { + color: $link-color; + } + &:hover { + border-bottom: none !important; + } + } +} + +.awg-preface-para { + margin: 0; + text-indent: 25px; + + &::ng-deep { + .heading { + display: block; + margin-bottom: 25px; + font-size: 1.5em; + font-weight: bold; + } + .heading, + .small, + .no-indent { + text-indent: 0; + } + .small:not(.spacebreak), + .no-indent { + margin-left: -25px; + } + .spacebreak { + display: block; + margin-top: 25px; + + &.no-indent { + margin-left: 0; + } + } + } +} diff --git a/src/app/views/edition-view/edition-outlets/edition-preface/edition-preface.component.spec.ts b/src/app/views/edition-view/edition-outlets/edition-preface/edition-preface.component.spec.ts new file mode 100644 index 000000000..453806044 --- /dev/null +++ b/src/app/views/edition-view/edition-outlets/edition-preface/edition-preface.component.spec.ts @@ -0,0 +1,321 @@ +import { DebugElement } from '@angular/core'; +import { ComponentFixture, fakeAsync, TestBed, waitForAsync } from '@angular/core/testing'; + +import { lastValueFrom, Observable, of as observableOf, ReplaySubject } from 'rxjs'; +import Spy = jasmine.Spy; + +import { clickAndAwaitChanges } from '@testing/click-helper'; +import { detectChangesOnPush } from '@testing/detect-changes-on-push-helper'; +import { + expectSpyCall, + expectToBe, + expectToContain, + expectToEqual, + getAndExpectDebugElementByCss, +} from '@testing/expect-helper'; +import { mockEditionData } from '@testing/mock-data'; + +import { CompileHtmlComponent } from '@awg-shared/compile-html'; +import { EDITION_GLYPHS_DATA } from '@awg-views/edition-view/data'; +import { PrefaceList } from '@awg-views/edition-view/models'; +import { EditionDataService, EditionService } from '@awg-views/edition-view/services'; + +import { EditionPrefaceComponent } from './edition-preface.component'; + +describe('EditionPrefaceComponent (DONE)', () => { + let component: EditionPrefaceComponent; + let fixture: ComponentFixture; + let compDe: DebugElement; + + let getGlyphSpy: Spy; + let setLanguageSpy: Spy; + let editionServiceUpdateIsPrefaceViewSpy: Spy; + let editionServiceClearIsPrefaceViewSpy: Spy; + let editionDataServiceGetPrefaceDataSpy: Spy; + + let mockEditionService: Partial; + let mockEditionDataService: Partial; + let mockIsPrefaceViewSubject: ReplaySubject; + + let expectedPrefaceData: PrefaceList; + + beforeEach(async () => { + mockIsPrefaceViewSubject = new ReplaySubject(1); + + mockEditionService = { + updateIsPrefaceView: (isView: boolean): void => mockIsPrefaceViewSubject.next(isView), + clearIsPrefaceView: (): void => mockIsPrefaceViewSubject.next(null), + }; + + mockEditionDataService = { + getEditionPrefaceData: (): Observable => observableOf(expectedPrefaceData), + }; + + await TestBed.configureTestingModule({ + declarations: [CompileHtmlComponent, EditionPrefaceComponent], + providers: [ + { provide: EditionService, useValue: mockEditionService }, + { provide: EditionDataService, useValue: mockEditionDataService }, + ], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(EditionPrefaceComponent); + component = fixture.componentInstance; + compDe = fixture.debugElement; + + mockEditionService = TestBed.inject(EditionService); + mockEditionDataService = TestBed.inject(EditionDataService); + + // Test data + expectedPrefaceData = JSON.parse(JSON.stringify(mockEditionData.mockPrefaceData)); + + // Spies on component functions + // `.and.callThrough` will track the spy down the nested describes, see + // https://jasmine.github.io/2.0/introduction.html#section-Spies:_%3Ccode%3Eand.callThrough%3C/code%3E + getGlyphSpy = spyOn(component, 'getGlyph').and.callThrough(); + setLanguageSpy = spyOn(component, 'setLanguage').and.callThrough(); + editionServiceUpdateIsPrefaceViewSpy = spyOn(mockEditionService, 'updateIsPrefaceView').and.callThrough(); + editionServiceClearIsPrefaceViewSpy = spyOn(mockEditionService, 'clearIsPrefaceView').and.callThrough(); + editionDataServiceGetPrefaceDataSpy = spyOn(mockEditionDataService, 'getEditionPrefaceData').and.callThrough(); + }); + + it('... should create', () => { + expect(component).toBeTruthy(); + }); + + describe('BEFORE initial data binding', () => { + it('... should not have `prefaceData$`', () => { + expect(component.prefaceData$).toBeUndefined(); + }); + + it('... should have `currentLanguage` = 0', () => { + expectToBe(component.currentLanguage, 0); + }); + + it('... should have `GLYPHS`', () => { + expectToEqual(component.GLYPHS, EDITION_GLYPHS_DATA); + }); + + it('... should have `ref`', () => { + expectToEqual(component.ref, component); + }); + + it('... should not have called EditionService', () => { + expectSpyCall(editionServiceUpdateIsPrefaceViewSpy, 0); + }); + + it('... should not have called EditionDataService', () => { + expectSpyCall(editionDataServiceGetPrefaceDataSpy, 0); + }); + + describe('VIEW', () => { + it('... should contain no outer div.row (yet)', () => { + getAndExpectDebugElementByCss(compDe, 'div.row', 0, 0); + }); + }); + }); + + describe('AFTER initial data binding', () => { + beforeEach(() => { + // Trigger initial data binding + fixture.detectChanges(); + }); + + it('... should have updated IsPrefaceViewFlag (via EditionService)', () => { + expectSpyCall(editionServiceUpdateIsPrefaceViewSpy, 1, true); + }); + + it('... should have called EditionDataService', () => { + expectSpyCall(editionDataServiceGetPrefaceDataSpy, 1); + }); + + it('... should have prefaceData$', waitForAsync(() => { + expectAsync(lastValueFrom(component.prefaceData$)).toBeResolved(); + expectAsync(lastValueFrom(component.prefaceData$)).toBeResolvedTo(expectedPrefaceData); + })); + + describe('VIEW', () => { + it('... should contain 1 outer div.awg-preface-view', () => { + getAndExpectDebugElementByCss(compDe, 'div.awg-preface-view', 1, 1); + }); + + it('... should contain 1 language-switcher paragraph', () => { + getAndExpectDebugElementByCss(compDe, 'p.awg-language-switcher', 1, 1); + }); + + it('... should contain 2 language-switcher anchor elements (DE | EN)', () => { + const pDes = getAndExpectDebugElementByCss(compDe, 'p.awg-language-switcher', 1, 1); + const pEl = pDes[0].nativeElement; + + expectToBe(pEl.textContent, 'DE | EN'); + + const aDes = getAndExpectDebugElementByCss(pDes[0], 'a', 2, 2); + const aEl1 = aDes[0].nativeElement; + const aEl2 = aDes[1].nativeElement; + + expectToBe(aEl1.textContent, 'DE'); + expectToBe(aEl2.textContent, 'EN'); + }); + + it('... should trigger `setLanguage` method on anchor click', fakeAsync(() => { + const pDes = getAndExpectDebugElementByCss(compDe, 'p.awg-language-switcher', 1, 1); + const aDes = getAndExpectDebugElementByCss(pDes[0], 'a', 2, 2); + + // Trigger click with click helper & wait for changes + clickAndAwaitChanges(aDes[0], fixture); + + expectSpyCall(setLanguageSpy, 1); + + // Trigger click with click helper & wait for changes + clickAndAwaitChanges(aDes[1], fixture); + + expectSpyCall(setLanguageSpy, 2); + })); + + it('... should set currentLanguage to 0 when clicking on first anchor', fakeAsync(() => { + const pDes = getAndExpectDebugElementByCss(compDe, 'p.awg-language-switcher', 1, 1); + const aDes = getAndExpectDebugElementByCss(pDes[0], 'a', 2, 2); + + // Click on first anchor + clickAndAwaitChanges(aDes[0], fixture); + + expectToBe(component.currentLanguage, 0); + })); + + it('... should set currentLanguage to 1 when clicking on second anchor', fakeAsync(() => { + const pDes = getAndExpectDebugElementByCss(compDe, 'p.awg-language-switcher', 1, 1); + const aDes = getAndExpectDebugElementByCss(pDes[0], 'a', 2, 2); + + // Click on second anchor + clickAndAwaitChanges(aDes[1], fixture); + + expectToBe(component.currentLanguage, 1); + })); + + it('... should have .active class on first anchor element when currentLanguage is 0', fakeAsync(() => { + const pDes = getAndExpectDebugElementByCss(compDe, 'p.awg-language-switcher', 1, 1); + const aDes = getAndExpectDebugElementByCss(pDes[0], 'a', 2, 2); + + // Click on first anchor + clickAndAwaitChanges(aDes[0], fixture); + + const aEl0 = aDes[0].nativeElement; + const aEl1 = aDes[1].nativeElement; + + expectToContain(aEl0.classList, 'active'); + expect(aEl1.classList).not.toContain('active'); + })); + + it('... should have .active class on second anchor element when currentLanguage is 1', fakeAsync(() => { + const pDes = getAndExpectDebugElementByCss(compDe, 'p.awg-language-switcher', 1, 1); + const aDes = getAndExpectDebugElementByCss(pDes[0], 'a', 2, 2); + + // Click on second anchor + clickAndAwaitChanges(aDes[1], fixture); + + const aEl0 = aDes[0].nativeElement; + const aEl1 = aDes[1].nativeElement; + + expect(aEl0.classList).not.toContain('active'); + expectToContain(aEl1.classList, 'active'); + })); + + it('... should contain as many preface paragraph elements in div.awg-preface-view as content items in preview data (german)', () => { + // Div debug element + const divDes = getAndExpectDebugElementByCss(compDe, 'div.awg-preface-view', 1, 1); + + getAndExpectDebugElementByCss( + divDes[0], + 'p.awg-preface-para', + expectedPrefaceData.preface[0].content.length, + expectedPrefaceData.preface[0].content.length + ); + }); + + it('... should contain as many preface paragraph elements in div.awg-preface-view as content items in preview data (english)', () => { + // Div debug element + const divDes = getAndExpectDebugElementByCss(compDe, 'div.awg-preface-view', 1, 1); + + getAndExpectDebugElementByCss( + divDes[0], + 'p.awg-preface-para', + expectedPrefaceData.preface[1].content.length, + expectedPrefaceData.preface[1].content.length + ); + }); + }); + + describe('#getGlyph()', () => { + it('... should have a method `getGlyph`', () => { + expect(component.getGlyph).toBeDefined(); + }); + + it('... should trigger on change detection', () => { + expectSpyCall(getGlyphSpy, 2); + + detectChangesOnPush(fixture); + + expectSpyCall(getGlyphSpy, 3); + }); + + it('... should return the correct hex value for a valid glyph alt value', () => { + expectToBe(component.getGlyph('[bb]'), '\uD834\uDD2B'); // DOUBLE_FLAT + expectToBe(component.getGlyph('[x]'), '\uD834\uDD2A'); // DOUBLE_SHARP + expectToBe(component.getGlyph('[b]'), '\u266D'); // FLAT + expectToBe(component.getGlyph('[#]'), '\u266F'); // SHARP + expectToBe(component.getGlyph('[a]'), '\u266E'); // NATURAL + expectToBe(component.getGlyph('[f]'), '\uD834\uDD91'); // FORTE + expectToBe(component.getGlyph('[ped]'), '\uD834\uDDAE'); // PEDAL + }); + + it('... should return an empty string for an invalid glyph alt value', () => { + expectToBe(component.getGlyph(''), ''); + expectToBe(component.getGlyph('[invalid]'), ''); + expectToBe(component.getGlyph('[not found]'), ''); + }); + }); + + describe('#setLanguage()', () => { + it('... should have a method `setLanguage`', () => { + expect(component.setLanguage).toBeDefined(); + }); + + it('... should trigger on click', fakeAsync(() => { + const pDes = getAndExpectDebugElementByCss(compDe, 'p.awg-language-switcher', 1, 1); + const aDes = getAndExpectDebugElementByCss(pDes[0], 'a', 2, 2); + + // Trigger click with click helper & wait for changes + clickAndAwaitChanges(aDes[0], fixture); + + expectSpyCall(setLanguageSpy, 1); + + // Trigger click with click helper & wait for changes + clickAndAwaitChanges(aDes[1], fixture); + + expectSpyCall(setLanguageSpy, 2); + })); + + it('... should set the currentLanguage to 0 when called with 0', () => { + component.setLanguage(0); + + expectToBe(component.currentLanguage, 0); + }); + + it('... should set the currentLanguage to 1 when called with 1', () => { + component.setLanguage(1); + + expectToBe(component.currentLanguage, 1); + }); + }); + + describe('#ngOnDestroy()', () => { + it('... should have cleared isPrefaceView$ on destroy (via EditionService)', () => { + component.ngOnDestroy(); + + expectSpyCall(editionServiceClearIsPrefaceViewSpy, 1); + }); + }); + }); +}); diff --git a/src/app/views/edition-view/edition-outlets/edition-preface/edition-preface.component.ts b/src/app/views/edition-view/edition-outlets/edition-preface/edition-preface.component.ts new file mode 100644 index 000000000..21bc53b7b --- /dev/null +++ b/src/app/views/edition-view/edition-outlets/edition-preface/edition-preface.component.ts @@ -0,0 +1,109 @@ +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { Observable } from 'rxjs'; + +import { EDITION_GLYPHS_DATA } from '@awg-views/edition-view/data'; +import { PrefaceList } from '@awg-views/edition-view/models'; +import { EditionDataService, EditionService } from '@awg-views/edition-view/services'; + +/** + * The EditionPreface component. + * + * It contains the preface section + * of the edition view of the app. + */ +@Component({ + selector: 'awg-edition-preface', + templateUrl: './edition-preface.component.html', + styleUrls: ['./edition-preface.component.scss'], +}) +export class EditionPrefaceComponent implements OnInit, OnDestroy { + /** + * Public variable: prefaceData$. + * + * It keeps an observable of the data of the edition preface. + */ + prefaceData$: Observable; + + /** + * Public variable: currentLanguage. + * + * It keeps the current language of the edition preface: 0 for German, 1 for English. + */ + currentLanguage = 0; + + /** + * Readonly variable: GLYPHS. + * + * It keeps the data for musical glyphs. + */ + readonly GLYPHS = EDITION_GLYPHS_DATA; + + /** + * Self-referring variable needed for CompileHtml library. + */ + ref: EditionPrefaceComponent; + + /** + * Constructor of the EditionPrefaceComponent. + * + * It declares private instances of the EditionService and EditionDataService + * and the self-referring ref variable needed for CompileHtml library. + * + * @param {EditionService} editionService Instance of the EditionService. + * @param {EditionDataService} editionDataService Instance of the EditionDataService. + */ + constructor( + private editionService: EditionService, + private editionDataService: EditionDataService + ) { + this.ref = this; + } + + /** + * Angular life cycle hook: ngOnInit. + * + * It calls the containing methods + * when initializing the component. + */ + ngOnInit(): void { + this.editionService.updateIsPrefaceView(true); + this.prefaceData$ = this.editionDataService.getEditionPrefaceData(); + } + + /** + * Public method: getGlyph. + * + * It returns the hex value string for a glyph referenced by the given glyph string. + * + * @param {string} glyphString The given glyph string. + * @returns {string} The hex value string of the given glyph string or empty string. + */ + getGlyph(glyphString: string): string { + const glyph = Object.values(this.GLYPHS).find(g => g.alt === glyphString); + return glyph ? glyph.hex : ''; + } + + /** + * Public method: setLanguage. + * + * It sets the current language of the edition preface. + * + * @param {number} language The given language number. + * @returns {void} Sets the current language. + */ + setLanguage(language: number): void { + this.currentLanguage = language; + } + + /** + * Angular life cycle hook: ngOnDestroy. + * + * It calls the containing methods + * when destroying the component. + * + * Destroys subscriptions. + */ + ngOnDestroy() { + this.editionService.clearIsPrefaceView(); + } +} diff --git a/src/app/views/edition-view/edition-outlets/edition-preface/edition-preface.module.ts b/src/app/views/edition-view/edition-outlets/edition-preface/edition-preface.module.ts new file mode 100644 index 000000000..b09afe66c --- /dev/null +++ b/src/app/views/edition-view/edition-outlets/edition-preface/edition-preface.module.ts @@ -0,0 +1,18 @@ +import { NgModule } from '@angular/core'; + +import { SharedModule } from '@awg-shared/shared.module'; + +import { EditionPrefaceRoutingModule, routedEditionPrefaceComponents } from './edition-preface-routing.module'; + +/** + * The EditionPreface module. + * + * It embeds the {@link EditionPrefaceComponent} and its + * [routing definition]{@link EditionPrefaceRoutingModule} + * as well as the {@link SharedModule}. + */ +@NgModule({ + imports: [SharedModule, EditionPrefaceRoutingModule], + declarations: [routedEditionPrefaceComponents], +}) +export class EditionPrefaceModule {} diff --git a/src/app/views/edition-view/edition-outlets/edition-preface/index.ts b/src/app/views/edition-view/edition-outlets/edition-preface/index.ts new file mode 100644 index 000000000..090e04721 --- /dev/null +++ b/src/app/views/edition-view/edition-outlets/edition-preface/index.ts @@ -0,0 +1 @@ +export * from './edition-preface.component'; diff --git a/src/app/views/edition-view/edition-outlets/edition-row-tables/edition-row-tables.component.html b/src/app/views/edition-view/edition-outlets/edition-row-tables/edition-row-tables.component.html index 6b00e4903..72a4ba5a9 100644 --- a/src/app/views/edition-view/edition-outlets/edition-row-tables/edition-row-tables.component.html +++ b/src/app/views/edition-view/edition-outlets/edition-row-tables/edition-row-tables.component.html @@ -2,7 +2,7 @@
@for (rowTable of rowTablesData?.rowTables; track rowTable) {
-
+
Reihentabelle {{ rowTable.short }} diff --git a/src/app/views/edition-view/edition-outlets/edition-row-tables/edition-row-tables.component.spec.ts b/src/app/views/edition-view/edition-outlets/edition-row-tables/edition-row-tables.component.spec.ts index 503a6a2c6..53096cd84 100644 --- a/src/app/views/edition-view/edition-outlets/edition-row-tables/edition-row-tables.component.spec.ts +++ b/src/app/views/edition-view/edition-outlets/edition-row-tables/edition-row-tables.component.spec.ts @@ -31,7 +31,7 @@ describe('EditionRowTablesComponent (DONE)', () => { let editionServiceUpdateIsRowTablesViewSpy: Spy; let editionServiceClearIsRowTablesViewSpy: Spy; - let editionDataServiceGetRowTablesSpy: Spy; + let editionDataServiceGetRowTablesDataSpy: Spy; let mockEditionService: Partial; let mockEditionDataService: Partial; @@ -78,7 +78,10 @@ describe('EditionRowTablesComponent (DONE)', () => { // https://jasmine.github.io/2.0/introduction.html#section-Spies:_%3Ccode%3Eand.callThrough%3C/code%3E editionServiceUpdateIsRowTablesViewSpy = spyOn(mockEditionService, 'updateIsRowTableView').and.callThrough(); editionServiceClearIsRowTablesViewSpy = spyOn(mockEditionService, 'clearIsRowTableView').and.callThrough(); - editionDataServiceGetRowTablesSpy = spyOn(mockEditionDataService, 'getEditionRowTablesData').and.callThrough(); + editionDataServiceGetRowTablesDataSpy = spyOn( + mockEditionDataService, + 'getEditionRowTablesData' + ).and.callThrough(); }); it('... should create', () => { @@ -95,7 +98,7 @@ describe('EditionRowTablesComponent (DONE)', () => { }); it('... should not have called EditionDataService', () => { - expectSpyCall(editionDataServiceGetRowTablesSpy, 0); + expectSpyCall(editionDataServiceGetRowTablesDataSpy, 0); }); describe('VIEW', () => { @@ -116,14 +119,12 @@ describe('EditionRowTablesComponent (DONE)', () => { }); it('... should have called EditionDataService', () => { - expectSpyCall(editionDataServiceGetRowTablesSpy, 1); + expectSpyCall(editionDataServiceGetRowTablesDataSpy, 1); }); it('... should have rowTablesData$', waitForAsync(() => { expectAsync(lastValueFrom(component.rowTablesData$)).toBeResolved(); - expectAsync(lastValueFrom(component.rowTablesData$)) - .withContext(`should be resolved to ${expectedRowTablesData}`) - .toBeResolvedTo(expectedRowTablesData); + expectAsync(lastValueFrom(component.rowTablesData$)).toBeResolvedTo(expectedRowTablesData); })); describe('VIEW', () => { @@ -299,7 +300,7 @@ describe('EditionRowTablesComponent (DONE)', () => { const linkDe = linkDes[index]; const expectedRouterLink = ['../complex' + expectedRowTablesData.rowTables[index].route, 'sheets']; - expect(routerLink.navigatedTo).toBeNull(); + expectToBe(routerLink.navigatedTo, null); click(linkDe); fixture.detectChanges(); diff --git a/src/app/views/edition-view/edition-outlets/edition-row-tables/edition-row-tables.component.ts b/src/app/views/edition-view/edition-outlets/edition-row-tables/edition-row-tables.component.ts index bc3bc3778..e54744d0d 100644 --- a/src/app/views/edition-view/edition-outlets/edition-row-tables/edition-row-tables.component.ts +++ b/src/app/views/edition-view/edition-outlets/edition-row-tables/edition-row-tables.component.ts @@ -1,7 +1,8 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; +import { Observable } from 'rxjs'; + import { EditionRowTablesList } from '@awg-views/edition-view/models'; import { EditionDataService, EditionService } from '@awg-views/edition-view/services'; -import { Observable } from 'rxjs'; /** * The EditionRowTables component. diff --git a/src/app/views/edition-view/edition-outlets/edition-row-tables/edition-row-tables.module.ts b/src/app/views/edition-view/edition-outlets/edition-row-tables/edition-row-tables.module.ts index 2678841fc..769471246 100644 --- a/src/app/views/edition-view/edition-outlets/edition-row-tables/edition-row-tables.module.ts +++ b/src/app/views/edition-view/edition-outlets/edition-row-tables/edition-row-tables.module.ts @@ -5,7 +5,7 @@ import { SharedModule } from '@awg-shared/shared.module'; import { EditionRowTablesRoutingModule, routedEditionRowTablesComponents } from './edition-row-tables-routing.module'; /** - * The editionRowTables module. + * The EditionRowTables module. * * It embeds the {@link EditionRowTablesComponent} and its * [routing definition]{@link EditionRowTablesRoutingModule} diff --git a/src/app/views/edition-view/edition-outlets/edition-series-detail/edition-section-detail/edition-section-detail.component.html b/src/app/views/edition-view/edition-outlets/edition-series-detail/edition-section-detail/edition-section-detail.component.html index c6dd0e52e..28098e4ab 100644 --- a/src/app/views/edition-view/edition-outlets/edition-series-detail/edition-section-detail/edition-section-detail.component.html +++ b/src/app/views/edition-view/edition-outlets/edition-series-detail/edition-section-detail/edition-section-detail.component.html @@ -1,19 +1,20 @@ @if ( selectedSection && - utils.isNotEmptyObject(selectedSection.complexes) && - (utils.isNotEmptyArray(selectedSection.complexes.opus) || utils.isNotEmptyArray(selectedSection.complexes.mnr)) + utils.isNotEmptyObject(selectedSection.complexTypes) && + (utils.isNotEmptyArray(selectedSection.complexTypes.opus) || + utils.isNotEmptyArray(selectedSection.complexTypes.mnr)) ) {
- @if (utils.isNotEmptyArray(selectedSection.complexes.opus)) { -
+ @if (utils.isNotEmptyArray(selectedSection.complexTypes.opus)) { +
nach Opusnummer:
- +
} - @if (utils.isNotEmptyArray(selectedSection.complexes.mnr)) { -
+ @if (utils.isNotEmptyArray(selectedSection.complexTypes.mnr)) { +
nach Moldenhauer-Nummer:
- +
}
diff --git a/src/app/views/edition-view/edition-outlets/edition-series-detail/edition-section-detail/edition-section-detail.component.spec.ts b/src/app/views/edition-view/edition-outlets/edition-series-detail/edition-section-detail/edition-section-detail.component.spec.ts index 0e63724a1..a596d9d60 100644 --- a/src/app/views/edition-view/edition-outlets/edition-series-detail/edition-section-detail/edition-section-detail.component.spec.ts +++ b/src/app/views/edition-view/edition-outlets/edition-series-detail/edition-section-detail/edition-section-detail.component.spec.ts @@ -7,21 +7,24 @@ import Spy = jasmine.Spy; import { expectSpyCall, + expectToBe, + expectToContain, + expectToEqual, getAndExpectDebugElementByCss, getAndExpectDebugElementByDirective, } from '@testing/expect-helper'; import { ActivatedRouteStub } from '@testing/router-stubs'; -import { EDITION_OUTLINE_DATA } from '@awg-app/views/edition-view/data'; -import { EditionOutlineComplex, EditionOutlineSection, EditionOutlineSeries } from '@awg-views/edition-view/models'; -import { EditionService } from '@awg-views/edition-view/services'; +import { EDITION_ROUTE_CONSTANTS } from '@awg-views/edition-view/edition-route-constants'; +import { EditionOutlineComplexItem, EditionOutlineSection, EditionOutlineSeries } from '@awg-views/edition-view/models'; +import { EditionComplexesService, EditionOutlineService, EditionService } from '@awg-views/edition-view/services'; import { EditionSectionDetailComponent } from './edition-section-detail.component'; @Component({ selector: 'awg-edition-complex-card', template: '' }) class EditionComplexCardStubComponent { @Input() - complexes: EditionOutlineComplex[]; + complexes: EditionOutlineComplexItem[]; } describe('EditionSectionDetailComponent (DONE)', () => { @@ -32,9 +35,9 @@ describe('EditionSectionDetailComponent (DONE)', () => { let mockActivatedRoute: ActivatedRouteStub; let mockEditionService: Partial; - let getSectionSpy: Spy; + let updateSectionFromRouteSpy: Spy; let editionServiceGetSelectedEditionSeriesSpy: Spy; - let editionServiceGetEditionSectionByIdSpy: Spy; + let editionOutlineServiceGetEditionSectionByIdSpy: Spy; let editionServiceUpdateSelectedEditionSectionSpy: Spy; let expectedSelectedSeries: EditionOutlineSeries; @@ -42,13 +45,15 @@ describe('EditionSectionDetailComponent (DONE)', () => { let expectedSeriesId: string; let expectedSectionId: string; + beforeAll(() => { + EditionComplexesService.initializeEditionComplexesList(); + EditionOutlineService.initializeEditionOutline(); + }); + beforeEach(async () => { // Mock edition service mockEditionService = { getSelectedEditionSeries: (): Observable => observableOf(expectedSelectedSeries), - - getEditionSectionById: (seriesId: string, sectionId: string): EditionOutlineSection => - expectedSelectedSection, updateSelectedEditionSection: (editionSection: EditionOutlineSection): void => {}, }; @@ -70,24 +75,27 @@ describe('EditionSectionDetailComponent (DONE)', () => { compDe = fixture.debugElement; // TestData - expectedSelectedSeries = JSON.parse(JSON.stringify(EDITION_OUTLINE_DATA[0])); - expectedSelectedSection = { ...expectedSelectedSeries.sections[4] }; + expectedSelectedSeries = EditionOutlineService.getEditionOutline()[0]; + expectedSelectedSection = expectedSelectedSeries.sections[4]; expectedSeriesId = expectedSelectedSeries.series.route; expectedSectionId = expectedSelectedSection.section.route; // Spies on component functions // `.and.callThrough` will track the spy down the nested describes, see // https://jasmine.github.io/2.0/introduction.html#section-Spies:_%3Ccode%3Eand.callThrough%3C/code%3E - getSectionSpy = spyOn(component, 'getSection').and.callThrough(); + updateSectionFromRouteSpy = spyOn(component, 'updateSectionFromRoute').and.callThrough(); editionServiceGetSelectedEditionSeriesSpy = spyOn( mockEditionService, 'getSelectedEditionSeries' ).and.callThrough(); - editionServiceGetEditionSectionByIdSpy = spyOn(mockEditionService, 'getEditionSectionById').and.callThrough(); editionServiceUpdateSelectedEditionSectionSpy = spyOn( mockEditionService, 'updateSelectedEditionSection' ).and.callThrough(); + editionOutlineServiceGetEditionSectionByIdSpy = spyOn( + EditionOutlineService, + 'getEditionSectionById' + ).and.callThrough(); }); it('... should create', () => { @@ -103,13 +111,13 @@ describe('EditionSectionDetailComponent (DONE)', () => { expect(component.selectedSection).toBeUndefined(); }); - describe('#getSection()', () => { - it('... should have a method `getSection`', () => { - expect(component.getSection).toBeDefined(); + describe('#updateSectionFromRoute()', () => { + it('... should have a method `updateSectionFromRoute`', () => { + expect(component.updateSectionFromRoute).toBeDefined(); }); it('... should not have been called', () => { - expectSpyCall(getSectionSpy, 0); + expectSpyCall(updateSectionFromRouteSpy, 0); }); }); @@ -133,9 +141,9 @@ describe('EditionSectionDetailComponent (DONE)', () => { fixture.detectChanges(); }); - describe('#getSection()', () => { + describe('#updateSectionFromRoute()', () => { it('... should have been called', () => { - expectSpyCall(getSectionSpy, 1); + expectSpyCall(updateSectionFromRouteSpy, 1); }); it('... should have called editionService.getSelectedEditionSeries', () => { @@ -143,27 +151,21 @@ describe('EditionSectionDetailComponent (DONE)', () => { }); it('... should have set selectedSeries (via EditionService)', waitForAsync(() => { - expectSpyCall(getSectionSpy, 1); + expectSpyCall(updateSectionFromRouteSpy, 1); expectSpyCall(editionServiceGetSelectedEditionSeriesSpy, 1); - expect(component.selectedSeries).toBeTruthy(); - expect(component.selectedSeries) - .withContext(`should equal ${expectedSelectedSeries}`) - .toEqual(expectedSelectedSeries); + expectToEqual(component.selectedSeries, expectedSelectedSeries); })); - it('... should have called editionService.getEditionSectionById', () => { - expectSpyCall(editionServiceGetEditionSectionByIdSpy, 1, [expectedSeriesId, expectedSectionId]); + it('... should have called EditionOutlineService.getEditionSectionById', () => { + expectSpyCall(editionOutlineServiceGetEditionSectionByIdSpy, 1, [expectedSeriesId, expectedSectionId]); }); - it('... should have set selectedSection (via EditionService)', waitForAsync(() => { - expectSpyCall(getSectionSpy, 1); - expectSpyCall(editionServiceGetEditionSectionByIdSpy, 1, [expectedSeriesId, expectedSectionId]); + it('... should have set selectedSection (via EditionOutlineService)', waitForAsync(() => { + expectSpyCall(updateSectionFromRouteSpy, 1); + expectSpyCall(editionOutlineServiceGetEditionSectionByIdSpy, 1, [expectedSeriesId, expectedSectionId]); - expect(component.selectedSection).toBeTruthy(); - expect(component.selectedSection) - .withContext(`should equal ${expectedSelectedSection}`) - .toEqual(expectedSelectedSection); + expectToEqual(component.selectedSection, expectedSelectedSection); })); it('... should have called editionService.updateSelectedEditionSection with selectedSection', () => { @@ -180,7 +182,9 @@ describe('EditionSectionDetailComponent (DONE)', () => { })); it('... if selected section has empty opus complexes, but given mnr complexes', waitForAsync(() => { - component.selectedSection.complexes.opus = undefined; + const shallowCopy = { ...component.selectedSection }; + shallowCopy.complexTypes = { ...component.selectedSection.complexTypes, opus: undefined }; + component.selectedSection = shallowCopy; fixture.detectChanges(); getAndExpectDebugElementByCss(compDe, 'div.awg-edition-section-detail', 1, 1); @@ -188,7 +192,9 @@ describe('EditionSectionDetailComponent (DONE)', () => { })); it('... if selected section has empty mnr complexes, but given opus complexes', waitForAsync(() => { - component.selectedSection.complexes.mnr = undefined; + const shallowCopy = { ...component.selectedSection }; + shallowCopy.complexTypes = { ...component.selectedSection.complexTypes, mnr: undefined }; + component.selectedSection = shallowCopy; fixture.detectChanges(); getAndExpectDebugElementByCss(compDe, 'div.awg-edition-section-detail', 1, 1); @@ -203,7 +209,9 @@ describe('EditionSectionDetailComponent (DONE)', () => { }); it('... should contain no inner div.awg-edition-section-detail-opus if no opus complexes are given', () => { - component.selectedSection.complexes.opus = undefined; + const shallowCopy = { ...component.selectedSection }; + shallowCopy.complexTypes = { ...component.selectedSection.complexTypes, opus: undefined }; + component.selectedSection = shallowCopy; fixture.detectChanges(); const divDe = getAndExpectDebugElementByCss(compDe, 'div.awg-edition-section-detail', 1, 1); @@ -222,10 +230,7 @@ describe('EditionSectionDetailComponent (DONE)', () => { const expectedHeaderText = 'nach Opusnummer:'; - expect(headerEl.textContent).toBeTruthy(); - expect(headerEl.textContent) - .withContext(`should be ${expectedHeaderText}`) - .toBe(expectedHeaderText); + expectToBe(headerEl.textContent, expectedHeaderText); }); it('... should contain 1 edition complex card component (stubbed)', () => { @@ -256,10 +261,7 @@ describe('EditionSectionDetailComponent (DONE)', () => { EditionComplexCardStubComponent ) as EditionComplexCardStubComponent; - expect(complexCardCmp.complexes).toBeTruthy(); - expect(complexCardCmp.complexes) - .withContext(`should equal ${expectedSelectedSection.complexes.opus}`) - .toEqual(expectedSelectedSection.complexes.opus); + expectToEqual(complexCardCmp.complexes, expectedSelectedSection.complexTypes.opus); }); }); @@ -270,7 +272,9 @@ describe('EditionSectionDetailComponent (DONE)', () => { }); it('... should contain no inner div.awg-edition-section-detail-mnr if no mnr complexes are given', () => { - component.selectedSection.complexes.mnr = undefined; + const shallowCopy = { ...component.selectedSection }; + shallowCopy.complexTypes = { ...component.selectedSection.complexTypes, mnr: undefined }; + component.selectedSection = shallowCopy; fixture.detectChanges(); const divDe = getAndExpectDebugElementByCss(compDe, 'div.awg-edition-section-detail', 1, 1); @@ -284,10 +288,7 @@ describe('EditionSectionDetailComponent (DONE)', () => { const expectedHeaderText = 'nach Moldenhauer-Nummer:'; - expect(headerEl.textContent).toBeTruthy(); - expect(headerEl.textContent) - .withContext(`should be ${expectedHeaderText}`) - .toBe(expectedHeaderText); + expectToBe(headerEl.textContent, expectedHeaderText); }); it('... should contain 1 edition complex card component (stubbed)', () => { @@ -308,10 +309,7 @@ describe('EditionSectionDetailComponent (DONE)', () => { EditionComplexCardStubComponent ) as EditionComplexCardStubComponent; - expect(complexCardCmp.complexes).toBeTruthy(); - expect(complexCardCmp.complexes) - .withContext(`should equal ${expectedSelectedSection.complexes.mnr}`) - .toEqual(expectedSelectedSection.complexes.mnr); + expectToEqual(complexCardCmp.complexes, expectedSelectedSection.complexTypes.mnr); }); }); }); @@ -319,7 +317,9 @@ describe('EditionSectionDetailComponent (DONE)', () => { describe('... with no complexes', () => { describe('... should contain no outer div.awg-edition-section-detail, but 1 div.alert-info ...', () => { it('... if selectedSection has no complexes...', waitForAsync(() => { - component.selectedSection.complexes = undefined; + const shallowCopy = { ...component.selectedSection }; + shallowCopy.complexTypes = undefined; + component.selectedSection = shallowCopy; fixture.detectChanges(); getAndExpectDebugElementByCss(compDe, 'div.awg-edition-section-detail', 0, 0); @@ -327,9 +327,13 @@ describe('EditionSectionDetailComponent (DONE)', () => { })); it('... if selectedSection has empty opus and mnr complexes', waitForAsync(() => { - component.selectedSection = expectedSelectedSeries.sections[4]; - component.selectedSection.complexes.opus = undefined; - component.selectedSection.complexes.mnr = undefined; + const shallowCopy = { ...component.selectedSection }; + shallowCopy.complexTypes = { + ...component.selectedSection.complexTypes, + opus: undefined, + mnr: undefined, + }; + component.selectedSection = shallowCopy; fixture.detectChanges(); getAndExpectDebugElementByCss(compDe, 'div.awg-edition-section-detail', 0, 0); @@ -338,31 +342,35 @@ describe('EditionSectionDetailComponent (DONE)', () => { }); it('... should contain 1 p.text-muted in div.alert-info', () => { - component.selectedSection.complexes = undefined; + const shallowCopy = { ...component.selectedSection }; + shallowCopy.complexTypes = undefined; + component.selectedSection = shallowCopy; fixture.detectChanges(); const divDe = getAndExpectDebugElementByCss(compDe, 'div.alert-info', 1, 1); const pDe = getAndExpectDebugElementByCss(divDe[0], 'p', 1, 1); const pEl = pDe[0].nativeElement; - expect(pEl.classList).toBeTruthy(); - expect(pEl.classList).withContext(`should contain 'text-muted`).toContain('text-muted'); + expectToContain(pEl.classList, 'text-muted'); }); it('... should display info message in p.text-muted', () => { - component.selectedSection.complexes = undefined; + const shallowCopy = { ...component.selectedSection }; + shallowCopy.complexTypes = undefined; + component.selectedSection = shallowCopy; fixture.detectChanges(); const divDe = getAndExpectDebugElementByCss(compDe, 'div.alert-info', 1, 1); const pDe = getAndExpectDebugElementByCss(divDe[0], 'p', 1, 1); const pEl = pDe[0].nativeElement; - const expectedNoComplexesMsg = `[Diese Inhalte erscheinen im Zusammenhang der vollständigen Edition von AWG ${expectedSelectedSeries.series.short}/${expectedSelectedSection.section.short}.]`; + const awg = EDITION_ROUTE_CONSTANTS.EDITION.short; + const series = expectedSelectedSeries.series.short; + const section = expectedSelectedSection.section.short; + + const expectedNoComplexesMsg = `[Diese Inhalte erscheinen im Zusammenhang der vollständigen Edition von ${awg} ${series}/${section}.]`; - expect(pEl.textContent).toBeTruthy(); - expect(pEl.textContent.trim()) - .withContext(`should contain ${expectedNoComplexesMsg}`) - .toContain(expectedNoComplexesMsg.trim()); + expectToBe(pEl.textContent.trim(), expectedNoComplexesMsg.trim()); }); }); }); diff --git a/src/app/views/edition-view/edition-outlets/edition-series-detail/edition-section-detail/edition-section-detail.component.ts b/src/app/views/edition-view/edition-outlets/edition-series-detail/edition-section-detail/edition-section-detail.component.ts index 727f7ada3..d064cb4b7 100644 --- a/src/app/views/edition-view/edition-outlets/edition-series-detail/edition-section-detail/edition-section-detail.component.ts +++ b/src/app/views/edition-view/edition-outlets/edition-series-detail/edition-section-detail/edition-section-detail.component.ts @@ -5,8 +5,8 @@ import { Subject } from 'rxjs'; import { filter, takeUntil } from 'rxjs/operators'; import { UtilityService } from '@awg-core/services'; -import { EditionOutlineSection, EditionOutlineSeries } from '@awg-views/edition-view/models'; -import { EditionService } from '@awg-views/edition-view/services'; +import { EditionOutlineComplexItem, EditionOutlineSection, EditionOutlineSeries } from '@awg-views/edition-view/models'; +import { EditionOutlineService, EditionService } from '@awg-views/edition-view/services'; /** * The EditionSectionDetail component. @@ -66,17 +66,17 @@ export class EditionSectionDetailComponent implements OnInit, OnDestroy { * when initializing the component. */ ngOnInit() { - this.getSection(); + this.updateSectionFromRoute(); } /** - * Public method: getSection. + * Public method: updateSectionFromRoute. * - * It gets the selected section by ID from the EditionService. + * It fetches the route params to get the id of the current section and updates the edition service. * - * @returns {void} Gets the edition section. + * @returns {void} Updates the edition section. */ - getSection(): void { + updateSectionFromRoute(): void { const sectionId = this.route.snapshot.paramMap.get('id'); this.editionService @@ -88,7 +88,7 @@ export class EditionSectionDetailComponent implements OnInit, OnDestroy { .subscribe(series => { this.selectedSeries = series; const seriesId = series.series.route; - this.selectedSection = this.editionService.getEditionSectionById(seriesId, sectionId); + this.selectedSection = EditionOutlineService.getEditionSectionById(seriesId, sectionId); this.editionService.updateSelectedEditionSection(this.selectedSection); }); } diff --git a/src/app/views/edition-view/edition-outlets/edition-series-detail/edition-sections/edition-sections.component.html b/src/app/views/edition-view/edition-outlets/edition-series-detail/edition-sections/edition-sections.component.html index ed5bc2534..6fc8db9fb 100644 --- a/src/app/views/edition-view/edition-outlets/edition-series-detail/edition-sections/edition-sections.component.html +++ b/src/app/views/edition-view/edition-outlets/edition-series-detail/edition-sections/edition-sections.component.html @@ -1,8 +1,8 @@ @if (selectedSeries$ | async; as selectedSeries) {
- @for (section of selectedSeries.sections; track section) { + @for (section of selectedSeries.sections; track $index) {
-
+
{{ section.section.full }} diff --git a/src/app/views/edition-view/edition-outlets/edition-series-detail/edition-sections/edition-sections.component.spec.ts b/src/app/views/edition-view/edition-outlets/edition-series-detail/edition-sections/edition-sections.component.spec.ts index 1e46ea530..26e85bc3b 100644 --- a/src/app/views/edition-view/edition-outlets/edition-series-detail/edition-sections/edition-sections.component.spec.ts +++ b/src/app/views/edition-view/edition-outlets/edition-series-detail/edition-sections/edition-sections.component.spec.ts @@ -1,26 +1,420 @@ +import { DebugElement } from '@angular/core'; import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { RouterOutletStubComponent } from '@testing/router-stubs'; +import { Observable, of as observableOf } from 'rxjs'; +import Spy = jasmine.Spy; + +import { click } from '@testing/click-helper'; +import { + expectSpyCall, + expectToBe, + expectToContain, + expectToEqual, + getAndExpectDebugElementByCss, + getAndExpectDebugElementByDirective, +} from '@testing/expect-helper'; +import { RouterLinkStubDirective } from '@testing/router-stubs'; + +import { EditionOutlineSection, EditionOutlineSeries } from '@awg-app/views/edition-view/models'; +import { EditionComplexesService, EditionOutlineService, EditionService } from '@awg-app/views/edition-view/services'; import { EditionSectionsComponent } from './edition-sections.component'; -describe('EditionSectionsComponent', () => { +describe('EditionSectionsComponent (DONE)', () => { let component: EditionSectionsComponent; let fixture: ComponentFixture; + let compDe: DebugElement; + + let mockEditionService: Partial; + + let clearSelectedSectionSpy: Spy; + let getSeriesSpy: Spy; + let editionServiceClearSelectedEditionSectionSpy: Spy; + let editionServiceGetSelectedEditionSeriesSpy: Spy; + + let expectedSelectedSeries: EditionOutlineSeries; + let expectedSelectedSection: EditionOutlineSection; + + beforeAll(() => { + EditionComplexesService.initializeEditionComplexesList(); + EditionOutlineService.initializeEditionOutline(); + }); beforeEach(waitForAsync(() => { + // Mock edition service + mockEditionService = { + getSelectedEditionSeries: (): Observable => observableOf(expectedSelectedSeries), + clearSelectedEditionSection: (): void => {}, + }; + TestBed.configureTestingModule({ - declarations: [EditionSectionsComponent, RouterOutletStubComponent], + declarations: [EditionSectionsComponent, RouterLinkStubDirective], + providers: [{ provide: EditionService, useValue: mockEditionService }], }).compileComponents(); })); beforeEach(() => { fixture = TestBed.createComponent(EditionSectionsComponent); component = fixture.componentInstance; - fixture.detectChanges(); + compDe = fixture.debugElement; + + // TestData + expectedSelectedSeries = EditionOutlineService.getEditionOutline()[0]; + expectedSelectedSection = expectedSelectedSeries.sections[4]; + + // Spies on component functions + // `.and.callThrough` will track the spy down the nested describes, see + // https://jasmine.github.io/2.0/introduction.html#section-Spies:_%3Ccode%3Eand.callThrough%3C/code%3E + + clearSelectedSectionSpy = spyOn(component, 'clearSelectedSection').and.callThrough(); + getSeriesSpy = spyOn(component, 'getSeries').and.callThrough(); + editionServiceClearSelectedEditionSectionSpy = spyOn( + mockEditionService, + 'clearSelectedEditionSection' + ).and.callThrough(); + editionServiceGetSelectedEditionSeriesSpy = spyOn( + mockEditionService, + 'getSelectedEditionSeries' + ).and.callThrough(); }); it('... should create', () => { expect(component).toBeTruthy(); }); + + describe('BEFORE initial data binding', () => { + it('... should not have `selectedSeries$`', () => { + expect(component.selectedSeries$).toBeUndefined(); + }); + + describe('VIEW', () => { + it('... should not contain one div.row', () => { + getAndExpectDebugElementByCss(compDe, 'div.row', 0, 0); + }); + }); + }); + + describe('AFTER initial data binding', () => { + beforeEach(() => { + component.selectedSeries$ = observableOf(expectedSelectedSeries); + + // Trigger initial data binding + fixture.detectChanges(); + }); + + it('... should have `selectedSeries$`', () => { + expect(component.selectedSeries$).toBeDefined(); + }); + + it('...should trigger `clearSelectedSection` method on init', () => { + expectSpyCall(clearSelectedSectionSpy, 1); + }); + + it('...should trigger `getSeries` method on init', () => { + expectSpyCall(getSeriesSpy, 1); + }); + + describe('VIEW', () => { + it('... should contain one div.row', () => { + getAndExpectDebugElementByCss(compDe, 'div.row', 1, 1); + }); + + it('... should contain as many div.cols with div.card as sections', () => { + const expectedSectionsLength = expectedSelectedSeries.sections.length; + getAndExpectDebugElementByCss( + compDe, + 'div.col > div.card', + expectedSectionsLength, + expectedSectionsLength + ); + }); + + describe('... div.card-body', () => { + it('... should contain one div.card-body in each div.card', () => { + const expectedSectionsLength = expectedSelectedSeries.sections.length; + + const cardDes = getAndExpectDebugElementByCss( + compDe, + 'div.card', + expectedSectionsLength, + expectedSectionsLength + ); + + cardDes.forEach(cardDe => { + getAndExpectDebugElementByCss(cardDe, 'div.card-body', 1, 1); + }); + }); + + it('... should contain one h5.card-title per section in div.card-body', () => { + const expectedSectionsLength = expectedSelectedSeries.sections.length; + + const cardDes = getAndExpectDebugElementByCss( + compDe, + 'div.card', + expectedSectionsLength, + expectedSectionsLength + ); + + cardDes.forEach(cardDe => { + const bodyDes = getAndExpectDebugElementByCss(cardDe, 'div.card-body', 1, 1); + const headerDes = getAndExpectDebugElementByCss(bodyDes[0], 'h5.card-title', 1, 1); + const headerEl = headerDes[0].nativeElement; + + expect(headerEl.textContent).toBeDefined(); + }); + }); + + it('... should display the section title in h5.card-title', () => { + const expectedSectionsLength = expectedSelectedSeries.sections.length; + + const cardDes = getAndExpectDebugElementByCss( + compDe, + 'div.card', + expectedSectionsLength, + expectedSectionsLength + ); + + cardDes.forEach((cardDe, index) => { + const bodyDes = getAndExpectDebugElementByCss(cardDe, 'div.card-body', 1, 1); + const headerDes = getAndExpectDebugElementByCss(bodyDes[0], 'h5.card-title', 1, 1); + const headerEl = headerDes[0].nativeElement; + + expectToBe(headerEl.textContent.trim(), expectedSelectedSeries.sections[index].section.full); + }); + }); + + it('... should mute the section title only if the section is disabled', () => { + const expectedSectionsLength = expectedSelectedSeries.sections.length; + + const cardDes = getAndExpectDebugElementByCss( + compDe, + 'div.card', + expectedSectionsLength, + expectedSectionsLength + ); + + cardDes.forEach((cardDe, index) => { + const bodyDes = getAndExpectDebugElementByCss(cardDe, 'div.card-body', 1, 1); + const headerDes = getAndExpectDebugElementByCss(bodyDes[0], 'h5.card-title', 1, 1); + const headerEl = headerDes[0].nativeElement; + + if (expectedSelectedSeries.sections[index].disabled) { + expectToContain(headerEl.classList, 'text-muted'); + } else { + expect(headerEl.classList).not.toContain('text-muted'); + } + }); + }); + }); + + describe('... div.card-footer', () => { + it('... should contain one div.card-footer in each div.card', () => { + const expectedSectionsLength = expectedSelectedSeries.sections.length; + + const cardDes = getAndExpectDebugElementByCss( + compDe, + 'div.card', + expectedSectionsLength, + expectedSectionsLength + ); + + cardDes.forEach(cardDe => { + getAndExpectDebugElementByCss(cardDe, 'div.card-footer', 1, 1); + }); + }); + + it('... should contain one routerLink per section in div.card-footer', () => { + const expectedSectionsLength = expectedSelectedSeries.sections.length; + + const cardDes = getAndExpectDebugElementByCss( + compDe, + 'div.card', + expectedSectionsLength, + expectedSectionsLength + ); + + cardDes.forEach(cardDe => { + const footerDes = getAndExpectDebugElementByCss(cardDe, 'div.card-footer', 1, 1); + getAndExpectDebugElementByDirective(footerDes[0], RouterLinkStubDirective, 1, 1); + }); + }); + + it('... should have correct routerLink in each div.card-footer', () => { + const expectedSectionsLength = expectedSelectedSeries.sections.length; + + const cardDes = getAndExpectDebugElementByCss( + compDe, + 'div.card', + expectedSectionsLength, + expectedSectionsLength + ); + + cardDes.forEach((cardDe, index) => { + const expectedSection = expectedSelectedSeries.sections[index].section; + + const footerDes = getAndExpectDebugElementByCss(cardDe, 'div.card-footer', 1, 1); + const footerLinkDes = getAndExpectDebugElementByDirective( + footerDes[0], + RouterLinkStubDirective, + 1, + 1 + ); + const footerLink = footerLinkDes[0].injector.get(RouterLinkStubDirective); + + const expectedLinkParams = [expectedSection.route]; + + expectToEqual(footerLink.linkParams, expectedLinkParams); + }); + }); + + it('... should display correct text in each routerLink in div.card-footer', () => { + const expectedSectionsLength = expectedSelectedSeries.sections.length; + + const cardDes = getAndExpectDebugElementByCss( + compDe, + 'div.card', + expectedSectionsLength, + expectedSectionsLength + ); + + cardDes.forEach(cardDe => { + const footerDes = getAndExpectDebugElementByCss(cardDe, 'div.card-footer', 1, 1); + const footerLinkDes = getAndExpectDebugElementByDirective( + footerDes[0], + RouterLinkStubDirective, + 1, + 1 + ); + const footerLinkEl = footerLinkDes[0].nativeElement; + + const expectedLinkText = 'Mehr ...'; + + expectToEqual(footerLinkEl.textContent.trim(), expectedLinkText); + }); + }); + + it('... should disable routerLink only if section is disabled', () => { + const expectedSectionsLength = expectedSelectedSeries.sections.length; + + const cardDes = getAndExpectDebugElementByCss( + compDe, + 'div.card', + expectedSectionsLength, + expectedSectionsLength + ); + + cardDes.forEach((cardDe, index) => { + const expectedSection = expectedSelectedSeries.sections[index]; + + const footerDes = getAndExpectDebugElementByCss(cardDe, 'div.card-footer', 1, 1); + const footerLinkDes = getAndExpectDebugElementByDirective( + footerDes[0], + RouterLinkStubDirective, + 1, + 1 + ); + const footerLinkEl = footerLinkDes[0].nativeElement; + + if (expectedSection.disabled) { + expectToContain(footerLinkEl.classList, 'disabled'); + } else { + expect(footerLinkEl.classList).not.toContain('disabled'); + } + }); + }); + }); + }); + + describe('#clearSelectedSection()', () => { + it('... should have a method `clearSelectedSection`', () => { + expect(component.clearSelectedSection).toBeDefined(); + }); + + it('...should call `clearSelectedEditionSeries` from EditionService', () => { + expectSpyCall(editionServiceClearSelectedEditionSectionSpy, 1); + + component.clearSelectedSection(); + + expectSpyCall(editionServiceClearSelectedEditionSectionSpy, 2); + }); + }); + + describe('#getSeries()', () => { + it('... should have a method `getSeries`', () => { + expect(component.getSeries).toBeDefined(); + }); + + it('...should call `getSelectedEditionSeries` from EditionService', () => { + expectSpyCall(editionServiceGetSelectedEditionSeriesSpy, 1); + + component.getSeries(); + + expectSpyCall(editionServiceGetSelectedEditionSeriesSpy, 2); + }); + + it('...should set `selectedSeries$`', () => { + component.selectedSeries$ = undefined; + fixture.detectChanges(); + + expect(component.selectedSeries$).toBeUndefined(); + + component.getSeries(); + + expect(component.selectedSeries$).toBeDefined(); + }); + }); + + describe('[routerLink]', () => { + let linkDes: DebugElement[]; + let routerLinks: string | any[]; + + beforeEach(() => { + linkDes = getAndExpectDebugElementByDirective(compDe, RouterLinkStubDirective, 5, 5); + + routerLinks = linkDes.map(de => de.injector.get(RouterLinkStubDirective)); + }); + + it('... can get correct number of routerLinks from template', () => { + const expectedSectionsLength = expectedSelectedSeries.sections.length; + + expectToBe(routerLinks.length, expectedSectionsLength); + }); + + it('... can get correct linkParams from template', () => { + let linkIndex = 0; + expectedSelectedSeries.sections.forEach((section, _sectionIndex) => { + if (!section.disabled) { + // Check the router link for the section + const expectedSectionLinkParams = [section.section.route]; + expectToEqual(routerLinks[linkIndex++].linkParams, expectedSectionLinkParams); + } + linkIndex++; + }); + }); + + it('... can click section link in template', () => { + const sectionLinkDe = linkDes[0]; + const sectionLink = routerLinks[0]; + + expectToBe(sectionLink.navigatedTo, null); + + click(sectionLinkDe); + fixture.detectChanges(); + + expectToEqual(sectionLink.navigatedTo, [expectedSelectedSeries.sections[0].section.route]); + }); + + it('... should navigate to section page when section link is clicked', () => { + const sectionLinkDe = linkDes[4]; + const sectionLink = routerLinks[4]; + + expectToBe(sectionLink.navigatedTo, null); + + click(sectionLinkDe); + fixture.detectChanges(); + + expectToEqual(sectionLink.navigatedTo, [expectedSelectedSeries.sections[4].section.route]); + }); + }); + }); }); diff --git a/src/app/views/edition-view/edition-outlets/edition-series-detail/edition-sections/edition-sections.component.ts b/src/app/views/edition-view/edition-outlets/edition-series-detail/edition-sections/edition-sections.component.ts index 3a603cfa6..1f819f5c2 100644 --- a/src/app/views/edition-view/edition-outlets/edition-series-detail/edition-sections/edition-sections.component.ts +++ b/src/app/views/edition-view/edition-outlets/edition-series-detail/edition-sections/edition-sections.component.ts @@ -43,24 +43,24 @@ export class EditionSectionsComponent implements OnInit { } /** - * Public method: getSeries. + * Public method: clearSelectedSection. * - * It gets the selected series from the EditionService. + * It clears the selected section from the EditionService. * - * @returns {void} Gets the edition series. + * @returns {void} Clears the edition section. */ - getSeries(): void { - this.selectedSeries$ = this.editionService.getSelectedEditionSeries(); + clearSelectedSection(): void { + this.editionService.clearSelectedEditionSection(); } /** - * Public method: clearSelectedSection. + * Public method: getSeries. * - * It clears the selected section from the EditionService. + * It gets the selected series from the EditionService. * - * @returns {void} Clears the edition section. + * @returns {void} Gets the edition series. */ - clearSelectedSection(): void { - this.editionService.clearSelectedEditionSection(); + getSeries(): void { + this.selectedSeries$ = this.editionService.getSelectedEditionSeries(); } } diff --git a/src/app/views/edition-view/edition-outlets/edition-series-detail/edition-series-detail.component.spec.ts b/src/app/views/edition-view/edition-outlets/edition-series-detail/edition-series-detail.component.spec.ts index c1f85e709..04da1efb5 100644 --- a/src/app/views/edition-view/edition-outlets/edition-series-detail/edition-series-detail.component.spec.ts +++ b/src/app/views/edition-view/edition-outlets/edition-series-detail/edition-series-detail.component.spec.ts @@ -21,7 +21,6 @@ describe('EditionSeriesDetailComponent', () => { beforeEach(async () => { // Mock edition service mockEditionService = { - getEditionSeriesById: (seriesId: string): EditionOutlineSeries => expectedEditionSeries, updateSelectedEditionSeries: (editionSeries: EditionOutlineSeries): void => {}, }; diff --git a/src/app/views/edition-view/edition-outlets/edition-series-detail/edition-series-detail.component.ts b/src/app/views/edition-view/edition-outlets/edition-series-detail/edition-series-detail.component.ts index 2eac194a2..9276cc5dc 100644 --- a/src/app/views/edition-view/edition-outlets/edition-series-detail/edition-series-detail.component.ts +++ b/src/app/views/edition-view/edition-outlets/edition-series-detail/edition-series-detail.component.ts @@ -2,7 +2,7 @@ import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { EditionOutlineSeries } from '@awg-views/edition-view/models'; -import { EditionService } from '@awg-views/edition-view/services'; +import { EditionOutlineService, EditionService } from '@awg-views/edition-view/services'; /** * The EditionSeriesDetail component. @@ -45,20 +45,20 @@ export class EditionSeriesDetailComponent implements OnInit { * when initializing the component. */ ngOnInit() { - this.getSeries(); + this.updateSeriesFromRoute(); } /** - * Public method: getSeries. + * Public method: updateSeriesFromRoute. * - * It gets the selected series by ID from the EditionService. + * It fetches the route params to get the id of the current series and updates the edition service. * - * @returns {void} Gets the edition series. + * @returns {void} Updates the edition series. */ - getSeries(): void { + updateSeriesFromRoute(): void { const id = this.route.snapshot.paramMap.get('id'); - this.selectedSeries = this.editionService.getEditionSeriesById(id); + this.selectedSeries = EditionOutlineService.getEditionSeriesById(id); this.editionService.updateSelectedEditionSeries(this.selectedSeries); } } diff --git a/src/app/views/edition-view/edition-outlets/edition-series/edition-series.component.html b/src/app/views/edition-view/edition-outlets/edition-series/edition-series.component.html index ad78cb2d8..ef930c38d 100644 --- a/src/app/views/edition-view/edition-outlets/edition-series/edition-series.component.html +++ b/src/app/views/edition-view/edition-outlets/edition-series/edition-series.component.html @@ -1,14 +1,14 @@ @if (editionOutline) {
- @for (series of editionOutline; track series) { + @for (series of editionOutline; track $index) {
-
+
{{ series.series.full }}
    - @for (section of series.sections; track section) { + @for (section of series.sections; track $index) {
  • @if (!section.disabled) { {{ diff --git a/src/app/views/edition-view/edition-outlets/edition-series/edition-series.component.spec.ts b/src/app/views/edition-view/edition-outlets/edition-series/edition-series.component.spec.ts index ea8228361..b77cf5fe2 100644 --- a/src/app/views/edition-view/edition-outlets/edition-series/edition-series.component.spec.ts +++ b/src/app/views/edition-view/edition-outlets/edition-series/edition-series.component.spec.ts @@ -11,12 +11,12 @@ import { getAndExpectDebugElementByCss, getAndExpectDebugElementByDirective, } from '@testing/expect-helper'; +import { mockEditionOutline } from '@testing/mock-data/mockEditionOutline'; import { RouterLinkStubDirective } from '@testing/router-stubs'; -import { EDITION_OUTLINE_DATA } from '@awg-views/edition-view/data'; import { EDITION_ROUTE_CONSTANTS } from '@awg-views/edition-view/edition-route-constants'; import { EditionOutlineSeries } from '@awg-views/edition-view/models'; -import { EditionService } from '@awg-views/edition-view/services'; +import { EditionComplexesService, EditionOutlineService, EditionService } from '@awg-views/edition-view/services'; import { EditionSeriesComponent } from './edition-series.component'; @@ -35,12 +35,18 @@ describe('EditionSeriesComponent (DONE)', () => { let expectedEditionOutline: EditionOutlineSeries[]; + beforeAll(() => { + EditionComplexesService.initializeEditionComplexesList(); + EditionOutlineService.initializeEditionOutline(); + }); + beforeEach(waitForAsync(() => { + // Mock edition service mockEditionService = { clearSelectedEditionSeries: () => {}, clearSelectedEditionSection: () => {}, - getEditionOutline: (): EditionOutlineSeries[] => EDITION_OUTLINE_DATA, }; + TestBed.configureTestingModule({ declarations: [EditionSeriesComponent, RouterLinkStubDirective], providers: [{ provide: EditionService, useValue: mockEditionService }], @@ -53,7 +59,7 @@ describe('EditionSeriesComponent (DONE)', () => { compDe = fixture.debugElement; // Test data - expectedEditionOutline = EDITION_OUTLINE_DATA; + expectedEditionOutline = EditionOutlineService.getEditionOutline(); // Spies clearSelectionsSpy = spyOn(component, 'clearSelections').and.callThrough(); @@ -66,7 +72,7 @@ describe('EditionSeriesComponent (DONE)', () => { mockEditionService, 'clearSelectedEditionSection' ).and.callThrough(); - serviceGetEditionOutlineSpy = spyOn(mockEditionService, 'getEditionOutline').and.callThrough(); + serviceGetEditionOutlineSpy = spyOn(EditionOutlineService, 'getEditionOutline').and.callThrough(); }); it('... should create', () => { @@ -92,15 +98,14 @@ describe('EditionSeriesComponent (DONE)', () => { describe('AFTER initial data binding', () => { beforeEach(() => { - // Component.editionOutline = expectedEditionOutline; + component.editionOutline = expectedEditionOutline; // Trigger initial data binding fixture.detectChanges(); }); it('... should have `editionOutline`', () => { - expect(component.editionOutline).toBeDefined(); - expect(component.editionOutline).toEqual(expectedEditionOutline); + expectToEqual(component.editionOutline, expectedEditionOutline); }); it('...should trigger `clearSelections` method on init', () => { @@ -119,54 +124,54 @@ describe('EditionSeriesComponent (DONE)', () => { it('... should contain as many div.col in div.row as there are series', () => { const expectedSeriesLength = expectedEditionOutline.length; - const rowDe = getAndExpectDebugElementByCss(compDe, 'div.row', 1, 1); + const rowDes = getAndExpectDebugElementByCss(compDe, 'div.row', 1, 1); - getAndExpectDebugElementByCss(rowDe[0], 'div.col', expectedSeriesLength, expectedSeriesLength); + getAndExpectDebugElementByCss(rowDes[0], 'div.col', expectedSeriesLength, expectedSeriesLength); }); it('... should contain a div.card in each div.col', () => { const expectedSeriesLength = expectedEditionOutline.length; - const colDe = getAndExpectDebugElementByCss( + const colDes = getAndExpectDebugElementByCss( compDe, 'div.col', expectedSeriesLength, expectedSeriesLength ); - colDe.forEach((de, _index) => { - getAndExpectDebugElementByCss(de, 'div.card', 1, 1); + colDes.forEach(colDe => { + getAndExpectDebugElementByCss(colDe, 'div.card', 1, 1); }); }); it('... should contain a h5.card-header in each div.card', () => { const expectedSeriesLength = expectedEditionOutline.length; - const cardDe = getAndExpectDebugElementByCss( + const cardDes = getAndExpectDebugElementByCss( compDe, 'div.card', expectedSeriesLength, expectedSeriesLength ); - cardDe.forEach((de, _index) => { - getAndExpectDebugElementByCss(de, 'h5.card-header', 1, 1); + cardDes.forEach(cardDe => { + getAndExpectDebugElementByCss(cardDe, 'h5.card-header', 1, 1); }); }); it('... should display series name in each h5.card-header', () => { const expectedSeriesLength = expectedEditionOutline.length; - const cardDe = getAndExpectDebugElementByCss( + const cardDes = getAndExpectDebugElementByCss( compDe, 'div.card', expectedSeriesLength, expectedSeriesLength ); - cardDe.forEach((de, index) => { + cardDes.forEach((cardDe, index) => { const expectedSeries = expectedEditionOutline[index].series; - const h5De = getAndExpectDebugElementByCss(de, 'h5.card-header', 1, 1); + const h5De = getAndExpectDebugElementByCss(cardDe, 'h5.card-header', 1, 1); const h5El = h5De[0].nativeElement; expectToBe(h5El.textContent.trim(), expectedSeries.full); @@ -176,48 +181,48 @@ describe('EditionSeriesComponent (DONE)', () => { it('... should contain a div.card-body in each div.card', () => { const expectedSeriesLength = expectedEditionOutline.length; - const cardDe = getAndExpectDebugElementByCss( + const cardDes = getAndExpectDebugElementByCss( compDe, 'div.card', expectedSeriesLength, expectedSeriesLength ); - cardDe.forEach((de, _index) => { - getAndExpectDebugElementByCss(de, 'div.card-body', 1, 1); + cardDes.forEach(cardDe => { + getAndExpectDebugElementByCss(cardDe, 'div.card-body', 1, 1); }); }); it('... should contain a ul.list-group in each div.card-body', () => { const expectedSeriesLength = expectedEditionOutline.length; - const cardBodyDe = getAndExpectDebugElementByCss( + const cardBodyDes = getAndExpectDebugElementByCss( compDe, 'div.card-body', expectedSeriesLength, expectedSeriesLength ); - cardBodyDe.forEach((de, _index) => { - getAndExpectDebugElementByCss(de, 'ul.list-group', 1, 1); + cardBodyDes.forEach(cardBodyDe => { + getAndExpectDebugElementByCss(cardBodyDe, 'ul.list-group', 1, 1); }); }); it('... should contain as many li.list-group-item in ul.list-group as there are sections in a series', () => { const expectedSeriesLength = expectedEditionOutline.length; - const ulDe = getAndExpectDebugElementByCss( + const ulDes = getAndExpectDebugElementByCss( compDe, 'ul.list-group', expectedSeriesLength, expectedSeriesLength ); - ulDe.forEach((de, index) => { + ulDes.forEach((ulDe, index) => { const expectedSectionsLength = expectedEditionOutline[index].sections.length; getAndExpectDebugElementByCss( - de, + ulDe, 'li.list-group-item', expectedSectionsLength, expectedSectionsLength @@ -228,26 +233,26 @@ describe('EditionSeriesComponent (DONE)', () => { it('... should display section name in each li.list-group-item', () => { const expectedSeriesLength = expectedEditionOutline.length; - const ulDe = getAndExpectDebugElementByCss( + const ulDes = getAndExpectDebugElementByCss( compDe, 'ul.list-group', expectedSeriesLength, expectedSeriesLength ); - ulDe.forEach((de, index) => { + ulDes.forEach((ulDe, index) => { const expectedSections = expectedEditionOutline[index].sections; - const liDe = getAndExpectDebugElementByCss( - de, + const liDes = getAndExpectDebugElementByCss( + ulDe, 'li.list-group-item', expectedSections.length, expectedSections.length ); - liDe.forEach((li, liIndex) => { + liDes.forEach((liDe, liIndex) => { const expectedSection = expectedSections[liIndex].section; - const liEl = li.nativeElement; + const liEl = liDe.nativeElement; expectToBe(liEl.textContent.trim(), expectedSection.full); }); @@ -257,29 +262,29 @@ describe('EditionSeriesComponent (DONE)', () => { it('... should contain a routerLink and no span.text-muted in li.list-group-item if section is not disabled', () => { const expectedSeriesLength = expectedEditionOutline.length; - const ulDe = getAndExpectDebugElementByCss( + const ulDes = getAndExpectDebugElementByCss( compDe, 'ul.list-group', expectedSeriesLength, expectedSeriesLength ); - ulDe.forEach((de, index) => { + ulDes.forEach((ulDe, index) => { const expectedSections = expectedEditionOutline[index].sections; - const liDe = getAndExpectDebugElementByCss( - de, + const liDes = getAndExpectDebugElementByCss( + ulDe, 'li.list-group-item', expectedSections.length, expectedSections.length ); - liDe.forEach((li, liIndex) => { + liDes.forEach((liDe, liIndex) => { const expectedSection = expectedSections[liIndex]; if (!expectedSection.disabled) { - getAndExpectDebugElementByDirective(li, RouterLinkStubDirective, 1, 1); - getAndExpectDebugElementByCss(li, 'span.text-muted', 0, 0); + getAndExpectDebugElementByDirective(liDe, RouterLinkStubDirective, 1, 1); + getAndExpectDebugElementByCss(liDe, 'span.text-muted', 0, 0); } }); }); @@ -288,29 +293,29 @@ describe('EditionSeriesComponent (DONE)', () => { it('... should contain no router link, but a span.text-muted in li.list-group-item if section is disabled', () => { const expectedSeriesLength = expectedEditionOutline.length; - const ulDe = getAndExpectDebugElementByCss( + const ulDes = getAndExpectDebugElementByCss( compDe, 'ul.list-group', expectedSeriesLength, expectedSeriesLength ); - ulDe.forEach((de, index) => { + ulDes.forEach((ulDe, index) => { const expectedSections = expectedEditionOutline[index].sections; - const liDe = getAndExpectDebugElementByCss( - de, + const liDes = getAndExpectDebugElementByCss( + ulDe, 'li.list-group-item', expectedSections.length, expectedSections.length ); - liDe.forEach((li, liIndex) => { + liDes.forEach((liDe, liIndex) => { const expectedSection = expectedSections[liIndex]; if (expectedSection.disabled) { - getAndExpectDebugElementByDirective(li, RouterLinkStubDirective, 0, 0); - getAndExpectDebugElementByCss(li, 'span.text-muted', 1, 1); + getAndExpectDebugElementByDirective(liDe, RouterLinkStubDirective, 0, 0); + getAndExpectDebugElementByCss(liDe, 'span.text-muted', 1, 1); } }); }); @@ -319,83 +324,83 @@ describe('EditionSeriesComponent (DONE)', () => { it('... should contain a div.card-footer in each div.card', () => { const expectedSeriesLength = expectedEditionOutline.length; - const cardDe = getAndExpectDebugElementByCss( + const cardDes = getAndExpectDebugElementByCss( compDe, 'div.card', expectedSeriesLength, expectedSeriesLength ); - cardDe.forEach((de, _index) => { - getAndExpectDebugElementByCss(de, 'div.card-footer', 1, 1); + cardDes.forEach((cardDe, _index) => { + getAndExpectDebugElementByCss(cardDe, 'div.card-footer', 1, 1); }); }); it('... should contain a routerLink in each div.card-footer', () => { const expectedSeriesLength = expectedEditionOutline.length; - const cardDe = getAndExpectDebugElementByCss( + const cardDes = getAndExpectDebugElementByCss( compDe, 'div.card', expectedSeriesLength, expectedSeriesLength ); - cardDe.forEach((de, _index) => { - const footerDe = getAndExpectDebugElementByCss(de, 'div.card-footer', 1, 1); - getAndExpectDebugElementByDirective(footerDe[0], RouterLinkStubDirective, 1, 1); + cardDes.forEach((cardDe, _index) => { + const footerDes = getAndExpectDebugElementByCss(cardDe, 'div.card-footer', 1, 1); + getAndExpectDebugElementByDirective(footerDes[0], RouterLinkStubDirective, 1, 1); }); }); it('... should have correct routerLink in each div.card-footer', () => { const expectedSeriesLength = expectedEditionOutline.length; - const cardDe = getAndExpectDebugElementByCss( + const cardDes = getAndExpectDebugElementByCss( compDe, 'div.card', expectedSeriesLength, expectedSeriesLength ); - cardDe.forEach((de, index) => { + cardDes.forEach((cardDe, index) => { const expectedSeries = expectedEditionOutline[index].series; - const footerDe = getAndExpectDebugElementByCss(de, 'div.card-footer', 1, 1); + const footerDes = getAndExpectDebugElementByCss(cardDe, 'div.card-footer', 1, 1); - const footerLinkDe = getAndExpectDebugElementByDirective( - footerDe[0], + const footerLinkDes = getAndExpectDebugElementByDirective( + footerDes[0], RouterLinkStubDirective, 1, 1 ); - const footerLink = footerLinkDe[0].injector.get(RouterLinkStubDirective); + const footerLink = footerLinkDes[0].injector.get(RouterLinkStubDirective); const expectedLinkParams = [expectedSeries.route]; - expect(footerLink.linkParams).toEqual(expectedLinkParams); + expectToEqual(footerLink.linkParams, expectedLinkParams); }); }); it('... should display correct text in each routerLink in div.card-footer', () => { const expectedSeriesLength = expectedEditionOutline.length; - const cardDe = getAndExpectDebugElementByCss( + const cardDes = getAndExpectDebugElementByCss( compDe, 'div.card', expectedSeriesLength, expectedSeriesLength ); - cardDe.forEach((de, _index) => { - const footerDe = getAndExpectDebugElementByCss(de, 'div.card-footer', 1, 1); + cardDes.forEach((cardDe, _index) => { + const footerDes = getAndExpectDebugElementByCss(cardDe, 'div.card-footer', 1, 1); - const footerLinkDe = getAndExpectDebugElementByDirective( - footerDe[0], + const footerLinkDes = getAndExpectDebugElementByDirective( + footerDes[0], RouterLinkStubDirective, 1, 1 ); - const footerLinkEl = footerLinkDe[0].nativeElement; + const footerLinkEl = footerLinkDes[0].nativeElement; const expectedLinkText = 'Mehr ...'; @@ -420,18 +425,18 @@ describe('EditionSeriesComponent (DONE)', () => { it('... can get correct linkParams from template', () => { let linkIndex = 0; - EDITION_OUTLINE_DATA.forEach((series, _seriesIndex) => { + expectedEditionOutline.forEach((series, _seriesIndex) => { series.sections.forEach((section, _sectionIndex) => { if (!section.disabled) { // Check the router link for the section const expectedSectionLinkParams = [series.series.route, 'section', section.section.route]; - expect(routerLinks[linkIndex++].linkParams).toEqual(expectedSectionLinkParams); + expectToEqual(routerLinks[linkIndex++].linkParams, expectedSectionLinkParams); } }); // Check the final router link for the series const expectedSeriesLinkParams = [series.series.route]; - expect(routerLinks[linkIndex++].linkParams).toEqual(expectedSeriesLinkParams); + expectToEqual(routerLinks[linkIndex++].linkParams, expectedSeriesLinkParams); }); }); @@ -439,7 +444,7 @@ describe('EditionSeriesComponent (DONE)', () => { const sectionLinkDe = linkDes[0]; const sectionLink = routerLinks[0]; - expect(sectionLink.navigatedTo).toBeNull(); + expectToBe(sectionLink.navigatedTo, null); click(sectionLinkDe); fixture.detectChanges(); @@ -451,7 +456,7 @@ describe('EditionSeriesComponent (DONE)', () => { const sectionLinkDe = linkDes[0]; const sectionLink = routerLinks[0]; - expect(sectionLink.navigatedTo).toBeNull(); + expectToBe(sectionLink.navigatedTo, null); click(sectionLinkDe); fixture.detectChanges(); @@ -463,7 +468,7 @@ describe('EditionSeriesComponent (DONE)', () => { const seriesLinkDe = linkDes[1]; const seriesLink = routerLinks[1]; - expect(seriesLink.navigatedTo).toBeNull(); + expectToBe(seriesLink.navigatedTo, null); click(seriesLinkDe); fixture.detectChanges(); @@ -471,11 +476,11 @@ describe('EditionSeriesComponent (DONE)', () => { expectToEqual(seriesLink.navigatedTo, ['1']); }); - it('... should navigate to section page when section link is clicked', () => { + it('... should navigate to series page when series link is clicked', () => { const seriesLinkDe = linkDes[1]; const seriesLink = routerLinks[1]; - expect(seriesLink.navigatedTo).toBeNull(); + expectToBe(seriesLink.navigatedTo, null); click(seriesLinkDe); fixture.detectChanges(); @@ -520,7 +525,7 @@ describe('EditionSeriesComponent (DONE)', () => { }); it('...should set `editionOutline`', () => { - const anotherEditionOutline = JSON.parse(JSON.stringify(EDITION_OUTLINE_DATA)); + const anotherEditionOutline = JSON.parse(JSON.stringify(mockEditionOutline)); anotherEditionOutline[0].series = EDITION_ROUTE_CONSTANTS.SERIES_2; serviceGetEditionOutlineSpy.and.returnValue(anotherEditionOutline); diff --git a/src/app/views/edition-view/edition-outlets/edition-series/edition-series.component.ts b/src/app/views/edition-view/edition-outlets/edition-series/edition-series.component.ts index e06bd33fb..fc9813244 100644 --- a/src/app/views/edition-view/edition-outlets/edition-series/edition-series.component.ts +++ b/src/app/views/edition-view/edition-outlets/edition-series/edition-series.component.ts @@ -1,7 +1,7 @@ import { Component, OnInit } from '@angular/core'; import { EditionOutlineSeries } from '@awg-views/edition-view/models'; -import { EditionService } from '@awg-views/edition-view/services'; +import { EditionOutlineService, EditionService } from '@awg-views/edition-view/services'; /** * The EditionSeries component. @@ -64,6 +64,6 @@ export class EditionSeriesComponent implements OnInit { * @returns {void} Gets the edition outline. */ getEditionOutline(): void { - this.editionOutline = this.editionService.getEditionOutline(); + this.editionOutline = EditionOutlineService.getEditionOutline(); } } diff --git a/src/app/views/edition-view/edition-outlets/edition-type/edition-type.component.html b/src/app/views/edition-view/edition-outlets/edition-type/edition-type.component.html deleted file mode 100644 index f6bb522eb..000000000 --- a/src/app/views/edition-view/edition-outlets/edition-type/edition-type.component.html +++ /dev/null @@ -1,3 +0,0 @@ -

    edition-type works!

    - - diff --git a/src/app/views/edition-view/edition-outlets/edition-type/edition-type.component.spec.ts b/src/app/views/edition-view/edition-outlets/edition-type/edition-type.component.spec.ts deleted file mode 100644 index 9127f822d..000000000 --- a/src/app/views/edition-view/edition-outlets/edition-type/edition-type.component.spec.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; - -import { RouterOutletStubComponent } from '@testing/router-stubs'; - -import { EditionTypeComponent } from './edition-type.component'; - -describe('EditionTypeComponent', () => { - let component: EditionTypeComponent; - let fixture: ComponentFixture; - - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [EditionTypeComponent, RouterOutletStubComponent], - }).compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(EditionTypeComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('... should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/views/edition-view/edition-outlets/edition-type/edition-type.component.ts b/src/app/views/edition-view/edition-outlets/edition-type/edition-type.component.ts deleted file mode 100644 index 57f27d7e9..000000000 --- a/src/app/views/edition-view/edition-outlets/edition-type/edition-type.component.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Component } from '@angular/core'; - -/** - * The EditionType component. - * - * It contains the type section - * of the edition view of the app. - */ -@Component({ - selector: 'awg-edition-type', - templateUrl: './edition-type.component.html', - styleUrls: ['./edition-type.component.scss'], -}) -export class EditionTypeComponent {} diff --git a/src/app/views/edition-view/edition-outlets/edition-type/index.ts b/src/app/views/edition-view/edition-outlets/edition-type/index.ts deleted file mode 100644 index dcad7d049..000000000 --- a/src/app/views/edition-view/edition-outlets/edition-type/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './edition-type.component'; diff --git a/src/app/views/edition-view/edition-route-constants.ts b/src/app/views/edition-view/edition-route-constants.ts index 2cdbaa20a..fd2b7a7ac 100644 --- a/src/app/views/edition-view/edition-route-constants.ts +++ b/src/app/views/edition-view/edition-route-constants.ts @@ -85,6 +85,15 @@ export class EDITION_ROUTE_CONSTANTS { full: 'Anton Webern Gesamtausgabe', }; + /** + * The route constant for the preface. + */ + static readonly PREFACE: EditionRouteConstant = { + route: 'preface', + short: 'Vorwort', + full: 'Vorwort / Preface', + }; + /** * The route constant for the row tables. */ diff --git a/src/app/views/edition-view/edition-view-routing.module.ts b/src/app/views/edition-view/edition-view-routing.module.ts index e222a9bfe..2dca199d7 100644 --- a/src/app/views/edition-view/edition-view-routing.module.ts +++ b/src/app/views/edition-view/edition-view-routing.module.ts @@ -7,7 +7,6 @@ import { EditionSeriesComponent } from './edition-outlets/edition-series'; import { EditionSeriesDetailComponent } from './edition-outlets/edition-series-detail'; import { EditionSectionDetailComponent } from './edition-outlets/edition-series-detail/edition-section-detail'; import { EditionSectionsComponent } from './edition-outlets/edition-series-detail/edition-sections'; -import { EditionTypeComponent } from './edition-outlets/edition-type'; import { EditionViewComponent } from './edition-view.component'; /* Routes of the EditionViewModule */ @@ -121,7 +120,13 @@ const EDITION_VIEW_ROUTES: Routes = [ ], }, { - // Overview of row tables. + path: 'preface', + loadChildren: () => + import('./edition-outlets/edition-preface/edition-preface.module').then( + m => m.EditionPrefaceModule + ), + }, + { path: 'row-tables', loadChildren: () => import('./edition-outlets/edition-row-tables/edition-row-tables.module').then( @@ -135,8 +140,7 @@ const EDITION_VIEW_ROUTES: Routes = [ /** * Routed components of the {@link EditionViewModule}: * {@link EditionViewComponent}, {@link EditionDetailNavComponent}, - * {@link EditionSectionsComponent}, {@link EditionSeriesComponent} - * and {@link EditionTypeComponent}. + * {@link EditionSectionsComponent} and {@link EditionSeriesComponent}. */ export const routedEditionViewComponents = [ EditionViewComponent, @@ -146,7 +150,6 @@ export const routedEditionViewComponents = [ EditionSectionDetailComponent, EditionSeriesComponent, EditionSeriesDetailComponent, - EditionTypeComponent, ]; /** diff --git a/src/app/views/edition-view/edition-view.component.html b/src/app/views/edition-view/edition-view.component.html index fa44cae89..a58713484 100644 --- a/src/app/views/edition-view/edition-view.component.html +++ b/src/app/views/edition-view/edition-view.component.html @@ -1,6 +1,24 @@
    + + + @if (isPrefaceView$ | async; as isPrefaceView) { +
    +
    + + {{ editionRouteConstants.EDITION?.short }} + + / + {{ editionRouteConstants.PREFACE.short }} +
    + + +
    + } + @if (isRowTableView$ | async; as isRowTableView) {
    @@ -15,33 +33,41 @@
    } - @if ((selectedEditionComplex$ | async) === null && (isRowTableView$ | async) === null) { + @if ( + (selectedEditionComplex$ | async) === null && + (isRowTableView$ | async) === null && + (isPrefaceView$ | async) === null + ) {
    + + {{ editionRouteConstants.EDITION?.short }} + + @if (selectedEditionSeries$ | async; as selectedSeries) { + + {{ selectedSeries?.series.full }} + + - {{ editionRouteConstants.EDITION?.short }} + - } @else { - {{ editionRouteConstants.EDITION?.short }} - } - / - @if (selectedEditionSeries$ | async; as selectedSeries) { - - @if (selectedEditionSection$ | async; as selectedSection) { - - {{ selectedSeries?.series.full }} - - } @else { - {{ selectedSeries?.series.full }} - } + / + @if (selectedEditionSection$ | async; as selectedSection) { + + + / - - } - @if (selectedEditionSection$ | async; as selectedSection) { - - {{ selectedSection?.section.full }} - + + {{ selectedSection?.section.full }} + + } @else { + + / + } + } @else { + + / }
    @@ -58,32 +84,33 @@
    {{ editionRouteConstants.EDITION?.short }} / - - {{ selectedEditionComplex.series.full }} + + {{ selectedEditionComplex.pubStatement.series.full }} / - {{ selectedEditionComplex.section.full }} + {{ selectedEditionComplex.pubStatement.section.full }}
    -

    - -

    + +

    Ediert von - @for ( - editor of selectedEditionComplex.responsibilityStatement.editors; - track editor; - let isLast = $last - ) { + @for (editor of selectedEditionComplex.respStatement.editors; track $index; let isLast = $last) { {{ editor.name }} @if (!isLast) { @@ -93,7 +120,7 @@

    }
    Versionsdatum: - {{ selectedEditionComplex.responsibilityStatement.lastModified }} + {{ selectedEditionComplex.respStatement.lastModified }}

    diff --git a/src/app/views/edition-view/edition-view.component.spec.ts b/src/app/views/edition-view/edition-view.component.spec.ts index 254f90633..f3695898d 100644 --- a/src/app/views/edition-view/edition-view.component.spec.ts +++ b/src/app/views/edition-view/edition-view.component.spec.ts @@ -14,17 +14,15 @@ import { getAndExpectDebugElementByCss, getAndExpectDebugElementByDirective, } from '@testing/expect-helper'; -import { mockEditionOutline } from '@testing/mock-data/mockEditionOutline'; import { ActivatedRouteStub, RouterLinkStubDirective, RouterOutletStubComponent } from '@testing/router-stubs'; -import { EDITION_COMPLEXES } from '@awg-views/edition-view/data'; import { EDITION_ROUTE_CONSTANTS } from '@awg-views/edition-view/edition-route-constants'; import { EditionComplex, EditionOutlineSection, EditionOutlineSeries } from '@awg-views/edition-view/models'; -import { EditionService } from '@awg-views/edition-view/services'; +import { EditionComplexesService, EditionOutlineService, EditionService } from '@awg-views/edition-view/services'; import { EditionViewComponent } from './edition-view.component'; -// Mock jumbotron component +// Mock components @Component({ selector: 'awg-edition-jumbotron', template: '' }) class EditionJumbotronStubComponent { @Input() @@ -33,6 +31,9 @@ class EditionJumbotronStubComponent { jumbotronTitle: string; } +@Component({ selector: 'awg-scroll-to-top', template: '' }) +class ScrollToTopStubComponent {} + describe('EditionViewComponent (DONE)', () => { let component: EditionViewComponent; let fixture: ComponentFixture; @@ -42,24 +43,31 @@ describe('EditionViewComponent (DONE)', () => { let mockActivatedRoute: ActivatedRouteStub; let mockEditionService: Partial; - let getSelectionsFromRouteSpy: Spy; + let setupEditionViewSpy: Spy; let routeToSidenavSpy: Spy; - let editionServiceGetEditionComplexSpy: Spy; + let editionServiceGetSelectedEditionComplexSpy: Spy; let editionServiceGetSelectedEditionSeriesSpy: Spy; let editionServiceGetSelectedEditionSectionSpy: Spy; + let editionServiceGetIsPrefaceViewSpy: Spy; let editionServiceGetIsRowTableViewSpy: Spy; + let expectedSelectedEditionComplexId: string; let expectedSelectedEditionComplex: EditionComplex; let expectedSelectedEditionSeries: EditionOutlineSeries; let expectedSelectedEditionSection: EditionOutlineSection; + let expectedIsPrefaceView: boolean; let expectedIsRowTableView: boolean; - const expectedSelectedEditionComplexId = 'OP12'; const expectedTitle = 'Inhalt'; const expectedId = 'awg-edition-view'; const expectedEditionRouteConstants: typeof EDITION_ROUTE_CONSTANTS = EDITION_ROUTE_CONSTANTS; + beforeAll(() => { + EditionComplexesService.initializeEditionComplexesList(); + EditionOutlineService.initializeEditionOutline(); + }); + beforeEach(waitForAsync(() => { // Mock router with spy object mockRouter = jasmine.createSpyObj('Router', ['navigate']); @@ -69,17 +77,18 @@ describe('EditionViewComponent (DONE)', () => { // Mock edition service mockEditionService = { - getEditionComplex: (): Observable => + getIsPrefaceView: (): Observable => observableOf(expectedIsPrefaceView), + getIsRowTableView: (): Observable => observableOf(expectedIsRowTableView), + getSelectedEditionComplex: (): Observable => // Return op. 12 by default - observableOf(EDITION_COMPLEXES[expectedSelectedEditionComplexId]), - updateEditionComplex: (editionComplex: EditionComplex): void => { + observableOf(EditionComplexesService.getEditionComplexById(expectedSelectedEditionComplexId)), + updateSelectedEditionComplex: (editionComplex: EditionComplex): void => { // Intentional empty test override }, getSelectedEditionSeries: (): Observable => observableOf(expectedSelectedEditionSeries), getSelectedEditionSection: (): Observable => - observableOf(expectedSelectedEditionSeries.sections[0]), - getIsRowTableView: (): Observable => observableOf(expectedIsRowTableView), + observableOf(expectedSelectedEditionSection), }; TestBed.configureTestingModule({ @@ -88,13 +97,11 @@ describe('EditionViewComponent (DONE)', () => { EditionJumbotronStubComponent, RouterOutletStubComponent, RouterLinkStubDirective, + ScrollToTopStubComponent, ], providers: [ { provide: EditionService, useValue: mockEditionService }, - { - provide: ActivatedRoute, - useValue: mockActivatedRoute, - }, + { provide: ActivatedRoute, useValue: mockActivatedRoute }, { provide: Router, useValue: mockRouter }, ], }).compileComponents(); @@ -108,19 +115,28 @@ describe('EditionViewComponent (DONE)', () => { mockEditionService = TestBed.inject(EditionService); // Test data - expectedSelectedEditionComplex = EDITION_COMPLEXES[expectedSelectedEditionComplexId]; // Op. 12 - expectedSelectedEditionSeries = mockEditionOutline[0]; - expectedSelectedEditionSection = expectedSelectedEditionSeries.sections[0]; + expectedIsPrefaceView = false; expectedIsRowTableView = true; + expectedSelectedEditionComplexId = 'OP12'; + expectedSelectedEditionComplex = EditionComplexesService.getEditionComplexById( + expectedSelectedEditionComplexId + ); + expectedSelectedEditionSeries = EditionOutlineService.getEditionOutline()[0]; // Series 1 + expectedSelectedEditionSection = expectedSelectedEditionSeries.sections[4]; // Section 5 // Spies on component functions // `.and.callThrough` will track the spy down the nested describes, see // https://jasmine.github.io/2.0/introduction.html#section-Spies:_%3Ccode%3Eand.callThrough%3C/code%3E - getSelectionsFromRouteSpy = spyOn(component, 'getSelectionsFromRoute').and.callThrough(); + setupEditionViewSpy = spyOn(component, 'setupEditionView').and.callThrough(); routeToSidenavSpy = spyOn(component, 'routeToSidenav').and.callThrough(); // Spies for service methods - editionServiceGetEditionComplexSpy = spyOn(mockEditionService, 'getEditionComplex').and.callThrough(); + editionServiceGetSelectedEditionComplexSpy = spyOn( + mockEditionService, + 'getSelectedEditionComplex' + ).and.callThrough(); + editionServiceGetIsPrefaceViewSpy = spyOn(mockEditionService, 'getIsPrefaceView').and.callThrough(); + editionServiceGetIsRowTableViewSpy = spyOn(mockEditionService, 'getIsRowTableView').and.callThrough(); editionServiceGetSelectedEditionSeriesSpy = spyOn( mockEditionService, 'getSelectedEditionSeries' @@ -129,7 +145,6 @@ describe('EditionViewComponent (DONE)', () => { mockEditionService, 'getSelectedEditionSection' ).and.callThrough(); - editionServiceGetIsRowTableViewSpy = spyOn(mockEditionService, 'getIsRowTableView').and.callThrough(); }); afterAll(() => { @@ -150,6 +165,10 @@ describe('EditionViewComponent (DONE)', () => { expectToEqual(component.editionRouteConstants, expectedEditionRouteConstants); }); + it('... should not have `isPrefaceView$`', () => { + expect(component.isPrefaceView$).toBeUndefined(); + }); + it('... should not have `isRowTableView$`', () => { expect(component.isRowTableView$).toBeUndefined(); }); @@ -167,6 +186,10 @@ describe('EditionViewComponent (DONE)', () => { }); describe('VIEW', () => { + it('... should contain one ScrollToTop component (stubbed)', () => { + getAndExpectDebugElementByDirective(compDe, ScrollToTopStubComponent, 1, 1); + }); + it('... should contain one outer div', () => { getAndExpectDebugElementByCss(compDe, 'div', 1, 1); }); @@ -188,21 +211,25 @@ describe('EditionViewComponent (DONE)', () => { }); }); - describe('#getSelectionsFromRoute()', () => { - it('... should have a method `getSelectionsFromRoute`', () => { - expect(component.getSelectionsFromRoute).toBeDefined(); + describe('#setupEditionView()', () => { + it('... should have a method `setupEditionView`', () => { + expect(component.setupEditionView).toBeDefined(); }); it('... should not have been called', () => { - expectSpyCall(getSelectionsFromRouteSpy, 0); + expectSpyCall(setupEditionViewSpy, 0); }); it('... should not have called EditionService', () => { - expectSpyCall(editionServiceGetEditionComplexSpy, 0); + expectSpyCall(editionServiceGetSelectedEditionComplexSpy, 0); expectSpyCall(editionServiceGetSelectedEditionSeriesSpy, 0); expectSpyCall(editionServiceGetSelectedEditionSectionSpy, 0); }); + it('... should not have set isPrefaceView$', () => { + expect(component.isPrefaceView$).toBeUndefined(); + }); + it('... should not have set isRowTableView$', () => { expect(component.isRowTableView$).toBeUndefined(); }); @@ -238,7 +265,59 @@ describe('EditionViewComponent (DONE)', () => { }); describe('VIEW', () => { - describe('... if isRowTableView$ is given, it', () => { + describe('... if isPrefaceView$ is given', () => { + beforeEach(waitForAsync(() => { + component.isPrefaceView$ = observableOf(true); + + // Trigger data binding + fixture.detectChanges(); + })); + + it('... should have one div.awg-edition-preface', () => { + getAndExpectDebugElementByCss(compDe, 'div.awg-edition-preface', 1, 1); + }); + + it('... should have an h6 (breadcrumb) and a JumbotronComponent (stubbed)', () => { + const divDes = getAndExpectDebugElementByCss(compDe, 'div.awg-edition-preface', 1, 1); + + getAndExpectDebugElementByCss(divDes[0], 'h6.awg-edition-info-breadcrumb', 1, 1); + + getAndExpectDebugElementByDirective(divDes[0], EditionJumbotronStubComponent, 1, 1); + }); + + it('... should display edition base root (AWG) and heading title in breadcrumb header (h6)', () => { + const hDes = getAndExpectDebugElementByCss( + compDe, + 'div.awg-edition-preface > h6.awg-edition-info-breadcrumb', + 1, + 1 + ); + const hEl = hDes[0].nativeElement; + + const expectedBreadCrumb = `${expectedEditionRouteConstants.EDITION.short} / ${expectedEditionRouteConstants.PREFACE.short}`; + + expectToBe(hEl.innerText, expectedBreadCrumb); + }); + + it('... should pass down `editionViewId` and `title` to JumbotronComponent (stubbed)', () => { + // Get debug and native element of JumbotronComponent + const divDes = getAndExpectDebugElementByCss(compDe, 'div.awg-edition-preface', 1, 1); + const jumbotronDes = getAndExpectDebugElementByDirective( + divDes[0], + EditionJumbotronStubComponent, + 1, + 1 + ); + const jumbotronCmp = jumbotronDes[0].injector.get( + EditionJumbotronStubComponent + ) as EditionJumbotronStubComponent; + + expectToBe(jumbotronCmp.jumbotronId, expectedId); + expectToBe(jumbotronCmp.jumbotronTitle, expectedEditionRouteConstants.PREFACE.full); + }); + }); + + describe('... if isRowTableView$ is given', () => { beforeEach(waitForAsync(() => { component.isRowTableView$ = observableOf(true); @@ -290,7 +369,7 @@ describe('EditionViewComponent (DONE)', () => { }); }); - describe('... if selectedEditionComplex$ is given, it', () => { + describe('... if selectedEditionComplex$ is given', () => { beforeEach(waitForAsync(() => { component.selectedEditionComplex$ = observableOf(expectedSelectedEditionComplex); @@ -302,11 +381,11 @@ describe('EditionViewComponent (DONE)', () => { getAndExpectDebugElementByCss(compDe, 'div.awg-edition-complex', 1, 1); }); - it('... should have an h6, an h3 and a responsibility div in div.awg-edition-complex', () => { + it('... should have an h6 (breadcrumb), a JumbotronComponent (stubbed) and a responsibility div in div.awg-edition-complex', () => { const divDes = getAndExpectDebugElementByCss(compDe, 'div.awg-edition-complex', 1, 1); - getAndExpectDebugElementByCss(divDes[0], 'h6', 1, 1); - getAndExpectDebugElementByCss(divDes[0], 'h3.awg-edition-info-header', 1, 1); + getAndExpectDebugElementByCss(divDes[0], 'h6.awg-edition-info-breadcrumb', 1, 1); + getAndExpectDebugElementByDirective(divDes[0], EditionJumbotronStubComponent, 1, 1); getAndExpectDebugElementByCss(divDes[0], 'div.awg-edition-responsibility', 1, 1); }); @@ -319,30 +398,35 @@ describe('EditionViewComponent (DONE)', () => { ); const hEl = hDes[0].nativeElement; - const expectedBreadCrumb = `${expectedEditionRouteConstants.EDITION.short} / ${expectedSelectedEditionComplex.series.full} / ${expectedSelectedEditionComplex.section.full}`; + const awg = EDITION_ROUTE_CONSTANTS.EDITION.short; + const series = expectedSelectedEditionComplex.pubStatement.series.full; + const section = expectedSelectedEditionComplex.pubStatement.section.full; + const expectedBreadCrumb = `${awg} / ${series} / ${section}`; expectToBe(hEl.innerText, expectedBreadCrumb); }); - it('... should display edition complex title in awg-edition-info-header', () => { - const hDes = getAndExpectDebugElementByCss( - compDe, - 'div.awg-edition-complex > h3.awg-edition-info-header', + it('... should pass down `editionViewId` and `title` to JumbotronComponent (stubbed)', () => { + // Get debug and native element of JumbotronComponent + const divDes = getAndExpectDebugElementByCss(compDe, 'div.awg-edition-complex', 1, 1); + const jumbotronDes = getAndExpectDebugElementByDirective( + divDes[0], + EditionJumbotronStubComponent, 1, 1 ); - const titleDes = getAndExpectDebugElementByCss(hDes[0], '.awg-edition-info-header-title', 1, 1); - const titleEl = titleDes[0].nativeElement; - - const expectedHeaderTitle = expectedSelectedEditionComplex.complexId.full; + const jumbotronCmp = jumbotronDes[0].injector.get( + EditionJumbotronStubComponent + ) as EditionJumbotronStubComponent; - expectToBe(titleEl.innerHTML, expectedHeaderTitle); + expectToBe(jumbotronCmp.jumbotronId, expectedId); + expectToBe(jumbotronCmp.jumbotronTitle, expectedSelectedEditionComplex.complexId.full); }); it('... should have one paragraph with editor and version in responsibility div', () => { const pDes = getAndExpectDebugElementByCss(compDe, 'div.awg-edition-responsibility > p', 1, 1); - const editors = expectedSelectedEditionComplex.responsibilityStatement.editors; + const editors = expectedSelectedEditionComplex.respStatement.editors; getAndExpectDebugElementByCss(pDes[0], 'span.editor', editors.length, editors.length); getAndExpectDebugElementByCss(pDes[0], 'span.version', 1, 1); @@ -351,7 +435,7 @@ describe('EditionViewComponent (DONE)', () => { it('... should display editor and version in responsibility div', () => { const pDes = getAndExpectDebugElementByCss(compDe, 'div.awg-edition-responsibility > p', 1, 1); - const expectedEditors = expectedSelectedEditionComplex.responsibilityStatement.editors; + const expectedEditors = expectedSelectedEditionComplex.respStatement.editors; const editorDes = getAndExpectDebugElementByCss( pDes[0], 'span.editor > a', @@ -369,14 +453,24 @@ describe('EditionViewComponent (DONE)', () => { expectToBe(editorEl.innerText, expectedEditors[i].name); }); - expectToBe( - versionEl.innerText, - expectedSelectedEditionComplex.responsibilityStatement.lastModified - ); + expectToBe(versionEl.innerText, expectedSelectedEditionComplex.respStatement.lastModified); }); }); - describe('... if selectedEditionComplex$ and isRowTableView$ are not given, it', () => { + describe('... if selectedEditionComplex$, isPrefaceView$ and isRowTableView$ are not given', () => { + beforeEach(waitForAsync(() => { + component.selectedEditionComplex$ = observableOf(null); + component.isPrefaceView$ = observableOf(null); + component.isRowTableView$ = observableOf(null); + + // Trigger data binding + fixture.detectChanges(); + })); + + it('... should not have a div.awg-edition-preface', () => { + getAndExpectDebugElementByCss(compDe, 'div.awg-edition-preface', 0, 0); + }); + it('... should not have a div.awg-edition-row-tables', () => { getAndExpectDebugElementByCss(compDe, 'div.awg-edition-row-tables', 0, 0); }); @@ -416,6 +510,12 @@ describe('EditionViewComponent (DONE)', () => { describe('... breadcrumb header (h6)', () => { it('... should display edition base root (AWG) if no series and section is given', () => { + component.selectedEditionSeries$ = observableOf(null); + component.selectedEditionSection$ = observableOf(null); + + // Trigger data binding + fixture.detectChanges(); + const hDes = getAndExpectDebugElementByCss( compDe, 'div.awg-edition-series > h6.awg-edition-info-breadcrumb', @@ -424,13 +524,18 @@ describe('EditionViewComponent (DONE)', () => { ); const hEl = hDes[0].nativeElement; - const expectedBreadCrumb = `${expectedEditionRouteConstants.EDITION.short} /`; + const awg = EDITION_ROUTE_CONSTANTS.EDITION.short; + const expectedBreadCrumb = `${awg} /`; expectToBe(hEl.innerText, expectedBreadCrumb); }); it('... should display edition series if series, but no section is given', () => { component.selectedEditionSeries$ = observableOf(expectedSelectedEditionSeries); + component.selectedEditionSection$ = observableOf(null); + + // Trigger data binding + fixture.detectChanges(); // Trigger data binding fixture.detectChanges(); @@ -443,7 +548,9 @@ describe('EditionViewComponent (DONE)', () => { ); const hEl = hDes[0].nativeElement; - const expectedBreadCrumb = `${expectedEditionRouteConstants.EDITION.short} / ${expectedSelectedEditionSeries.series.full} /`; + const awg = EDITION_ROUTE_CONSTANTS.EDITION.short; + const series = expectedSelectedEditionComplex.pubStatement.series.full; + const expectedBreadCrumb = `${awg} / ${series} /`; expectToBe(hEl.innerText, expectedBreadCrumb); }); @@ -463,7 +570,10 @@ describe('EditionViewComponent (DONE)', () => { ); const hEl = hDes[0].nativeElement; - const expectedBreadCrumb = `${expectedEditionRouteConstants.EDITION.short} / ${expectedSelectedEditionSeries.series.full} / ${expectedSelectedEditionSection.section.full}`; + const awg = EDITION_ROUTE_CONSTANTS.EDITION.short; + const series = expectedSelectedEditionComplex.pubStatement.series.full; + const section = expectedSelectedEditionComplex.pubStatement.section.full; + const expectedBreadCrumb = `${awg} / ${series} / ${section}`; expectToBe(hEl.innerText, expectedBreadCrumb); }); @@ -471,13 +581,25 @@ describe('EditionViewComponent (DONE)', () => { }); }); - describe('#getSelectionsFromRoute()', () => { + describe('#setupEditionView()', () => { it('... should have been called', () => { - expectSpyCall(getSelectionsFromRouteSpy, 1); + expectSpyCall(setupEditionViewSpy, 1); }); + it('... should get isPrefaceView$ (via EditionService)', waitForAsync(() => { + expectSpyCall(setupEditionViewSpy, 1); + expectSpyCall(editionServiceGetIsPrefaceViewSpy, 1); + + expect(component.isPrefaceView$).toBeDefined(); + component.isPrefaceView$.subscribe({ + next: (isView: boolean) => { + expectToBe(isView, expectedIsPrefaceView); + }, + }); + })); + it('... should get isRowTableView$ (via EditionService)', waitForAsync(() => { - expectSpyCall(getSelectionsFromRouteSpy, 1); + expectSpyCall(setupEditionViewSpy, 1); expectSpyCall(editionServiceGetIsRowTableViewSpy, 1); expect(component.isRowTableView$).toBeDefined(); @@ -489,7 +611,7 @@ describe('EditionViewComponent (DONE)', () => { })); it('... should get selectedEditionSeries$ (via EditionService)', waitForAsync(() => { - expectSpyCall(getSelectionsFromRouteSpy, 1); + expectSpyCall(setupEditionViewSpy, 1); expectSpyCall(editionServiceGetSelectedEditionSeriesSpy, 1); expect(component.selectedEditionSeries$).toBeDefined(); @@ -501,7 +623,7 @@ describe('EditionViewComponent (DONE)', () => { })); it('... should get selectedEditionSection$ (via EditionService)', waitForAsync(() => { - expectSpyCall(getSelectionsFromRouteSpy, 1); + expectSpyCall(setupEditionViewSpy, 1); expectSpyCall(editionServiceGetSelectedEditionSectionSpy, 1); expect(component.selectedEditionSection$).toBeDefined(); @@ -513,13 +635,16 @@ describe('EditionViewComponent (DONE)', () => { })); it('... should get selectedEditionComplex$ (via EditionService)', waitForAsync(() => { - expectSpyCall(getSelectionsFromRouteSpy, 1); - expectSpyCall(editionServiceGetEditionComplexSpy, 1); + expectSpyCall(setupEditionViewSpy, 1); + expectSpyCall(editionServiceGetSelectedEditionComplexSpy, 1); expect(component.selectedEditionComplex$).toBeDefined(); component.selectedEditionComplex$.subscribe({ next: (complex: EditionComplex) => { - expectToEqual(complex, EDITION_COMPLEXES[expectedSelectedEditionComplexId]); + expectToEqual( + complex, + EditionComplexesService.getEditionComplexById(expectedSelectedEditionComplexId) + ); }, }); })); diff --git a/src/app/views/edition-view/edition-view.component.ts b/src/app/views/edition-view/edition-view.component.ts index 1ce5a4eed..6169b22c6 100644 --- a/src/app/views/edition-view/edition-view.component.ts +++ b/src/app/views/edition-view/edition-view.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from '@angular/core'; -import { ActivatedRoute, Router } from '@angular/router'; +import { Router } from '@angular/router'; import { delay, Observable } from 'rxjs'; @@ -34,6 +34,14 @@ export class EditionViewComponent implements OnInit { */ editionViewId = 'awg-edition-view'; + /** + * Public variable: isPrefaceView$. + * + * Observable that keeps the information + * about the flag for the preface view. + */ + isPrefaceView$: Observable; + /** * Public variable: isRowTableView$. * @@ -53,9 +61,7 @@ export class EditionViewComponent implements OnInit { /** * Public variable: selectedEditionSection$. * - * It keeps the selected section of the edition as an Observable of EditionOutlineSection; -; -. + * It keeps the selected section of the edition as an Observable of EditionOutlineSection. */ selectedEditionSection$: Observable; @@ -73,12 +79,10 @@ export class EditionViewComponent implements OnInit { * EditionService, ActivatedRoute and Router. * * @param {EditionService} editionService Instance of the EditionService. - * @param {ActivatedRoute} route Instance of the Angular ActivatedRoute. * @param {Router} router Instance of the Angular router. */ constructor( private editionService: EditionService, - private route: ActivatedRoute, private router: Router ) {} @@ -98,21 +102,24 @@ export class EditionViewComponent implements OnInit { * when initializing the component. */ ngOnInit() { - this.getSelectionsFromRoute(); + this.setupEditionView(); this.routeToSidenav(); } /** - * Public method: getSelectionsFromRoute. + * Public method: setupEditionView. * - * It loads the selected series, section, and edition complex from the edition service (if given). + * It sets up the edition view by loading + * the selected series, section, and edition complex + * from the edition service. * - * @returns {void} Gets the selected series, section, and edition complex from the edition service. + * @returns {void} Sets up the edition view. */ - getSelectionsFromRoute(): void { + setupEditionView(): void { this.selectedEditionSeries$ = this.editionService.getSelectedEditionSeries().pipe(delay(0)); this.selectedEditionSection$ = this.editionService.getSelectedEditionSection().pipe(delay(0)); - this.selectedEditionComplex$ = this.editionService.getEditionComplex().pipe(delay(0)); + this.selectedEditionComplex$ = this.editionService.getSelectedEditionComplex().pipe(delay(0)); + this.isPrefaceView$ = this.editionService.getIsPrefaceView().pipe(delay(0)); this.isRowTableView$ = this.editionService.getIsRowTableView().pipe(delay(0)); } diff --git a/src/app/views/edition-view/models/edition-complex.model.ts b/src/app/views/edition-view/models/edition-complex.model.ts index 63465bb05..ab43d860d 100644 --- a/src/app/views/edition-view/models/edition-complex.model.ts +++ b/src/app/views/edition-view/models/edition-complex.model.ts @@ -6,12 +6,42 @@ import { import { EditionRouteConstant } from './edition-route-constant.model'; /** - * The EditionTitleStatement class. + * The EditionComplexJsonData interface. + * + * It is used in the context of the edition view + * to describe the structure of a JSON data for an edition complex. + */ +export interface EditionComplexJsonData { + /** + * The edition complex data. + */ + [key: string]: { + titleStatement: { title: string; catalogueType: string; catalogueNumber: string }; + respStatement: { editors: { name: string; homepage: string }[]; lastModified: string }; + pubStatement: { series: string; section: string }; + }; +} + +/** + * The EditionComplexesJsonData interface. + * + * It is used in the context of the edition view + * to describe the structure of a JSON data for edition complexes. + */ +export interface EditionComplexesJsonData { + /** + * The edition complexes data. + */ + editionComplexes: EditionComplexJsonData[]; +} + +/** + * The EditionComplexTitleStatement class. * * It is used in the context of the edition view * to store information about the title statement of an edition complex. */ -export class EditionTitleStatement { +export class EditionComplexTitleStatement { /** * The title of a title statement. */ @@ -29,12 +59,12 @@ export class EditionTitleStatement { } /** - * The EditionResponsibilityStatement class. + * The EditionComplexRespStatement class. * * It is used in the context of the edition view * to store information about the responsibility statement of an edition complex. */ -export class EditionResponsibilityStatement { +export class EditionComplexRespStatement { /** * The editors of an edition complex. */ @@ -47,41 +77,49 @@ export class EditionResponsibilityStatement { } /** - * The EditionComplex class. + * The EditionComplexPubStatement class. * * It is used in the context of the edition view - * to store information about an edition complex. + * to store information about the publication statement of an edition complex. */ -export class EditionComplex { +export class EditionComplexPubStatement { /** - * The title statement of the current edition complex. + * The route for the current series. */ - titleStatement: EditionTitleStatement; + series: EditionRouteConstant; /** - * The responsibility statement of the current edition complex. + * The route for the current section. */ - responsibilityStatement: EditionResponsibilityStatement; + section: EditionRouteConstant; +} +/** + * The EditionComplex class. + * + * It is used in the context of the edition view + * to store information about an edition complex. + */ +export class EditionComplex { /** - * The id for the current edition complex. + * The title statement of the current edition complex. */ - complexId: EditionRouteConstant; + titleStatement: EditionComplexTitleStatement; /** - * The route for the current series. + * The responsibility statement of the current edition complex. */ - series: EditionRouteConstant; + respStatement: EditionComplexRespStatement; /** - * The route for the current section. + * The publication statement of the current edition complex. */ - section: EditionRouteConstant; + pubStatement: EditionComplexPubStatement; /** - * The route for the current type of an edition. + * The id for the current edition complex. */ - type: EditionRouteConstant; + complexId: EditionRouteConstant; /** * The base route of an edition complex. @@ -95,18 +133,14 @@ export class EditionComplex { * * It initializes the class with an edition complex Object from the EditionConstants. * - * @param {EditionTitleStatement} titleStatement The given TitleStatement for the edition complex. - * @param {EditionResponsibilityStatement} responsibilityStatement The given ResponsibilityStatement for the edition complex. - * @param {EditionRouteConstant} series The given series. - * @param {EditionRouteConstant} section The given section. - * @param {EditionRouteConstant} type The given edition type. + * @param {{ title: string; catalogueType: string; catalogueNumber: string }} titleStatement The given TitleStatement for the edition complex. + * @param {EditionComplexRespStatement} respStatement The given ResponsibilityStatement for the edition complex. + * @param {{ series: string; section: string }} pubStatement The given PublicationStatement for the edition complex. */ constructor( - titleStatement: EditionTitleStatement, - responsibilityStatement: EditionResponsibilityStatement, - series?: EditionRouteConstant, - section?: EditionRouteConstant, - type?: EditionRouteConstant + titleStatement: { title: string; catalogueType: string; catalogueNumber: string }, + respStatement: EditionComplexRespStatement, + pubStatement: { series: string; section: string } ) { if (!titleStatement?.catalogueType || !titleStatement?.catalogueNumber) { return; @@ -117,28 +151,67 @@ export class EditionComplex { const spacer = ' '; // Set dynamic routes - this.titleStatement = titleStatement; - this.responsibilityStatement = responsibilityStatement || new EditionResponsibilityStatement(); + this.titleStatement = { + ...titleStatement, + catalogueType: this._mapCatalogueType(titleStatement.catalogueType), + }; + + this.respStatement = respStatement ?? new EditionComplexRespStatement(); + + this.pubStatement = { + series: this._mapPubStatement('SERIES_', pubStatement?.series), + section: this._mapPubStatement('SECTION_', pubStatement?.section), + }; this.complexId = new EditionRouteConstant(); - if (this.titleStatement.catalogueType === EDITION_CATALOGUE_TYPE_CONSTANTS.OPUS) { - this.complexId.route = EDITION_CATALOGUE_TYPE_CONSTANTS.OPUS.route; - } else if (this.titleStatement.catalogueType === EDITION_CATALOGUE_TYPE_CONSTANTS.MNR) { - this.complexId.route = EDITION_CATALOGUE_TYPE_CONSTANTS.MNR.route; - } else if (this.titleStatement.catalogueType === EDITION_CATALOGUE_TYPE_CONSTANTS.MNR_PLUS) { - this.complexId.route = EDITION_CATALOGUE_TYPE_CONSTANTS.MNR_PLUS.route; - } + this.complexId.route = this.titleStatement.catalogueType.route; // For routes, replace slashes in catalogue number with underscores this.complexId.route += this.titleStatement.catalogueNumber.replace(/\//g, '_'); - this.complexId.short = this.titleStatement.catalogueType.short + spacer + this.titleStatement.catalogueNumber; + this.complexId.short = `${this.titleStatement.catalogueType.short}${spacer}${this.titleStatement.catalogueNumber}`; this.complexId.full = `${this.titleStatement.title} ${this.complexId.short}`; - this.series = series || new EditionRouteConstant(); - this.section = section || new EditionRouteConstant(); - this.type = type || new EditionRouteConstant(); - // Set base route - const rootPath = EDITION_ROUTE_CONSTANTS.EDITION.route + EDITION_ROUTE_CONSTANTS.COMPLEX.route; - this.baseRoute = rootPath + this.complexId.route + delimiter; + const rootPath = `${EDITION_ROUTE_CONSTANTS.EDITION.route}${EDITION_ROUTE_CONSTANTS.COMPLEX.route}`; + this.baseRoute = `${rootPath}${this.complexId.route}${delimiter}`; + } + + /** + * Private method: _mapCatalogueType. + * + * It maps the catalogue type to the corresponding route constant. + * + * @param {string} catalogueType The given catalogue type. + * + * @returns {EditionRouteConstant} The corresponding route constant. + */ + private _mapCatalogueType(catalogueType: string): EditionRouteConstant { + return EDITION_CATALOGUE_TYPE_CONSTANTS[catalogueType.toUpperCase()]; + } + + /** + * Private method: _mapPubStatement. + * + * It maps the publication statement to the corresponding route constant. + * + * @param {string} prefix The given prefix. + * @param {string} value The given value. + * + * @returns {EditionRouteConstant} The corresponding route constant. + */ + private _mapPubStatement(prefix: string, value?: string): EditionRouteConstant { + return EDITION_ROUTE_CONSTANTS[`${prefix}${value?.toUpperCase()}`]; } } + +/** + * The EditionComplexesList class. + * + * It is used in the context of the edition view + * to describe a list of edition complexes. + */ +export class EditionComplexesList { + /** + * The list of edition complexes. + */ + [key: string]: EditionComplex; +} diff --git a/src/app/views/edition-view/models/edition-outline.model.ts b/src/app/views/edition-view/models/edition-outline.model.ts index ece8d9373..080248156 100644 --- a/src/app/views/edition-view/models/edition-outline.model.ts +++ b/src/app/views/edition-view/models/edition-outline.model.ts @@ -1,45 +1,87 @@ +import { EDITION_ROUTE_CONSTANTS } from '@awg-views/edition-view/edition-route-constants'; +import { EditionRouteConstant } from '@awg-views/edition-view/models'; +import { EditionComplexesService } from '@awg-views/edition-view/services'; + import { EditionComplex } from './edition-complex.model'; -import { EditionRouteConstant } from './edition-route-constant.model'; /** - * The EditionOutlineSeries interface. + * The EditionOutlineSeriesJsonData interface. * * It is used in the context of the edition view - * to structure outline information of the edition series. + * to describe the structure of a JSON data for an edition outline series. */ -export interface EditionOutlineSeries { +export interface EditionOutlineSeriesJsonData { /** - * The series route of an edition series. + * The series data. */ - series: EditionRouteConstant; + series: string; /** - * The section route of an edition series. + * The sections data. */ - sections: EditionOutlineSection[]; + sections: EditionOutlineSectionsJsonData[]; } /** - * The EditionOutlineSection interface. + * The EditionOutlineSectionsJsonData interface. * * It is used in the context of the edition view - * to structure outline information of the edition sections. + * to describe the structure of a JSON data for an edition outline sections. */ -export interface EditionOutlineSection { +export interface EditionOutlineSectionsJsonData { /** - * The section route of an edition section. + * The section data. */ - section: EditionRouteConstant; + section: string; /** - * The edition complexes of an edition section. + * The complexTypes data */ - complexes: EditionOutlineComplexTypes; + complexTypes: { + opus: [{ complex: string; disabled: boolean }]; + mnr: [{ complex: string; disabled: boolean }]; + }; /** - * Boolean flag if an edition section is disabled. + * Boolean flag if a section is disabled. + */ + disabled: boolean; +} + +/** + * The EditionOutlineJsonData interface. + * + * It is used in the context of the edition view + * to describe the structure of a JSON data for an edition outline. + */ +export interface EditionOutlineJsonData { + /** + * The edition outline data. + */ + editionOutline: EditionOutlineSeriesJsonData[]; +} + +/** + * The EditionOutlineComplex interface. + * + * It is used in the context of the edition view + * to structure outline information of an edition complex. + */ +export interface EditionOutlineComplexItem { + /** + * The edition complex. + */ + complex: EditionComplex; + + /** + * Boolean flag if an edition complex is disabled. */ disabled: boolean; + + /** + * The sub-complexes of an edition complex. + */ + subComplexes?: EditionOutlineComplexItem[]; } /** @@ -52,28 +94,144 @@ export interface EditionOutlineComplexTypes { /** * The opus parts of an edition complex. */ - opus: EditionOutlineComplex[]; + opus: EditionOutlineComplexItem[]; /** * The mnr parts of an edition complex. */ - mnr: EditionOutlineComplex[]; + mnr: EditionOutlineComplexItem[]; } /** - * The EditionOutlineComplex interface. + * The EditionOutlineSection interface. * * It is used in the context of the edition view - * to structure outline information of an edition complex. + * to structure outline information of the edition sections. */ -export interface EditionOutlineComplex { +export interface EditionOutlineSection { /** - * The edition complex. + * The section route of an edition section. */ - complex: EditionComplex; + section: EditionRouteConstant; /** - * Boolean flag if an edition complex is disabled. + * The edition complex types of an edition section. + */ + complexTypes: EditionOutlineComplexTypes; + + /** + * Boolean flag if an edition section is disabled. */ disabled: boolean; } + +/** + * The EditionOutlineSeries interface. + * + * It is used in the context of the edition view + * to structure outline information of the edition series. + */ +export interface EditionOutlineSeries { + /** + * The series route of an edition series. + */ + series: EditionRouteConstant; + + /** + * The section route of an edition series. + */ + sections: EditionOutlineSection[]; +} + +/** + * The EditionOutline interface. + * + * It is used in the context of the edition view + * to structure outline information of the edition. + */ +export class EditionOutline { + /** + * The outline of the edition. + */ + outline: EditionOutlineSeries[]; + + /** + * Constructor of the EditionOutline class. + * + * It initializes the class with an edition outline Object. + * + * @param {EditionOutlineSeriesJsonData[]} outlineData The given edition outline. + */ + constructor(outlineData: EditionOutlineSeriesJsonData[]) { + if (!outlineData) { + return; + } + + this.outline = outlineData.map(this._mapSeries); + } + + /** + * Private method: _mapSeries. + * + * It maps the series data. + * + * @param {EditionOutlineSeriesJsonData} data The series data to map. + * @param {string} data.series The given series string. + * @param {EditionOutlineSectionsJsonData[]} data.sections The given sections data. + * + * @returns {EditionOutlineSeries} The mapped series. + */ + private _mapSeries = ({ series, sections }: EditionOutlineSeriesJsonData): EditionOutlineSeries => { + const seriesConstant: EditionRouteConstant = EDITION_ROUTE_CONSTANTS['SERIES_' + series]; + return { + series: seriesConstant, + sections: sections.map(section => this._mapSection(section, series)), + }; + }; + + /** + * Private method: _mapSection. + * + * It maps the section data. + * + * @param {EditionOutlineSectionsJsonData} data The section data to map. + * @param {string} data.section The given section string. + * @param {Object} data.complexTypes The given complex types data. + * @param {boolean} data.disabled The given disabled flag. + * + * @returns {EditionOutlineSection} The mapped section. + */ + private _mapSection = ( + { section, complexTypes, disabled }: EditionOutlineSectionsJsonData, + series: string + ): EditionOutlineSection => { + const sectionConstant: EditionRouteConstant = + series === '3' && section === '5' + ? EDITION_ROUTE_CONSTANTS.SERIES_3_SECTION_5 + : EDITION_ROUTE_CONSTANTS['SECTION_' + section]; + + return { + section: sectionConstant, + complexTypes: { + opus: this._mapComplexItems(complexTypes.opus), + mnr: this._mapComplexItems(complexTypes.mnr), + }, + disabled, + }; + }; + + /** + * Private method: _mapComplexItems. + * + * It maps the complex items. + * + * @param {EditionOutlineComplexItem[]} complexItems The complex items to map. + * + * @returns {EditionOutlineComplexItem[]} The mapped complex items. + */ + private _mapComplexItems = (complexItems: { complex: string; disabled: boolean }[]): EditionOutlineComplexItem[] => + complexItems.map(({ complex, disabled }) => ({ + complex: EditionComplexesService.getEditionComplexById(complex), + disabled, + })); +} diff --git a/src/app/views/edition-view/models/folio-calculation.model.ts b/src/app/views/edition-view/models/folio-calculation.model.ts index 157b77da7..631beb8c6 100644 --- a/src/app/views/edition-view/models/folio-calculation.model.ts +++ b/src/app/views/edition-view/models/folio-calculation.model.ts @@ -277,8 +277,20 @@ export class FolioCalculationContentSegmentVertices { const systemIndex = isStart ? section.startSystem - 1 : section.endSystem - 1; const systemLines = this.systems.SYSTEMS_LINES.SYSTEMS_ARRAYS[systemIndex]; + let offset = 0; + switch (section.relativeToSystem) { + case 'below': + offset = 20; + break; + case 'above': + offset = -20; + break; + default: + offset = 0; + } + const yValue = isStart ? systemLines.at(0).START_POINT.y : systemLines.at(-1).END_POINT.y; - const correction = this.segmentOffsetCorrection * (isStart ? -1 : 1); + const correction = this.segmentOffsetCorrection * (isStart ? -1 : 1) + offset; return round(yValue + correction, 2); } diff --git a/src/app/views/edition-view/models/folio.model.ts b/src/app/views/edition-view/models/folio.model.ts index 7b8b776f2..5f04ba1b1 100644 --- a/src/app/views/edition-view/models/folio.model.ts +++ b/src/app/views/edition-view/models/folio.model.ts @@ -165,4 +165,9 @@ export class FolioSection { * The folio section's optional position (number). */ position?: number; + + /** + * The folio section's optional position relative to the system (string). + */ + relativeToSystem?: string; } diff --git a/src/app/views/edition-view/models/index.ts b/src/app/views/edition-view/models/index.ts index a22692c8b..bb023019d 100644 --- a/src/app/views/edition-view/models/index.ts +++ b/src/app/views/edition-view/models/index.ts @@ -10,8 +10,20 @@ import { D3Selection } from './d3-selection.model'; import { D3ZoomBehaviour } from './d3-zoom-behaviour.model'; -import { EditionComplex, EditionTitleStatement } from './edition-complex.model'; -import { EditionOutlineComplex, EditionOutlineSection, EditionOutlineSeries } from './edition-outline.model'; +import { + EditionComplex, + EditionComplexesJsonData, + EditionComplexesList, + EditionComplexJsonData, + EditionComplexTitleStatement, +} from './edition-complex.model'; +import { + EditionOutline, + EditionOutlineComplexItem, + EditionOutlineJsonData, + EditionOutlineSection, + EditionOutlineSeries, +} from './edition-outline.model'; import { EditionRouteConstant } from './edition-route-constant.model'; import { EditionRowTables, EditionRowTablesList } from './edition-row-tables.model'; import { EditionSvgLinkBox } from './edition-svg-link-box.model'; @@ -25,6 +37,7 @@ import { Folio, FolioContent, FolioConvolute, FolioConvoluteList, FolioFormat, F import { Graph, GraphList, GraphRDFData, GraphSparqlQuery } from './graph.model'; import { Intro, IntroList } from './intro.model'; +import { Preface, PrefaceList } from './preface.model'; import { SourceDescription, @@ -38,7 +51,7 @@ import { import { SourceEvaluation, SourceEvaluationList } from './source-evaluation.model'; import { Source, SourceList } from './source-list.model'; -import { TextcriticalComment, Textcritics, TextcriticsList } from './textcritics.model'; +import { TextcriticalComment, TextcriticalCommentBlock, Textcritics, TextcriticsList } from './textcritics.model'; import { TkaTableHeaderColumn } from './tka-table-header.model'; import { ViewBox } from './view-box.model'; @@ -46,7 +59,13 @@ export { D3Selection, D3ZoomBehaviour, EditionComplex, - EditionOutlineComplex, + EditionComplexesJsonData, + EditionComplexesList, + EditionComplexJsonData, + EditionComplexTitleStatement, + EditionOutline, + EditionOutlineComplexItem, + EditionOutlineJsonData, EditionOutlineSection, EditionOutlineSeries, EditionRouteConstant, @@ -58,7 +77,6 @@ export { EditionSvgOverlayTypes, EditionSvgSheet, EditionSvgSheetList, - EditionTitleStatement, Folio, FolioCalculation, FolioCalculationLine, @@ -77,6 +95,8 @@ export { GraphSparqlQuery, Intro, IntroList, + Preface, + PrefaceList, Source, SourceDescription, SourceDescriptionList, @@ -89,6 +109,7 @@ export { SourceEvaluationList, SourceList, TextcriticalComment, + TextcriticalCommentBlock, Textcritics, TextcriticsList, TkaTableHeaderColumn, diff --git a/src/app/views/edition-view/models/preface.model.ts b/src/app/views/edition-view/models/preface.model.ts new file mode 100644 index 000000000..b9ca5ebea --- /dev/null +++ b/src/app/views/edition-view/models/preface.model.ts @@ -0,0 +1,32 @@ +/** + * The Preface class. + * + * It is used in the context of the edition view + * to store the data for a single preface + * from a preface json file. + */ +export class Preface { + /** + * The id of a preface. + */ + id: string; + + /** + * The content array of a preface. + */ + content: string[]; +} + +/** + * The PrefaceList class. + * + * It is used in the context of the edition view + * to store the data for a preface list + * from a preface json file. + */ +export class PrefaceList { + /** + * The array of prefaces from a preface list. + */ + preface: Preface[]; +} diff --git a/src/app/views/edition-view/models/textcritics.model.ts b/src/app/views/edition-view/models/textcritics.model.ts index d9faa1112..52f943dc4 100644 --- a/src/app/views/edition-view/models/textcritics.model.ts +++ b/src/app/views/edition-view/models/textcritics.model.ts @@ -1,5 +1,24 @@ import { EditionSvgLinkBox } from './edition-svg-link-box.model'; +/** + * The TextcriticalBlock class. + * + * It is used in the context of the edition view + * to store the data for a single textcritical block + * from a textcritics json file. + */ +export class TextcriticalCommentBlock { + /** + * An optional header of the textcritical block. + */ + blockHeader?: string; + + /** + * The array of textcritical comments in the textcritical block. + */ + blockComments: TextcriticalComment[]; +} + /** * The TextcriticalComment class. * @@ -60,7 +79,7 @@ export class Textcritics { /** * The array of textcritical comments from a textcritics list. */ - comments: TextcriticalComment[]; + comments: TextcriticalCommentBlock[]; /** * The array of link boxes from a textcritics list. diff --git a/src/app/views/edition-view/services/edition-complexes.service.spec.ts b/src/app/views/edition-view/services/edition-complexes.service.spec.ts new file mode 100644 index 000000000..96997b066 --- /dev/null +++ b/src/app/views/edition-view/services/edition-complexes.service.spec.ts @@ -0,0 +1,250 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import { TestBed } from '@angular/core/testing'; + +import Spy = jasmine.Spy; + +import { cleanStylesFromDOM } from '@testing/clean-up-helper'; +import { expectSpyCall, expectToEqual } from '@testing/expect-helper'; + +import { EditionComplex } from '@awg-views/edition-view/models'; + +import { EditionComplexesService } from './edition-complexes.service'; + +describe('EditionComplexesService (DONE)', () => { + let initializeEditionComplexesListSpy: Spy; + let setEditionComplexesListSpy: Spy; + let fetchEditionComplexesDataSpy: Spy; + + beforeEach(() => { + TestBed.configureTestingModule({}); + + // Spies for service methods + initializeEditionComplexesListSpy = spyOn( + EditionComplexesService, + 'initializeEditionComplexesList' + ).and.callThrough(); + setEditionComplexesListSpy = spyOn(EditionComplexesService, 'setEditionComplexesList').and.callThrough(); + fetchEditionComplexesDataSpy = spyOn( + EditionComplexesService as any, + '_fetchEditionComplexesData' + ).and.callThrough(); + }); + + afterAll(() => { + cleanStylesFromDOM(); + }); + + it('... should create', () => { + expect(EditionComplexesService).toBeTruthy(); + }); + + it('... should have `_editionComplexesList`', () => { + expect((EditionComplexesService as any)._editionComplexesList).toBeTruthy(); + }); + + describe('#initializeEditionComplexesList()', () => { + it('... should have a method `initializeEditionComplexesList`', () => { + expect(EditionComplexesService.initializeEditionComplexesList).toBeDefined(); + }); + + it('... should trigger `_fetchEditionComplexesData` and set the edition complexes list', () => { + EditionComplexesService.initializeEditionComplexesList(); + + const editionComplexesList = EditionComplexesService.getEditionComplexesList(); + + expectSpyCall(initializeEditionComplexesListSpy, 1); + expectSpyCall(fetchEditionComplexesDataSpy, 1); + expectSpyCall(setEditionComplexesListSpy, 1, [editionComplexesList]); + }); + + it('... should initialize the edition complexes list', () => { + EditionComplexesService.initializeEditionComplexesList(); + + const editionComplexesList = EditionComplexesService.getEditionComplexesList(); + + expect(editionComplexesList).toBeDefined(); + expect(editionComplexesList).not.toBe({}); + + // Test for samples + expect(Object.keys(editionComplexesList).length).toBeGreaterThan(0); + expect(editionComplexesList['OP3']).toBeDefined(); + expect(editionComplexesList['M22']).toBeDefined(); + + // Test for sample properties + expect(editionComplexesList['OP3'].titleStatement).toBeDefined(); + expect(editionComplexesList['OP3'].respStatement).toBeDefined(); + expect(editionComplexesList['OP3'].pubStatement).toBeDefined(); + }); + }); + + describe('#getEditionComplexById()', () => { + it('... should have a method `getEditionComplexById`', () => { + expect(EditionComplexesService.getEditionComplexById).toBeDefined(); + }); + + it('... should return the correct edition complex by ID', () => { + const testComplex = new EditionComplex( + { + title: 'Test Opus Complex', + catalogueType: 'OPUS', + catalogueNumber: '100', + }, + { + editors: [], + lastModified: '---', + }, + { series: '1', section: '5' } + ); + const testComplexId = 'op100'; + const expectedList = { [testComplexId.toUpperCase()]: testComplex }; + EditionComplexesService.setEditionComplexesList(expectedList); + + const complex = EditionComplexesService.getEditionComplexById(testComplexId); + + expect(complex).toBeTruthy(); + expectToEqual(complex, testComplex); + }); + }); + + describe('#getEditionComplexesList()', () => { + it('... should have a method `getEditionComplexesList`', () => { + expect(EditionComplexesService.getEditionComplexesList).toBeDefined(); + }); + + it('... should return the edition complexes list', () => { + EditionComplexesService.initializeEditionComplexesList(); + + const editionComplexesList = EditionComplexesService.getEditionComplexesList(); + + expect(editionComplexesList).toBeDefined(); + expect(editionComplexesList).not.toBe({}); + + // Test for samples + expect(Object.keys(editionComplexesList).length).toBeGreaterThan(0); + expect(editionComplexesList['OP3']).toBeDefined(); + expect(editionComplexesList['M22']).toBeDefined(); + + // Test for sample properties + expect(editionComplexesList['OP3'].titleStatement).toBeDefined(); + expect(editionComplexesList['OP3'].respStatement).toBeDefined(); + expect(editionComplexesList['OP3'].pubStatement).toBeDefined(); + }); + }); + + describe('#setEditionComplexesList()', () => { + it('... should have a method `setEditionComplexesList`', () => { + expect(EditionComplexesService.setEditionComplexesList).toBeDefined(); + }); + + it('... should set the edition complexes list', () => { + const testComplex = new EditionComplex( + { + title: 'Test Opus Complex', + catalogueType: 'OPUS', + catalogueNumber: '100', + }, + { + editors: [], + lastModified: '---', + }, + { series: '1', section: '5' } + ); + const testComplexId = 'op100'; + const expectedList = { [testComplexId.toUpperCase()]: testComplex }; + EditionComplexesService.setEditionComplexesList(expectedList); + + const editionComplexesList = EditionComplexesService.getEditionComplexesList(); + + expectToEqual(editionComplexesList, expectedList); + }); + + it('... should set an edition complex with opus number', () => { + const testComplex = new EditionComplex( + { + title: 'Test Opus Complex', + catalogueType: 'OPUS', + catalogueNumber: '100', + }, + { + editors: [], + lastModified: '---', + }, + { series: '1', section: '5' } + ); + const testComplexId = 'op100'; + const expectedList = { [testComplexId.toUpperCase()]: testComplex }; + EditionComplexesService.setEditionComplexesList(expectedList); + + const editionComplexesList = EditionComplexesService.getEditionComplexesList(); + + expectToEqual(editionComplexesList, expectedList); + }); + + it('... should set an edition complex with M number', () => { + const testComplex = new EditionComplex( + { + title: 'Test M Complex', + catalogueType: 'MNR', + catalogueNumber: '100', + }, + { + editors: [], + lastModified: '---', + }, + { series: '1', section: '5' } + ); + const testComplexId = 'm100'; + const expectedList = { [testComplexId.toUpperCase()]: testComplex }; + EditionComplexesService.setEditionComplexesList(expectedList); + + const editionComplexesList = EditionComplexesService.getEditionComplexesList(); + + expectToEqual(editionComplexesList, expectedList); + }); + + it('... should set an edition complex with M* number', () => { + const testComplex = new EditionComplex( + { + title: 'Test M Complex', + catalogueType: 'MNR_PLUS', + catalogueNumber: '100', + }, + { + editors: [], + lastModified: '---', + }, + { series: '1', section: '5' } + ); + const testComplexId = 'm_plus100'; + const expectedList = { [testComplexId.toUpperCase()]: testComplex }; + EditionComplexesService.setEditionComplexesList(expectedList); + + const editionComplexesList = EditionComplexesService.getEditionComplexesList(); + + expectToEqual(editionComplexesList, expectedList); + }); + }); + + describe('#_fetchEditionComplexesData()', () => { + it('... should have a method `_fetchEditionComplexesData`', () => { + expect((EditionComplexesService as any)._fetchEditionComplexesData).toBeDefined(); + }); + + it('... should fetch the edition complexes data', () => { + const editionComplexesList = (EditionComplexesService as any)._fetchEditionComplexesData(); + + expect(editionComplexesList).toBeDefined(); + expect(editionComplexesList).not.toBe({}); + + // Test for samples + expect(Object.keys(editionComplexesList).length).toBeGreaterThan(0); + expect(editionComplexesList['OP3']).toBeDefined(); + expect(editionComplexesList['M22']).toBeDefined(); + + // Test for sample properties + expect(editionComplexesList['OP3'].titleStatement).toBeDefined(); + expect(editionComplexesList['OP3'].respStatement).toBeDefined(); + expect(editionComplexesList['OP3'].pubStatement).toBeDefined(); + }); + }); +}); diff --git a/src/app/views/edition-view/services/edition-complexes.service.ts b/src/app/views/edition-view/services/edition-complexes.service.ts new file mode 100644 index 000000000..c2753e109 --- /dev/null +++ b/src/app/views/edition-view/services/edition-complexes.service.ts @@ -0,0 +1,99 @@ +import { Injectable } from '@angular/core'; + +import { EditionComplex, EditionComplexesList, EditionComplexJsonData } from '@awg-views/edition-view/models'; + +import * as jsonEditionComplexes from 'assets/data/edition/edition-complexes.json'; + +/** + * The EditionComplexes service. + * + * It handles the provision of the edition complexes. + * + * Provided in: `root`. + */ +@Injectable({ + providedIn: 'root', +}) +export class EditionComplexesService { + /** + * Static variable: _editionComplexesList. + * + * It keeps the edition complexes list. + */ + private static _editionComplexesList: EditionComplexesList = {}; + + /** + * Static method: initEditionComplexesList. + * + * It initializes the edition complexes list. + * + * @returns {void} Initializes the edition complexes list. + */ + static initializeEditionComplexesList(): void { + const complexes = EditionComplexesService._fetchEditionComplexesData(); + EditionComplexesService.setEditionComplexesList(complexes); + } + + /** + * Static method: getEditionComplexById. + * + * It finds an edition complex by a given id. + * + * @param {string} id The given id. + * + * @returns {EditionComplex} The found edition complex. + */ + static getEditionComplexById(id: string): EditionComplex { + return EditionComplexesService._editionComplexesList[id.toUpperCase()]; + } + + /** + * Static method: getEditionComplexesList. + * + * It gets the edition complexes list. + * + * @returns {EditionComplexesList} The edition complexes list. + */ + static getEditionComplexesList(): EditionComplexesList { + return EditionComplexesService._editionComplexesList; + } + + /** + * Static method: setEditionComplexesList. + * + * It sets the edition complexes list. + * + * @param {EditionComplexesList} complexesList The given edition complexes list. + * + * @returns {void} Sets the edition complexes list. + */ + static setEditionComplexesList(complexesList: EditionComplexesList): void { + EditionComplexesService._editionComplexesList = complexesList; + } + + /** + * Public method: _fetchEditionComplexesData. + * + * It fetches the data from a JSON file + * for the complexes of the edition view. + * + * @returns {EditionComplexesList} The EditionComplexesList data. + */ + private static _fetchEditionComplexesData(): EditionComplexesList { + // Load the JSON data directly from the file + const complexesData = (jsonEditionComplexes as any).default; + const editionComplexesList: EditionComplexesList = {}; + + complexesData.editionComplexes.forEach((complex: EditionComplexJsonData) => { + Object.entries(complex).forEach(([complexKey, complexValue]) => { + editionComplexesList[complexKey] = new EditionComplex( + complexValue.titleStatement, + complexValue.respStatement, + complexValue.pubStatement + ); + }); + }); + + return editionComplexesList; + } +} diff --git a/src/app/views/edition-view/services/edition-data.service.spec.ts b/src/app/views/edition-view/services/edition-data.service.spec.ts index dafeeb5cf..ae93ba06e 100644 --- a/src/app/views/edition-view/services/edition-data.service.spec.ts +++ b/src/app/views/edition-view/services/edition-data.service.spec.ts @@ -15,9 +15,10 @@ import Spy = jasmine.Spy; import { cleanStylesFromDOM } from '@testing/clean-up-helper'; import { expectSpyCall, expectToBe, expectToEqual } from '@testing/expect-helper'; +import { mockEditionData } from '@testing/mock-data'; import { mockConsole } from '@testing/mock-helper'; -import { EDITION_ASSETS_DATA, EDITION_COMPLEXES } from '@awg-views/edition-view/data'; +import { EDITION_ASSETS_DATA } from '@awg-views/edition-view/data'; import { EDITION_ROUTE_CONSTANTS } from '@awg-views/edition-view/edition-route-constants'; import { EditionComplex, @@ -30,6 +31,7 @@ import { GraphList, Intro, IntroList, + PrefaceList, Source, SourceDescription, SourceDescriptionList, @@ -39,8 +41,8 @@ import { Textcritics, TextcriticsList, } from '@awg-views/edition-view/models'; +import { EditionComplexesService } from '@awg-views/edition-view/services'; -import { mockEditionData } from '@testing/mock-data'; import { EditionDataService } from './edition-data.service'; describe('EditionDataService (DONE)', () => { @@ -51,32 +53,32 @@ describe('EditionDataService (DONE)', () => { let httpClient: HttpClient; let httpTestingController: HttpTestingController; + let expectedPrefaceData: PrefaceList; let expectedRowTablesData: EditionRowTablesList; - const expectedEditionComplex: EditionComplex = EDITION_COMPLEXES.OP12; - const expectedAssetPathBaseRoute = EDITION_ASSETS_DATA.BASE_ROUTE; - const delimiter = '/'; - const expectedComplexRoute = - delimiter + - EDITION_ROUTE_CONSTANTS.SERIES.route + - delimiter + - expectedEditionComplex.series.route + - EDITION_ROUTE_CONSTANTS.SECTION.route + - expectedEditionComplex.section.route + - expectedEditionComplex.complexId.route; - const expectedAssetPath = expectedAssetPathBaseRoute + expectedComplexRoute; - let regexBase = new RegExp(expectedAssetPath); + let expectedEditionComplex: EditionComplex; + let expectedComplexRoute: string; + let expectedAssetPath: string; + let regexBase: RegExp; + + let expectedFolioConvoluteFilePath: string; + let expectedGraphFilePath: string; + let expectedIntroFilePath: string; + let expectedPrefaceFilePath: string; + let expectedRowTablesFilePath: string; + let expectedSheetsFilePath: string; + let expectedSourceListFilePath: string; + let expectedSourceDescriptionFilePath: string; + let expectedSourceEvaluationFilePath: string; + let expectedTextcriticsFilePath: string; + const delimiter = '/'; + const expectedAssetPathBaseRoute = EDITION_ASSETS_DATA.BASE_ROUTE; const files = EDITION_ASSETS_DATA.FILES; - const expectedFolioConvoluteFilePath = `${expectedAssetPath}/${files.folioConvoluteFile}`; - const expectedGraphFilePath = `${expectedAssetPath}/${files.graphFile}`; - const expectedIntroFilePath = `${expectedAssetPath}/${files.introFile}`; - const expectedRowTablesFilePath = `${expectedAssetPathBaseRoute}/${files.rowTablesFile}`; - const expectedSheetsFilePath = `${expectedAssetPath}/${files.svgSheetsFile}`; - const expectedSourceListFilePath = `${expectedAssetPath}/${files.sourceListFile}`; - const expectedSourceDescriptionFilePath = `${expectedAssetPath}/${files.sourceDescriptionListFile}`; - const expectedSourceEvaluationFilePath = `${expectedAssetPath}/${files.sourceEvaluationListFile}`; - const expectedTextcriticsFilePath = `${expectedAssetPath}/${files.textcriticsFile}`; + + beforeAll(() => { + EditionComplexesService.initializeEditionComplexesList(); + }); beforeEach(() => { TestBed.configureTestingModule({ @@ -90,6 +92,30 @@ describe('EditionDataService (DONE)', () => { httpTestingController = TestBed.inject(HttpTestingController); // Test data + expectedEditionComplex = EditionComplexesService.getEditionComplexById('OP12'); + expectedComplexRoute = + delimiter + + EDITION_ROUTE_CONSTANTS.SERIES.route + + delimiter + + expectedEditionComplex.pubStatement.series.route + + EDITION_ROUTE_CONSTANTS.SECTION.route + + expectedEditionComplex.pubStatement.section.route + + expectedEditionComplex.complexId.route; + expectedAssetPath = expectedAssetPathBaseRoute + expectedComplexRoute; + regexBase = new RegExp(expectedAssetPath); + + expectedFolioConvoluteFilePath = `${expectedAssetPath}/${files.folioConvoluteFile}`; + expectedGraphFilePath = `${expectedAssetPath}/${files.graphFile}`; + expectedIntroFilePath = `${expectedAssetPath}/${files.introFile}`; + expectedPrefaceFilePath = `${expectedAssetPathBaseRoute}/${files.prefaceFile}`; + expectedRowTablesFilePath = `${expectedAssetPathBaseRoute}/${files.rowTablesFile}`; + expectedSheetsFilePath = `${expectedAssetPath}/${files.svgSheetsFile}`; + expectedSourceListFilePath = `${expectedAssetPath}/${files.sourceListFile}`; + expectedSourceDescriptionFilePath = `${expectedAssetPath}/${files.sourceDescriptionListFile}`; + expectedSourceEvaluationFilePath = `${expectedAssetPath}/${files.sourceEvaluationListFile}`; + expectedTextcriticsFilePath = `${expectedAssetPath}/${files.textcriticsFile}`; + + expectedPrefaceData = JSON.parse(JSON.stringify(mockEditionData.mockPrefaceData)); expectedRowTablesData = JSON.parse(JSON.stringify(mockEditionData.mockRowTablesData)); // Spies on console logs @@ -1860,6 +1886,214 @@ describe('EditionDataService (DONE)', () => { }); }); + describe('#getEditionPrefaceData()', () => { + it('... should have a method `getEditionPrefaceData`', () => { + expect(editionDataService.getEditionPrefaceData).toBeDefined(); + }); + + describe('request', () => { + it('... should set assetPath', waitForAsync(() => { + // Call service function + editionDataService.getEditionPrefaceData().subscribe({ + next: res => { + expect(res).toBeTruthy(); + }, + error: () => { + fail('should not call error'); + }, + }); + + expectToBe((editionDataService as any)._assetPath, expectedAssetPathBaseRoute); + })); + + it('... should call #_getPrefaceData', waitForAsync(() => { + // Set spy on private method + const getPrefaceDataSpy: Spy = spyOn(editionDataService as any, '_getPrefaceData').and.callThrough(); + + // Call service function + editionDataService.getEditionPrefaceData().subscribe({ + next: res => { + expect(res).toBeTruthy(); + }, + error: () => { + fail('should not call error'); + }, + }); + + expectSpyCall(getPrefaceDataSpy, 1); + })); + + it('... should trigger #getJsonData with correct url', waitForAsync(() => { + // Set spy on private method + const getPrefaceDataSpy: Spy = spyOn(editionDataService as any, '_getPrefaceData').and.callThrough(); + const getJsonDataSpy: Spy = spyOn(editionDataService as any, '_getJsonData').and.callThrough(); + + // Call service function + editionDataService.getEditionPrefaceData().subscribe({ + next: res => { + expect(res).toBeTruthy(); + }, + error: () => { + fail('should not call error'); + }, + }); + + expectSpyCall(getPrefaceDataSpy, 1); + expectSpyCall(getJsonDataSpy, 1, expectedPrefaceFilePath); + })); + + it('... should perform an HTTP GET request to preface file', waitForAsync(() => { + // Set spy on private method + const getJsonDataSpy: Spy = spyOn(editionDataService as any, '_getJsonData').and.callThrough(); + + // Call service function + editionDataService.getEditionPrefaceData().subscribe({ + next: res => { + expectToEqual(res, new PrefaceList()); + }, + error: () => { + fail('should not call error'); + }, + }); + + // Expect one request to every file with given settings + regexBase = new RegExp(expectedAssetPathBaseRoute); + const call = httpTestingController.match( + (req: HttpRequest) => + req.method === 'GET' && req.responseType === 'json' && regexBase.test(req.url) + ); + + expectSpyCall(getJsonDataSpy, 1, expectedPrefaceFilePath); + + expectToBe(call.length, 1); + expectToBe(call[0].request.method, 'GET'); + expectToBe(call[0].request.responseType, 'json'); + expectToBe(call[0].request.url, expectedPrefaceFilePath); + + // Assert that there are no more pending requests + httpTestingController.verify(); + })); + }); + + describe('success', () => { + it('... should return an Observable(PrefaceList)', waitForAsync(() => { + const rt = expectedPrefaceData; + + const expectedResult = rt; + + // Set spy on private method + const getPrefaceDataSpy: Spy = spyOn(editionDataService as any, '_getPrefaceData').and.returnValue( + observableOf(expectedResult) + ); + + // Call service function (success) + editionDataService.getEditionPrefaceData().subscribe({ + next: res => { + expectToEqual(res, expectedResult); + expectToBe(res.preface[0].id, 'de'); + expectToBe(res.preface[1].id, 'en'); + }, + error: () => { + fail('should not call error'); + }, + }); + + expectSpyCall(getPrefaceDataSpy, 1); + })); + + it('... should return an empty PrefaceList Observable per default', waitForAsync(() => { + const expectedResult = new PrefaceList(); + + // Set spy on private method + const getPrefaceDataSpy: Spy = spyOn(editionDataService as any, '_getPrefaceData').and.returnValue( + EMPTY.pipe(defaultIfEmpty(expectedResult)) + ); + + // Call service function (success) + editionDataService.getEditionPrefaceData().subscribe({ + next: res => { + expectToEqual(res, expectedResult); + }, + error: () => { + fail('should not call error'); + }, + }); + + expectSpyCall(getPrefaceDataSpy, 1); + })); + }); + + describe('fail', () => { + it('... should log an error for every failed request', waitForAsync(() => { + const expectedResult = []; + + // Call service function (success) + editionDataService.getEditionPrefaceData().subscribe({ + next: (res: any) => { + expectToEqual(res, expectedResult); + }, + error: () => { + fail('should not call error'); + }, + }); + + // Expect one request to to every file with given settings + regexBase = new RegExp(expectedAssetPathBaseRoute); + const call = httpTestingController.match( + (req: HttpRequest) => + req.method === 'GET' && req.responseType === 'json' && regexBase.test(req.url) + ); + + expectToBe(call[0].request.url, expectedPrefaceFilePath); + + // Resolve request with mocked error + call[0].flush(null, new HttpErrorResponse({ status: 400, statusText: 'ERROR_LOADING_PREFACELIST' })); + + // Check for console output + expectSpyCall( + consoleSpy, + 1, + `_getJsonData failed: Http failure response for ${call[0].request.url}: 400 ERROR_LOADING_PREFACELIST` + ); + + // Assert that there are no more pending requests + httpTestingController.verify(); + })); + + it('... should return [] if request failed', waitForAsync(() => { + const expectedResult = []; + + // Call service function (success) + editionDataService.getEditionPrefaceData().subscribe({ + next: (res: any) => { + expectToEqual(res, expectedResult); + }, + error: () => { + fail('should not call error'); + }, + }); + + // Expect one request to to every file with given settings + regexBase = new RegExp(expectedAssetPathBaseRoute); + const call = httpTestingController.match( + (req: HttpRequest) => + req.method === 'GET' && req.responseType === 'json' && regexBase.test(req.url) + ); + + expectToBe(call[0].request.url, expectedPrefaceFilePath); + + // Resolve request with mocked error + call[0].flush(null, new HttpErrorResponse({ status: 400, statusText: 'ERROR_LOADING_PREFACELIST' })); + + // Check for console output + expectSpyCall(consoleSpy, 1); + + // Assert that there are no more pending requests + httpTestingController.verify(); + })); + }); + }); + describe('#getRowTablesData()', () => { it('... should have a method `getRowTablesData`', () => { expect(editionDataService.getEditionRowTablesData).toBeDefined(); diff --git a/src/app/views/edition-view/services/edition-data.service.ts b/src/app/views/edition-view/services/edition-data.service.ts index 4b6cd020e..8dcd97507 100644 --- a/src/app/views/edition-view/services/edition-data.service.ts +++ b/src/app/views/edition-view/services/edition-data.service.ts @@ -13,6 +13,7 @@ import { FolioConvoluteList, GraphList, IntroList, + PrefaceList, SourceDescriptionList, SourceEvaluationList, SourceList, @@ -49,37 +50,6 @@ export class EditionDataService { */ constructor(private http: HttpClient) {} - /** - * Public method: getEditionSheetsData. - * - * It provides the data from a JSON file - * for the current edition complex of the edition sheets view - * (folio convolute, edition svg sheets and textcritics list) - * as a fork-joined observable array. - * - * @param {EditionComplex} editionComplex The current edition complex. - * - * @returns {Observable<[FolioConvoluteList, EditionSvgSheetList, TextcriticsList]>} - * The fork-joined observable array with the FolioConvoluteList, - * EditionSvgSheetList and TextcriticsList data. - * Only the first emit is needed. - */ - getEditionSheetsData( - editionComplex: EditionComplex - ): Observable<(FolioConvoluteList | EditionSvgSheetList | TextcriticsList)[]> { - this._assetPath = this._setAssetPathForEditionComplex(editionComplex); - const folioData$: Observable = this._getFolioConvoluteData(); - const svgSheetsData$: Observable = this._getSvgSheetsData(); - const textciticsListData$: Observable = this._getTextcriticsListData(); - - return observableForkJoin([folioData$, svgSheetsData$, textciticsListData$]).pipe( - // Default empty value - defaultIfEmpty([new FolioConvoluteList(), new EditionSvgSheetList(), new TextcriticsList()]), - // Take only first request (JSON fetch) - take(1) - ); - } - /** * Public method: getEditionGraphData. * @@ -124,6 +94,26 @@ export class EditionDataService { ); } + /** + * Public method: getEditionPrefaceData. + * + * It provides the data from a JSON file + * for the preface of the edition view. + * + * @returns {Observable} The observable with the PrefaceList data. + */ + getEditionPrefaceData(): Observable { + this._assetPath = EDITION_ASSETS_DATA.BASE_ROUTE; + const prefaceData$: Observable = this._getPrefaceData(); + + return prefaceData$.pipe( + // Default empty value + defaultIfEmpty(new PrefaceList()), + // Take only first request (JSON fetch) + take(1) + ); + } + /** * Public method: getEditionReportData. * @@ -184,6 +174,37 @@ export class EditionDataService { ); } + /** + * Public method: getEditionSheetsData. + * + * It provides the data from a JSON file + * for the current edition complex of the edition sheets view + * (folio convolute, edition svg sheets and textcritics list) + * as a fork-joined observable array. + * + * @param {EditionComplex} editionComplex The current edition complex. + * + * @returns {Observable<[FolioConvoluteList, EditionSvgSheetList, TextcriticsList]>} + * The fork-joined observable array with the FolioConvoluteList, + * EditionSvgSheetList and TextcriticsList data. + * Only the first emit is needed. + */ + getEditionSheetsData( + editionComplex: EditionComplex + ): Observable<(FolioConvoluteList | EditionSvgSheetList | TextcriticsList)[]> { + this._assetPath = this._setAssetPathForEditionComplex(editionComplex); + const folioData$: Observable = this._getFolioConvoluteData(); + const svgSheetsData$: Observable = this._getSvgSheetsData(); + const textciticsListData$: Observable = this._getTextcriticsListData(); + + return observableForkJoin([folioData$, svgSheetsData$, textciticsListData$]).pipe( + // Default empty value + defaultIfEmpty([new FolioConvoluteList(), new EditionSvgSheetList(), new TextcriticsList()]), + // Take only first request (JSON fetch) + take(1) + ); + } + /** * Private method: _setAssetPathForEditionComplex. * @@ -199,9 +220,9 @@ export class EditionDataService { delimiter + EDITION_ROUTE_CONSTANTS.SERIES.route + delimiter + - editionComplex.series.route + + editionComplex.pubStatement.series.route + EDITION_ROUTE_CONSTANTS.SECTION.route + - editionComplex.section.route + + editionComplex.pubStatement.section.route + editionComplex.complexId.route; return EDITION_ASSETS_DATA.BASE_ROUTE + complexRoute; } @@ -251,6 +272,21 @@ export class EditionDataService { return this._getJsonData(url); } + /** + * Private method: _getPrefaceData. + * + * It sets the path to the JSON file with + * the preface data and triggers + * the method to get the JSON data. + * + * @returns {Observable} The observable with the Preface data. + */ + private _getPrefaceData(): Observable { + const file = EDITION_ASSETS_DATA.FILES.prefaceFile; + const url = `${this._assetPath}/${file}`; + return this._getJsonData(url); + } + /** * Private method: _getRowTablesData. * diff --git a/src/app/views/edition-view/services/edition-outline.service.spec.ts b/src/app/views/edition-view/services/edition-outline.service.spec.ts new file mode 100644 index 000000000..4f0f4999a --- /dev/null +++ b/src/app/views/edition-view/services/edition-outline.service.spec.ts @@ -0,0 +1,238 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import { TestBed } from '@angular/core/testing'; + +import Spy = jasmine.Spy; + +import { cleanStylesFromDOM } from '@testing/clean-up-helper'; +import { expectSpyCall, expectToEqual } from '@testing/expect-helper'; + +import { EDITION_ROUTE_CONSTANTS } from '@awg-views/edition-view/edition-route-constants'; +import { EditionOutline, EditionOutlineSeries } from '@awg-views/edition-view/models'; + +import { EditionOutlineService } from './edition-outline.service'; + +describe('EditionOutlineService (DONE)', () => { + let initializeEditionOutlineSpy: Spy; + let setEditionOutlineSpy: Spy; + let fetchEditionOutlineDataSpy: Spy; + + beforeAll(() => { + EditionOutlineService.initializeEditionOutline(); + }); + + beforeEach(() => { + TestBed.configureTestingModule({}); + + // Spies for service methods + initializeEditionOutlineSpy = spyOn(EditionOutlineService, 'initializeEditionOutline').and.callThrough(); + setEditionOutlineSpy = spyOn(EditionOutlineService, 'setEditionOutline').and.callThrough(); + fetchEditionOutlineDataSpy = spyOn(EditionOutlineService as any, '_fetchEditionOutlineData').and.callThrough(); + }); + + afterAll(() => { + cleanStylesFromDOM(); + }); + + it('... should create', () => { + expect(EditionOutlineService).toBeTruthy(); + }); + + it('... should have `_editionOutline`', () => { + expect((EditionOutlineService as any)._editionOutline).toBeTruthy(); + }); + + describe('#initializeEditionOutline()', () => { + it('... should have a method `initializeEditionOutline`', () => { + expect(EditionOutlineService.initializeEditionOutline).toBeDefined(); + }); + + it('... should trigger `_fetchEditionOutlineData` and set the edition complexes list', () => { + EditionOutlineService.initializeEditionOutline(); + + const editionOutline = EditionOutlineService.getEditionOutline(); + + expectSpyCall(initializeEditionOutlineSpy, 1); + expectSpyCall(fetchEditionOutlineDataSpy, 1); + expectSpyCall(setEditionOutlineSpy, 1, [editionOutline]); + }); + + it('... should initialize the edition outline', () => { + EditionOutlineService.initializeEditionOutline(); + + const editionOutline = EditionOutlineService.getEditionOutline(); + + expect(editionOutline).toBeDefined(); + expect(editionOutline).not.toBe([]); + + // Test for samples + expect(editionOutline.length).toBeGreaterThan(0); + expectToEqual(editionOutline[0].series, EDITION_ROUTE_CONSTANTS.SERIES_1); + expectToEqual(editionOutline[1].series, EDITION_ROUTE_CONSTANTS.SERIES_2); + expectToEqual(editionOutline[2].series, EDITION_ROUTE_CONSTANTS.SERIES_3); + }); + }); + + describe('#getEditionOutline()', () => { + it('... should have a method `getEditionOutline`', () => { + expect(EditionOutlineService.getEditionOutline).toBeDefined(); + }); + + it('... should return the edition outline', () => { + const editionOutline = EditionOutlineService.getEditionOutline(); + + expect(editionOutline).toBeDefined(); + expect(editionOutline).not.toBe([]); + + // Test for samples + expect(editionOutline.length).toBeGreaterThan(0); + expectToEqual(editionOutline[0].series, EDITION_ROUTE_CONSTANTS.SERIES_1); + expectToEqual(editionOutline[1].series, EDITION_ROUTE_CONSTANTS.SERIES_2); + expectToEqual(editionOutline[2].series, EDITION_ROUTE_CONSTANTS.SERIES_3); + }); + }); + + describe('#setEditionOutline()', () => { + it('... should have a method `setEditionOutline`', () => { + expect(EditionOutlineService.setEditionOutline).toBeDefined(); + }); + + it('... should set the edition outline', () => { + const expectedOutline = new EditionOutline([ + { + series: '2', + sections: [ + { + section: '5', + complexTypes: { + opus: [ + { + complex: '', + disabled: true, + }, + ], + mnr: [{ complex: '', disabled: true }], + }, + disabled: true, + }, + { + section: '4', + complexTypes: { + opus: [ + { + complex: '', + disabled: true, + }, + ], + mnr: [{ complex: '', disabled: true }], + }, + disabled: false, + }, + ], + }, + ]); + + EditionOutlineService.setEditionOutline(expectedOutline.outline); + + const editionOutline = EditionOutlineService.getEditionOutline(); + + expectToEqual(editionOutline, expectedOutline.outline); + }); + + it('... should do nothing if the edition outline is null', () => { + const expectedOutline = new EditionOutline(null); + + EditionOutlineService.setEditionOutline(expectedOutline.outline); + + const editionOutline = EditionOutlineService.getEditionOutline(); + + expect(editionOutline).toBeUndefined(); + }); + }); + + describe('#getEditionSeriesById()', () => { + it('... should have a method `getEditionSeriesById`', () => { + expect(EditionOutlineService.getEditionSeriesById).toBeDefined(); + }); + + it('... should return editionSeries with given id', () => { + const expectedOutline: EditionOutlineSeries[] = [ + { + series: EDITION_ROUTE_CONSTANTS.SERIES_2, + sections: [ + { + section: EDITION_ROUTE_CONSTANTS.SECTION_5, + complexTypes: { opus: [], mnr: [] }, + disabled: true, + }, + { + section: EDITION_ROUTE_CONSTANTS.SECTION_4, + complexTypes: { opus: [], mnr: [] }, + disabled: false, + }, + ], + }, + ]; + EditionOutlineService.setEditionOutline(expectedOutline); + + const series = EditionOutlineService.getEditionSeriesById(EDITION_ROUTE_CONSTANTS.SERIES_2.route); + + expectToEqual(series, expectedOutline[0]); + }); + }); + + describe('#getEditionSectionById()', () => { + it('... should have a method `getEditionSectionById`', () => { + expect(EditionOutlineService.getEditionSectionById).toBeDefined(); + }); + + it('... should return editionSection with given id', () => { + const expectedOutline: EditionOutlineSeries[] = [ + { + series: EDITION_ROUTE_CONSTANTS.SERIES_2, + sections: [ + { + section: EDITION_ROUTE_CONSTANTS.SECTION_5, + complexTypes: { opus: [], mnr: [] }, + disabled: true, + }, + { + section: EDITION_ROUTE_CONSTANTS.SECTION_4, + complexTypes: { opus: [], mnr: [] }, + disabled: false, + }, + ], + }, + ]; + expectedOutline[0].sections.forEach(section => { + const expectedEditionSection = section; + + const getSection = EditionOutlineService.getEditionSectionById( + EDITION_ROUTE_CONSTANTS.SERIES_2.route, + section.section.route + ); + + expectToEqual(getSection, expectedEditionSection); + }); + }); + }); + + describe('#_fetchEditionOutlineData()', () => { + it('... should have a method `_fetchEditionOutlineData`', () => { + expect((EditionOutlineService as any)._fetchEditionOutlineData).toBeDefined(); + }); + + it('... should fetch the edition outline data', () => { + const editionOutline = (EditionOutlineService as any)._fetchEditionOutlineData(); + + expect(editionOutline).toBeDefined(); + expect(editionOutline).not.toBe({}); + expect(Object.keys(editionOutline).length).toBeGreaterThan(0); + expect(editionOutline.outline).toBeDefined(); + + // Test for samples + expectToEqual(editionOutline.outline[0].series, EDITION_ROUTE_CONSTANTS.SERIES_1); + expectToEqual(editionOutline.outline[1].series, EDITION_ROUTE_CONSTANTS.SERIES_2); + expectToEqual(editionOutline.outline[2].series, EDITION_ROUTE_CONSTANTS.SERIES_3); + }); + }); +}); diff --git a/src/app/views/edition-view/services/edition-outline.service.ts b/src/app/views/edition-view/services/edition-outline.service.ts new file mode 100644 index 000000000..85a045d6d --- /dev/null +++ b/src/app/views/edition-view/services/edition-outline.service.ts @@ -0,0 +1,108 @@ +import { Injectable } from '@angular/core'; + +import { + EditionOutline, + EditionOutlineJsonData, + EditionOutlineSection, + EditionOutlineSeries, +} from '@awg-views/edition-view/models'; + +import * as jsonEditionOutline from 'assets/data/edition/edition-outline.json'; + +/** + * The EditionComplexes service. + * + * It handles the provision of the edition complexes. + * + * Provided in: `root`. + */ +@Injectable({ + providedIn: 'root', +}) +export class EditionOutlineService { + /** + * Static variable: _EditionOutline. + * + * It keeps the edition outline. + */ + private static _editionOutline: EditionOutlineSeries[] = []; + + /** + * Static method: initEditionOutline. + * + * It initializes the edition outline. + * + * @returns {void} Initializes the edition outline. + */ + static initializeEditionOutline(): void { + const outline = EditionOutlineService._fetchEditionOutlineData(); + EditionOutlineService.setEditionOutline(outline.outline); + } + + /** + * Static method: getEditionOutline. + * + * It provides the edition outline with its series. + * + * @returns {EditionOutline} The edition outline. + */ + static getEditionOutline(): EditionOutlineSeries[] { + return EditionOutlineService._editionOutline; + } + + /** + * Static method: getEditionSeriesById. + * + * It finds a series of the edition by a given id. + * + * @param {string} seriesId The given series id. + * + * @returns {EditionOutlineSeries} The found edition series. + */ + static getEditionSeriesById(seriesId: string): EditionOutlineSeries { + return EditionOutlineService.getEditionOutline().find(series => series.series.route === seriesId); + } + + /** + * Static method: getEditionSectionById. + * + * It finds a section of an edition series by a given id. + * + * @param {string} seriesId The given series id. + * @param {string} sectionId The given series id. + * + * @returns {EditionOutlineSection} The found edition section. + */ + static getEditionSectionById(seriesId: string, sectionId: string): EditionOutlineSection { + const series = EditionOutlineService.getEditionSeriesById(seriesId); + return series.sections.find(section => section.section.route === sectionId); + } + + /** + * Static method: setEditionOutline. + * + * It sets the edition outline. + * + * @param {EditionOutline} outline The given edition outline. + * + * @returns {void} Sets the edition outline. + */ + static setEditionOutline(outline: EditionOutlineSeries[]): void { + EditionOutlineService._editionOutline = outline; + } + + /** + * Public method: _fetchEditionOutlineData. + * + * It fetches the data from a JSON file + * for the outline of the edition view. + * + * @returns {EditionOutline} The EditionOutline data. + */ + private static _fetchEditionOutlineData(): EditionOutline { + // Load the JSON data directly from the file + const outlineData: EditionOutlineJsonData = (jsonEditionOutline as any).default; + + return new EditionOutline(outlineData['editionOutline']); + } +} diff --git a/src/app/views/edition-view/services/edition-sheets.service.spec.ts b/src/app/views/edition-view/services/edition-sheets.service.spec.ts index f68c56c67..8e80d90e1 100644 --- a/src/app/views/edition-view/services/edition-sheets.service.spec.ts +++ b/src/app/views/edition-view/services/edition-sheets.service.spec.ts @@ -10,7 +10,7 @@ import { EditionSvgSheet, EditionSvgSheetList, FolioConvolute, - TextcriticalComment, + TextcriticalCommentBlock, Textcritics, } from '@awg-views/edition-view/models'; @@ -23,7 +23,7 @@ describe('EditionSheetsService (DONE)', () => { let expectedOverlays: EditionSvgOverlay[]; let expectedSelectedSheet: EditionSvgSheet; let expectedSheets: EditionSvgSheetList['sheets']; - let expectedTka: TextcriticalComment[]; + let expectedTextcriticalCommentBlocks: TextcriticalCommentBlock[]; let expectedTextcriticsArray: Textcritics[]; beforeEach(() => { @@ -38,7 +38,7 @@ describe('EditionSheetsService (DONE)', () => { expectedSelectedSheet = JSON.parse(JSON.stringify(mockEditionData.mockSvgSheet_Sk2)); expectedSheets = mockEditionData.mockSvgSheetList.sheets; expectedTextcriticsArray = mockEditionData.mockTextcriticsData.textcritics; - expectedTka = expectedTextcriticsArray.at(1).comments; + expectedTextcriticalCommentBlocks = expectedTextcriticsArray.at(1).comments; }); afterAll(() => { @@ -248,62 +248,94 @@ describe('EditionSheetsService (DONE)', () => { }); describe('... should return empty array', () => { - it('if no TkA are given', () => { + it('if no textcritical comment blocks are given', () => { const value = editionSheetsService.getTextcriticalCommentsForOverlays(undefined, expectedOverlays); - expect(value).toBeDefined(); - expect(value).toEqual([]); + expectToEqual(value, []); }); it('... if no overlays are given', () => { - const value = editionSheetsService.getTextcriticalCommentsForOverlays(expectedTka, undefined); + const value = editionSheetsService.getTextcriticalCommentsForOverlays( + expectedTextcriticalCommentBlocks, + undefined + ); - expect(value).toBeDefined(); - expect(value).toEqual([]); + expectToEqual(value, []); }); - }); - it('... should find a comment for a selected item by id', () => { - expectedTka.forEach(tka => { - expectedOverlays = [new EditionSvgOverlay(EditionSvgOverlayTypes.tka, tka.svgGroupId, true)]; - const expectedResult = [tka]; + it('... if no comments match the given overlay', () => { + expectedOverlays = [new EditionSvgOverlay(EditionSvgOverlayTypes.tka, 'notExistingId', true)]; - const filteredComments = editionSheetsService.getTextcriticalCommentsForOverlays( - expectedTka, + const value = editionSheetsService.getTextcriticalCommentsForOverlays( + expectedTextcriticalCommentBlocks, expectedOverlays ); - expectToEqual(filteredComments, expectedResult); + expectToEqual(value, []); }); }); - it('... should find comments for multiple selected items by id', () => { - expectedOverlays = [ - new EditionSvgOverlay(EditionSvgOverlayTypes.tka, expectedTka.at(0).svgGroupId, true), - new EditionSvgOverlay(EditionSvgOverlayTypes.tka, expectedTka.at(-1).svgGroupId, true), - ]; - const expectedResult = [expectedTka.at(0), expectedTka.at(-1)]; + it('... should find all comments of the given textcritics', () => { + expectedOverlays = []; + expectedTextcriticalCommentBlocks.forEach(textcriticalCommentBlock => { + textcriticalCommentBlock.blockComments.forEach(comment => { + expectedOverlays.push(new EditionSvgOverlay(EditionSvgOverlayTypes.tka, comment.svgGroupId, true)); + }); + }); + + const expectedResult = expectedTextcriticalCommentBlocks; const filteredComments = editionSheetsService.getTextcriticalCommentsForOverlays( - expectedTka, + expectedTextcriticalCommentBlocks, expectedOverlays ); expectToEqual(filteredComments, expectedResult); }); - it('... should find all comments of the given textcritics', () => { - expectedOverlays = []; - expectedTka.forEach(tka => { - expectedOverlays.push(new EditionSvgOverlay(EditionSvgOverlayTypes.tka, tka.svgGroupId, true)); + it('... should find a comment for a single selected item by id', () => { + expectedTextcriticalCommentBlocks.forEach(textcriticalCommentBlock => { + textcriticalCommentBlock.blockComments.forEach(comment => { + expectedOverlays = [new EditionSvgOverlay(EditionSvgOverlayTypes.tka, comment.svgGroupId, true)]; + + const expectedResult = [ + { + ...textcriticalCommentBlock, + blockComments: [comment], + }, + ]; + + const filteredComments = editionSheetsService.getTextcriticalCommentsForOverlays( + expectedTextcriticalCommentBlocks, + expectedOverlays + ); + + expectToEqual(filteredComments, expectedResult); + }); }); + }); + + it('... should find comments for multiple selected items by id', () => { + const selectedComments = [ + expectedTextcriticalCommentBlocks.at(0).blockComments.at(0), + expectedTextcriticalCommentBlocks.at(-1).blockComments.at(0), + ]; + + expectedOverlays = selectedComments.map( + comment => new EditionSvgOverlay(EditionSvgOverlayTypes.tka, comment.svgGroupId, true) + ); + + const expectedResult = selectedComments.map(comment => ({ + ...expectedTextcriticalCommentBlocks.find(block => block.blockComments.includes(comment)), + blockComments: [comment], + })); const filteredComments = editionSheetsService.getTextcriticalCommentsForOverlays( - expectedTka, + expectedTextcriticalCommentBlocks, expectedOverlays ); - expectToEqual(filteredComments, expectedTka); + expectToEqual(filteredComments, expectedResult); }); }); diff --git a/src/app/views/edition-view/services/edition-sheets.service.ts b/src/app/views/edition-view/services/edition-sheets.service.ts index cddc1d547..3a137168b 100644 --- a/src/app/views/edition-view/services/edition-sheets.service.ts +++ b/src/app/views/edition-view/services/edition-sheets.service.ts @@ -5,7 +5,7 @@ import { EditionSvgSheet, EditionSvgSheetList, FolioConvolute, - TextcriticalComment, + TextcriticalCommentBlock, Textcritics, } from '@awg-views/edition-view/models'; @@ -106,18 +106,28 @@ export class EditionSheetsService { * * It provides the textcritical comments for the selected svg overlays. * - * @param {TextcriticalComment[]} textcriticalComments The given textcritical comments. + * @param {TextcriticalCommentBlock[]} textcriticalCommentBlocks The given textcritical comment blocks. * @param {EditionSvgOverlay[]} overlays The given svg overlays. - * @returns {TextcriticalComment[]} Array with filtered textcritical comments. + * @returns {TextcriticalCommentBlock[]} Array with filtered textcritical comment block. */ getTextcriticalCommentsForOverlays( - textcriticalComments: TextcriticalComment[], + textcriticalCommentBlocks: TextcriticalCommentBlock[], overlays: EditionSvgOverlay[] - ): TextcriticalComment[] { - if (!textcriticalComments || !overlays) { + ): TextcriticalCommentBlock[] { + if (!textcriticalCommentBlocks || !overlays) { return []; } - return textcriticalComments.filter(comment => overlays.some(overlay => comment.svgGroupId === overlay.id)); + return textcriticalCommentBlocks + .map(block => { + const filteredBlock = { + ...block, + blockComments: block.blockComments.filter(comment => + overlays.some(overlay => comment.svgGroupId === overlay.id) + ), + }; + return filteredBlock; + }) + .filter(block => block.blockComments.length > 0); } /** diff --git a/src/app/views/edition-view/services/edition-svg-drawing.service.spec.ts b/src/app/views/edition-view/services/edition-svg-drawing.service.spec.ts index 1f1c41301..5760d4a1f 100644 --- a/src/app/views/edition-view/services/edition-svg-drawing.service.spec.ts +++ b/src/app/views/edition-view/services/edition-svg-drawing.service.spec.ts @@ -270,7 +270,7 @@ describe('EditionSvgDrawingService (DONE)', () => { service.fillD3SelectionWithColor(d3Selection, color); expect(d3Selection).toBeDefined(); - expect(d3Selection.attr('fill')).toBeNull(); + expectToBe(d3Selection.attr('fill'), null); }); }); diff --git a/src/app/views/edition-view/services/edition.service.spec.ts b/src/app/views/edition-view/services/edition.service.spec.ts index 0cba0556e..b0b3ff37d 100644 --- a/src/app/views/edition-view/services/edition.service.spec.ts +++ b/src/app/views/edition-view/services/edition.service.spec.ts @@ -2,11 +2,12 @@ import { TestBed, waitForAsync } from '@angular/core/testing'; import { cleanStylesFromDOM } from '@testing/clean-up-helper'; +import { expectToBe, expectToEqual } from '@testing/expect-helper'; -import { EDITION_COMPLEXES, EDITION_OUTLINE_DATA } from '@awg-views/edition-view/data'; +import { EDITION_ROUTE_CONSTANTS } from '@awg-views/edition-view/edition-route-constants'; import { EditionComplex, EditionOutlineSection, EditionOutlineSeries } from '@awg-views/edition-view/models'; +import { EditionComplexesService, EditionOutlineService } from '@awg-views/edition-view/services'; -import { EDITION_ROUTE_CONSTANTS } from '../edition-route-constants'; import { EditionService } from './edition.service'; describe('EditionService (DONE)', () => { @@ -17,8 +18,14 @@ describe('EditionService (DONE)', () => { let expectedEditionSeries: EditionOutlineSeries; let expectedEditionSeriesRoute: string; let expectedEditionSection: EditionOutlineSection; + let expectedIsPrefaceView: boolean; let expectedIsRowTableView: boolean; + beforeAll(() => { + EditionComplexesService.initializeEditionComplexesList(); + EditionOutlineService.initializeEditionOutline(); + }); + beforeEach(() => { TestBed.configureTestingModule({ providers: [EditionService], @@ -27,11 +34,12 @@ describe('EditionService (DONE)', () => { editionService = TestBed.inject(EditionService); // Test data (default) - expectedEditionComplex = EDITION_COMPLEXES.OP12; - expectedEditionOutline = EDITION_OUTLINE_DATA; + expectedEditionComplex = EditionComplexesService.getEditionComplexById('OP12'); + expectedEditionOutline = EditionOutlineService.getEditionOutline(); expectedEditionSeriesRoute = EDITION_ROUTE_CONSTANTS.EDITION.route + EDITION_ROUTE_CONSTANTS.SERIES.route; - expectedEditionSeries = EDITION_OUTLINE_DATA[0]; - expectedEditionSection = EDITION_OUTLINE_DATA[0].sections[0]; + expectedEditionSeries = expectedEditionOutline[0]; + expectedEditionSection = expectedEditionOutline[0].sections[0]; + expectedIsPrefaceView = true; expectedIsRowTableView = true; }); @@ -44,18 +52,15 @@ describe('EditionService (DONE)', () => { }); it('... should have bufferSize = 1', () => { - expect((editionService as any)._bufferSize).toBeTruthy(); - expect((editionService as any)._bufferSize) - .withContext('should be 1') - .toBe(1); + expectToBe((editionService as any)._bufferSize, 1); }); - it('... should have _editionComplexSubject', () => { - expect((editionService as any)._editionComplexSubject).toBeTruthy(); + it('... should have _isPrefaceViewSubject', () => { + expect((editionService as any)._isPrefaceViewSubject).toBeTruthy(); }); - it('... should have _editionComplexStream$', () => { - expect((editionService as any)._editionComplexStream$).toBeTruthy(); + it('... should have _isPrefaceViewStream$', () => { + expect((editionService as any)._isPrefaceViewStream$).toBeTruthy(); }); it('... should have _isRowTableViewSubject', () => { @@ -66,6 +71,14 @@ describe('EditionService (DONE)', () => { expect((editionService as any)._isRowTableViewStream$).toBeTruthy(); }); + it('... should have _selectedEditionComplexSubject', () => { + expect((editionService as any)._selectedEditionComplexSubject).toBeTruthy(); + }); + + it('... should have _selectedEditionComplexStream$', () => { + expect((editionService as any)._selectedEditionComplexStream$).toBeTruthy(); + }); + it('... should have _selectedEditionSeriesSubject', () => { expect((editionService as any)._selectedEditionSeriesSubject).toBeTruthy(); }); @@ -79,149 +92,94 @@ describe('EditionService (DONE)', () => { }); describe('EditionComplex', () => { - describe('#getEditionComplex()', () => { - it('... should have a method `getEditionComplex`', () => { - expect(editionService.getEditionComplex).toBeDefined(); + describe('#getSelectedEditionComplex()', () => { + it('... should have a method `getSelectedEditionComplex`', () => { + expect(editionService.getSelectedEditionComplex).toBeDefined(); }); it('... should return given editionComplex', waitForAsync(() => { - editionService.getEditionComplex().subscribe({ + editionService.getSelectedEditionComplex().subscribe({ next: (editionComplex: EditionComplex) => { - expect(editionComplex).toBeTruthy(); - expect(editionComplex) - .withContext(`should equal ${expectedEditionComplex}`) - .toEqual(expectedEditionComplex); + expectToEqual(editionComplex, expectedEditionComplex); }, }); // Set editionComplex (with default value) - editionService.updateEditionComplex(expectedEditionComplex); + editionService.updateSelectedEditionComplex(expectedEditionComplex); })); it('... should return updated editionComplex', waitForAsync(() => { - editionService.getEditionComplex().subscribe({ + editionService.getSelectedEditionComplex().subscribe({ next: (editionComplex: EditionComplex) => { - expect(editionComplex).toBeTruthy(); - expect(editionComplex) - .withContext(`should equal ${expectedEditionComplex}`) - .toEqual(expectedEditionComplex); + expectToEqual(editionComplex, expectedEditionComplex); }, }); // Set editionComplex (with default value) - editionService.updateEditionComplex(expectedEditionComplex); + editionService.updateSelectedEditionComplex(expectedEditionComplex); // Update editionComplex - expectedEditionComplex = EDITION_COMPLEXES.OP25; - editionService.updateEditionComplex(expectedEditionComplex); + expectedEditionComplex = EditionComplexesService.getEditionComplexById('OP25'); + editionService.updateSelectedEditionComplex(expectedEditionComplex); })); }); - describe('#updateEditionComplex()', () => { - it('... should have a method `updateEditionComplex`', () => { - expect(editionService.updateEditionComplex).toBeDefined(); + describe('#updateSelectedEditionComplex()', () => { + it('... should have a method `updateSelectedEditionComplex`', () => { + expect(editionService.updateSelectedEditionComplex).toBeDefined(); }); it('... should emit updated editionComplex', waitForAsync(() => { - editionService.getEditionComplex().subscribe({ + editionService.getSelectedEditionComplex().subscribe({ next: (editionComplex: EditionComplex) => { - expect(editionComplex).toBeTruthy(); - expect(editionComplex) - .withContext(`should equal ${expectedEditionComplex}`) - .toEqual(expectedEditionComplex); + expectToEqual(editionComplex, expectedEditionComplex); }, }); // Set editionComplex - editionService.updateEditionComplex(expectedEditionComplex); + editionService.updateSelectedEditionComplex(expectedEditionComplex); // Update editionComplex - expectedEditionComplex = EDITION_COMPLEXES.OP25; - editionService.updateEditionComplex(expectedEditionComplex); + expectedEditionComplex = EditionComplexesService.getEditionComplexById('OP25'); + editionService.updateSelectedEditionComplex(expectedEditionComplex); })); }); - describe('#clearEditionComplex()', () => { - it('... should have a method `clearEditionComplex`', () => { - expect(editionService.clearEditionComplex).toBeDefined(); + describe('#clearSelectedEditionComplex()', () => { + it('... should have a method `clearSelectedEditionComplex`', () => { + expect(editionService.clearSelectedEditionComplex).toBeDefined(); }); it('... should update edition complex with null value', waitForAsync(() => { - editionService.getEditionComplex().subscribe({ + editionService.getSelectedEditionComplex().subscribe({ next: (editionComplex: EditionComplex) => { - expect(editionComplex).toBeNull(); - expect(editionComplex) - .withContext(`should equal ${expectedEditionComplex}`) - .toEqual(expectedEditionComplex); + expectToEqual(editionComplex, expectedEditionComplex); }, }); // Clear editionComplex expectedEditionComplex = null; - editionService.clearEditionComplex(); + editionService.clearSelectedEditionComplex(); })); - it('... should overwrite existing search results', waitForAsync(() => { - editionService.getEditionComplex().subscribe({ + it('... should overwrite existing values', waitForAsync(() => { + editionService.getSelectedEditionComplex().subscribe({ next: (editionComplex: EditionComplex) => { - expect(editionComplex) - .withContext(`should equal ${expectedEditionComplex}`) - .toEqual(expectedEditionComplex); + expectToEqual(editionComplex, expectedEditionComplex); }, }); // Update editionComplex - editionService.updateEditionComplex(expectedEditionComplex); + editionService.updateSelectedEditionComplex(expectedEditionComplex); // Clear editionComplex expectedEditionComplex = null; - editionService.clearEditionComplex(); + editionService.clearSelectedEditionComplex(); })); }); }); - describe('#getEditionOutline()', () => { - it('... should have a method `getEditionOutline`', () => { - expect(editionService.getEditionOutline).toBeDefined(); - }); - - it('... should return editionOutline', () => { - const outline = editionService.getEditionOutline(); - - expect(outline).toBeTruthy(); - expect(outline).withContext(`should equal ${expectedEditionOutline}`).toEqual(expectedEditionOutline); - }); - }); - describe('EditionSeries', () => { - describe('#getEditionSeriesRoute()', () => { - it('... should have a method `getEditionSeriesRoute`', () => { - expect(editionService.getEditionSeriesRoute).toBeDefined(); - }); - - it('... should return editionSeriesRoute', () => { - const route = editionService.getEditionSeriesRoute(); - - expect(route).toBeTruthy(); - expect(route) - .withContext(` should equal ${expectedEditionSeriesRoute}`) - .toEqual(expectedEditionSeriesRoute); - }); - }); - - describe('#getEditionSeriesById()', () => { - it('... should have a method `getEditionSeriesById`', () => { - expect(editionService.getEditionSeriesById).toBeDefined(); - }); - - it('... should return editionSeries with given id', () => { - const series = editionService.getEditionSeriesById(EDITION_ROUTE_CONSTANTS.SERIES_1.route); - - expect(series).toBeTruthy(); - expect(series).withContext(`should equal ${expectedEditionSeries}`).toEqual(expectedEditionSeries); - }); - }); - describe('#getSelectedEditionSeries()', () => { it('... should have a method `getSelectedEditionSeries`', () => { expect(editionService.getSelectedEditionSeries).toBeDefined(); @@ -230,10 +188,7 @@ describe('EditionService (DONE)', () => { it('... should return selected editionSeries', waitForAsync(() => { editionService.getSelectedEditionSeries().subscribe({ next: (editionSeries: EditionOutlineSeries) => { - expect(editionSeries).toBeTruthy(); - expect(editionSeries) - .withContext(`should equal ${expectedEditionSeries}`) - .toEqual(expectedEditionSeries); + expectToEqual(editionSeries, expectedEditionSeries); }, }); @@ -244,10 +199,7 @@ describe('EditionService (DONE)', () => { it('... should return updated editionSeries', waitForAsync(() => { editionService.getSelectedEditionSeries().subscribe({ next: (editionSeries: EditionOutlineSeries) => { - expect(editionSeries).toBeTruthy(); - expect(editionSeries) - .withContext(`should equal ${expectedEditionSeries}`) - .toEqual(expectedEditionSeries); + expectToEqual(editionSeries, expectedEditionSeries); }, }); @@ -255,7 +207,7 @@ describe('EditionService (DONE)', () => { editionService.updateSelectedEditionSeries(expectedEditionSeries); // Update editionSeries - expectedEditionSeries = EDITION_OUTLINE_DATA[1]; + expectedEditionSeries = expectedEditionOutline[1]; editionService.updateSelectedEditionSeries(expectedEditionSeries); })); }); @@ -268,10 +220,7 @@ describe('EditionService (DONE)', () => { it('... should emit updated editionSeries', waitForAsync(() => { editionService.getSelectedEditionSeries().subscribe({ next: (editionSeries: EditionOutlineSeries) => { - expect(editionSeries).toBeTruthy(); - expect(editionSeries) - .withContext(`should equal ${expectedEditionSeries}`) - .toEqual(expectedEditionSeries); + expectToEqual(editionSeries, expectedEditionSeries); }, }); @@ -279,7 +228,7 @@ describe('EditionService (DONE)', () => { editionService.updateSelectedEditionSeries(expectedEditionSeries); // Update editionSeries - expectedEditionSeries = EDITION_OUTLINE_DATA[1]; + expectedEditionSeries = expectedEditionOutline[1]; editionService.updateSelectedEditionSeries(expectedEditionSeries); })); }); @@ -292,10 +241,7 @@ describe('EditionService (DONE)', () => { it('... should update editionSeries with null value', waitForAsync(() => { editionService.getSelectedEditionSeries().subscribe({ next: (editionSeries: EditionOutlineSeries) => { - expect(editionSeries).toBeNull(); - expect(editionSeries) - .withContext(`should equal ${expectedEditionSeries}`) - .toEqual(expectedEditionSeries); + expectToEqual(editionSeries, expectedEditionSeries); }, }); @@ -304,12 +250,10 @@ describe('EditionService (DONE)', () => { editionService.clearSelectedEditionSeries(); })); - it('... should overwrite existing search results', waitForAsync(() => { + it('... should overwrite existing values', waitForAsync(() => { editionService.getSelectedEditionSeries().subscribe({ next: (editionSeries: EditionOutlineSeries) => { - expect(editionSeries) - .withContext(`should equal ${expectedEditionSeries}`) - .toEqual(expectedEditionSeries); + expectToEqual(editionSeries, expectedEditionSeries); }, }); @@ -324,28 +268,6 @@ describe('EditionService (DONE)', () => { }); describe('EditionSection', () => { - describe('#getEditionSectionById()', () => { - it('... should have a method `getEditionSectionById`', () => { - expect(editionService.getEditionSectionById).toBeDefined(); - }); - - it('... should return editionSection with given id', () => { - expectedEditionOutline[0].sections.forEach((section, index) => { - expectedEditionSection = section; - - const getSection = editionService.getEditionSectionById( - EDITION_ROUTE_CONSTANTS.SERIES_1.route, - EDITION_ROUTE_CONSTANTS[`SECTION_${index + 1}`].route - ); - - expect(getSection).toBeTruthy(); - expect(getSection) - .withContext(`should equal ${expectedEditionSection}`) - .toEqual(expectedEditionSection); - }); - }); - }); - describe('#getSelectedEditionSection()', () => { it('... should have a method `getSelectedEditionSection`', () => { expect(editionService.getSelectedEditionSection).toBeDefined(); @@ -354,10 +276,7 @@ describe('EditionService (DONE)', () => { it('... should return selected editionSection', waitForAsync(() => { editionService.getSelectedEditionSection().subscribe({ next: (editionSection: EditionOutlineSection) => { - expect(editionSection).toBeTruthy(); - expect(editionSection) - .withContext(`should equal ${expectedEditionSection}`) - .toEqual(expectedEditionSection); + expectToEqual(editionSection, expectedEditionSection); }, }); @@ -368,10 +287,7 @@ describe('EditionService (DONE)', () => { it('... should return updated editionSection', waitForAsync(() => { editionService.getSelectedEditionSection().subscribe({ next: (editionSection: EditionOutlineSection) => { - expect(editionSection).toBeTruthy(); - expect(editionSection) - .withContext(`should equal ${expectedEditionSection}`) - .toEqual(expectedEditionSection); + expectToEqual(editionSection, expectedEditionSection); }, }); @@ -379,7 +295,7 @@ describe('EditionService (DONE)', () => { editionService.updateSelectedEditionSection(expectedEditionSection); // Update editionSection - expectedEditionSection = EDITION_OUTLINE_DATA[0].sections[4]; + expectedEditionSection = expectedEditionOutline[0].sections[4]; editionService.updateSelectedEditionSection(expectedEditionSection); })); }); @@ -392,10 +308,7 @@ describe('EditionService (DONE)', () => { it('... should emit updated editionSection', waitForAsync(() => { editionService.getSelectedEditionSection().subscribe({ next: (editionSection: EditionOutlineSection) => { - expect(editionSection).toBeTruthy(); - expect(editionSection) - .withContext(`should equal ${expectedEditionSection}`) - .toEqual(expectedEditionSection); + expectToEqual(editionSection, expectedEditionSection); }, }); @@ -403,7 +316,7 @@ describe('EditionService (DONE)', () => { editionService.updateSelectedEditionSection(expectedEditionSection); // Update editionSection - expectedEditionSection = EDITION_OUTLINE_DATA[0].sections[4]; + expectedEditionSection = expectedEditionOutline[0].sections[4]; editionService.updateSelectedEditionSection(expectedEditionSection); })); }); @@ -416,10 +329,7 @@ describe('EditionService (DONE)', () => { it('... should update editionSection with null value', waitForAsync(() => { editionService.getSelectedEditionSection().subscribe({ next: (editionSection: EditionOutlineSection) => { - expect(editionSection).toBeNull(); - expect(editionSection) - .withContext(`should equal ${expectedEditionSection}`) - .toEqual(expectedEditionSection); + expectToEqual(editionSection, expectedEditionSection); }, }); @@ -428,12 +338,10 @@ describe('EditionService (DONE)', () => { editionService.clearSelectedEditionSection(); })); - it('... should overwrite existing search results', waitForAsync(() => { + it('... should overwrite existing values', waitForAsync(() => { editionService.getSelectedEditionSection().subscribe({ next: (editionSection: EditionOutlineSection) => { - expect(editionSection) - .withContext(`should equal ${expectedEditionSection}`) - .toEqual(expectedEditionSection); + expectToEqual(editionSection, expectedEditionSection); }, }); @@ -447,6 +355,94 @@ describe('EditionService (DONE)', () => { }); }); + describe('PrefaceView', () => { + describe('#getIsPrefaceView()', () => { + it('... should have a method `getIsPrefaceView`', () => { + expect(editionService.getIsPrefaceView).toBeDefined(); + }); + + it('... should return isPrefaceView', waitForAsync(() => { + editionService.getIsPrefaceView().subscribe({ + next: (isRowTableView: boolean) => { + expectToBe(isRowTableView, expectedIsPrefaceView); + }, + }); + + // Set isPrefaceView (with default value) + editionService.updateIsPrefaceView(expectedIsPrefaceView); + })); + + it('... should return updated isPrefaceView', waitForAsync(() => { + editionService.getIsPrefaceView().subscribe({ + next: (isPrefaceView: boolean) => { + expectToBe(isPrefaceView, expectedIsPrefaceView); + }, + }); + + // Set isPrefaceView (with default value) + editionService.updateIsPrefaceView(expectedIsPrefaceView); + + // Update isPrefaceView + expectedIsPrefaceView = false; + editionService.updateIsPrefaceView(expectedIsPrefaceView); + })); + }); + + describe('#updateIsPrefaceView()', () => { + it('... should have a method `updateIsPrefaceView`', () => { + expect(editionService.updateIsPrefaceView).toBeDefined(); + }); + + it('... should emit updated isPrefaceView', waitForAsync(() => { + editionService.getIsPrefaceView().subscribe({ + next: (isPrefaceView: boolean) => { + expectToBe(isPrefaceView, expectedIsPrefaceView); + }, + }); + + // Set isPrefaceView (with default value) + editionService.updateIsPrefaceView(expectedIsPrefaceView); + + // Update isPrefaceView + expectedIsPrefaceView = false; + editionService.updateIsPrefaceView(expectedIsPrefaceView); + })); + }); + + describe('#clearIsPrefaceView()', () => { + it('... should have a method `clearIsPrefaceView`', () => { + expect(editionService.clearIsPrefaceView).toBeDefined(); + }); + + it('... should update isPrefaceView with null value', waitForAsync(() => { + editionService.getIsPrefaceView().subscribe({ + next: (isPrefaceView: boolean) => { + expectToBe(isPrefaceView, expectedIsPrefaceView); + }, + }); + + // Clear isPrefaceView + expectedIsPrefaceView = null; + editionService.clearIsPrefaceView(); + })); + + it('... should overwrite existing values', waitForAsync(() => { + editionService.getIsPrefaceView().subscribe({ + next: (isPrefaceView: boolean) => { + expectToBe(isPrefaceView, expectedIsPrefaceView); + }, + }); + + // Update isPrefaceView + editionService.updateIsPrefaceView(expectedIsPrefaceView); + + // Clear isPrefaceView + expectedIsPrefaceView = null; + editionService.clearIsPrefaceView(); + })); + }); + }); + describe('RowTableView', () => { describe('#getIsRowTableView()', () => { it('... should have a method `getIsRowTableView`', () => { @@ -456,10 +452,7 @@ describe('EditionService (DONE)', () => { it('... should return isRowTableView', waitForAsync(() => { editionService.getIsRowTableView().subscribe({ next: (isRowTableView: boolean) => { - expect(isRowTableView).toBeTruthy(); - expect(isRowTableView) - .withContext(`should equal ${expectedIsRowTableView}`) - .toEqual(expectedIsRowTableView); + expectToBe(isRowTableView, expectedIsRowTableView); }, }); @@ -470,10 +463,7 @@ describe('EditionService (DONE)', () => { it('... should return updated isRowTableView', waitForAsync(() => { editionService.getIsRowTableView().subscribe({ next: (isRowTableView: boolean) => { - expect(isRowTableView).toBeDefined(); - expect(isRowTableView) - .withContext(`should equal ${expectedIsRowTableView}`) - .toEqual(expectedIsRowTableView); + expectToBe(isRowTableView, expectedIsRowTableView); }, }); @@ -494,10 +484,7 @@ describe('EditionService (DONE)', () => { it('... should emit updated isRowTableView', waitForAsync(() => { editionService.getIsRowTableView().subscribe({ next: (isRowTableView: boolean) => { - expect(isRowTableView).toBeDefined(); - expect(isRowTableView) - .withContext(`should equal ${expectedIsRowTableView}`) - .toEqual(expectedIsRowTableView); + expectToBe(isRowTableView, expectedIsRowTableView); }, }); @@ -518,10 +505,7 @@ describe('EditionService (DONE)', () => { it('... should update isRowTableView with null value', waitForAsync(() => { editionService.getIsRowTableView().subscribe({ next: (isRowTableView: boolean) => { - expect(isRowTableView).toBeNull(); - expect(isRowTableView) - .withContext(`should equal ${expectedIsRowTableView}`) - .toEqual(expectedIsRowTableView); + expectToBe(isRowTableView, expectedIsRowTableView); }, }); @@ -530,12 +514,10 @@ describe('EditionService (DONE)', () => { editionService.clearIsRowTableView(); })); - it('... should overwrite existing search results', waitForAsync(() => { + it('... should overwrite existing values', waitForAsync(() => { editionService.getIsRowTableView().subscribe({ next: (isRowTableView: boolean) => { - expect(isRowTableView) - .withContext(`should equal ${expectedIsRowTableView}`) - .toEqual(expectedIsRowTableView); + expectToBe(isRowTableView, expectedIsRowTableView); }, }); diff --git a/src/app/views/edition-view/services/edition.service.ts b/src/app/views/edition-view/services/edition.service.ts index 0c8f6650a..5870d11ec 100644 --- a/src/app/views/edition-view/services/edition.service.ts +++ b/src/app/views/edition-view/services/edition.service.ts @@ -2,8 +2,6 @@ import { Injectable } from '@angular/core'; import { Observable, ReplaySubject } from 'rxjs'; -import { EDITION_OUTLINE_DATA } from '@awg-views/edition-view/data'; -import { EDITION_ROUTE_CONSTANTS } from '@awg-views/edition-view/edition-route-constants'; import { EditionComplex, EditionOutlineSection, EditionOutlineSeries } from '@awg-views/edition-view/models'; /** @@ -25,14 +23,14 @@ export class EditionService { private _bufferSize = 1; /** - * Private replay subject to handle edition complex. + * Private replay subject to flag preface view. */ - private _editionComplexSubject = new ReplaySubject(this._bufferSize); + private _isPrefaceViewSubject = new ReplaySubject(this._bufferSize); /** - * Private readonly edition complex stream as observable (`ReplaySubject`). + * Private readonly isPrefaceView stream as observable (`ReplaySubject`). */ - private readonly _editionComplexStream$ = this._editionComplexSubject.asObservable(); + private readonly _isPrefaceViewStream$ = this._isPrefaceViewSubject.asObservable(); /** * Private replay subject to flag row table view. @@ -44,6 +42,16 @@ export class EditionService { */ private readonly _isRowTableViewStream$ = this._isRowTableViewSubject.asObservable(); + /** + * Private replay subject to handle the selected edition complex. + */ + private _selectedEditionComplexSubject = new ReplaySubject(this._bufferSize); + + /** + * Private readonly edition complex stream as observable (`ReplaySubject`). + */ + private readonly _selectedEditionComplexStream$ = this._selectedEditionComplexSubject.asObservable(); + /** * Private replay subject to handle the selected edition series. */ @@ -65,88 +73,38 @@ export class EditionService { private readonly _selectedEditionSectionStream$ = this._selectedEditionSectionSubject.asObservable(); /** - * Public method: getEditionComplex. + * Public method: getSelectedEditionComplex. * - * It provides the latest edition complex from the edition complex stream. + * It provides the latest selected edition complex from the edition complex stream. * * @returns {Observable} The edition complex stream as observable. */ - getEditionComplex(): Observable { - return this._editionComplexStream$; + getSelectedEditionComplex(): Observable { + return this._selectedEditionComplexStream$; } /** - * Public method: updateEditionComplex. + * Public method: updateSelectedEditionComplex. * - * It updates the edition complex stream with the given edition complex. + * It updates the selected edition complex stream with the given edition complex. * * @param {EditionComplex} editionComplex The given edition complex. * * @returns {void} Sets the next edition complex to the stream. */ - updateEditionComplex(editionComplex: EditionComplex): void { - this._editionComplexSubject.next(editionComplex); + updateSelectedEditionComplex(editionComplex: EditionComplex): void { + this._selectedEditionComplexSubject.next(editionComplex); } /** - * Public method: clearEditionComplex. + * Public method: clearSelectedEditionComplex. * - * It clears the edition complex stream. + * It clears the selected edition complex stream. * * @returns {void} Clears the edition complex stream. */ - clearEditionComplex(): void { - this._editionComplexSubject.next(null); - } - - /** - * Public method: getEditionOutline. - * - * It provides the outline of the edition with its series. - * - * @returns {EditionOutlineSeries[]} The edition outline. - */ - getEditionOutline(): EditionOutlineSeries[] { - return EDITION_OUTLINE_DATA; - } - - /** - * Public method: getEditionSeriesRoute. - * - * It provides the base route for the edition series section of the app. - * - * @returns {string} The edition series route. - */ - getEditionSeriesRoute(): string { - return EDITION_ROUTE_CONSTANTS.EDITION.route + EDITION_ROUTE_CONSTANTS.SERIES.route; - } - - /** - * Public method: getEditionSeriesById. - * - * It finds a series of the edition by a given id. - * - * @param {string} seriesId The given series id. - * - * @returns {EditionOutlineSeries} The found edition series. - */ - getEditionSeriesById(seriesId: string): EditionOutlineSeries { - return EDITION_OUTLINE_DATA.find(series => series.series.route === seriesId); - } - - /** - * Public method: getEditionSectionById. - * - * It finds a section of an edition series by a given id. - * - * @param {string} seriesId The given series id. - * @param {string} sectionId The given series id. - * - * @returns {EditionOutlineSection} The found edition section. - */ - getEditionSectionById(seriesId: string, sectionId: string): EditionOutlineSection { - const series = this.getEditionSeriesById(seriesId); - return series.sections.find(section => section.section.route === sectionId); + clearSelectedEditionComplex(): void { + this._selectedEditionComplexSubject.next(null); } /** @@ -217,6 +175,41 @@ export class EditionService { this._selectedEditionSectionSubject.next(null); } + /** + * Public method: getIsPrefaceView. + * + * It provides the latest isPrefaceView flag from the isPrefaceView stream. + * + * @returns {Observable} The isPrefaceView stream as observable. + */ + getIsPrefaceView(): Observable { + return this._isPrefaceViewStream$; + } + + /** + * Public method: updateIsPrefaceView. + * + * It updates the isPrefaceView stream with the given boolean value. + * + * @param {boolean} isView The given isPrefaceView flag. + * + * @returns {void} Sets the next isPrefaceView flag to the stream. + */ + updateIsPrefaceView(isView: boolean): void { + this._isPrefaceViewSubject.next(isView); + } + + /** + * Public method: clearIsPrefaceView. + * + * It clears the isPrefaceView stream. + * + * @returns {void} Clears the isPrefaceView stream. + */ + clearIsPrefaceView(): void { + this._isPrefaceViewSubject.next(null); + } + /** * Public method: getIsRowTableView. * diff --git a/src/app/views/edition-view/services/index.ts b/src/app/views/edition-view/services/index.ts index 9f8fa93d6..e78cc0839 100644 --- a/src/app/views/edition-view/services/index.ts +++ b/src/app/views/edition-view/services/index.ts @@ -7,9 +7,18 @@ * */ +import { EditionComplexesService } from './edition-complexes.service'; import { EditionDataService } from './edition-data.service'; +import { EditionOutlineService } from './edition-outline.service'; import { EditionSheetsService } from './edition-sheets.service'; import { EditionSvgDrawingService } from './edition-svg-drawing.service'; import { EditionService } from './edition.service'; -export { EditionDataService, EditionSheetsService, EditionSvgDrawingService, EditionService }; +export { + EditionComplexesService, + EditionDataService, + EditionOutlineService, + EditionService, + EditionSheetsService, + EditionSvgDrawingService, +}; diff --git a/src/app/views/home-view/home-view.component.spec.ts b/src/app/views/home-view/home-view.component.spec.ts index 74914e54a..d0defcea8 100644 --- a/src/app/views/home-view/home-view.component.spec.ts +++ b/src/app/views/home-view/home-view.component.spec.ts @@ -17,11 +17,11 @@ import { } from '@testing/expect-helper'; import { RouterLinkStubDirective } from '@testing/router-stubs'; -import { METADATA } from '@awg-app/core/core-data'; -import { MetaPage, MetaSectionTypes } from '@awg-app/core/core-models'; -import { EDITION_COMPLEXES } from '@awg-views/edition-view/data'; +import { METADATA } from '@awg-core/core-data'; +import { MetaPage, MetaSectionTypes } from '@awg-core/core-models'; import { EDITION_ROUTE_CONSTANTS, EDITION_TYPE_CONSTANTS } from '@awg-views/edition-view/edition-route-constants'; import { EditionComplex } from '@awg-views/edition-view/models'; +import { EditionComplexesService } from '@awg-views/edition-view/services'; import { HomeViewComponent } from './home-view.component'; @@ -38,7 +38,7 @@ class HeadingStubComponent { function generateExpectedOrderOfRouterlinks(editionComplexes: EditionComplex[]): string[][] { const editionAndGraphLinks = editionComplexes.flatMap(complex => { const routes = [[complex.baseRoute, EDITION_ROUTE_CONSTANTS.EDITION_SHEETS.route]]; - if (complex === EDITION_COMPLEXES.OP25) { + if (complex === EditionComplexesService.getEditionComplexById('OP25')) { routes.push([complex.baseRoute, EDITION_ROUTE_CONSTANTS.EDITION_GRAPH.route]); } return routes; @@ -101,17 +101,17 @@ describe('HomeViewComponent (DONE)', () => { expectedPageMetaData = METADATA[MetaSectionTypes.page]; expectedEditionComplexes = [ - EDITION_COMPLEXES.OP3, - EDITION_COMPLEXES.OP4, - EDITION_COMPLEXES.OP12, - EDITION_COMPLEXES.OP23, - EDITION_COMPLEXES.OP25, - EDITION_COMPLEXES.M22, - EDITION_COMPLEXES.M30, - EDITION_COMPLEXES.M31, - EDITION_COMPLEXES.M34, - EDITION_COMPLEXES.M35_42, - EDITION_COMPLEXES.M37, + EditionComplexesService.getEditionComplexById('OP3'), + EditionComplexesService.getEditionComplexById('OP4'), + EditionComplexesService.getEditionComplexById('OP12'), + EditionComplexesService.getEditionComplexById('OP23'), + EditionComplexesService.getEditionComplexById('OP25'), + EditionComplexesService.getEditionComplexById('M22'), + EditionComplexesService.getEditionComplexById('M30'), + EditionComplexesService.getEditionComplexById('M31'), + EditionComplexesService.getEditionComplexById('M34'), + EditionComplexesService.getEditionComplexById('M35_42'), + EditionComplexesService.getEditionComplexById('M37'), ]; expectedOrderOfRouterlinks = generateExpectedOrderOfRouterlinks(expectedEditionComplexes); @@ -512,7 +512,7 @@ describe('HomeViewComponent (DONE)', () => { const linkDe = linkDes[index]; const expectedRouterLink = expectedOrderOfRouterlinks[index]; - expect(routerLink.navigatedTo).toBeNull(); + expectToBe(routerLink.navigatedTo, null); click(linkDe); fixture.detectChanges(); diff --git a/src/app/views/home-view/home-view.component.ts b/src/app/views/home-view/home-view.component.ts index 6ab62bb22..24f5da10b 100644 --- a/src/app/views/home-view/home-view.component.ts +++ b/src/app/views/home-view/home-view.component.ts @@ -1,11 +1,11 @@ import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; import { Router } from '@angular/router'; -import { MetaPage, MetaSectionTypes } from '@awg-app/core/core-models'; -import { CoreService } from '@awg-app/core/services'; -import { EDITION_COMPLEXES } from '@awg-views/edition-view/data'; +import { MetaPage, MetaSectionTypes } from '@awg-core/core-models'; +import { CoreService } from '@awg-core/services'; import { EDITION_ROUTE_CONSTANTS, EDITION_TYPE_CONSTANTS } from '@awg-views/edition-view/edition-route-constants'; import { EditionComplex } from '@awg-views/edition-view/models'; +import { EditionComplexesService } from '@awg-views/edition-view/services'; /** * The HomeView component. @@ -49,17 +49,17 @@ export class HomeViewComponent implements OnInit { * It keeps the array of displayed edition complexes. */ readonly DISPLAYED_EDITION_COMPLEXES: EditionComplex[] = [ - EDITION_COMPLEXES.OP3, - EDITION_COMPLEXES.OP4, - EDITION_COMPLEXES.OP12, - EDITION_COMPLEXES.OP23, - EDITION_COMPLEXES.OP25, - EDITION_COMPLEXES.M22, - EDITION_COMPLEXES.M30, - EDITION_COMPLEXES.M31, - EDITION_COMPLEXES.M34, - EDITION_COMPLEXES.M35_42, - EDITION_COMPLEXES.M37, + EditionComplexesService.getEditionComplexById('OP3'), + EditionComplexesService.getEditionComplexById('OP4'), + EditionComplexesService.getEditionComplexById('OP12'), + EditionComplexesService.getEditionComplexById('OP23'), + EditionComplexesService.getEditionComplexById('OP25'), + EditionComplexesService.getEditionComplexById('M22'), + EditionComplexesService.getEditionComplexById('M30'), + EditionComplexesService.getEditionComplexById('M31'), + EditionComplexesService.getEditionComplexById('M34'), + EditionComplexesService.getEditionComplexById('M35_42'), + EditionComplexesService.getEditionComplexById('M37'), ]; /** diff --git a/src/app/views/page-not-found-view/page-not-found-view.component.spec.ts b/src/app/views/page-not-found-view/page-not-found-view.component.spec.ts index e66c96eba..919cd2e0b 100644 --- a/src/app/views/page-not-found-view/page-not-found-view.component.spec.ts +++ b/src/app/views/page-not-found-view/page-not-found-view.component.spec.ts @@ -4,7 +4,13 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { cleanStylesFromDOM } from '@testing/clean-up-helper'; import { click } from '@testing/click-helper'; -import { getAndExpectDebugElementByCss, getAndExpectDebugElementByDirective } from '@testing/expect-helper'; +import { + expectToBe, + expectToContain, + expectToEqual, + getAndExpectDebugElementByCss, + getAndExpectDebugElementByDirective, +} from '@testing/expect-helper'; import { RouterLinkStubDirective } from '@testing/router-stubs'; import { PageNotFoundViewComponent } from './page-not-found-view.component'; @@ -44,27 +50,13 @@ describe('PageNotFoundViewComponent (DONE)', () => { describe('BEFORE initial data binding', () => { it('... should have pageNotFoundTitle and pageNotFoundSubtitle', () => { - expect(component.pageNotFoundTitle).toBeTruthy(); - expect(component.pageNotFoundTitle) - .withContext(`should be ${expectedPageNotFoundTitle}`) - .toBe(expectedPageNotFoundTitle); - - expect(component.pageNotFoundSubTitle).toBeTruthy(); - expect(component.pageNotFoundSubTitle) - .withContext(`should be ${expectedPageNotFoundSubTitle}`) - .toBe(expectedPageNotFoundSubTitle); + expectToBe(component.pageNotFoundTitle, expectedPageNotFoundTitle); + expectToBe(component.pageNotFoundSubTitle, expectedPageNotFoundSubTitle); }); it('... should have correct values from getters', () => { - expect(component.pageNotFoundImgPath).toBeTruthy(); - expect(component.pageNotFoundImgPath) - .withContext(`should be ${expectedPageNotFoundImgPath}`) - .toBe(expectedPageNotFoundImgPath); - - expect(component.awgContactUrl).toBeTruthy(); - expect(component.awgContactUrl) - .withContext(`should be ${expectedAwgContactUrl}`) - .toBe(expectedAwgContactUrl); + expectToBe(component.pageNotFoundImgPath, expectedPageNotFoundImgPath); + expectToBe(component.awgContactUrl, expectedAwgContactUrl); }); describe('VIEW', () => { @@ -96,8 +88,7 @@ describe('PageNotFoundViewComponent (DONE)', () => { ); const imgEl = imgDes[0].nativeElement; - expect(imgEl.src).toBeDefined(); - expect(imgEl.src).toBeFalsy(); + expectToBe(imgEl.src, ''); }); it('... should contain 2 paragraphs (contact and back) in body', () => { @@ -115,19 +106,15 @@ describe('PageNotFoundViewComponent (DONE)', () => { const subtitleDes = getAndExpectDebugElementByCss(compDe, 'h5#awg-page-not-found-subtitle', 1, 1); const subtitleEl = subtitleDes[0].nativeElement; - expect(titleEl.textContent).toBeDefined(); - expect(titleEl.textContent).toBeFalsy(); - - expect(subtitleEl.textContent).toBeDefined(); - expect(subtitleEl.textContent).toBeFalsy(); + expectToBe(titleEl.textContent, ''); + expectToBe(subtitleEl.textContent, ''); }); it('... should not render contact url yet', () => { const contactDes = getAndExpectDebugElementByCss(compDe, 'p#awg-page-not-found-contact > a', 1, 1); const contactEl = contactDes[0].nativeElement; - expect(contactEl.href).toBeDefined(); - expect(contactEl.href).toBeFalsy(); + expectToBe(contactEl.href, ''); }); }); }); @@ -143,40 +130,28 @@ describe('PageNotFoundViewComponent (DONE)', () => { const titleDes = getAndExpectDebugElementByCss(compDe, 'h2#awg-page-not-found-title', 1, 1); const titleEl = titleDes[0].nativeElement; - expect(titleEl.textContent).toBeTruthy(); - expect(titleEl.textContent) - .withContext(`should contain ${expectedPageNotFoundTitle}`) - .toContain(expectedPageNotFoundTitle); + expectToContain(titleEl.textContent, expectedPageNotFoundTitle); }); it('... should render pageNotFoundSubTitle in the `h5`-element', () => { const subtitleDes = getAndExpectDebugElementByCss(compDe, 'h5#awg-page-not-found-subtitle', 1, 1); const subtitleEl = subtitleDes[0].nativeElement; - expect(subtitleEl.textContent).toBeTruthy(); - expect(subtitleEl.textContent) - .withContext(`should contain ${expectedPageNotFoundSubTitle}`) - .toContain(expectedPageNotFoundSubTitle); + expectToContain(subtitleEl.textContent, expectedPageNotFoundSubTitle); }); it('... should render image', () => { const imgDes = getAndExpectDebugElementByCss(compDe, 'div.awg-page-not-found-image > img', 1, 1); const imgEl = imgDes[0].nativeElement; - expect(imgEl.src).toBeTruthy(); - expect(imgEl.src) - .withContext(`should contain ${expectedPageNotFoundImgPath}`) - .toContain(expectedPageNotFoundImgPath); + expectToContain(imgEl.src, expectedPageNotFoundImgPath); }); it('... should render contact url', () => { const contactDes = getAndExpectDebugElementByCss(compDe, 'p#awg-page-not-found-contact > a', 1, 1); const contactEl = contactDes[0].nativeElement; - expect(contactEl.href).toBeTruthy(); - expect(contactEl.href) - .withContext(`should contain ${expectedAwgContactUrl}`) - .toBe(expectedAwgContactUrl); + expectToContain(contactEl.href, expectedAwgContactUrl); }); }); @@ -190,23 +165,23 @@ describe('PageNotFoundViewComponent (DONE)', () => { }); it('... can get correct number of routerLinks from template', () => { - expect(routerLinks.length).withContext('should have 1 routerLink').toBe(1); + expectToBe(routerLinks.length, 1); }); it('... can get correct linkParams from template', () => { - expect(routerLinks[0].linkParams).withContext(`should equal ['/home']`).toEqual(['/home']); + expectToEqual(routerLinks[0].linkParams, ['/home']); }); it('... can click home link in template', () => { const homeLinkDe = linkDes[0]; // Home link DebugElement const homeLink = routerLinks[0]; // Home link directive - expect(homeLink.navigatedTo).toBeNull(); + expectToBe(homeLink.navigatedTo, null); click(homeLinkDe); fixture.detectChanges(); - expect(homeLink.navigatedTo).withContext(`should equal ['/home']`).toEqual(['/home']); + expectToEqual(homeLink.navigatedTo, ['/home']); }); }); }); diff --git a/src/app/views/structure-view/structure-view.component.spec.ts b/src/app/views/structure-view/structure-view.component.spec.ts index dd331ab4d..22fcceb9c 100644 --- a/src/app/views/structure-view/structure-view.component.spec.ts +++ b/src/app/views/structure-view/structure-view.component.spec.ts @@ -8,6 +8,7 @@ import Spy = jasmine.Spy; import { cleanStylesFromDOM } from '@testing/clean-up-helper'; import { expectSpyCall, + expectToBe, getAndExpectDebugElementByCss, getAndExpectDebugElementByDirective, } from '@testing/expect-helper'; @@ -64,11 +65,8 @@ describe('StructureViewComponent (DONE)', () => { describe('BEFORE initial data binding', () => { it('... should have title and id', () => { - expect(component.structureViewTitle).toBeDefined(); - expect(component.structureViewTitle).toBe(expectedTitle); - - expect(component.structureViewId).toBeDefined(); - expect(component.structureViewId).toBe(expectedId); + expectToBe(component.structureViewTitle, expectedTitle); + expectToBe(component.structureViewId, expectedId); }); describe('#routeToSidenav()', () => { @@ -133,8 +131,7 @@ describe('StructureViewComponent (DONE)', () => { expect(navArgs).toBeDefined(); expect(navArgs[0]).toBeDefined(); - expect(outletRoute).toBeDefined(); - expect(outletRoute).withContext(`should be: ${expectedRoute}`).toBe(expectedRoute); + expectToBe(outletRoute, expectedRoute); expect(navigationSpy).toHaveBeenCalledWith(navArgs[0], navArgs[1]); }); @@ -145,8 +142,7 @@ describe('StructureViewComponent (DONE)', () => { const navExtras = navArgs[1]; expect(navExtras).toBeDefined(); - expect(navExtras.preserveFragment).toBeDefined(); - expect(navExtras.preserveFragment).withContext('should be `preserveFragment:true`').toBe(true); + expectToBe(navExtras.preserveFragment, true); expect(navigationSpy).toHaveBeenCalledWith(navArgs[0], navArgs[1]); }); @@ -157,11 +153,8 @@ describe('StructureViewComponent (DONE)', () => { const headingDes = getAndExpectDebugElementByDirective(compDe, HeadingStubComponent, 1, 1); const headingCmp = headingDes[0].injector.get(HeadingStubComponent) as HeadingStubComponent; - expect(headingCmp.title).toBeTruthy(); - expect(headingCmp.title).withContext(`should have title: ${expectedTitle}`).toBe(expectedTitle); - - expect(headingCmp.id).toBeTruthy(); - expect(headingCmp.id).withContext(`should have title: ${expectedId}`).toBe(expectedId); + expectToBe(headingCmp.title, expectedTitle); + expectToBe(headingCmp.id, expectedId); }); }); }); diff --git a/src/assets/data/edition/edition-complexes.json b/src/assets/data/edition/edition-complexes.json new file mode 100644 index 000000000..e40c59e4c --- /dev/null +++ b/src/assets/data/edition/edition-complexes.json @@ -0,0 +1,774 @@ +{ + "editionComplexes": [ + { + "M22": { + "titleStatement": { + "title": "Studienkomposition für Klavier/Streichquartett", + "catalogueType": "MNR", + "catalogueNumber": "22" + }, + "respStatement": { + "editors": [ + { + "name": "Michael Matter", + "homepage": "https://www.anton-webern.ch/index.php?id=3" + } + ], + "lastModified": "21. März 2024" + }, + "pubStatement": { + "series": "2", + "section": "2a" + } + } + }, + { + "M30": { + "titleStatement": { + "title": "Studienkomposition für Klavier", + "catalogueType": "MNR", + "catalogueNumber": "30" + }, + "respStatement": { + "editors": [ + { + "name": "Michael Matter", + "homepage": "https://www.anton-webern.ch/index.php?id=3" + } + ], + "lastModified": "19. Januar 2024" + }, + "pubStatement": { + "series": "2", + "section": "2a" + } + } + }, + { + "M31": { + "titleStatement": { + "title": "Studienkomposition für Klavier", + "catalogueType": "MNR", + "catalogueNumber": "31" + }, + "respStatement": { + "editors": [ + { + "name": "Michael Matter", + "homepage": "https://www.anton-webern.ch/index.php?id=3" + } + ], + "lastModified": "19. Januar 2024" + }, + "pubStatement": { + "series": "2", + "section": "2a" + } + } + }, + { + "M34": { + "titleStatement": { + "title": "Studienkomposition für Klavier", + "catalogueType": "MNR", + "catalogueNumber": "34" + }, + "respStatement": { + "editors": [ + { + "name": "Michael Matter", + "homepage": "https://www.anton-webern.ch/index.php?id=3" + } + ], + "lastModified": "6. Mai 2023" + }, + "pubStatement": { + "series": "2", + "section": "2a" + } + } + }, + { + "M35_42": { + "titleStatement": { + "title": "Studienkomposition für Klavier", + "catalogueType": "MNR", + "catalogueNumber": "35/42" + }, + "respStatement": { + "editors": [ + { + "name": "Michael Matter", + "homepage": "https://www.anton-webern.ch/index.php?id=3" + } + ], + "lastModified": "8. Februar 2024" + }, + "pubStatement": { + "series": "2", + "section": "2a" + } + } + }, + { + "M36": { + "titleStatement": { + "title": "Studienkomposition für Klavier", + "catalogueType": "MNR", + "catalogueNumber": "36" + }, + "respStatement": { + "editors": [ + { + "name": "Michael Matter", + "homepage": "https://www.anton-webern.ch/index.php?id=3" + } + ], + "lastModified": "14. August 2024" + }, + "pubStatement": { + "series": "2", + "section": "2a" + } + } + }, + { + "M37": { + "titleStatement": { + "title": "Studienkomposition für Klavier", + "catalogueType": "MNR", + "catalogueNumber": "37" + }, + "respStatement": { + "editors": [ + { + "name": "Michael Matter", + "homepage": "https://www.anton-webern.ch/index.php?id=3" + } + ], + "lastModified": "19. Januar 2024" + }, + "pubStatement": { + "series": "2", + "section": "2a" + } + } + }, + { + "M38": { + "titleStatement": { + "title": "Studienkomposition für Klavier", + "catalogueType": "MNR", + "catalogueNumber": "38" + }, + "respStatement": { + "editors": [ + { + "name": "Michael Matter", + "homepage": "https://www.anton-webern.ch/index.php?id=3" + } + ], + "lastModified": "15. August 2024" + }, + "pubStatement": { + "series": "2", + "section": "2a" + } + } + }, + { + "M133": { + "titleStatement": { + "title": "„Dies ist ein Lied“", + "catalogueType": "MNR", + "catalogueNumber": "133" + }, + "respStatement": { + "editors": [ + { + "name": "Thomas Ahrend", + "homepage": "https://www.anton-webern.ch/index.php?id=3" + } + ], + "lastModified": "6. Juni 2024" + }, + "pubStatement": { + "series": "1", + "section": "5" + } + } + }, + { + "M134": { + "titleStatement": { + "title": "„Im Windesweben“", + "catalogueType": "MNR", + "catalogueNumber": "134" + }, + "respStatement": { + "editors": [ + { + "name": "Thomas Ahrend", + "homepage": "https://www.anton-webern.ch/index.php?id=3" + } + ], + "lastModified": "6. Juni 2024" + }, + "pubStatement": { + "series": "1", + "section": "5" + } + } + }, + { + "M135": { + "titleStatement": { + "title": "„An Bachesranft“", + "catalogueType": "MNR", + "catalogueNumber": "135" + }, + "respStatement": { + "editors": [ + { + "name": "Thomas Ahrend", + "homepage": "https://www.anton-webern.ch/index.php?id=3" + } + ], + "lastModified": "6. Juni 2024" + }, + "pubStatement": { + "series": "1", + "section": "5" + } + } + }, + { + "M136": { + "titleStatement": { + "title": "„Im Morgentaun“", + "catalogueType": "MNR", + "catalogueNumber": "136" + }, + "respStatement": { + "editors": [ + { + "name": "Thomas Ahrend", + "homepage": "https://www.anton-webern.ch/index.php?id=3" + } + ], + "lastModified": "6. Juni 2024" + }, + "pubStatement": { + "series": "1", + "section": "5" + } + } + }, + { + "M137": { + "titleStatement": { + "title": "„Kahl reckt der Baum“", + "catalogueType": "MNR", + "catalogueNumber": "137" + }, + "respStatement": { + "editors": [ + { + "name": "Thomas Ahrend", + "homepage": "https://www.anton-webern.ch/index.php?id=3" + } + ], + "lastModified": "6. Juni 2024" + }, + "pubStatement": { + "series": "1", + "section": "5" + } + } + }, + { + "M138": { + "titleStatement": { + "title": "Eingang („Welt der Gestalten“)", + "catalogueType": "MNR", + "catalogueNumber": "138" + }, + "respStatement": { + "editors": [ + { + "name": "Thomas Ahrend", + "homepage": "https://www.anton-webern.ch/index.php?id=3" + } + ], + "lastModified": "6. Juni 2024" + }, + "pubStatement": { + "series": "1", + "section": "5" + } + } + }, + { + "M139": { + "titleStatement": { + "title": "„Noch zwingt mich Treue“", + "catalogueType": "MNR", + "catalogueNumber": "139" + }, + "respStatement": { + "editors": [ + { + "name": "Thomas Ahrend", + "homepage": "https://www.anton-webern.ch/index.php?id=3" + } + ], + "lastModified": "6. Juni 2024" + }, + "pubStatement": { + "series": "1", + "section": "5" + } + } + }, + { + "M140": { + "titleStatement": { + "title": "„Ja Heil und Dank dir“", + "catalogueType": "MNR", + "catalogueNumber": "140" + }, + "respStatement": { + "editors": [ + { + "name": "Thomas Ahrend", + "homepage": "https://www.anton-webern.ch/index.php?id=3" + } + ], + "lastModified": "6. Juni 2024" + }, + "pubStatement": { + "series": "1", + "section": "5" + } + } + }, + { + "M141": { + "titleStatement": { + "title": "„So ich traurig bin“", + "catalogueType": "MNR", + "catalogueNumber": "141" + }, + "respStatement": { + "editors": [ + { + "name": "Thomas Ahrend", + "homepage": "https://www.anton-webern.ch/index.php?id" + } + ], + "lastModified": "6. Juni 2024" + }, + "pubStatement": { + "series": "1", + "section": "5" + } + } + }, + { + "M142": { + "titleStatement": { + "title": "„Ihr tratet zu dem Herde“", + "catalogueType": "MNR", + "catalogueNumber": "142" + }, + "respStatement": { + "editors": [ + { + "name": "Thomas Ahrend", + "homepage": "https://www.anton-webern.ch/index.php?id" + } + ], + "lastModified": "6. Juni 2024" + }, + "pubStatement": { + "series": "1", + "section": "5" + } + } + }, + { + "M143": { + "titleStatement": { + "title": "„Erwachen aus dem tiefsten Traumesschoße“", + "catalogueType": "MNR", + "catalogueNumber": "143" + }, + "respStatement": { + "editors": [ + { + "name": "Thomas Ahrend", + "homepage": "https://www.anton-webern.ch/index.php?id" + } + ], + "lastModified": "6. Juni 2024" + }, + "pubStatement": { + "series": "1", + "section": "5" + } + } + }, + { + "M144": { + "titleStatement": { + "title": "Kunfttag I („Dem bist du Kind“)", + "catalogueType": "MNR", + "catalogueNumber": "144" + }, + "respStatement": { + "editors": [ + { + "name": "Thomas Ahrend", + "homepage": "https://www.anton-webern.ch/index.php?id" + } + ], + "lastModified": "6. Juni 2024" + }, + "pubStatement": { + "series": "1", + "section": "5" + } + } + }, + { + "M145": { + "titleStatement": { + "title": "Trauer I („So wart bis ich dies dir noch künde“)", + "catalogueType": "MNR", + "catalogueNumber": "145" + }, + "respStatement": { + "editors": [ + { + "name": "Thomas Ahrend", + "homepage": "https://www.anton-webern.ch/index.php?id" + } + ], + "lastModified": "6. Juni 2024" + }, + "pubStatement": { + "series": "1", + "section": "5" + } + } + }, + { + "M146": { + "titleStatement": { + "title": "„Das lockere Saatgefilde“", + "catalogueType": "MNR", + "catalogueNumber": "146" + }, + "respStatement": { + "editors": [ + { + "name": "Thomas Ahrend", + "homepage": "https://www.anton-webern.ch/index.php?id" + } + ], + "lastModified": "6. Juni 2024" + }, + "pubStatement": { + "series": "1", + "section": "5" + } + } + }, + { + "M212": { + "titleStatement": { + "title": "„Der Tag ist vergangen“", + "catalogueType": "MNR", + "catalogueNumber": "212" + }, + "respStatement": { + "editors": [ + { + "name": "Thomas Ahrend", + "homepage": "https://www.anton-webern.ch/index.php?id" + } + ], + "lastModified": "---" + }, + "pubStatement": { + "series": "1", + "section": "5" + } + } + }, + { + "M213": { + "titleStatement": { + "title": "„Schien mir’s, als ich sah die Sonne“", + "catalogueType": "MNR", + "catalogueNumber": "213" + }, + "respStatement": { + "editors": [ + { + "name": "Thomas Ahrend", + "homepage": "https://www.anton-webern.ch/index.php?id" + } + ], + "lastModified": "---" + }, + "pubStatement": { + "series": "1", + "section": "5" + } + } + }, + { + "M216": { + "titleStatement": { + "title": "Gleich und Gleich („Ein Blumenglöckchen“)", + "catalogueType": "MNR", + "catalogueNumber": "216" + }, + "respStatement": { + "editors": [ + { + "name": "Thomas Ahrend", + "homepage": "https://www.anton-webern.ch/index.php?id" + } + ], + "lastModified": "---" + }, + "pubStatement": { + "series": "1", + "section": "5" + } + } + }, + { + "M217": { + "titleStatement": { + "title": "Die geheimnisvolle Flöte („An einem Abend“)", + "catalogueType": "MNR", + "catalogueNumber": "217" + }, + "respStatement": { + "editors": [ + { + "name": "Thomas Ahrend", + "homepage": "https://www.anton-webern.ch/index.php?id" + } + ], + "lastModified": "---" + }, + "pubStatement": { + "series": "1", + "section": "5" + } + } + }, + { + "OP3": { + "titleStatement": { + "title": "Fünf Lieder aus Der siebente Ring von Stefan George", + "catalogueType": "OPUS", + "catalogueNumber": "3" + }, + "respStatement": { + "editors": [ + { + "name": "Thomas Ahrend", + "homepage": "https://www.anton-webern.ch/index.php?id" + } + ], + "lastModified": "6. Juni 2024" + }, + "pubStatement": { + "series": "1", + "section": "5" + } + } + }, + { + "OP4": { + "titleStatement": { + "title": "Fünf Lieder nach Gedichten von Stefan George", + "catalogueType": "OPUS", + "catalogueNumber": "4" + }, + "respStatement": { + "editors": [ + { + "name": "Thomas Ahrend", + "homepage": "https://www.anton-webern.ch/index.php?id" + } + ], + "lastModified": "6. Juni 2024" + }, + "pubStatement": { + "series": "1", + "section": "5" + } + } + }, + { + "OP12": { + "titleStatement": { + "title": "Vier Lieder", + "catalogueType": "OPUS", + "catalogueNumber": "12" + }, + "respStatement": { + "editors": [ + { + "name": "Thomas Ahrend", + "homepage": "https://www.anton-webern.ch/index.php?id" + } + ], + "lastModified": "9. April 2024" + }, + "pubStatement": { + "series": "1", + "section": "5" + } + } + }, + { + "OP19": { + "titleStatement": { + "title": "Zwei Lieder für gemischten Chor und Ensemble", + "catalogueType": "OPUS", + "catalogueNumber": "19" + }, + "respStatement": { + "editors": [ + { + "name": "Thomas Ahrend", + "homepage": "https://www.anton-webern.ch/index.php?id" + } + ], + "lastModified": "6. Mai 2023" + }, + "pubStatement": { + "series": "1", + "section": "3" + } + } + }, + { + "OP22": { + "titleStatement": { + "title": "Quartett für Geige, Klarinette, Tenorsaxophon und Klavier", + "catalogueType": "OPUS", + "catalogueNumber": "22" + }, + "respStatement": { + "editors": [ + { + "name": "Thomas Ahrend", + "homepage": "https://www.anton-webern.ch/index.php?id" + } + ], + "lastModified": "6. Mai 2023" + }, + "pubStatement": { + "series": "1", + "section": "2" + } + } + }, + { + "OP23": { + "titleStatement": { + "title": "Drei Gesänge aus Viae Inviae von Hildegard Jone", + "catalogueType": "OPUS", + "catalogueNumber": "23" + }, + "respStatement": { + "editors": [ + { + "name": "Thomas Ahrend", + "homepage": "https://www.anton-webern.ch/index.php?id" + } + ], + "lastModified": "17. April 2024" + }, + "pubStatement": { + "series": "1", + "section": "5" + } + } + }, + { + "OP24": { + "titleStatement": { + "title": "Konzert für neun Instrumente", + "catalogueType": "OPUS", + "catalogueNumber": "24" + }, + "respStatement": { + "editors": [ + { + "name": "Thomas Ahrend", + "homepage": "https://www.anton-webern.ch/index.php?id" + } + ], + "lastModified": "6. Mai 2023" + }, + "pubStatement": { + "series": "1", + "section": "1" + } + } + }, + { + "OP25": { + "titleStatement": { + "title": "Drei Lieder nach Gedichten von Hildegard Jone", + "catalogueType": "OPUS", + "catalogueNumber": "25" + }, + "respStatement": { + "editors": [ + { + "name": "Thomas Ahrend", + "homepage": "https://www.anton-webern.ch/index.php?id" + } + ], + "lastModified": "17. April 2024" + }, + "pubStatement": { + "series": "1", + "section": "5" + } + } + }, + { + "OP27": { + "titleStatement": { + "title": "Variationen für Klavier", + "catalogueType": "OPUS", + "catalogueNumber": "27" + }, + "respStatement": { + "editors": [ + { + "name": "Thomas Ahrend", + "homepage": "https://www.anton-webern.ch/index.php?id" + } + ], + "lastModified": "6. Mai 2023" + }, + "pubStatement": { + "series": "1", + "section": "2" + } + } + } + ] +} diff --git a/src/assets/data/edition/edition-outline.json b/src/assets/data/edition/edition-outline.json new file mode 100644 index 000000000..189cd012f --- /dev/null +++ b/src/assets/data/edition/edition-outline.json @@ -0,0 +1,139 @@ +{ + "editionOutline": [ + { + "series": "1", + "sections": [ + { + "section": "1", + "complexTypes": { "opus": [], "mnr": [] }, + "disabled": true + }, + { + "section": "2", + "complexTypes": { "opus": [], "mnr": [] }, + "disabled": true + }, + { + "section": "3", + "complexTypes": { "opus": [], "mnr": [] }, + "disabled": true + }, + { + "section": "4", + "complexTypes": { "opus": [], "mnr": [] }, + "disabled": true + }, + { + "section": "5", + "complexTypes": { + "opus": [ + { "complex": "OP3", "disabled": false }, + { "complex": "OP4", "disabled": false }, + { "complex": "OP12", "disabled": false }, + { "complex": "OP23", "disabled": false }, + { "complex": "OP25", "disabled": false } + ], + "mnr": [ + { "complex": "M133", "disabled": true }, + { "complex": "M134", "disabled": true }, + { "complex": "M135", "disabled": true }, + { "complex": "M136", "disabled": true }, + { "complex": "M137", "disabled": true }, + { "complex": "M138", "disabled": true }, + { "complex": "M139", "disabled": true }, + { "complex": "M140", "disabled": true }, + { "complex": "M141", "disabled": true }, + { "complex": "M142", "disabled": true }, + { "complex": "M143", "disabled": false }, + { "complex": "M144", "disabled": false }, + { "complex": "M145", "disabled": false }, + { "complex": "M146", "disabled": false }, + { "complex": "M213", "disabled": true }, + { "complex": "M212", "disabled": true }, + { "complex": "M216", "disabled": true }, + { "complex": "M217", "disabled": true } + ] + }, + "disabled": false + } + ] + }, + { + "series": "2", + "sections": [ + { + "section": "1", + "complexTypes": { "opus": [], "mnr": [] }, + "disabled": true + }, + { + "section": "2A", + "complexTypes": { + "opus": [], + "mnr": [ + { "complex": "M22", "disabled": false }, + { "complex": "M30", "disabled": false }, + { "complex": "M31", "disabled": false }, + { "complex": "M34", "disabled": false }, + { "complex": "M35_42", "disabled": false }, + { "complex": "M36", "disabled": false }, + { "complex": "M37", "disabled": false }, + { "complex": "M38", "disabled": false } + ] + }, + "disabled": false + }, + { + "section": "2B", + "complexTypes": { "opus": [], "mnr": [] }, + "disabled": true + }, + { + "section": "3", + "complexTypes": { "opus": [], "mnr": [] }, + "disabled": true + }, + { + "section": "4", + "complexTypes": { "opus": [], "mnr": [] }, + "disabled": true + }, + { + "section": "5", + "complexTypes": { "opus": [], "mnr": [] }, + "disabled": true + } + ] + }, + { + "series": "3", + "sections": [ + { + "section": "1", + "complexTypes": { "opus": [], "mnr": [] }, + "disabled": true + }, + { + "section": "2", + "complexTypes": { "opus": [], "mnr": [] }, + "disabled": true + }, + { + "section": "3", + "complexTypes": { "opus": [], "mnr": [] }, + "disabled": true + }, + { + "section": "4", + "complexTypes": { "opus": [], "mnr": [] }, + "disabled": true + }, + { + "section": "5", + "complexTypes": { "opus": [], "mnr": [] }, + "disabled": true + } + ] + } + ] +} diff --git a/src/assets/data/edition/preface.json b/src/assets/data/edition/preface.json new file mode 100644 index 000000000..7d63d08a7 --- /dev/null +++ b/src/assets/data/edition/preface.json @@ -0,0 +1,84 @@ +{ + "preface": [ + { + "id": "de", + "content": [ + " Die Anton Webern Gesamtausgabe (AWG) versteht sich als historisch-kritische Gesamtausgabe der Kompositionen Anton Weberns. Sie ist historisch, indem sie die Kompositionen durch Dokumentation verschiedener Textfassungen und ihrer Skizzen als in sich chronologisch differenzierte Editionskomplexe präsentiert sowie deren Entstehung in den Zusammenhang der Biographie des Komponisten und der allgemeinen Musikgeschichte einordnet. Sie ist kritisch, indem sie sämtliche erreichbaren Quellen vergleicht und textkritisch prüft. Sie ist eine Gesamtausgabe, indem sie die auf Grundlage dieser Quellenkritik erkennbaren Textfassungen und Skizzen sämtlicher, auch fragmentarischer Kompositionen ediert. Sie ist eine Gesamtausgabe, indem sie Notentexte mit dem methodischen Bewusstsein vorlegt, dass eine Edition grundsätzlich eine Interpretation des durch die Quellen bezeugten Texts darstellt.", + "Die AWG gliedert sich in drei Serien:", + "Serie I  Werke mit Opuszahlen", + "Serie II Nachgelassene Kompositionen und Fragmente", + "Serie IIIBearbeitungen von Werken anderer Komponisten", + "Jede der Serien umfasst fünf Abteilungen:", + "Abteilung 1Orchestermusik", + "Abteilung 2Kammer- und Klaviermusik", + "Abteilung 3Chormusik", + "Abteilung 4Vokalmusik mit Ensemblebegleitung", + "Abteilung 5Klavierlieder (Serie III: Klavierauszüge)", + "Die Abteilungen präsentieren an der Besetzung orientierte Editionskomplexe, d. h. editorisch aufbereitete Textfassungen und Skizzen von einzelnen Kompositionen oder Zusammenstellungen mehrerer Sätze bzw. Stücke oder Lieder. Soweit möglich, werden chronologisch differenzierbare Stadien dieser Editionskomplexe als solche dargestellt und gemäß den in den Quellen erkennbaren Titeln, Nummerierungen und Opuszahlen benannt, auch wenn diese in späteren Stadien unter Umständen obsolet geworden sind.", + "Skizzen und Textfassungen eines Editionskomplexes werden jeweils im Sinne einer möglichen chronologischen Entstehung nummeriert, ohne dass die dadurch implizierte Reihenfolge beansprucht, einer in allen Aspekten textgenetischen Darstellung gerecht zu werden.", + "Mit Rücksicht auf die Überlieferungssituation der für die Editionskomplexe relevanten Quellen sowie mit Blick auf unterschiedliche mögliche Nutzungsinteressen unterscheidet die AWG drei verschiedene Editionsformen:", + "– Werkeditionen", + "– Texteditionen", + "– Skizzeneditionen", + "Als Werkeditionen werden jene Textfassungen von Kompositionen präsentiert, die zu Lebzeiten Weberns im Druck erschienen sind oder für den Druck vorgesehen waren: also seine als op. 1 bis op. 31 gezählten Werke sowie die publizierten oder für den Druck vorgesehenen Bearbeitungen von Werken anderer Komponisten.", + "Die Werkeditionen bieten einen vollständigen und eindeutigen Notentext, der die Gepflogenheiten der heutigen musikalischen Praxis berücksichtigt, aber auch signifikante Notationsgewohnheiten Weberns (z. B. die Balkenziehung bei Vokalstimmen) beibehält. Der edierte Notentext beruht auf dem Vergleich aller zum Zeitpunkt der Edition zugänglichen Quellen und ihrer kritischen Bewertung. In der Regel wird eine Hauptquelle benannt, deren gegebenenfalls unvollständige, fehlerhafte oder nicht eindeutige Stellen durch die kritisch überprüften Lesarten vorhandener Referenzquellen ergänzt oder korrigiert, falls nötig auch durch Konjekturen geklärt werden. Über die textkonstituierenden Entscheidungen informieren die Textkritischen Anmerkungen im Kritischen Bericht; auf editorische Zusätze im edierten Notentext wie eckige Klammern, Strichelungen und Asterisken wird im Unterschied zu Texteditionen (siehe unten) verzichtet.", + "In den Werkeditionen sind darüber hinaus folgende Bereiche des Notentexts vereinheitlicht:", + "– Die Schreibweise von Titeln und Satznummerierungen. Über abweichende Schreibweisen in den Quellen informiert die Quellenbeschreibung.", + "– Die Instrumentennamen und die Partituranordnung. Die Vereinheitlichung orientiert sich dabei an erkennbaren Gepflogenheiten Weberns. Bei einigen vokal-kammermusikalischen Besetzungen werden die für Webern typischen Partituranordnungen beibehalten (z. B. die einheitliche Setzung der Vokalstimme oberhalb aller Instrumente in op. 14 oder die Zusammenfassung von Klarinette und Gitarre zu einer Gruppe in op. 18). Über abweichende Anordnungen der Instrumente und Schreibweisen der Instrumentennamen in den Quellen informiert die Quellenbeschreibung.", + "– Die Taktzählung wird am Anfang einer Akkolade angegeben. Über in den Quellen vorhandene Taktzahlen informiert die Quellenbeschreibung.", + "– Halsrichtung, Bogenausrichtung und die Position von Spielanweisungen und Tempoangaben werden standardisiert.", + "– Rhythmische Proportionsziffern (von Triolen usw.) werden stillschweigend ergänzt, ihre Position wird standardisiert. Bei Proportionen, die Pausen oder nicht zusammengebalkte Noten einbeziehen, werden verdeutlichende Klammern ebenfalls stillschweigend ergänzt.", + "– Bei Schlüsselwechseln werden rechts vom Taktstrich stehende Schlüssel stillschweigend einheitlich links vor den Taktstrich gesetzt und gegebenenfalls am Ende einer Akkolade als Kustos ergänzt. Bei Taktartwechsel oder Änderung der Tonart im ersten Takt einer Akkolade werden die entsprechenden Vorzeichnungen am Ende der vorhergehenden Akkolade ebenfalls stillschweigend als Kustos ergänzt.", + "– Abkürzungen von Anweisungen wie cresc., dim., pizz. usw. werden in der Regel stillschweigend vereinheitlicht. Bemerkenswerte Schreibweisen (wie z. B. expr. statt espr. [lies: espressivo]) werden in den Textkritischen Anmerkungen erwähnt.", + "Als Texteditionen werden Textfassungen von Kompositionen präsentiert, die über eine bloße ‚Skizzierung‘ hinausgehen, aber keinen eindeutigen Abschluss im Sinne eines im Druck publizierten Werkes erfahren haben: also in der Regel mit Tinte niedergeschriebene Studienkompositionen, Fragmente, aber insbesondere auch Textfassungen von zu einem späteren Zeitpunkt gedruckten Kompositionen, die in einzelnen Aspekten unterschiedlich ausgearbeitet sein können. (Mit Blick auf die ‚lyrische‘ Konzentration vieler Kompositionen Weberns können auch vermeintlich bloß notenorthographische Abweichungen – z. B. in der Balkenziehung – eine eigene Textfassung konstituieren.)", + "Die Texteditionen bieten den Notentext einer bestimmten (in der Regel durch eine oder mehrere handschriftliche Quellen dokumentierten), möglicherweise auch fragmentarischen Textfassung, ohne den Grad der Vollständigkeit und Eindeutigkeit der Werkeditionen anzustreben. Korrekturen und Ergänzungen der Edition erfolgen entweder lediglich in unzweifelhaften Fällen (z. B. bei falschen oder fehlenden Schlüsseln, Pausen usw.) oder dienen als Vorschläge bei nicht eindeutigen Stellen (z. B. bei möglicherweise fehlenden Akzidenzien). Diese editorischen Eingriffe sind durch eckige Klammern, Strichelung oder Asterisk („*“) gekennzeichnet. Ergänzungen werden nur dann in den Textkritischen Anmerkungen erläutert, wenn sie sich nicht durch den gegebenen Kontext erklären; Korrekturen werden grundsätzlich in den Textkritischen Anmerkungen erläutert. Die Texteditionen verwenden im Prinzip die Vereinheitlichungen der Werkeditionen (siehe oben), weichen von diesen aber insbesondere in der Handhabung von uneinheitlichen Schreibweisen bzw. Abkürzungen von Tempo- und Spielanweisungen ab: So werden z. B. die in handschriftlichen Quellen unterschiedlich geschriebenen Anweisungen „Pedal“, „Ped.“ oder „Ped[.]“ übernommen und nicht zu dem für den Druck typischen {{ref.getGlyph('[ped]')}}.-Zeichen vereinheitlicht. Auch andere in den Quellen vorhandene Eigenarten werden – soweit notentypographisch umsetzbar – beibehalten.", + "Die Skizzeneditionen präsentieren diplomatische Transkriptionen von in der Regel mit Bleistift notierten Skizzen, die als inhaltliche Einheiten identifiziert und mit Skizzensiglen versehen werden. Der Ort einer Skizze auf einer oder mehreren Seiten und im Verhältnis zu anderen dort ebenfalls befindlichen Skizzen wird durch Seiten- und Systemangaben, graphische Platzhalter für benachbarte Skizzeneinheiten sowie eine graphische Konvolutübersicht angegeben. Der originale Zeilenfall (Akkoladen- bzw. Seitenwechsel) der Skizzen wird beibehalten. Editorische Zusätze stehen in eckigen Klammern (Schlüssel, Akzidenzien usw.) oder sind kursiv gesetzt (System- und Taktzahlen usw.). Erkennbare Korrekturschichten werden, soweit möglich, durch Kleinstichnotation und andere graphische Unterscheidungen (z. B. Grau- bzw. Farbton) gekennzeichnet. Über die auf diese Weise dargestellten Schichten gibt der Textkritische Kommentar Auskunft. Andere Besonderheiten werden dort ebenfalls beschrieben.", + "Die AWG erscheint in sich gegenseitig ergänzenden und ineinander verschränkten Medien: einerseits als Print-Edition, andererseits als im World Wide Web offen zugängliche Online-Edition. Die Bände der Print-Edition enthalten eine Einleitung zur Entstehung der Kompositionen, die edierten Notentexte als Werkeditionen bzw. Texteditionen und einen in textkritischer Hinsicht substanziellen Auszug des Kritischen Berichts. In der Online-Edition werden ebenfalls die Einleitungen, Texteditionen sowie darüber hinaus die Skizzeneditionen präsentiert. Die vollständigen Kritischen Berichte, insbesondere mit den in der Print-Edition ausgesparten ausführlichen Quellenbeschreibungen, erscheinen ebenfalls online.", + "", + "Weberns Kompositionen werden auf der Grundlage der „Moldenhauer-Nummern“ identifiziert. (Hans und Rosaleen Moldenhauer, Anton von Webern. Chronik seines Lebens und Werkes, Zürich: Atlantis, 1980, S. 639–667. Das entsprechende Verzeichnis der englischen Originalausgabe [Anton von Webern. A Chronicle of His Life and Work, London: Gollancz, 1978 bzw. New York: Knopf, 1979, S. 697–750] weist für M 10 bis M 21 eine in chronologischer Hinsicht fehlerhafte Nummerierung auf, die in der deutschen Übersetzung korrigiert wurde.) Die AWG hat trotz vereinzelter Zweifel an ihrer chronologischen Richtigkeit diese Nummerierung, die die Grundlage zur Strukturierung von Weberns kompositorischem Oeuvre bildet, als AWG-IDs übernommen, erweitert oder modifiziert sie jedoch bei Bedarf. Den von Moldenhauer nicht erfassten Stücken ordnet die AWG ungeachtet der Chronologie eine neue Nummer zu (gekennzeichnet durch ein vorangestelltes „M*“). Zur klaren Abgrenzung von den ursprünglichen 347 Moldenhauer-Nummern beginnen diese ab der Nummer 400. Einen Überblick über alle AWG-IDs bietet die Datenbank der AWG. Die Datenbank umfasst darüber hinaus Informationen zu Werken und zur Biographie Anton Weberns sowie zu weiteren Kontextmaterialien und Forschungsliteratur.", + "Zugang zur AWG-Online-Edition: edition.anton-webern.ch", + " Zugang zur AWG-Datenbank: https://ark.dasch.swiss/ark:/72163/1/0806" + ] + }, + { + "id": "en", + "content": [ + "The Anton Webern Gesamtausgabe (AWG) is a historical-critical complete edition of Anton Webern’s compositions. It is historical in that it documents different versions of the musical text (Textfassungen) plus related sketches for each composition, organized chronologically and grouped together in clusters where the common circumstances of their composition imply that they should be presented together (such clusters are in the German-language documentation of the Anton Webern Gesamtausgabe referred to throughout as Editionskomplexe). The AWG also situates these compositions and their genesis in the context of the composer’s biography and of general music history. It is critical in that it compares all the available sources and examines them critically. It is a complete edition in that it uses the aforementioned critical appraisal of the sources to edit all the recognizable versions and sketches of Webern’s compositions, including those that are extant as fragments. It is a complete edition in that its methodological basis for presenting a musical text presupposes an awareness that such an edition is fundamentally an interpretation of the text to which the sources bear witness.", + "The AWG is divided into three series:", + "Series I  Works with Opus Number", + "Series II Posthumous Compositions and Fragments", + "Series IIIArrangements of Works by Other Composers", + "Each Series comprises five Sections:", + "Section 1Music for Orchestra", + "Section 2Chamber Music and Piano Music", + "Section 3Choral Music", + "Section 4Vocal Music with Ensemble Accompaniment", + "Section 5Songs for Voice and Piano (Series III: Vocal Scores)", + "These five Sections present the different versions and sketches of individual compositions, or compilations of different movements, pieces or songs edited here as coherent clusters where appropriate, grouped overall according to their instrumentation. As far as possible, these clusters will present the different stages of composition inasmuch as the individual chronology can be determined. Titles, opus numbers and individual numberings will be retained as given in the sources, even when these identifying factors have become obsolete in the later stages of composition.", + "Sketches and the different versions of the musical text grouped together here in the aforementioned clusters will be numbered in line with their probable compositional chronology, without the resultant, implicit numbering having any unequivocal claim to describing all possible aspects of the work’s genesis.", + "We here distinguish between three different forms of edition, bearing in mind both the manner in which the different, relevant sources have come down to us, and the different possible interests of those using the AWG:", + "– Work editions (Werkeditionen)", + "– Text editions (Texteditionen)", + "– Sketch editions (Skizzeneditionen)", + "Those versions of the musical text that were published during Webern’s lifetime or were intended for publication are presented here as work editions, i. e. the works numbered from Op. 1 to Op. 31, plus his arrangements of works by other composers that he either published or intended for publication.", + "These work editions offer a complete, unambiguous musical text that takes into account the conventions of today’s musical practice, but that also retains any significant notational habits on Webern’s part (such as the manner in which he notated the beaming in his vocal lines). The musical text edited here is the result of a comparison and critical evaluation of all the sources available to us when making the edition in question. As a rule, we specify one principal source in which any incomplete, erroneous or ambiguous passages have been either supplemented or corrected by means of a critical examination of readings in the extant reference sources; if necessary, such passages are also clarified through conjecture. The Critical Notes (Textkritische Anmerkungen) in the Critical Report provide information on the decisions that have been made when determining the text. In contrast to the text editions (see below), we here forgo editorial additions to the musical text such as square brackets, dotted lines or asterisks.", + "Above and beyond this, the work editions also standardize the following aspects of the musical text:", + "– The spelling of titles and the numbering of movements. The Description of Sources (Quellenbeschreibung) will provide information on any divergent instances in the sources.", + "– The names of instruments and the order of instruments given in the score. We standardize these in line with Webern’s manifest practice. In the case of certain ensembles for voices and instruments, their order in the score is given in the form that was typical for Webern (such as the uniform placement of the vocal part above all the instruments in Op. 14 or the grouping of clarinet and guitar together in Op. 18). The Description of Sources will provide information about any divergent instances in the sources regarding instrument names or the order of instruments in the score.", + "– The measure number is indicated at the beginning of each system. The Description of Sources will provide information about any measure numbers in the sources.", + "– The direction of note stems, the alignment of slurs and the position of playing instructions and tempo indications are similarly standardized.", + "– Proportional numbers for rhythms (for triplets etc.) are added without comment and their position standardized. When such instances include rests or notes that are not beamed together, clarifying brackets are similarly added without comment.", + "– At changes of clef, clefs given to the right of a bar line are here placed uniformly to the left of the bar line in question; where necessary, a cautionary clef may be added at the end of a system. Where the metre or the key signature changes in the first measure of a system, this new key signature or metre is also placed at the end of the preceding system.", + "– As a rule, abbreviations of instructions such as cresc., dim., pizz., etc., are standardized without comment. Notable divergent spellings (such as expr. instead of espr. [meaning “espressivo”]) are mentioned in the Critical Notes.", + "Text editions are versions of the musical text of a composition that go beyond the stage of a mere “sketch” but that have not been concluded unambiguously as is the case with a work that has been published in printed form. In other words, these are generally compositional studies written in ink, fragments, or (indeed especially) versions of the musical text of a composition that was published at a later date but in which specific aspects might have been elaborated differently. (Given the “lyrical” concentration found in many of Webern’s compositions, even certain divergences that seem to affect only the orthography of the musical notation – such as beaming – can in fact constitute a separate version of a musical text).", + "These text editions offer a specific version of a musical text (usually documented by one or more manuscript sources), or quite possibly also a fragmentary version of it, without aiming to achieve the same degree of completeness and unambiguity of the work editions. Corrections and additions in these editions are made only in unequivocal cases (such as incorrect or missing clefs or rests, etc.) or serve as suggestions in ambiguous passages (such as accidentals that appear to be missing). Such editorial interventions are indicated by square brackets, dotted lines or asterisks (“*”). Additions to the text are only explained in the Critical Notes if they are not self-explanatory in their specific context; corrections are always explained there. In principle, these text editions apply the same standardizing principles as the work editions (see above), but deviate from these especially in their treatment of inconsistent spellings or the abbreviations of tempo markings and playing instructions. For example, the instructions “Pedal”, “Ped.” and “Ped[.]”, which are variously written thus in the manuscript sources, have been adopted here and not standardized as the sign {{ref.getGlyph('[ped]')}}. typically used in printed music. Other idiosyncrasies found in the sources have similarly been retained as far as possible in the musical typography utilized here.", + "The sketch editions present diplomatic transcriptions of sketches that have usually been notated in pencil, whose content identifies them as a single unit, and that are here given sketch identifiers variously comprising numbers and letters. The location of a sketch on one or more pages, and its position in relation to other sketches similarly located there, are indicated by page and system references, graphic placeholders for neighbouring sketch units, and a graphic overview of the miscellany in question. The original line breaks in the sketches (system or page changes) have been retained. Editorial additions are given in square brackets (clefs, accidentals, etc.) or italicized (system numbers and bar numbers, etc.). Wherever possible, recognizable layers of corrections are indicated by a smaller music font and other graphic means of distinction (such as being displayed in grey or colour). The Critical Commentary (Textkritscher Kommentar) provides information on the correction layers that are presented in this way. Other special features are also described there.", + "The AWG is being published in mutually complementary, interlinked media, both as a print edition and as an online edition that is openly accessible on the World Wide Web. The printed volumes will contain an introduction providing information on the genesis of the works, editions of the musical texts as either work editions or text editions, and an excerpt from the Critical Report that will provide substantial Critical Notes. The online edition will present the introductions and text editions, but also the sketch editions. The complete Critical Reports, which will includethe extensive Descriptions of Sources that will be omitted from the print edition, will also be published online.", + "", + "Webern’s compositions are identified here on the basis of the “Moldenhauer numbers” (see Hans and Rosaleen Moldenhauer, Anton von Webern. Chronik seines Lebens und Werkes, Zurich: Atlantis, 1980, pp. 639–667. The corresponding worklist of the original English edition [Anton von Webern. A Chronicle of His Life and Work, London: Gollancz, 1978 and New York: Knopf, 1979, pp. 697–750] gives chronologically incorrect numbers for M 10 to M 21, which were corrected in the German translation). Despite occasional doubts about the Moldenhauers’ chronological accuracy, the AWG has adopted their system for its own identifying numbers (“AWG-ID” numbers) while expanding or modifying it where necessary. Those works that Moldenhauer did not list are assigned a new number in the AWG (indicated by a preceding “M*”), regardless of chronology. In order to distinguish these clearly from the original 347 Moldenhauer numbers, these new numbers begin at 400. An overview of all the AWG-ID numbers is provided by the AWG database, which also includes information on Anton Webern’s works and biography and further contextual materials and research literature.", + "Access to the AWG Online Edition: edition.anton-webern.ch", + "Access to the AWG Database: https://ark.dasch.swiss/ark:/72163/1/0806" + ] + } + ] +} diff --git a/src/assets/data/edition/series/1/section/1/op24/textcritics.json b/src/assets/data/edition/series/1/section/1/op24/textcritics.json index 126060324..4ba6043ff 100644 --- a/src/assets/data/edition/series/1/section/1/op24/textcritics.json +++ b/src/assets/data/edition/series/1/section/1/op24/textcritics.json @@ -9,417 +9,422 @@ "rowtable": true, "comments": [ { - "svgGroupId": "text1164", - "measure": "Bl. 1r", - "system": "1a", - "position": "Gf", - "comment": "Reihennummerierung 1 mit rotem Buntstift." - }, - { - "svgGroupId": "g3639", - "measure": "Bl. 1r", - "system": "1a", - "position": "Gf: 4. Reihenton", - "comment": "Kr. d. U. (lies: Krebs der Umkehrung) mit Bleistift überschreibt radierte Schicht." - }, - { - "svgGroupId": "text1166", - "measure": "Bl. 1r", - "system": "1a", - "position": "Gf: 7. Reihenton", - "comment": "Krebs mit Bleistift." - }, - { - "svgGroupId": "g5165", - "measure": "Bl. 1r", - "system": "1a", - "position": "Gf: 10. Reihenton", - "comment": "Umkehrung und 7 mit Bleistift. 7 bezieht sich auf die Entsprechung des 10.–12. Reihentons mit dem ersten Trichord von Gfis (7)." - }, - { - "svgGroupId": "g8248", - "measure": "Bl. 1r", - "system": "1–2", - "position": "Gf: 12. Reihenton, KUg: 1. Reihenton; Uf: 12. Reihenton, Kes: 1. Reihenton", - "comment": "Pfeile mit Bleistift. " - }, - { - "svgGroupId": "text2202", - "measure": "Bl. 1r", - "system": "1b", - "position": "Kes", - "comment": "Reihennummerierung 2 mit rotem Buntstift." - }, - { - "svgGroupId": "text1172", - "measure": "Bl. 1r", - "system": "2a", - "position": "Uf", - "comment": "Reihennummerierung 3 mit rotem Buntstift." - }, - { - "svgGroupId": "g5982", - "measure": "Bl. 1r", - "system": "2a", - "position": "Uf: 6.–11. Reihenton", - "comment": "Auf Rasur, mit Tinte überschrieben." - }, - { - "svgGroupId": "text2204", - "measure": "Bl. 1r", - "system": "2b", - "position": "KUg", - "comment": "Reihennummerierung 4 mit rotem Buntstift." - }, - { - "svgGroupId": "text1174", - "measure": "Bl. 1r", - "system": "3a", - "position": "Gfis", - "comment": "Reihennummerierung 5 mit grünem Buntstift." - }, - { - "svgGroupId": "text2206", - "measure": "Bl. 1r", - "system": "3b", - "position": "Ke", - "comment": "Reihennummerierung 6 mit grünem Buntstift." - }, - { - "svgGroupId": "text1176", - "measure": "Bl. 1r", - "system": "4a", - "position": "Ufis", - "comment": "Reihennummerierung 7 mit grünem Buntstift." - }, - { - "svgGroupId": "text2208", - "measure": "Bl. 1r", - "system": "4b", - "position": "KUgis", - "comment": "Reihennummerierung 8 mit grünem Buntstift." - }, - { - "svgGroupId": "g8832", - "measure": "Bl. 1r", - "system": "4b", - "position": "KUgis: 7.–8. Reihenton", - "comment": "Markierung zwischen h und b mit Bleistift." - }, - { - "svgGroupId": "text1178", - "measure": "Bl. 1r", - "system": "5a", - "position": "Ge", - "comment": "Reihennummerierung 9 mit grünem Buntstift." - }, - { - "svgGroupId": "text2210", - "measure": "Bl. 1r", - "system": "5b", - "position": "Kd", - "comment": "Reihennummerierung 10 mit grünem Buntstift." - }, - { - "svgGroupId": "text1180", - "measure": "Bl. 1r", - "system": "6a", - "position": "Ue", - "comment": "Reihennummerierung 11 mit grünem Buntstift." - }, - { - "svgGroupId": "text2212", - "measure": "Bl. 1r", - "system": "6b", - "position": "KUfis", - "comment": "Reihennummerierung 12 mit grünem Buntstift." - }, - { - "svgGroupId": "text1182", - "measure": "Bl. 1r", - "system": "7a", - "position": "Gg", - "comment": "Reihennummerierung 13 mit blauem Buntstift." - }, - { - "svgGroupId": "text2214", - "measure": "Bl. 1r", - "system": "7b", - "position": "Kf", - "comment": "Reihennummerierung 14 mit blauem Buntstift." - }, - { - "svgGroupId": "text1184", - "measure": "Bl. 1r", - "system": "8a", - "position": "Ug", - "comment": "Reihennummerierung 15 mit blauem Buntstift." - }, - { - "svgGroupId": "text2216", - "measure": "Bl. 1r", - "system": "8b", - "position": "KUa", - "comment": "Reihennummerierung 16 mit blauem Buntstift." - }, - { - "svgGroupId": "text1186", - "measure": "Bl. 1r", - "system": "9a", - "position": "Ges", - "comment": "Reihennummerierung 17 mit blauem Buntstift." - }, - { - "svgGroupId": "text2218", - "measure": "Bl. 1r", - "system": "9b", - "position": "Kdes", - "comment": "Reihennummerierung 18 mit blauem Buntstift." - }, - { - "svgGroupId": "text1188", - "measure": "Bl. 1r", - "system": "10a", - "position": "Ues", - "comment": "Reihennummerierung 19 mit blauem Buntstift." - }, - { - "svgGroupId": "text2220", - "measure": "Bl. 1r", - "system": "10b", - "position": "KUf", - "comment": "Reihennummerierung 20 mit blauem Buntstift." - }, - { - "svgGroupId": "text2230", - "measure": "Bl. 1r", - "system": "10b", - "position": "Kf: 7. Reihenton", - "comment": "25 mit Bleistift. Bezieht sich auf die Entsprechung des 7.–9. Reihentons mit dem ersten Trichord von Gas (25)." - }, - { - "svgGroupId": "text1190", - "measure": "Bl. 1r", - "system": "11a", - "position": "Gh", - "comment": "Reihennummerierung 21 mit Bleistift." - }, - { - "svgGroupId": "text2222", - "measure": "Bl. 1r", - "system": "11b", - "position": "Ka", - "comment": "Reihennummerierung 22 mit Bleistift." - }, - { - "svgGroupId": "text1192", - "measure": "Bl. 1r", - "system": "12a", - "position": "Uh", - "comment": "Reihennummerierung 23 mit Bleistift." - }, - { - "svgGroupId": "text2224", - "measure": "Bl. 1r", - "system": "12b", - "position": "KUcis", - "comment": "Reihennummerierung 24 mit Bleistift." - }, - { - "svgGroupId": "text1030", - "measure": "Bl. 2r", - "system": "1a", - "position": "Gas", - "comment": "Reihennummerierung 25 mit rotem Buntstift." - }, - { - "svgGroupId": "text1838", - "measure": "Bl. 2r", - "system": "1b", - "position": "Kges", - "comment": "Reihennummerierung 26 mit rotem Buntstift." - }, - { - "svgGroupId": "text1032", - "measure": "Bl. 2r", - "system": "2a", - "position": "Uas", - "comment": "Reihennummerierung 27 mit rotem Buntstift." - }, - { - "svgGroupId": "text1840", - "measure": "Bl. 2r", - "system": "2b", - "position": "KUb", - "comment": "Reihennummerierung 28 mit rotem Buntstift." - }, - { - "svgGroupId": "text1054", - "measure": "Bl. 2r", - "system": "3a", - "position": "Gd", - "comment": "Reihennummerierung 29 mit rotem Buntstift." - }, - { - "svgGroupId": "g9145", - "measure": "Bl. 2r", - "system": "3a", - "position": "Gd: 4. Reihenton", - "comment": "Auf Rasur, mit Tinte überschrieben." - }, - { - "svgGroupId": "text1842", - "measure": "Bl. 2r", - "system": "3b", - "position": "Kc", - "comment": "Reihennummerierung 30 mit rotem Buntstift." - }, - { - "svgGroupId": "text1034", - "measure": "Bl. 2r", - "system": "4a", - "position": "Ud", - "comment": "Reihennummerierung 31 mit rotem Buntstift." - }, - { - "svgGroupId": "text1844", - "measure": "Bl. 2r", - "system": "4b", - "position": "KUe", - "comment": "Reihennummerierung 32 mit rotem Buntstift." - }, - { - "svgGroupId": "text1036", - "measure": "Bl. 2r", - "system": "5a", - "position": "Ga", - "comment": "Reihennummerierung 33 mit blauem Buntstift." - }, - { - "svgGroupId": "text1846", - "measure": "Bl. 2r", - "system": "5b", - "position": "Kg", - "comment": "Reihennummerierung 34 mit blauem Buntstift." - }, - { - "svgGroupId": "text1038", - "measure": "Bl. 2r", - "system": "6a", - "position": "Ua", - "comment": "Reihennummerierung 35 mit blauem Buntstift." - }, - { - "svgGroupId": "text1848", - "measure": "Bl. 2r", - "system": "6b", - "position": "KUh", - "comment": "Reihennummerierung 36 mit blauem Buntstift." - }, - { - "svgGroupId": "text1040", - "measure": "Bl. 2r", - "system": "7a", - "position": "Gdes", - "comment": "Reihennummerierung 37 mit blauem Buntstift." - }, - { - "svgGroupId": "text1850", - "measure": "Bl. 2r", - "system": "7b", - "position": "Kh", - "comment": "Reihennummerierung 38 mit blauem Buntstift." - }, - { - "svgGroupId": "text1042", - "measure": "Bl. 2r", - "system": "8a", - "position": "Udes", - "comment": "Reihennummerierung 39 mit blauem Buntstift." - }, - { - "svgGroupId": "text1852", - "measure": "Bl. 2r", - "system": "8b", - "position": "KUes", - "comment": "Reihennummerierung 40 mit blauem Buntstift." - }, - { - "svgGroupId": "text1044", - "measure": "Bl. 2r", - "system": "9a", - "position": "Gb", - "comment": "Reihennummerierung 41 mit Bleistift." - }, - { - "svgGroupId": "text1854", - "measure": "Bl. 2r", - "system": "9b", - "position": "Kas", - "comment": "Reihennummerierung 42 mit Bleistift." - }, - { - "svgGroupId": "text1046", - "measure": "Bl. 2r", - "system": "10a", - "position": "Ub", - "comment": "Reihennummerierung 43 mit Bleistift." - }, - { - "svgGroupId": "text1856", - "measure": "Bl. 2r", - "system": "10b", - "position": "KUc", - "comment": "Reihennummerierung 44 mit Bleistift." - }, - { - "svgGroupId": "text1048", - "measure": "Bl. 2r", - "system": "11a", - "position": "Gc", - "comment": "Reihennummerierung 45 mit Bleistift." - }, - { - "svgGroupId": "g22233", - "measure": "Bl. 2r", - "system": "11a", - "position": "Gc: 9. Reihenton", - "comment": "Auf Rasur, mit Tinte überschrieben." - }, - { - "svgGroupId": "text1858", - "measure": "Bl. 2r", - "system": "11b", - "position": "Kb", - "comment": "Reihennummerierung 46 mit Bleistift." - }, - { - "svgGroupId": "text1050", - "measure": "Bl. 2r", - "system": "12a", - "position": "Uc", - "comment": "Reihennummerierung 47 mit Bleistift." - }, - { - "svgGroupId": "g22969", - "measure": "Bl. 2r", - "system": "12a", - "position": "Uc: 4. Reihenton", - "comment": "Auf Rasur, mit Tinte überschrieben." - }, - { - "svgGroupId": "text1860", - "measure": "Bl. 2r", - "system": "12b", - "position": "KUd", - "comment": "Reihennummerierung 48 mit Bleistift." - }, - { - "svgGroupId": "g15689", - "measure": "Bl. 2r", - "system": "12b", - "position": "KUd: 12. Reihenton", - "comment": "Auf Rasur, mit Tinte überschrieben." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "text1164", + "measure": "Bl. 1r", + "system": "1a", + "position": "Gf", + "comment": "Reihennummerierung 1 mit rotem Buntstift." + }, + { + "svgGroupId": "g3639", + "measure": "Bl. 1r", + "system": "1a", + "position": "Gf: 4. Reihenton", + "comment": "Kr. d. U. (lies: Krebs der Umkehrung) mit Bleistift überschreibt radierte Schicht." + }, + { + "svgGroupId": "text1166", + "measure": "Bl. 1r", + "system": "1a", + "position": "Gf: 7. Reihenton", + "comment": "Krebs mit Bleistift." + }, + { + "svgGroupId": "g5165", + "measure": "Bl. 1r", + "system": "1a", + "position": "Gf: 10. Reihenton", + "comment": "Umkehrung und 7 mit Bleistift. 7 bezieht sich auf die Entsprechung des 10.–12. Reihentons mit dem ersten Trichord von Gfis (7)." + }, + { + "svgGroupId": "g8248", + "measure": "Bl. 1r", + "system": "1–2", + "position": "Gf: 12. Reihenton, KUg: 1. Reihenton; Uf: 12. Reihenton, Kes: 1. Reihenton", + "comment": "Pfeile mit Bleistift. " + }, + { + "svgGroupId": "text2202", + "measure": "Bl. 1r", + "system": "1b", + "position": "Kes", + "comment": "Reihennummerierung 2 mit rotem Buntstift." + }, + { + "svgGroupId": "text1172", + "measure": "Bl. 1r", + "system": "2a", + "position": "Uf", + "comment": "Reihennummerierung 3 mit rotem Buntstift." + }, + { + "svgGroupId": "g5982", + "measure": "Bl. 1r", + "system": "2a", + "position": "Uf: 6.–11. Reihenton", + "comment": "Auf Rasur, mit Tinte überschrieben." + }, + { + "svgGroupId": "text2204", + "measure": "Bl. 1r", + "system": "2b", + "position": "KUg", + "comment": "Reihennummerierung 4 mit rotem Buntstift." + }, + { + "svgGroupId": "text1174", + "measure": "Bl. 1r", + "system": "3a", + "position": "Gfis", + "comment": "Reihennummerierung 5 mit grünem Buntstift." + }, + { + "svgGroupId": "text2206", + "measure": "Bl. 1r", + "system": "3b", + "position": "Ke", + "comment": "Reihennummerierung 6 mit grünem Buntstift." + }, + { + "svgGroupId": "text1176", + "measure": "Bl. 1r", + "system": "4a", + "position": "Ufis", + "comment": "Reihennummerierung 7 mit grünem Buntstift." + }, + { + "svgGroupId": "text2208", + "measure": "Bl. 1r", + "system": "4b", + "position": "KUgis", + "comment": "Reihennummerierung 8 mit grünem Buntstift." + }, + { + "svgGroupId": "g8832", + "measure": "Bl. 1r", + "system": "4b", + "position": "KUgis: 7.–8. Reihenton", + "comment": "Markierung zwischen h und b mit Bleistift." + }, + { + "svgGroupId": "text1178", + "measure": "Bl. 1r", + "system": "5a", + "position": "Ge", + "comment": "Reihennummerierung 9 mit grünem Buntstift." + }, + { + "svgGroupId": "text2210", + "measure": "Bl. 1r", + "system": "5b", + "position": "Kd", + "comment": "Reihennummerierung 10 mit grünem Buntstift." + }, + { + "svgGroupId": "text1180", + "measure": "Bl. 1r", + "system": "6a", + "position": "Ue", + "comment": "Reihennummerierung 11 mit grünem Buntstift." + }, + { + "svgGroupId": "text2212", + "measure": "Bl. 1r", + "system": "6b", + "position": "KUfis", + "comment": "Reihennummerierung 12 mit grünem Buntstift." + }, + { + "svgGroupId": "text1182", + "measure": "Bl. 1r", + "system": "7a", + "position": "Gg", + "comment": "Reihennummerierung 13 mit blauem Buntstift." + }, + { + "svgGroupId": "text2214", + "measure": "Bl. 1r", + "system": "7b", + "position": "Kf", + "comment": "Reihennummerierung 14 mit blauem Buntstift." + }, + { + "svgGroupId": "text1184", + "measure": "Bl. 1r", + "system": "8a", + "position": "Ug", + "comment": "Reihennummerierung 15 mit blauem Buntstift." + }, + { + "svgGroupId": "text2216", + "measure": "Bl. 1r", + "system": "8b", + "position": "KUa", + "comment": "Reihennummerierung 16 mit blauem Buntstift." + }, + { + "svgGroupId": "text1186", + "measure": "Bl. 1r", + "system": "9a", + "position": "Ges", + "comment": "Reihennummerierung 17 mit blauem Buntstift." + }, + { + "svgGroupId": "text2218", + "measure": "Bl. 1r", + "system": "9b", + "position": "Kdes", + "comment": "Reihennummerierung 18 mit blauem Buntstift." + }, + { + "svgGroupId": "text1188", + "measure": "Bl. 1r", + "system": "10a", + "position": "Ues", + "comment": "Reihennummerierung 19 mit blauem Buntstift." + }, + { + "svgGroupId": "text2220", + "measure": "Bl. 1r", + "system": "10b", + "position": "KUf", + "comment": "Reihennummerierung 20 mit blauem Buntstift." + }, + { + "svgGroupId": "text2230", + "measure": "Bl. 1r", + "system": "10b", + "position": "Kf: 7. Reihenton", + "comment": "25 mit Bleistift. Bezieht sich auf die Entsprechung des 7.–9. Reihentons mit dem ersten Trichord von Gas (25)." + }, + { + "svgGroupId": "text1190", + "measure": "Bl. 1r", + "system": "11a", + "position": "Gh", + "comment": "Reihennummerierung 21 mit Bleistift." + }, + { + "svgGroupId": "text2222", + "measure": "Bl. 1r", + "system": "11b", + "position": "Ka", + "comment": "Reihennummerierung 22 mit Bleistift." + }, + { + "svgGroupId": "text1192", + "measure": "Bl. 1r", + "system": "12a", + "position": "Uh", + "comment": "Reihennummerierung 23 mit Bleistift." + }, + { + "svgGroupId": "text2224", + "measure": "Bl. 1r", + "system": "12b", + "position": "KUcis", + "comment": "Reihennummerierung 24 mit Bleistift." + }, + { + "svgGroupId": "text1030", + "measure": "Bl. 2r", + "system": "1a", + "position": "Gas", + "comment": "Reihennummerierung 25 mit rotem Buntstift." + }, + { + "svgGroupId": "text1838", + "measure": "Bl. 2r", + "system": "1b", + "position": "Kges", + "comment": "Reihennummerierung 26 mit rotem Buntstift." + }, + { + "svgGroupId": "text1032", + "measure": "Bl. 2r", + "system": "2a", + "position": "Uas", + "comment": "Reihennummerierung 27 mit rotem Buntstift." + }, + { + "svgGroupId": "text1840", + "measure": "Bl. 2r", + "system": "2b", + "position": "KUb", + "comment": "Reihennummerierung 28 mit rotem Buntstift." + }, + { + "svgGroupId": "text1054", + "measure": "Bl. 2r", + "system": "3a", + "position": "Gd", + "comment": "Reihennummerierung 29 mit rotem Buntstift." + }, + { + "svgGroupId": "g9145", + "measure": "Bl. 2r", + "system": "3a", + "position": "Gd: 4. Reihenton", + "comment": "Auf Rasur, mit Tinte überschrieben." + }, + { + "svgGroupId": "text1842", + "measure": "Bl. 2r", + "system": "3b", + "position": "Kc", + "comment": "Reihennummerierung 30 mit rotem Buntstift." + }, + { + "svgGroupId": "text1034", + "measure": "Bl. 2r", + "system": "4a", + "position": "Ud", + "comment": "Reihennummerierung 31 mit rotem Buntstift." + }, + { + "svgGroupId": "text1844", + "measure": "Bl. 2r", + "system": "4b", + "position": "KUe", + "comment": "Reihennummerierung 32 mit rotem Buntstift." + }, + { + "svgGroupId": "text1036", + "measure": "Bl. 2r", + "system": "5a", + "position": "Ga", + "comment": "Reihennummerierung 33 mit blauem Buntstift." + }, + { + "svgGroupId": "text1846", + "measure": "Bl. 2r", + "system": "5b", + "position": "Kg", + "comment": "Reihennummerierung 34 mit blauem Buntstift." + }, + { + "svgGroupId": "text1038", + "measure": "Bl. 2r", + "system": "6a", + "position": "Ua", + "comment": "Reihennummerierung 35 mit blauem Buntstift." + }, + { + "svgGroupId": "text1848", + "measure": "Bl. 2r", + "system": "6b", + "position": "KUh", + "comment": "Reihennummerierung 36 mit blauem Buntstift." + }, + { + "svgGroupId": "text1040", + "measure": "Bl. 2r", + "system": "7a", + "position": "Gdes", + "comment": "Reihennummerierung 37 mit blauem Buntstift." + }, + { + "svgGroupId": "text1850", + "measure": "Bl. 2r", + "system": "7b", + "position": "Kh", + "comment": "Reihennummerierung 38 mit blauem Buntstift." + }, + { + "svgGroupId": "text1042", + "measure": "Bl. 2r", + "system": "8a", + "position": "Udes", + "comment": "Reihennummerierung 39 mit blauem Buntstift." + }, + { + "svgGroupId": "text1852", + "measure": "Bl. 2r", + "system": "8b", + "position": "KUes", + "comment": "Reihennummerierung 40 mit blauem Buntstift." + }, + { + "svgGroupId": "text1044", + "measure": "Bl. 2r", + "system": "9a", + "position": "Gb", + "comment": "Reihennummerierung 41 mit Bleistift." + }, + { + "svgGroupId": "text1854", + "measure": "Bl. 2r", + "system": "9b", + "position": "Kas", + "comment": "Reihennummerierung 42 mit Bleistift." + }, + { + "svgGroupId": "text1046", + "measure": "Bl. 2r", + "system": "10a", + "position": "Ub", + "comment": "Reihennummerierung 43 mit Bleistift." + }, + { + "svgGroupId": "text1856", + "measure": "Bl. 2r", + "system": "10b", + "position": "KUc", + "comment": "Reihennummerierung 44 mit Bleistift." + }, + { + "svgGroupId": "text1048", + "measure": "Bl. 2r", + "system": "11a", + "position": "Gc", + "comment": "Reihennummerierung 45 mit Bleistift." + }, + { + "svgGroupId": "g22233", + "measure": "Bl. 2r", + "system": "11a", + "position": "Gc: 9. Reihenton", + "comment": "Auf Rasur, mit Tinte überschrieben." + }, + { + "svgGroupId": "text1858", + "measure": "Bl. 2r", + "system": "11b", + "position": "Kb", + "comment": "Reihennummerierung 46 mit Bleistift." + }, + { + "svgGroupId": "text1050", + "measure": "Bl. 2r", + "system": "12a", + "position": "Uc", + "comment": "Reihennummerierung 47 mit Bleistift." + }, + { + "svgGroupId": "g22969", + "measure": "Bl. 2r", + "system": "12a", + "position": "Uc: 4. Reihenton", + "comment": "Auf Rasur, mit Tinte überschrieben." + }, + { + "svgGroupId": "text1860", + "measure": "Bl. 2r", + "system": "12b", + "position": "KUd", + "comment": "Reihennummerierung 48 mit Bleistift." + }, + { + "svgGroupId": "g15689", + "measure": "Bl. 2r", + "system": "12b", + "position": "KUd: 12. Reihenton", + "comment": "Auf Rasur, mit Tinte überschrieben." + } + ] } ] } diff --git a/src/assets/data/edition/series/1/section/2/op22/textcritics.json b/src/assets/data/edition/series/1/section/2/op22/textcritics.json index 515701220..ab911e1a9 100644 --- a/src/assets/data/edition/series/1/section/2/op22/textcritics.json +++ b/src/assets/data/edition/series/1/section/2/op22/textcritics.json @@ -9,298 +9,303 @@ "rowtable": true, "comments": [ { - "svgGroupId": "text752", - "measure": "Bl. 1r", - "system": "1a", - "position": "Gges", - "comment": "Reihennummerierung I. mit rotem Buntstift." - }, - { - "svgGroupId": "g2072", - "measure": "Bl. 1r", - "system": "1b", - "position": "Kc", - "comment": "Reihennummerierung II mit rotem Buntstift, . mit Bleistift." - }, - { - "svgGroupId": "text754", - "measure": "Bl. 1r", - "system": "2a", - "position": "Ufis", - "comment": "Reihennummerierung III mit rotem Buntstift." - }, - { - "svgGroupId": "g2095", - "measure": "Bl. 1r", - "system": "2b", - "position": "KUc", - "comment": "Reihennummerierung IV. mit rotem Buntstift." - }, - { - "svgGroupId": "text756", - "measure": "Bl. 1r", - "system": "3a", - "position": "Gg", - "comment": "Reihennummerierung V mit grünem Buntstift." - }, - { - "svgGroupId": "text1234", - "measure": "Bl. 1r", - "system": "3b", - "position": "Kdes", - "comment": "Reihennummerierung VI mit grünem Buntstift." - }, - { - "svgGroupId": "text758", - "measure": "Bl. 1r", - "system": "4a", - "position": "Ug", - "comment": "Reihennummerierung VII. mit grünem Buntstift." - }, - { - "svgGroupId": "text1236", - "measure": "Bl. 1r", - "system": "4b", - "position": "KUcis", - "comment": "Reihennummerierung VIII mit grünem Buntstift." - }, - { - "svgGroupId": "text760", - "measure": "Bl. 1r", - "system": "5a", - "position": "Gf", - "comment": "Reihennummerierung IX. mit grünem Buntstift." - }, - { - "svgGroupId": "text1237", - "measure": "Bl. 1r", - "system": "5b", - "position": "Kh", - "comment": "Reihennummerierung X mit grünem Buntstift." - }, - { - "svgGroupId": "text762", - "measure": "Bl. 1r", - "system": "6a", - "position": "Uf", - "comment": "Reihennummerierung XI mit grünem Buntstift." - }, - { - "svgGroupId": "text1235", - "measure": "Bl. 1r", - "system": "6b", - "position": "KUh", - "comment": "Reihennummerierung XII mit grünem Buntstift." - }, - { - "svgGroupId": "g2281", - "measure": "Bl. 1r", - "system": "7-8", - "position": "Gc, Kfis, Uc, KUfis", - "comment": "Noten mit schwarzer Tinte." - }, - { - "svgGroupId": "text714", - "measure": "Bl. 2r", - "system": "1a", - "position": "Gas", - "comment": "Reihennummerierung XVII mit rotem Buntstift." - }, - { - "svgGroupId": "text1238", - "measure": "Bl. 2r", - "system": "1b", - "position": "Kd", - "comment": "Reihennummerierung XVIII mit rotem Buntstift." - }, - { - "svgGroupId": "text718", - "measure": "Bl. 2r", - "system": "2a", - "position": "Ugis", - "comment": "Reihennummerierung XIX mit rotem Buntstift." - }, - { - "svgGroupId": "text1240", - "measure": "Bl. 2r", - "system": "2b", - "position": "KUd", - "comment": "Reihennummerierung XX mit rotem Buntstift." - }, - { - "svgGroupId": "text736", - "measure": "Bl. 2r", - "system": "3a", - "position": "Ge", - "comment": "Reihennummerierung 21 mit rotem Buntstift." - }, - { - "svgGroupId": "text1242", - "measure": "Bl. 2r", - "system": "3b", - "position": "Kb", - "comment": "Reihennummerierung 22 mit rotem Buntstift." - }, - { - "svgGroupId": "text757", - "measure": "Bl. 2r", - "system": "4a", - "position": "Ue", - "comment": "Reihennummerierung 23 mit rotem Buntstift." - }, - { - "svgGroupId": "text1244", - "measure": "Bl. 2r", - "system": "4b", - "position": "KUb", - "comment": "Reihennummerierung 24 mit Bleistift." - }, - { - "svgGroupId": "g2043", - "measure": "Bl. 2r", - "system": "5a", - "position": "Gh", - "comment": "Reihennummerierung 25. mit blauem Buntstift, 25 mit Bleistift nachgezogen." - }, - { - "svgGroupId": "g2050", - "measure": "Bl. 2r", - "system": "5b", - "position": "Kf", - "comment": "Reihennummerierung 26 mit blauem Buntstift, mit Bleistift nachgezogen." - }, - { - "svgGroupId": "text750", - "measure": "Bl. 2r", - "system": "6a", - "position": "Uh", - "comment": "Reihennummerierung 27 mit blauem Buntstift." - }, - { - "svgGroupId": "text1248", - "measure": "Bl. 2r", - "system": "6b", - "position": "KUf", - "comment": "Reihennummerierung 28 mit blauem Buntstift." - }, - { - "svgGroupId": "g2059", - "measure": "Bl. 2r", - "system": "7a", - "position": "Gcis", - "comment": "Reihennummerierung 29 mit blauem Buntstift, mit Bleistift nachgezogen." - }, - { - "svgGroupId": "text1250", - "measure": "Bl. 2r", - "system": "7b", - "position": "Kg", - "comment": "Reihennummerierung 30 mit blauem Buntstift." - }, - { - "svgGroupId": "g2067", - "measure": "Bl. 2r", - "system": "8a", - "position": "Ucis", - "comment": "Reihennummerierung 31 mit blauem Buntstift, mit Bleistift nachgezogen." - }, - { - "svgGroupId": "g2075", - "measure": "Bl. 2r", - "system": "8b", - "position": "KUg", - "comment": "Reihennummerierung 32 mit blauem Buntstift, mit Bleistift nachgezogen." - }, - { - "svgGroupId": "text734", - "measure": "Bl. 3r", - "system": "1a", - "position": "Ga", - "comment": "Reihennummerierung 33. mit blauem Buntstift." - }, - { - "svgGroupId": "text1239", - "measure": "Bl. 3r", - "system": "1b", - "position": "Kes", - "comment": "Reihennummerierung 34. mit blauem Buntstift." - }, - { - "svgGroupId": "text738", - "measure": "Bl. 3r", - "system": "2a", - "position": "Ua", - "comment": "Reihennummerierung 35. mit blauem Buntstift." - }, - { - "svgGroupId": "text1241", - "measure": "Bl. 3r", - "system": "2b", - "position": "KUes", - "comment": "Reihennummerierung 36 mit blauem Buntstift." - }, - { - "svgGroupId": "text740", - "measure": "Bl. 3r", - "system": "3a", - "position": "Ges", - "comment": "Reihennummerierung 37. mit blauem Buntstift." - }, - { - "svgGroupId": "text1243", - "measure": "Bl. 3r", - "system": "3b", - "position": "Ka", - "comment": "Reihennummerierung 38 mit blauem Buntstift." - }, - { - "svgGroupId": "text761", - "measure": "Bl. 3r", - "system": "4a", - "position": "Ues", - "comment": "Reihennummerierung 39. mit blauem Buntstift." - }, - { - "svgGroupId": "g2030", - "measure": "Bl. 3r", - "system": "4a", - "position": "Ues: 1. Reihenton", - "comment": "es1 radiert und geändert zu es2." - }, - { - "svgGroupId": "text1245", - "measure": "Bl. 3r", - "system": "4b", - "position": "KUa", - "comment": "Reihennummerierung 40 mit blauem Buntstift." - }, - { - "svgGroupId": "g2012", - "measure": "Bl. 3r", - "system": "5a", - "position": "Gb: 2. Reihenton", - "comment": "{{ref.getGlyph('[a]')}} mit Bleistift nachgezogen." - }, - { - "svgGroupId": "g2041", - "measure": "Bl. 3r", - "system": "5a", - "position": "Gb: 3. Reihenton", - "comment": "{{ref.getGlyph('[#]')}}fis1 mit Bleistift nachgezogen." - }, - { - "svgGroupId": "g2051", - "measure": "Bl. 3r", - "system": "5a", - "position": "Gb: 4. Reihenton", - "comment": "{{ref.getGlyph('[a]')}}a1 mit Bleistift nachgezogen." - }, - { - "svgGroupId": "g2061", - "measure": "Bl. 3r", - "system": "8a", - "position": "Ud", - "comment": "4 in Reihennummerierung 47. überschreibt nicht entzifferbare Schicht." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "text752", + "measure": "Bl. 1r", + "system": "1a", + "position": "Gges", + "comment": "Reihennummerierung I. mit rotem Buntstift." + }, + { + "svgGroupId": "g2072", + "measure": "Bl. 1r", + "system": "1b", + "position": "Kc", + "comment": "Reihennummerierung II mit rotem Buntstift, . mit Bleistift." + }, + { + "svgGroupId": "text754", + "measure": "Bl. 1r", + "system": "2a", + "position": "Ufis", + "comment": "Reihennummerierung III mit rotem Buntstift." + }, + { + "svgGroupId": "g2095", + "measure": "Bl. 1r", + "system": "2b", + "position": "KUc", + "comment": "Reihennummerierung IV. mit rotem Buntstift." + }, + { + "svgGroupId": "text756", + "measure": "Bl. 1r", + "system": "3a", + "position": "Gg", + "comment": "Reihennummerierung V mit grünem Buntstift." + }, + { + "svgGroupId": "text1234", + "measure": "Bl. 1r", + "system": "3b", + "position": "Kdes", + "comment": "Reihennummerierung VI mit grünem Buntstift." + }, + { + "svgGroupId": "text758", + "measure": "Bl. 1r", + "system": "4a", + "position": "Ug", + "comment": "Reihennummerierung VII. mit grünem Buntstift." + }, + { + "svgGroupId": "text1236", + "measure": "Bl. 1r", + "system": "4b", + "position": "KUcis", + "comment": "Reihennummerierung VIII mit grünem Buntstift." + }, + { + "svgGroupId": "text760", + "measure": "Bl. 1r", + "system": "5a", + "position": "Gf", + "comment": "Reihennummerierung IX. mit grünem Buntstift." + }, + { + "svgGroupId": "text1237", + "measure": "Bl. 1r", + "system": "5b", + "position": "Kh", + "comment": "Reihennummerierung X mit grünem Buntstift." + }, + { + "svgGroupId": "text762", + "measure": "Bl. 1r", + "system": "6a", + "position": "Uf", + "comment": "Reihennummerierung XI mit grünem Buntstift." + }, + { + "svgGroupId": "text1235", + "measure": "Bl. 1r", + "system": "6b", + "position": "KUh", + "comment": "Reihennummerierung XII mit grünem Buntstift." + }, + { + "svgGroupId": "g2281", + "measure": "Bl. 1r", + "system": "7-8", + "position": "Gc, Kfis, Uc, KUfis", + "comment": "Noten mit schwarzer Tinte." + }, + { + "svgGroupId": "text714", + "measure": "Bl. 2r", + "system": "1a", + "position": "Gas", + "comment": "Reihennummerierung XVII mit rotem Buntstift." + }, + { + "svgGroupId": "text1238", + "measure": "Bl. 2r", + "system": "1b", + "position": "Kd", + "comment": "Reihennummerierung XVIII mit rotem Buntstift." + }, + { + "svgGroupId": "text718", + "measure": "Bl. 2r", + "system": "2a", + "position": "Ugis", + "comment": "Reihennummerierung XIX mit rotem Buntstift." + }, + { + "svgGroupId": "text1240", + "measure": "Bl. 2r", + "system": "2b", + "position": "KUd", + "comment": "Reihennummerierung XX mit rotem Buntstift." + }, + { + "svgGroupId": "text736", + "measure": "Bl. 2r", + "system": "3a", + "position": "Ge", + "comment": "Reihennummerierung 21 mit rotem Buntstift." + }, + { + "svgGroupId": "text1242", + "measure": "Bl. 2r", + "system": "3b", + "position": "Kb", + "comment": "Reihennummerierung 22 mit rotem Buntstift." + }, + { + "svgGroupId": "text757", + "measure": "Bl. 2r", + "system": "4a", + "position": "Ue", + "comment": "Reihennummerierung 23 mit rotem Buntstift." + }, + { + "svgGroupId": "text1244", + "measure": "Bl. 2r", + "system": "4b", + "position": "KUb", + "comment": "Reihennummerierung 24 mit Bleistift." + }, + { + "svgGroupId": "g2043", + "measure": "Bl. 2r", + "system": "5a", + "position": "Gh", + "comment": "Reihennummerierung 25. mit blauem Buntstift, 25 mit Bleistift nachgezogen." + }, + { + "svgGroupId": "g2050", + "measure": "Bl. 2r", + "system": "5b", + "position": "Kf", + "comment": "Reihennummerierung 26 mit blauem Buntstift, mit Bleistift nachgezogen." + }, + { + "svgGroupId": "text750", + "measure": "Bl. 2r", + "system": "6a", + "position": "Uh", + "comment": "Reihennummerierung 27 mit blauem Buntstift." + }, + { + "svgGroupId": "text1248", + "measure": "Bl. 2r", + "system": "6b", + "position": "KUf", + "comment": "Reihennummerierung 28 mit blauem Buntstift." + }, + { + "svgGroupId": "g2059", + "measure": "Bl. 2r", + "system": "7a", + "position": "Gcis", + "comment": "Reihennummerierung 29 mit blauem Buntstift, mit Bleistift nachgezogen." + }, + { + "svgGroupId": "text1250", + "measure": "Bl. 2r", + "system": "7b", + "position": "Kg", + "comment": "Reihennummerierung 30 mit blauem Buntstift." + }, + { + "svgGroupId": "g2067", + "measure": "Bl. 2r", + "system": "8a", + "position": "Ucis", + "comment": "Reihennummerierung 31 mit blauem Buntstift, mit Bleistift nachgezogen." + }, + { + "svgGroupId": "g2075", + "measure": "Bl. 2r", + "system": "8b", + "position": "KUg", + "comment": "Reihennummerierung 32 mit blauem Buntstift, mit Bleistift nachgezogen." + }, + { + "svgGroupId": "text734", + "measure": "Bl. 3r", + "system": "1a", + "position": "Ga", + "comment": "Reihennummerierung 33. mit blauem Buntstift." + }, + { + "svgGroupId": "text1239", + "measure": "Bl. 3r", + "system": "1b", + "position": "Kes", + "comment": "Reihennummerierung 34. mit blauem Buntstift." + }, + { + "svgGroupId": "text738", + "measure": "Bl. 3r", + "system": "2a", + "position": "Ua", + "comment": "Reihennummerierung 35. mit blauem Buntstift." + }, + { + "svgGroupId": "text1241", + "measure": "Bl. 3r", + "system": "2b", + "position": "KUes", + "comment": "Reihennummerierung 36 mit blauem Buntstift." + }, + { + "svgGroupId": "text740", + "measure": "Bl. 3r", + "system": "3a", + "position": "Ges", + "comment": "Reihennummerierung 37. mit blauem Buntstift." + }, + { + "svgGroupId": "text1243", + "measure": "Bl. 3r", + "system": "3b", + "position": "Ka", + "comment": "Reihennummerierung 38 mit blauem Buntstift." + }, + { + "svgGroupId": "text761", + "measure": "Bl. 3r", + "system": "4a", + "position": "Ues", + "comment": "Reihennummerierung 39. mit blauem Buntstift." + }, + { + "svgGroupId": "g2030", + "measure": "Bl. 3r", + "system": "4a", + "position": "Ues: 1. Reihenton", + "comment": "es1 radiert und geändert zu es2." + }, + { + "svgGroupId": "text1245", + "measure": "Bl. 3r", + "system": "4b", + "position": "KUa", + "comment": "Reihennummerierung 40 mit blauem Buntstift." + }, + { + "svgGroupId": "g2012", + "measure": "Bl. 3r", + "system": "5a", + "position": "Gb: 2. Reihenton", + "comment": "{{ref.getGlyph('[a]')}} mit Bleistift nachgezogen." + }, + { + "svgGroupId": "g2041", + "measure": "Bl. 3r", + "system": "5a", + "position": "Gb: 3. Reihenton", + "comment": "{{ref.getGlyph('[#]')}}fis1 mit Bleistift nachgezogen." + }, + { + "svgGroupId": "g2051", + "measure": "Bl. 3r", + "system": "5a", + "position": "Gb: 4. Reihenton", + "comment": "{{ref.getGlyph('[a]')}}a1 mit Bleistift nachgezogen." + }, + { + "svgGroupId": "g2061", + "measure": "Bl. 3r", + "system": "8a", + "position": "Ud", + "comment": "4 in Reihennummerierung 47. überschreibt nicht entzifferbare Schicht." + } + ] } ] } diff --git a/src/assets/data/edition/series/1/section/2/op27/textcritics.json b/src/assets/data/edition/series/1/section/2/op27/textcritics.json index bf211a431..a854951b2 100644 --- a/src/assets/data/edition/series/1/section/2/op27/textcritics.json +++ b/src/assets/data/edition/series/1/section/2/op27/textcritics.json @@ -9,480 +9,485 @@ "rowtable": true, "comments": [ { - "svgGroupId": "text834", - "measure": "Bl. 1r", - "system": "1a", - "position": "Ges", - "comment": "Reihennummerierung 1 mit rotem Buntstift." - }, - { - "svgGroupId": "g4936", - "measure": "Bl. 1r", - "system": "1a", - "position": "Ges: 2. Reihenton", - "comment": "Ansatz zu Notenkopf ♮h2 mit Bleistift, Hilfslinie mit Tinte, radiert." - }, - { - "svgGroupId": "g6408", - "measure": "Bl. 1r", - "system": "1a", - "position": "Ges: 2.–3. Reihenton", - "comment": "Auf Rasur: vermutlich ♮h1–♭b1 geändert zu ♮h–♭b." - }, - { - "svgGroupId": "g7114", - "measure": "Bl. 1r", - "system": "1a–8a", - "position": "G- und U-Formen: 6.–7. Reihenton", - "comment": "Strich zur Gliederung der Hexachorde mit rotem Buntstift. Vermutlich nachträglich gezogen, da der Strich mit einzelnen Notenköpfen kollidiert." - }, - { - "svgGroupId": "text1252", - "measure": "Bl. 1r", - "system": "1b", - "position": "Kgis", - "comment": "Reihennummerierung 2 mit rotem Buntstift." - }, - { - "svgGroupId": "g7843", - "measure": "Bl. 1r", - "system": "1b–8b", - "position": "K- und KU-Formen: 6.–7. Reihenton", - "comment": "Strich zur Gliederung der Hexachorde mit rotem Buntstift. Vermutlich nachträglich gezogen, da der Strich mit einzelnen Notenköpfen kollidiert." - }, - { - "svgGroupId": "g7880", - "measure": "Bl. 1r", - "system": "1b", - "position": "Kgis: 10.–11. Reihenton", - "comment": "Auf Rasur: vermutlich ♭b1–♮h1 geändert zu ♭b–♮h." - }, - { - "svgGroupId": "text836", - "measure": "Bl. 1r", - "system": "2a", - "position": "Ues", - "comment": "Reihennummerierung 3 mit rotem Buntstift." - }, - { - "svgGroupId": "text1254", - "measure": "Bl. 1r", - "system": "2b", - "position": "KUb", - "comment": "Reihennummerierung 4 mit rotem Buntstift." - }, - { - "svgGroupId": "text701", - "measure": "Bl. 1r", - "system": "3a", - "position": "Ga", - "comment": "Reihennummerierung 5 mit grünem Buntstift (verblasst)." - }, - { - "svgGroupId": "text1256", - "measure": "Bl. 1r", - "system": "3b", - "position": "Kd", - "comment": "Reihennummerierung 6 mit grünem Buntstift (verblasst)." - }, - { - "svgGroupId": "text704", - "measure": "Bl. 1r", - "system": "4a", - "position": "Ua", - "comment": "Reihennummerierung 7 mit grünem Buntstift (verblasst)." - }, - { - "svgGroupId": "text1258", - "measure": "Bl. 1r", - "system": "4b", - "position": "KUe", - "comment": "Reihennummerierung 8 mit grünem Buntstift (verblasst)." - }, - { - "svgGroupId": "text690", - "measure": "Bl. 1r", - "system": "5a", - "position": "Gas", - "comment": "Reihennummerierung 9 mit grünem Buntstift (verblasst)." - }, - { - "svgGroupId": "text1260", - "measure": "Bl. 1r", - "system": "5b", - "position": "Kcis", - "comment": "Reihennummerierung 10 mit grünem Buntstift (verblasst)." - }, - { - "svgGroupId": "text692", - "measure": "Bl. 1r", - "system": "6a", - "position": "Uas", - "comment": "Reihennummerierung 11 mit grünem Buntstift (verblasst)." - }, - { - "svgGroupId": "text1234", - "measure": "Bl. 1r", - "system": "6b", - "position": "KUes", - "comment": "Reihennummerierung 12 mit grünem Buntstift (verblasst)." - }, - { - "svgGroupId": "text694", - "measure": "Bl. 1r", - "system": "7a", - "position": "Gb", - "comment": "Reihennummerierung 13 mit grünem Buntstift (verblasst)." - }, - { - "svgGroupId": "g15850", - "measure": "Bl. 1r", - "system": "7a", - "position": "Gb: 5. Reihenton", - "comment": "Auf Rasur: vermutlich ♯gis1 geändert zu ♭as1." - }, - { - "svgGroupId": "text1262", - "measure": "Bl. 1r", - "system": "7b", - "position": "Kdis", - "comment": "Reihennummerierung 14 mit grünem Buntstift (verblasst)." - }, - { - "svgGroupId": "g16586", - "measure": "Bl. 1r", - "system": "7b", - "position": "Kdis: 8. Reihenton", - "comment": "Auf Rasur: vermutlich ♯gis1 geändert zu ♭as1." - }, - { - "svgGroupId": "text695", - "measure": "Bl. 1r", - "system": "8a", - "position": "Ub", - "comment": "Reihennummerierung 15 mit grünem Buntstift (verblasst)." - }, - { - "svgGroupId": "text1236", - "measure": "Bl. 1r", - "system": "8b", - "position": "KUf", - "comment": "Reihennummerierung 16 mit grünem Buntstift (verblasst)." - }, - { - "svgGroupId": "text680", - "measure": "Bl. 2r", - "system": "1a", - "position": "Ge", - "comment": "Reihennummerierung 17 mit grünem Buntstift." - }, - { - "svgGroupId": "g16543", - "measure": "Bl. 2r", - "system": "1a", - "position": "Ge: 1. Reihenton", - "comment": "Auf Rasur." - }, - { - "svgGroupId": "g4899", - "measure": "Bl. 2r", - "system": "1a–8a", - "position": "G- und U-Formen: 6.–7. Reihenton", - "comment": "Strich zur Gliederung der Hexachorde mit rotem Buntstift. Vermutlich nachträglich gezogen, da der Strich mit einzelnen Notenköpfen kollidiert." - }, - { - "svgGroupId": "text1388", - "measure": "Bl. 2r", - "system": "1b", - "position": "Ka", - "comment": "Reihennummerierung 18 mit grünem Buntstift." - }, - { - "svgGroupId": "g2883", - "measure": "Bl. 2r", - "system": "1b–8b", - "position": "K- und KU-Formen: 6.–7. Reihenton", - "comment": "Strich zur Gliederung der Hexachorde mit rotem Buntstift. Vermutlich nachträglich gezogen, da der Strich mit einzelnen Notenköpfen kollidiert." - }, - { - "svgGroupId": "text682", - "measure": "Bl. 2r", - "system": "2a", - "position": "Ue", - "comment": "Reihennummerierung 19 mit grünem Buntstift." - }, - { - "svgGroupId": "text1390", - "measure": "Bl. 2r", - "system": "2b", - "position": "KUh", - "comment": "Reihennummerierung 20 mit grünem Buntstift." - }, - { - "svgGroupId": "text684", - "measure": "Bl. 2r", - "system": "3a", - "position": "Gd", - "comment": "Reihennummerierung 21 mit grünem Buntstift." - }, - { - "svgGroupId": "text1392", - "measure": "Bl. 2r", - "system": "3b", - "position": "Kg", - "comment": "Reihennummerierung 22 mit grünem Buntstift." - }, - { - "svgGroupId": "text705", - "measure": "Bl. 2r", - "system": "4a", - "position": "Ud", - "comment": "Reihennummerierung 23 mit grünem Buntstift." - }, - { - "svgGroupId": "text1394", - "measure": "Bl. 2r", - "system": "4b", - "position": "KUa", - "comment": "Reihennummerierung 24 mit grünem Buntstift." - }, - { - "svgGroupId": "text696", - "measure": "Bl. 2r", - "system": "5a", - "position": "Gfis", - "comment": "Reihennummerierung 25 mit rotem Buntstift." - }, - { - "svgGroupId": "text1396", - "measure": "Bl. 2r", - "system": "5b", - "position": "Kh", - "comment": "Reihennummerierung 26 mit rotem Buntstift." - }, - { - "svgGroupId": "text698", - "measure": "Bl. 2r", - "system": "6a", - "position": "Ufis", - "comment": "Reihennummerierung 27 mit rotem Buntstift." - }, - { - "svgGroupId": "text1398", - "measure": "Bl. 2r", - "system": "6b", - "position": "KUcis", - "comment": "Reihennummerierung 28 mit rotem Buntstift." - }, - { - "svgGroupId": "text693", - "measure": "Bl. 2r", - "system": "7a", - "position": "Gc", - "comment": "Reihennummerierung 29 mit rotem Buntstift." - }, - { - "svgGroupId": "text1400", - "measure": "Bl. 2r", - "system": "7b", - "position": "Kf", - "comment": "Reihennummerierung 30 mit rotem Buntstift." - }, - { - "svgGroupId": "text702", - "measure": "Bl. 2r", - "system": "8a", - "position": "Uc", - "comment": "Reihennummerierung 31 mit rotem Buntstift." - }, - { - "svgGroupId": "g14355", - "measure": "Bl. 1r", - "system": "8a", - "position": "Uc: 9.–10. Reihenton", - "comment": "Auf Rasur." - }, - { - "svgGroupId": "text1402", - "measure": "Bl. 2r", - "system": "8b", - "position": "KUg", - "comment": "Reihennummerierung 32 mit rotem Buntstift." - }, - { - "svgGroupId": "text697", - "measure": "Bl. 3r", - "system": "1a", - "position": "Gf", - "comment": "Reihennummerierung 33 mit grünem Buntstift." - }, - { - "svgGroupId": "g1443", - "measure": "Bl. 3r", - "system": "1a–8a", - "position": "G- und U-Formen: 6.–7. Reihenton", - "comment": "Strich zur Gliederung der Hexachorde mit rotem Buntstift. Vermutlich nachträglich gezogen, da der Strich mit einzelnen Notenköpfen kollidiert." - }, - { - "svgGroupId": "text1352", - "measure": "Bl. 3r", - "system": "1b", - "position": "Kb", - "comment": "Reihennummerierung 34 mit grünem Buntstift." - }, - { - "svgGroupId": "g1446", - "measure": "Bl. 3r", - "system": "1b–8b", - "position": "K- und KU-Formen: 6.–7. Reihenton", - "comment": "Strich zur Gliederung der Hexachorde mit rotem Buntstift. Vermutlich nachträglich gezogen, da der Strich mit einzelnen Notenköpfen kollidiert." - }, - { - "svgGroupId": "text699", - "measure": "Bl. 3r", - "system": "2a", - "position": "Uf", - "comment": "Reihennummerierung 35 mit grünem Buntstift." - }, - { - "svgGroupId": "text1354", - "measure": "Bl. 3r", - "system": "2b", - "position": "KUc", - "comment": "Reihennummerierung 36 mit grünem Buntstift." - }, - { - "svgGroupId": "text700", - "measure": "Bl. 3r", - "system": "3a", - "position": "Gcis", - "comment": "Reihennummerierung 37 mit grünem Buntstift." - }, - { - "svgGroupId": "text1356", - "measure": "Bl. 3r", - "system": "3b", - "position": "Kfis", - "comment": "Reihennummerierung 38 mit grünem Buntstift." - }, - { - "svgGroupId": "text703", - "measure": "Bl. 3r", - "system": "4a", - "position": "Ucis", - "comment": "Reihennummerierung 39 mit grünem Buntstift." - }, - { - "svgGroupId": "g1457", - "measure": "Bl. 1r", - "system": "4a", - "position": "Ucis: 1. Reihenton", - "comment": "Auf Rasur: vermutlich ♯cis2 geändert zu ♯cis1." - }, - { - "svgGroupId": "text1358", - "measure": "Bl. 3r", - "system": "4b", - "position": "KUas", - "comment": "Reihennummerierung 40 mit grünem Buntstift." - }, - { - "svgGroupId": "text707", - "measure": "Bl. 3r", - "system": "5a", - "position": "Gg", - "comment": "Reihennummerierung 41 mit rotem Buntstift." - }, - { - "svgGroupId": "text1360", - "measure": "Bl. 3r", - "system": "5b", - "position": "Kc", - "comment": "Reihennummerierung 42 mit rotem Buntstift." - }, - { - "svgGroupId": "text706", - "measure": "Bl. 3r", - "system": "6a", - "position": "Ug", - "comment": "Reihennummerierung 43 mit rotem Buntstift." - }, - { - "svgGroupId": "text1362", - "measure": "Bl. 3r", - "system": "6b", - "position": "KUd", - "comment": "Reihennummerierung 44 mit rotem Buntstift." - }, - { - "svgGroupId": "text708", - "measure": "Bl. 3r", - "system": "7a", - "position": "Gh", - "comment": "Reihennummerierung 45 mit rotem Buntstift." - }, - { - "svgGroupId": "text1364", - "measure": "Bl. 3r", - "system": "7b", - "position": "Ke", - "comment": "Reihennummerierung 46 mit rotem Buntstift." - }, - { - "svgGroupId": "text710", - "measure": "Bl. 3r", - "system": "8a", - "position": "Uh", - "comment": "Reihennummerierung 47 mit rotem Buntstift." - }, - { - "svgGroupId": "g2622", - "measure": "Bl. 3r", - "system": "8a", - "position": "Uh: 1. Reihenton", - "comment": "Eingekreist mit Bleistift." - }, - { - "svgGroupId": "g6816", - "measure": "Bl. 3r", - "system": "8a", - "position": "Uh: 2. Reihenton", - "comment": "Auf Rasur: vermutlich ♭es1 geändert zu ♯dis1." - }, - { - "svgGroupId": "g11924", - "measure": "Bl. 3r", - "system": "8a", - "position": "Uh: 7. Reihenton", - "comment": "Auf Rasur: vermutlich ♯gis1 geändert zu ♭as1." - }, - { - "svgGroupId": "text1366", - "measure": "Bl. 3r", - "system": "8b", - "position": "KUfis", - "comment": "Reihennummerierung 48 mit rotem Buntstift." - }, - { - "svgGroupId": "g11188", - "measure": "Bl. 3r", - "system": "8b", - "position": "KUfis: 4.–5. Reihenton", - "comment": "Eingekreist mit Bleistift." - }, - { - "svgGroupId": "g9733", - "measure": "Bl. 3r", - "system": "8b", - "position": "KUfis: 11. Reihenton", - "comment": "Auf Rasur: vermutlich ♭es1 geändert zu ♯dis1." - }, - { - "svgGroupId": "g8997", - "measure": "Bl. 3r", - "system": "8b", - "position": "KUfis: 12. Reihenton", - "comment": "Eingekreist mit Bleistift." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "text834", + "measure": "Bl. 1r", + "system": "1a", + "position": "Ges", + "comment": "Reihennummerierung 1 mit rotem Buntstift." + }, + { + "svgGroupId": "g4936", + "measure": "Bl. 1r", + "system": "1a", + "position": "Ges: 2. Reihenton", + "comment": "Ansatz zu Notenkopf ♮h2 mit Bleistift, Hilfslinie mit Tinte, radiert." + }, + { + "svgGroupId": "g6408", + "measure": "Bl. 1r", + "system": "1a", + "position": "Ges: 2.–3. Reihenton", + "comment": "Auf Rasur: vermutlich ♮h1–♭b1 geändert zu ♮h–♭b." + }, + { + "svgGroupId": "g7114", + "measure": "Bl. 1r", + "system": "1a–8a", + "position": "G- und U-Formen: 6.–7. Reihenton", + "comment": "Strich zur Gliederung der Hexachorde mit rotem Buntstift. Vermutlich nachträglich gezogen, da der Strich mit einzelnen Notenköpfen kollidiert." + }, + { + "svgGroupId": "text1252", + "measure": "Bl. 1r", + "system": "1b", + "position": "Kgis", + "comment": "Reihennummerierung 2 mit rotem Buntstift." + }, + { + "svgGroupId": "g7843", + "measure": "Bl. 1r", + "system": "1b–8b", + "position": "K- und KU-Formen: 6.–7. Reihenton", + "comment": "Strich zur Gliederung der Hexachorde mit rotem Buntstift. Vermutlich nachträglich gezogen, da der Strich mit einzelnen Notenköpfen kollidiert." + }, + { + "svgGroupId": "g7880", + "measure": "Bl. 1r", + "system": "1b", + "position": "Kgis: 10.–11. Reihenton", + "comment": "Auf Rasur: vermutlich ♭b1–♮h1 geändert zu ♭b–♮h." + }, + { + "svgGroupId": "text836", + "measure": "Bl. 1r", + "system": "2a", + "position": "Ues", + "comment": "Reihennummerierung 3 mit rotem Buntstift." + }, + { + "svgGroupId": "text1254", + "measure": "Bl. 1r", + "system": "2b", + "position": "KUb", + "comment": "Reihennummerierung 4 mit rotem Buntstift." + }, + { + "svgGroupId": "text701", + "measure": "Bl. 1r", + "system": "3a", + "position": "Ga", + "comment": "Reihennummerierung 5 mit grünem Buntstift (verblasst)." + }, + { + "svgGroupId": "text1256", + "measure": "Bl. 1r", + "system": "3b", + "position": "Kd", + "comment": "Reihennummerierung 6 mit grünem Buntstift (verblasst)." + }, + { + "svgGroupId": "text704", + "measure": "Bl. 1r", + "system": "4a", + "position": "Ua", + "comment": "Reihennummerierung 7 mit grünem Buntstift (verblasst)." + }, + { + "svgGroupId": "text1258", + "measure": "Bl. 1r", + "system": "4b", + "position": "KUe", + "comment": "Reihennummerierung 8 mit grünem Buntstift (verblasst)." + }, + { + "svgGroupId": "text690", + "measure": "Bl. 1r", + "system": "5a", + "position": "Gas", + "comment": "Reihennummerierung 9 mit grünem Buntstift (verblasst)." + }, + { + "svgGroupId": "text1260", + "measure": "Bl. 1r", + "system": "5b", + "position": "Kcis", + "comment": "Reihennummerierung 10 mit grünem Buntstift (verblasst)." + }, + { + "svgGroupId": "text692", + "measure": "Bl. 1r", + "system": "6a", + "position": "Uas", + "comment": "Reihennummerierung 11 mit grünem Buntstift (verblasst)." + }, + { + "svgGroupId": "text1234", + "measure": "Bl. 1r", + "system": "6b", + "position": "KUes", + "comment": "Reihennummerierung 12 mit grünem Buntstift (verblasst)." + }, + { + "svgGroupId": "text694", + "measure": "Bl. 1r", + "system": "7a", + "position": "Gb", + "comment": "Reihennummerierung 13 mit grünem Buntstift (verblasst)." + }, + { + "svgGroupId": "g15850", + "measure": "Bl. 1r", + "system": "7a", + "position": "Gb: 5. Reihenton", + "comment": "Auf Rasur: vermutlich ♯gis1 geändert zu ♭as1." + }, + { + "svgGroupId": "text1262", + "measure": "Bl. 1r", + "system": "7b", + "position": "Kdis", + "comment": "Reihennummerierung 14 mit grünem Buntstift (verblasst)." + }, + { + "svgGroupId": "g16586", + "measure": "Bl. 1r", + "system": "7b", + "position": "Kdis: 8. Reihenton", + "comment": "Auf Rasur: vermutlich ♯gis1 geändert zu ♭as1." + }, + { + "svgGroupId": "text695", + "measure": "Bl. 1r", + "system": "8a", + "position": "Ub", + "comment": "Reihennummerierung 15 mit grünem Buntstift (verblasst)." + }, + { + "svgGroupId": "text1236", + "measure": "Bl. 1r", + "system": "8b", + "position": "KUf", + "comment": "Reihennummerierung 16 mit grünem Buntstift (verblasst)." + }, + { + "svgGroupId": "text680", + "measure": "Bl. 2r", + "system": "1a", + "position": "Ge", + "comment": "Reihennummerierung 17 mit grünem Buntstift." + }, + { + "svgGroupId": "g16543", + "measure": "Bl. 2r", + "system": "1a", + "position": "Ge: 1. Reihenton", + "comment": "Auf Rasur." + }, + { + "svgGroupId": "g4899", + "measure": "Bl. 2r", + "system": "1a–8a", + "position": "G- und U-Formen: 6.–7. Reihenton", + "comment": "Strich zur Gliederung der Hexachorde mit rotem Buntstift. Vermutlich nachträglich gezogen, da der Strich mit einzelnen Notenköpfen kollidiert." + }, + { + "svgGroupId": "text1388", + "measure": "Bl. 2r", + "system": "1b", + "position": "Ka", + "comment": "Reihennummerierung 18 mit grünem Buntstift." + }, + { + "svgGroupId": "g2883", + "measure": "Bl. 2r", + "system": "1b–8b", + "position": "K- und KU-Formen: 6.–7. Reihenton", + "comment": "Strich zur Gliederung der Hexachorde mit rotem Buntstift. Vermutlich nachträglich gezogen, da der Strich mit einzelnen Notenköpfen kollidiert." + }, + { + "svgGroupId": "text682", + "measure": "Bl. 2r", + "system": "2a", + "position": "Ue", + "comment": "Reihennummerierung 19 mit grünem Buntstift." + }, + { + "svgGroupId": "text1390", + "measure": "Bl. 2r", + "system": "2b", + "position": "KUh", + "comment": "Reihennummerierung 20 mit grünem Buntstift." + }, + { + "svgGroupId": "text684", + "measure": "Bl. 2r", + "system": "3a", + "position": "Gd", + "comment": "Reihennummerierung 21 mit grünem Buntstift." + }, + { + "svgGroupId": "text1392", + "measure": "Bl. 2r", + "system": "3b", + "position": "Kg", + "comment": "Reihennummerierung 22 mit grünem Buntstift." + }, + { + "svgGroupId": "text705", + "measure": "Bl. 2r", + "system": "4a", + "position": "Ud", + "comment": "Reihennummerierung 23 mit grünem Buntstift." + }, + { + "svgGroupId": "text1394", + "measure": "Bl. 2r", + "system": "4b", + "position": "KUa", + "comment": "Reihennummerierung 24 mit grünem Buntstift." + }, + { + "svgGroupId": "text696", + "measure": "Bl. 2r", + "system": "5a", + "position": "Gfis", + "comment": "Reihennummerierung 25 mit rotem Buntstift." + }, + { + "svgGroupId": "text1396", + "measure": "Bl. 2r", + "system": "5b", + "position": "Kh", + "comment": "Reihennummerierung 26 mit rotem Buntstift." + }, + { + "svgGroupId": "text698", + "measure": "Bl. 2r", + "system": "6a", + "position": "Ufis", + "comment": "Reihennummerierung 27 mit rotem Buntstift." + }, + { + "svgGroupId": "text1398", + "measure": "Bl. 2r", + "system": "6b", + "position": "KUcis", + "comment": "Reihennummerierung 28 mit rotem Buntstift." + }, + { + "svgGroupId": "text693", + "measure": "Bl. 2r", + "system": "7a", + "position": "Gc", + "comment": "Reihennummerierung 29 mit rotem Buntstift." + }, + { + "svgGroupId": "text1400", + "measure": "Bl. 2r", + "system": "7b", + "position": "Kf", + "comment": "Reihennummerierung 30 mit rotem Buntstift." + }, + { + "svgGroupId": "text702", + "measure": "Bl. 2r", + "system": "8a", + "position": "Uc", + "comment": "Reihennummerierung 31 mit rotem Buntstift." + }, + { + "svgGroupId": "g14355", + "measure": "Bl. 1r", + "system": "8a", + "position": "Uc: 9.–10. Reihenton", + "comment": "Auf Rasur." + }, + { + "svgGroupId": "text1402", + "measure": "Bl. 2r", + "system": "8b", + "position": "KUg", + "comment": "Reihennummerierung 32 mit rotem Buntstift." + }, + { + "svgGroupId": "text697", + "measure": "Bl. 3r", + "system": "1a", + "position": "Gf", + "comment": "Reihennummerierung 33 mit grünem Buntstift." + }, + { + "svgGroupId": "g1443", + "measure": "Bl. 3r", + "system": "1a–8a", + "position": "G- und U-Formen: 6.–7. Reihenton", + "comment": "Strich zur Gliederung der Hexachorde mit rotem Buntstift. Vermutlich nachträglich gezogen, da der Strich mit einzelnen Notenköpfen kollidiert." + }, + { + "svgGroupId": "text1352", + "measure": "Bl. 3r", + "system": "1b", + "position": "Kb", + "comment": "Reihennummerierung 34 mit grünem Buntstift." + }, + { + "svgGroupId": "g1446", + "measure": "Bl. 3r", + "system": "1b–8b", + "position": "K- und KU-Formen: 6.–7. Reihenton", + "comment": "Strich zur Gliederung der Hexachorde mit rotem Buntstift. Vermutlich nachträglich gezogen, da der Strich mit einzelnen Notenköpfen kollidiert." + }, + { + "svgGroupId": "text699", + "measure": "Bl. 3r", + "system": "2a", + "position": "Uf", + "comment": "Reihennummerierung 35 mit grünem Buntstift." + }, + { + "svgGroupId": "text1354", + "measure": "Bl. 3r", + "system": "2b", + "position": "KUc", + "comment": "Reihennummerierung 36 mit grünem Buntstift." + }, + { + "svgGroupId": "text700", + "measure": "Bl. 3r", + "system": "3a", + "position": "Gcis", + "comment": "Reihennummerierung 37 mit grünem Buntstift." + }, + { + "svgGroupId": "text1356", + "measure": "Bl. 3r", + "system": "3b", + "position": "Kfis", + "comment": "Reihennummerierung 38 mit grünem Buntstift." + }, + { + "svgGroupId": "text703", + "measure": "Bl. 3r", + "system": "4a", + "position": "Ucis", + "comment": "Reihennummerierung 39 mit grünem Buntstift." + }, + { + "svgGroupId": "g1457", + "measure": "Bl. 1r", + "system": "4a", + "position": "Ucis: 1. Reihenton", + "comment": "Auf Rasur: vermutlich ♯cis2 geändert zu ♯cis1." + }, + { + "svgGroupId": "text1358", + "measure": "Bl. 3r", + "system": "4b", + "position": "KUas", + "comment": "Reihennummerierung 40 mit grünem Buntstift." + }, + { + "svgGroupId": "text707", + "measure": "Bl. 3r", + "system": "5a", + "position": "Gg", + "comment": "Reihennummerierung 41 mit rotem Buntstift." + }, + { + "svgGroupId": "text1360", + "measure": "Bl. 3r", + "system": "5b", + "position": "Kc", + "comment": "Reihennummerierung 42 mit rotem Buntstift." + }, + { + "svgGroupId": "text706", + "measure": "Bl. 3r", + "system": "6a", + "position": "Ug", + "comment": "Reihennummerierung 43 mit rotem Buntstift." + }, + { + "svgGroupId": "text1362", + "measure": "Bl. 3r", + "system": "6b", + "position": "KUd", + "comment": "Reihennummerierung 44 mit rotem Buntstift." + }, + { + "svgGroupId": "text708", + "measure": "Bl. 3r", + "system": "7a", + "position": "Gh", + "comment": "Reihennummerierung 45 mit rotem Buntstift." + }, + { + "svgGroupId": "text1364", + "measure": "Bl. 3r", + "system": "7b", + "position": "Ke", + "comment": "Reihennummerierung 46 mit rotem Buntstift." + }, + { + "svgGroupId": "text710", + "measure": "Bl. 3r", + "system": "8a", + "position": "Uh", + "comment": "Reihennummerierung 47 mit rotem Buntstift." + }, + { + "svgGroupId": "g2622", + "measure": "Bl. 3r", + "system": "8a", + "position": "Uh: 1. Reihenton", + "comment": "Eingekreist mit Bleistift." + }, + { + "svgGroupId": "g6816", + "measure": "Bl. 3r", + "system": "8a", + "position": "Uh: 2. Reihenton", + "comment": "Auf Rasur: vermutlich ♭es1 geändert zu ♯dis1." + }, + { + "svgGroupId": "g11924", + "measure": "Bl. 3r", + "system": "8a", + "position": "Uh: 7. Reihenton", + "comment": "Auf Rasur: vermutlich ♯gis1 geändert zu ♭as1." + }, + { + "svgGroupId": "text1366", + "measure": "Bl. 3r", + "system": "8b", + "position": "KUfis", + "comment": "Reihennummerierung 48 mit rotem Buntstift." + }, + { + "svgGroupId": "g11188", + "measure": "Bl. 3r", + "system": "8b", + "position": "KUfis: 4.–5. Reihenton", + "comment": "Eingekreist mit Bleistift." + }, + { + "svgGroupId": "g9733", + "measure": "Bl. 3r", + "system": "8b", + "position": "KUfis: 11. Reihenton", + "comment": "Auf Rasur: vermutlich ♭es1 geändert zu ♯dis1." + }, + { + "svgGroupId": "g8997", + "measure": "Bl. 3r", + "system": "8b", + "position": "KUfis: 12. Reihenton", + "comment": "Eingekreist mit Bleistift." + } + ] } ] } diff --git a/src/assets/data/edition/series/1/section/3/op19/textcritics.json b/src/assets/data/edition/series/1/section/3/op19/textcritics.json index 4587389da..9440d8ba6 100644 --- a/src/assets/data/edition/series/1/section/3/op19/textcritics.json +++ b/src/assets/data/edition/series/1/section/3/op19/textcritics.json @@ -7,74 +7,79 @@ "rowtable": true, "comments": [ { - "svgGroupId": "g1298", - "measure": "Bl. 1r", - "system": "1a", - "position": "Gg", - "comment": "Vertikaler Strich, Reihennummerierung und -bezeichnung Gr. (lies: Grundform) mit rotem Buntstift. I. überschreibt 1." - }, - { - "svgGroupId": "g1311", - "measure": "Bl. 1r", - "system": "1b", - "position": "Kc", - "comment": "Reihennummerierung und -bezeichnung Kr (lies: Krebsform) mit rotem Buntstift. II. überschreibt 2." - }, - { - "svgGroupId": "g1207", - "measure": "Bl. 1r", - "system": "1b", - "position": "Kc: 8.–9. Reihenton", - "comment": " mit rotem Buntstift." - }, - { - "svgGroupId": "g1324", - "measure": "Bl. 1r", - "system": "2a", - "position": "Ug", - "comment": "Reihennummerierung und -bezeichnung U (lies: Umkehrungsform) mit blauem Buntstift." - }, - { - "svgGroupId": "g1337", - "measure": "Bl. 1r", - "system": "2b", - "position": "KUd: 1. Reihenton", - "comment": "Reihennummerierung und -bezeichnung U Kr (lies: Umkehrung der Krebsform) mit blauem Buntstift. IV überschreibt 4." - }, - { - "svgGroupId": "g1355", - "measure": "Bl. 1r", - "system": "4a", - "position": "Gcis", - "comment": "Vertikaler Strich, Reihennummerierung und -bezeichnung Transp. (lies: Transposition der Grundform) mit Kopierstift. 5 gestrichen." - }, - { - "svgGroupId": "g1369", - "measure": "Bl. 1r", - "system": "4b", - "position": "Kges", - "comment": "Reihennummerierung und -bezeichnung Kr Tr (lies: Krebs der transponierten Grundform) mit Kopierstift." - }, - { - "svgGroupId": "g1416", - "measure": "Bl. 1r", - "system": "5a", - "position": "UcisU Tr (lies: Umkehrung der transponierten Grundform) mit grünem Buntstift. 7 mit Bleistift, gestrichen mit grünem Buntstift." - }, - { - "svgGroupId": "g1438", - "measure": "Bl. 1r", - "system": "5b", - "position": "KUgis", - "comment": "Reihennummerierung und -bezeichnung Krebs U Tr (lies: Krebs der Umkehrung der transponierten Grundform) mit grünem Buntstift. 8 mit grünem Buntstift überschreibt 8 mit Bleistift (nachgezogen)." - }, - { - "svgGroupId": "g1318", - "measure": "Bl. 1r", - "system": "5b", - "position": "KUgis: 2.–4.Reihenton", - "comment": "Bogen mit dünnem Bleistift." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1298", + "measure": "Bl. 1r", + "system": "1a", + "position": "Gg", + "comment": "Vertikaler Strich, Reihennummerierung und -bezeichnung Gr. (lies: Grundform) mit rotem Buntstift. I. überschreibt 1." + }, + { + "svgGroupId": "g1311", + "measure": "Bl. 1r", + "system": "1b", + "position": "Kc", + "comment": "Reihennummerierung und -bezeichnung Kr (lies: Krebsform) mit rotem Buntstift. II. überschreibt 2." + }, + { + "svgGroupId": "g1207", + "measure": "Bl. 1r", + "system": "1b", + "position": "Kc: 8.–9. Reihenton", + "comment": " mit rotem Buntstift." + }, + { + "svgGroupId": "g1324", + "measure": "Bl. 1r", + "system": "2a", + "position": "Ug", + "comment": "Reihennummerierung und -bezeichnung U (lies: Umkehrungsform) mit blauem Buntstift." + }, + { + "svgGroupId": "g1337", + "measure": "Bl. 1r", + "system": "2b", + "position": "KUd: 1. Reihenton", + "comment": "Reihennummerierung und -bezeichnung U Kr (lies: Umkehrung der Krebsform) mit blauem Buntstift. IV überschreibt 4." + }, + { + "svgGroupId": "g1355", + "measure": "Bl. 1r", + "system": "4a", + "position": "Gcis", + "comment": "Vertikaler Strich, Reihennummerierung und -bezeichnung Transp. (lies: Transposition der Grundform) mit Kopierstift. 5 gestrichen." + }, + { + "svgGroupId": "g1369", + "measure": "Bl. 1r", + "system": "4b", + "position": "Kges", + "comment": "Reihennummerierung und -bezeichnung Kr Tr (lies: Krebs der transponierten Grundform) mit Kopierstift." + }, + { + "svgGroupId": "g1416", + "measure": "Bl. 1r", + "system": "5a", + "position": "UcisU Tr (lies: Umkehrung der transponierten Grundform) mit grünem Buntstift. 7 mit Bleistift, gestrichen mit grünem Buntstift." + }, + { + "svgGroupId": "g1438", + "measure": "Bl. 1r", + "system": "5b", + "position": "KUgis", + "comment": "Reihennummerierung und -bezeichnung Krebs U Tr (lies: Krebs der Umkehrung der transponierten Grundform) mit grünem Buntstift. 8 mit grünem Buntstift überschreibt 8 mit Bleistift (nachgezogen)." + }, + { + "svgGroupId": "g1318", + "measure": "Bl. 1r", + "system": "5b", + "position": "KUgis: 2.–4.Reihenton", + "comment": "Bogen mit dünnem Bleistift." + } + ] } ] } diff --git a/src/assets/data/edition/series/1/section/5/op12/intro.json b/src/assets/data/edition/series/1/section/5/op12/intro.json index 6558b0660..396f5c04b 100644 --- a/src/assets/data/edition/series/1/section/5/op12/intro.json +++ b/src/assets/data/edition/series/1/section/5/op12/intro.json @@ -17,11 +17,11 @@ "Weberns erste vollendete Komposition nach der zweijährigen Militärzeit ist Gleich und Gleich M 216, dessen Verlaufsskizze in A mit dem 31. März 1917 datiert ist. Nach dem 1903 komponierten Klavierlied Blumengruß M 2084 handelt es sich hier um die zweite Goethe-Vertonung Weberns überhaupt. Eine eingehendere Rezeption dieses Dichters durch Webern vor 1917 ist nicht dokumentiert, auch wenn sich Erwähnungen zur Lektüre sporadisch finden.85 Laut seinem eigenhändigen in den 1910er Jahren begonnenen Bücher- und Notenverzeichnis besaß Webern die folgende Ausgabe: Sämtliche Werke. Jubiläumsausgabe in 40 Bänden, Stuttgart und Berlin: Cotta, [1902–1912].86 Weitere Spuren einer kompositorischen Auseinandersetzung mit Goethe-Texten in diesem zeitlichen Umfeld finden sich in zwei weiteren Skizzen bzw. Fragmenten von 1917 (Gegenwart für Gesang [Bariton?] und Klavier M 220) und 1918 (Cirrus für Gesang und Orchester M 235).'87", "Die Niederschrift der Textfassung 1 von Gleich und Gleich M 216 in C ist vermutlich in zeitlicher Nähe zur Verlaufsskizze entstanden. Sie weist Änderungen im Sinne von Textfassung 2 in F auf, die für die Druckfassung von 1925 erarbeitet wurde. Eine weitere, nicht überarbeitete Niederschrift von Textfassung 1 in D ist u. a. aufgrund der verwendeten lateinischen Schrift für den vertonten Text chronologisch nach C einzuordnen. Über den genauen Zeitpunkt und die Funktion dieser Niederschrift ist nichts bekannt. Die Bezeichnung als „op. 12“ im Titel deutet auf ein Datum frühestens nach April 1920 hin (siehe unten).", "In einem seiner späteren Vorträge „Wege zur neuen Musik“ von Anfang 1932 erwähnt Webern die Einleitungstakte von Gleich und Gleich M 216 als ein Beispiel für die bereits intuitiv erfassten Prinzipien der späteren Zwölftonkomposition, da in jenen alle zwölf Tonhöhenklassen der chromatischen Skala präsentiert werden: „Das Gesetz war uns damals noch nicht bewußt, aber es war längst gefühlt.“88 Seine nächsten vollendeten Goethe-Vertonungen, die Zwei Lieder op. 19, stammen erst von 1925/26. Diese gehören zu seinen ersten ausdrücklichen Zwölftonkompositionen und sind gleichzeitig seine letzten vollendeten auf Texte Goethes.", - "Die Verlaufsskizze in A von Die geheimnisvolle Flöte M 217 ist mit dem 10. April 1917 datiert, schließt zeitlich also unmittelbar an die Beendigung von Gleich und Gleich M 216 an. (In Briefen an Berg, Jalowetz oder Schönberg aus dieser Zeit erwähnt Webern keine dieser beiden Arbeiten.) Der vertonte Text von Die geheimnisvolle Flöte ist eine freie Nachdichtung eines Gedichts des chinesischen Autors Li Tai-po (lies: Li Bai) aus Hans Bethges zuerst 1907 erschienener Sammlung Die chinesische Flöte. Das in Weberns Nachlass erhaltene Exemplar der vierten Auflage des Buches weist den autographen Datumseintrag „3. 12. 12.“ (sein 29. Geburtstag) auf der Rückseite des vorderen Einbanddeckels auf.89 Einige Gedichte dieser Sammlung waren Webern spätestens bereits ein Jahr zuvor als Vorlage von Gustav Mahlers Lied von der Erde bekannt geworden, dessen Uraufführung er am 20. November 1911 in München beigewohnt hatte.90 Er selbst hatte aus Die chinesische Flöte bereits im Februar 1914 das Orchesterlied Die Einsame M 199 komponiert; im Juli 1917 folgte In der Fremde M 223. Diese beiden Lieder wurden später in die Vier Lieder für Gesang und Orchester op. 13 eingegliedert. Darüber hinaus sind zwei weitere unvollendete Entwürfe Weberns auf Texte aus Die Chinesische Flöte überliefert: Nächtliches Bild M 233 (Herbst 1918) und Der Frühlingsregen M 244 (vermutlich 1920).", + "Die Verlaufsskizze in A von Die geheimnisvolle Flöte M 217 ist mit dem 10. April 1917 datiert, schließt zeitlich also unmittelbar an die Beendigung von Gleich und Gleich M 216 an. (In Briefen an Berg, Jalowetz oder Schönberg aus dieser Zeit erwähnt Webern keine dieser beiden Arbeiten.) Der vertonte Text von Die geheimnisvolle Flöte ist eine freie Nachdichtung eines Gedichts des chinesischen Autors Li Tai-po (lies: Li Bai) aus Hans Bethges zuerst 1907 erschienener Sammlung Die chinesische Flöte. Das in Weberns Nachlass erhaltene Exemplar der vierten Auflage des Buches weist den autographen Datumseintrag „3. 12. 12.“ (sein 29. Geburtstag) auf der Rückseite des vorderen Einbanddeckels auf.89 Einige Gedichte dieser Sammlung waren Webern spätestens bereits ein Jahr zuvor als Vorlage von Gustav Mahlers&ngsp;Lied von der Erde bekannt geworden, dessen Uraufführung er am 20. November 1911 in München beigewohnt hatte.90 Er selbst hatte aus Die chinesische Flöte bereits im Februar 1914 das Orchesterlied Die Einsame M 199 komponiert; im Juli 1917 folgte In der Fremde M 223. Diese beiden Lieder wurden später in die Vier Lieder für Gesang und Orchester op. 13 eingegliedert. Darüber hinaus sind zwei weitere unvollendete Entwürfe Weberns auf Texte aus Die Chinesische Flöte überliefert: Nächtliches Bild M 233 (Herbst 1918) und Der Frühlingsregen M 244 (vermutlich 1920).", "Die Grundschicht der Niederschrift von Die geheimnisvolle Flöte M 217 in C (Textfassung „0“) lässt sich nicht mehr eindeutig entziffern. Sie dürfte aber, wie im Falle von Gleich und Gleich M 216 in C, in zeitlicher Nähe zur Verlaufsskizze entstanden sein und weist Änderungen mit Tinte und Bleistift auf. Zusammen mit einem ebenfalls nicht mehr eindeutig zu eruierenden Zwischenstadium erfolgten diese möglicherweise bereits im Sinne von Textfassung 1 in F, die für die Druckfassung von 1925 erarbeitet wurde.", "Die Zusammenstellung der vier Klavierlieder zu einer mit Opuszahl versehenen Sammlung erfolgte spätestens 1920, als Webern in einer vermutlich nach April dieses Jahres für die Universal Edition angefertigten Werkliste auch „4 Klavierlieder“ als „op. 10“ anführt.91 Diese Opuszahl entspricht einer getilgten Zählung auf dem Umschlagblatt von Quelle C, wo sie später zu „op. 12“ korrigiert wurde.92 Diese in Abhängigkeit zur Zählung anderer Werke vorgenommene Änderung erfolgte spätestens Anfang 1921: In einem im Februar erschienenen Artikel von Egon Wellesz werden die Lieder explizit als „opus 12“ angesprochen.93 Die in dieser Publikation enthaltenen Notenbeispiele sind auf der Grundlage von Textfassung 2 von „Der Tag ist vergangen“ M 212 bzw. Textfassung 1 von Gleich und Gleich M 216 angefertigt worden, also vermutlich mit C oder (im Falle von M 216:) D im entsprechenden Korrekturstadium als Vorlage. Im Mai 1922 erschien Textfassung 2 von „Der Tag ist vergangen“ M 212 separat (aber mit Hinweis auf die Zugehörigkeit zu op. 12) als Notenbeilage in den Musikblättern des Anbruch (E). Webern überarbeitete „Der Tag ist vergangen“ M 212 in seinem Handexemplar EH zu Textfassung 3 und Gleich und Gleich M 216 in C zu Textfassung 2. Bis spätestens zum Jahreswechsel 1924/25 erstellte er eine Stichvorlage F der Vier Lieder op. 12, die er in einem Brief an den Direktor der Universal Edition, Emil Hertzka, vom 3. Januar 1925 als eine seiner Arbeiten, die er „derzeit im ‚Vorrat‘ habe“, dem Verlag anbot und offensichtlich kurz darauf übergab.94 Am 12. Juni desselben Jahres sandte er die imprimierte zweite Korrektur des Stiches an den Verlag, am 20. Juni das imprimierte Titelblatt.95 Der Druck G der Vier Lieder op. 12 erschien am 30. September 1925 in einer Auflage von 499 Exemplaren.96", "Eine begeisterte Reaktion erhielt Webern von Alban Berg, der ihm wenige Tage nach dem Erscheinen der Lieder schrieb:", - "Was für eine große Freude hast Du mir, mein Lieber, mit Deinem Op. 12 gemacht! Das ist wiederum – so wie ja alles von Dir – ein echter Webern. Schon die Zusammenstellung der wundervollen Texte u. die Zusammenziehung zu einem Ganzen! Und gar erst die Musik! Ja es erscheint mir, als sähe ich Dich auf ganz neue Weise. Welch ein Ton in dem Strindberg-lied. Und überhaupt welch eine Vielfalt in den 4 Liedern. Das letzte z. Bsp[.]: eine solche Anmuth. Man kann ruhig sagen: die findet sich sonst in der ganzen Musikliteratur nicht wieder –; so ein Lied von Dir ist für mich geradezu ein Freudenspender, ein Spender einer mein ganzes Sein überstrahlenden Freude. Wie wenn an trüben Tagen plötzlich die Sonne hervorbricht u. man gar nicht weiß, warum man plötzlich froh wird.97", + "Was für eine große Freude hast Du mir, mein Lieber, mit Deinem Op. 12 gemacht! Das ist wiederum – so wie ja alles von Dir – ein echter Webern. Schon die Zusammenstellung der wundervollen Texte u. die Zusammenziehung zu einem&ngsp;Ganzen! Und gar erst die Musik! Ja es erscheint mir, als sähe ich Dich auf ganz neue Weise. Welch ein Ton in dem Strindberg-lied. Und überhaupt welch eine Vielfalt in den 4 Liedern. Das letzte z. Bsp[.]: eine solche Anmuth. Man kann ruhig sagen: die findet sich sonst in der ganzen Musikliteratur nicht wieder –; so ein Lied von Dir ist für mich geradezu ein Freudenspender, ein Spender einer mein ganzes Sein überstrahlenden Freude. Wie wenn an trüben Tagen plötzlich die Sonne hervorbricht u. man gar nicht weiß, warum man plötzlich froh wird.97", "Die Uraufführung des gesamten Opus 12 fand am 8. Januar 1927 im kleinen Saal des Musikvereins Wien mit der niederländischen Sängerin Co van Geuns und Eduard Steuermann am Klavier statt. Im selben Konzert wurde Alban Bergs Lyrische Suite durch das Wiener Streichquartett (Kolisch-Quartett) uraufgeführt sowie Johann Sebastian Bachs Konzert für vier Klaviere BWV 1065 unter Weberns Dirigat gespielt.98 Zur Uraufführung seiner Lieder schrieb Webern an Schönberg einige Tage später lapidar: „Am selben Abend wie das Quartett Bergs wurde auch ein Lieder-Opus von mir uraufgeführt. Das gelang sehr gut.“99 Auch in einer positiven Besprechung des Konzerts der Arbeiter-Zeitung steht die Komposition Bergs im Vordergrund, über die Vier Lieder op. 12 heißt es vergleichsweise kurz:", "Viel Erfolg hatten auch neue Lieder von Anton    W e b e r n , die Co van  G e u n s , von Eduard    S t e u e r m a n n    am Klavier geleitet, mit hervorragender Musikalität vortrug. Hier sind kurze lyrische Gedichte in Tonformen gepreßt, deren Zusammensetzung dem unbefangenen Hörer nicht klar sein kann. Er muß sich also an die Ausdruckswerte halten, die reichlich zu finden sind, auch wenn es durch die merkwürdige Führung der Gesangstimme schwer ist, ihr immer zu folgen. Die Lieder wurden wiederholt und dadurch leichter verständlich gemacht.100", "Laut einem Tagebucheintrag Weberns war Gleich und Gleich M 216 bereits im Oktober 1926 von einer „holl.[ändischen] Sängerin“ gesungen worden,101 vermutlich ebenfalls von van Geuns, die einige Zeit nach der Uraufführung der Vier Lieder op. 12 Anfang Januar 1927 auch in Köln mit Liedern von Webern (also wahrscheinlich auch aus op. 12) und von Alexander Zemlinsky auftrat.102 Wie bei den George-Liedern wurde bei mehreren Aufführungen zu Weberns Lebzeiten (und wohl mit dessen Einverständnis bzw. auf seine Anregung hin) wiederholt nur eine Auswahl der Vier Lieder op. 12 gesungen bzw. wurden einzelne Lieder mit solchen aus den George-Liedern op. 3 und op. 4 kombiniert. Nachweisbar sind, neben den erwähnten Aufführungen mit van Geuns, Konzerte an folgenden Daten:", diff --git a/src/assets/data/edition/series/1/section/5/op12/source-description.json b/src/assets/data/edition/series/1/section/5/op12/source-description.json index f410a664f..049a43302 100644 --- a/src/assets/data/edition/series/1/section/5/op12/source-description.json +++ b/src/assets/data/edition/series/1/section/5/op12/source-description.json @@ -1070,46 +1070,51 @@ ], "comments": [ { - "measure": "3–4", - "system": "", - "position": "", - "comment": "Auf Tektur." - }, - { - "measure": "4", - "system": "Klav. o.", - "position": "", - "comment": "Auf Rasur. Ante correcturam: Ganze Pause? Bassschlüssel nach Korrektur hinzugefügt." - }, - { - "measure": "4", - "system": "Klav. u.", - "position": "2. Pause", - "comment": "Auf Rasur. Ante correcturam: es/as." - }, - { - "measure": "13", - "system": "Ges.", - "position": "", - "comment": "{{ref.getGlyph('[ppp]')}} gestrichen oder Tinte zerlaufen?" - }, - { - "measure": "18", - "system": "Ges.", - "position": "3. Note", - "comment": "Auf Rasur." - }, - { - "measure": "22", - "system": "Klav. u.", - "position": "1. Note", - "comment": "{{ref.getGlyph('[b]')}} gestrichen." - }, - { - "measure": "23", - "system": "Klav. o.", - "position": "Taktanfang", - "comment": "Bassschlüssel auf Rasur." + "blockHeader": "", + "blockComments": [ + { + "measure": "3–4", + "system": "", + "position": "", + "comment": "Auf Tektur." + }, + { + "measure": "4", + "system": "Klav. o.", + "position": "", + "comment": "Auf Rasur. Ante correcturam: Ganze Pause? Bassschlüssel nach Korrektur hinzugefügt." + }, + { + "measure": "4", + "system": "Klav. u.", + "position": "2. Pause", + "comment": "Auf Rasur. Ante correcturam: es/as." + }, + { + "measure": "13", + "system": "Ges.", + "position": "", + "comment": "{{ref.getGlyph('[ppp]')}} gestrichen oder Tinte zerlaufen?" + }, + { + "measure": "18", + "system": "Ges.", + "position": "3. Note", + "comment": "Auf Rasur." + }, + { + "measure": "22", + "system": "Klav. u.", + "position": "1. Note", + "comment": "{{ref.getGlyph('[b]')}} gestrichen." + }, + { + "measure": "23", + "system": "Klav. o.", + "position": "Taktanfang", + "comment": "Bassschlüssel auf Rasur." + } + ] } ] }, @@ -1121,40 +1126,45 @@ ], "comments": [ { - "measure": "8", - "system": "Klav. o.", - "position": "3. Note", - "comment": "g/cis1/fis1 ersetzt b/des1/ges1." - }, - { - "measure": "9", - "system": "Klav. u.", - "position": "1. Note", - "comment": "Kreis unter der Note." - }, - { - "measure": "11", - "system": "Klav. u.", - "position": "Taktanfang", - "comment": "{{ref.getGlyph('[#]')}} (zu virtuellem cis) hinzugefügt." - }, - { - "measure": "11", - "system": "Klav.", - "position": "nach 1/4", - "comment": "Viertelpause ergänzt und damit implizit den 2/4-Takt zu einem 3/4-Takt erweitert." - }, - { - "measure": "12", - "system": "Klav. o.", - "position": "4/8", - "comment": "{{ref.getGlyph('[a]')}} zu e2 überschreibt {{ref.getGlyph('[b]')}} zu es2." - }, - { - "measure": "12", - "system": "Klav. u.", - "position": "4/8", - "comment": "Es ersetzt {{ref.getGlyph('[a]')}}F1." + "blockHeader": "", + "blockComments": [ + { + "measure": "8", + "system": "Klav. o.", + "position": "3. Note", + "comment": "g/cis1/fis1 ersetzt b/des1/ges1." + }, + { + "measure": "9", + "system": "Klav. u.", + "position": "1. Note", + "comment": "Kreis unter der Note." + }, + { + "measure": "11", + "system": "Klav. u.", + "position": "Taktanfang", + "comment": "{{ref.getGlyph('[#]')}} (zu virtuellem cis) hinzugefügt." + }, + { + "measure": "11", + "system": "Klav.", + "position": "nach 1/4", + "comment": "Viertelpause ergänzt und damit implizit den 2/4-Takt zu einem 3/4-Takt erweitert." + }, + { + "measure": "12", + "system": "Klav. o.", + "position": "4/8", + "comment": "{{ref.getGlyph('[a]')}} zu e2 überschreibt {{ref.getGlyph('[b]')}} zu es2." + }, + { + "measure": "12", + "system": "Klav. u.", + "position": "4/8", + "comment": "Es ersetzt {{ref.getGlyph('[a]')}}F1." + } + ] } ] } @@ -1748,11 +1758,459 @@ "id": "source_EH", "siglum": "E", "siglumAddendum": "H", - "type": "Handexemplar von E mit Korrekturen Weberns („Der Tag ist vergangen“ M 212: Fassung [2→] 3).", + "type": "Handexemplar von E mit Korrekturen Weberns: „Der Tag ist vergangen“ M 212: Textfassung 2→3.", "location": "CH-Bps, Sammlung Anton Webern, Basel, P IV 29.", "description": { "desc": [ "Siehe E." + ], + "corrections": [ + { + "id": "source_EH_corr", + "label": "Korrekturen in EH (mit Bleistift)", + "description": [ + "Die Beschreibung der Korrekturen bezieht sich auf „Der Tag ist vergangen“ M 212: Textfassung 2." + ], + "comments": [ + { + "blockHeader": "", + "blockComments": [ + { + "measure": "1", + "system": "Klav.", + "position": "1. Note", + "comment": "{{ref.getGlyph('[ppp]')}} geändert zu {{ref.getGlyph('[pp]')}}." + }, + { + "measure": "1", + "system": "Klav. o.", + "position": "1/8–2/4", + "comment": "Crescendogabel zwischen den Systemen gestrichen. Crescendogabel 1–2/8, Decrescendogabel 2/8 bis Taktende über dem System hinzugefügt." + }, + { + "measure": "1
    bis 2", + "system": "Klav. o.", + "position": "1/8
    4/8", + "comment": "Legatobogen geändert zu zwei Legatobögen von T. 1 1/8 bis T. 2 1/8 und T. 2 2.–3. Note." + }, + { + "measure": "2", + "system": "Klav. o.", + "position": "2. Note", + "comment": "zögernd geändert zu rit. - - - (mit Geltungsstrichelung bis Taktende).
    {{ref.getGlyph('[ppp]')}} hinzugefügt." + }, + { + "measure": "3", + "system": "Klav. u.", + "position": "2–3/8", + "comment": "Achtelfähnchen bei 2/8 geändert zu Balken." + }, + { + "measure": "3", + "system": "Ges.", + "position": "6/8", + "comment": "Tenutostrich hinzugefügt." + }, + { + "measure": "3
    bis 5", + "system": "Ges.", + "position": "6/8
    3/8", + "comment": "Zuerst: Bogen über den Noten hinzugefügt.
    Dann: Bogen wieder gestrichen.
    Siehe Korrektur in T. 4 3/8 bis T. 5 3/8." + }, + { + "measure": "4", + "system": "Ges.", + "position": "2–4/8", + "comment": "Crescendogabel gestrichen." + }, + { + "measure": "4", + "system": "Klav.", + "position": "1.–2. Note", + "comment": "Legatobogen und Decrescendogabel hinzugefügt." + }, + { + "measure": "4", + "system": "Ges.", + "position": "3–4/8", + "comment": "Crescendogabel hinzugefügt." + }, + { + "measure": "4
    bis 5", + "system": "Ges.", + "position": "3/8
    3/8", + "comment": "Bogen hinzugefügt.
    Siehe Korrektur in T. 3 6/8 bis T. 5 3/8." + }, + { + "measure": "4", + "system": "Klav. o.", + "position": "letzte Pause", + "comment": "Viertelpause gestrichen." + }, + { + "measure": "4", + "system": "Klav.", + "position": "2. Note", + "comment": "{{ref.getGlyph('[pp]')}} gestrichen." + }, + { + "measure": "5", + "system": "Ges.", + "position": "3–4/8", + "comment": "Achtelfähnchen geändert zu Balken." + }, + { + "measure": "5
    bis 7", + "system": "Ges.", + "position": "4/8
    1/4", + "comment": "Bogen hinzugefügt." + }, + { + "measure": "6", + "system": "Ges.", + "position": "2.–4. Note", + "comment": "Zunächst: Fähnchen bei 3.–4. Note geändert zu Balken über den Noten.
    Dann: Balken bei 2.–4. Note unter den Noten hinzugefügt." + }, + { + "measure": "7", + "system": "Klav. o.", + "position": "2–3/8", + "comment": "Achtelfähnchen geändert zu Balken." + }, + { + "measure": "7", + "system": "Klav.", + "position": "2–3/8", + "comment": "Decrescendogabel hinzugefügt." + }, + { + "measure": "7", + "system": "Klav. u.", + "position": "2–3/8", + "comment": "Achtelfähnchen geändert zu Balken." + }, + { + "measure": "7", + "system": "Ges.", + "position": "2.–3. Note", + "comment": "Achtelfähnchen geändert zu Balken." + }, + { + "measure": "7
    bis 8", + "system": "Ges.", + "position": "2. Note
    1. Note", + "comment": "Bogen hinzugefügt." + }, + { + "measure": "7
    bis 8", + "system": "Ges.", + "position": "3. Note
    nach 1/4", + "comment": "Ende der Crescendogabel T. 7 3. Note verlängert zu T. 8 nach 1/4." + }, + { + "measure": "7
    bis 8", + "system": "Ges.", + "position": "3. Note
    3/8", + "comment": "dis fis e unter den Noten es2–ges2–fes2." + }, + { + "measure": "8", + "system": "Klav. o. u.", + "position": "1.–2. Note", + "comment": "Stacctopunkte überschrieben zu Tenutostrichen." + }, + { + "measure": "8
    bis 9", + "system": "Ges.", + "position": "3/8
    2. Note", + "comment": "Bogen hinzugefügt." + }, + { + "measure": "8
    bis 9", + "system": "Ges.", + "position": "4/8
    2. Note", + "comment": "Ende der Crescendogabel T. 8 4/8 verlängert zu T. 9 2. Note." + }, + { + "measure": "9", + "system": "Klav.", + "position": "1/4", + "comment": "{{ref.getGlyph('[p]')}} geändert zu {{ref.getGlyph('[pp]')}}." + }, + { + "measure": "9", + "system": "Ges.", + "position": "", + "comment": "Drei Vierteltriolen geändert zu triolischer Viertel- und Achtelnote sowie triolischer Achtelpause und Viertelnote." + }, + { + "measure": "9", + "system": "Ges.", + "position": "3. Note", + "comment": "{{ref.getGlyph('[pp]')}} hinzugefügt." + }, + { + "measure": "9
    bis 11", + "system": "Ges.", + "position": "3. Note
    1/4", + "comment": "Bogen hinzugefügt." + }, + { + "measure": "9
    bis 10", + "system": "Klav. u.", + "position": "4/8
    1/4", + "comment": "Legatobogen gestrichen." + }, + { + "measure": "9
    bis 11", + "system": "Klav. u.", + "position": "4/8
    1/4", + "comment": "Legatobogen hinzugefügt." + }, + { + "measure": "10", + "system": "Klav. o.", + "position": "1., 2. Note", + "comment": "Tenutostriche gestrichen." + }, + { + "measure": "10
    bis 11", + "system": "Klav. o.", + "position": "1. Note
    2. Note", + "comment": "Legatobogen hinzugefügt. Siehe Korrektur T. 10 2. Note bis T. 11 2. Note.
    Crescendogabel T. 10 1. Note bis nach 2. Note und Decrescendogabel T. 11 1.–2. Note geändert zu Decrescendogabel T. 10 1. Note bis T. 11 2. Note." + }, + { + "measure": "10", + "system": "Ges.", + "position": "2–4/8", + "comment": "Achtelfähnchen bei 3–4/8 geändert zu Balken." + }, + { + "measure": "10
    bis 11", + "system": "Klav. o.", + "position": "2. Note
    2. Note", + "comment": "Legatobogen gestrichen. Siehe Korrektur T. 10 1. Note bis T. 11 2. Note." + }, + { + "measure": "10", + "system": "Klav. u.", + "position": "2/4", + "comment": "Tenutostrich gestrichen." + }, + { + "measure": "11", + "system": "Klav. o.", + "position": "2. Note", + "comment": "{{ref.getGlyph('[pp]')}} hinzugefügt." + }, + { + "measure": "12", + "system": "", + "position": "Taktanfang", + "comment": "molto (scil: „molto rit.“) gestrichen." + }, + { + "measure": "12/13", + "system": "", + "position": "Taktstrich", + "comment": "Fermaten über Ges. und Klav. o. hinzugefügt." + }, + { + "measure": "13", + "system": "Ges.", + "position": "1/8", + "comment": "Fermate gestrichen." + }, + { + "measure": "13", + "system": "Klav. o.", + "position": "", + "comment": "Fermate gestrichen." + }, + { + "measure": "13", + "system": "Klav. u.", + "position": "1/4", + "comment": "Fermate gestrichen." + }, + { + "measure": "13
    bis 14", + "system": "Ges.", + "position": "2/8
    2. Note?", + "comment": "Bogen hinzugefügt." + }, + { + "measure": "13", + "system": "Ges.", + "position": "5–6/8", + "comment": "Achtelfähnchen geändert zu Balken." + }, + { + "measure": "13", + "system": "Klav. u.", + "position": "3/4", + "comment": "{{ref.getGlyph('[ppp]')}} geändert zu {{ref.getGlyph('[pp]')}}." + }, + { + "measure": "14", + "system": "Ges.", + "position": "1.–3. Note", + "comment": "Achtelfähnchen geändert zu Balken." + }, + { + "measure": "14", + "system": "Klav. (u.)", + "position": "1/8", + "comment": "ohne Pedal gestrichen." + }, + { + "measure": "14", + "system": "Klav. u.", + "position": "1.–2. Note", + "comment": "Decrescendogabel hinzugefügt." + }, + { + "measure": "14", + "system": "Klav. u.", + "position": "2. Note", + "comment": "Decrescendogabel gestrichen." + }, + { + "measure": "14
    bis 15", + "system": "Ges.", + "position": "3. Note
    2/8", + "comment": "Anfang des Bogens geändert von T. 14 3/8." + }, + { + "measure": "14
    bis 15", + "system": "Ges.", + "position": "3. Note
    2/8", + "comment": "Crescendogabel von T. 14 4/8 bis T. 15 1/8 geändert zu T. 14 3. Note bis T. 15 2/8." + }, + { + "measure": "15", + "system": "Ges.", + "position": "2/8–8/16", + "comment": "Zunächst: Fähnchen bei 3.–4. Note geändert zu Balken.
    Dann: Balken bei 2.–4. Note hinzugefügt." + }, + { + "measure": "15", + "system": "Ges.", + "position": "3. Note", + "comment": "{{ref.getGlyph('[pp]')}} gestrichen." + }, + { + "measure": "15
    bis 16", + "system": "Ges.", + "position": "3. Note
    2/4", + "comment": "Crescendogabel T. 15 3.–4. Note und Decrescendogabel T. 16 1–2/4 geändert zu Decrescendogabel.
    Anfang des Bogens T. 16 1/4 geändert zu T. 15 3. Note." + }, + { + "measure": "15", + "system": "Klav. o.", + "position": "1.–2. Note", + "comment": "{{ref.getGlyph('[pp]')}} zu 1. Note gestrichen und Crescendogabel geändert zu Decrescendogabel." + }, + { + "measure": "16", + "system": "Klav.", + "position": "(3/4)", + "comment": "Crescendogabel gestrichen." + }, + { + "measure": "17", + "system": "Klav.", + "position": "Taktanfang bis 1/4", + "comment": "Decrescendogabel von T. 16 hinzugefügt. (E: Akkoladenwechsel nach T. 16.)" + }, + { + "measure": "17", + "system": "Ges.", + "position": "1–4/8", + "comment": "Achtelfähnchen geändert zu Balken." + }, + { + "measure": "17
    bis 18", + "system": "Ges.", + "position": "1/8
    2. Note", + "comment": "Bogen hinzugefügt." + }, + { + "measure": "17", + "system": "Ges.", + "position": "2–3/8", + "comment": "Crescendogabel gestrichen." + }, + { + "measure": "17", + "system": "Klav.", + "position": "2. Note", + "comment": "{{ref.getGlyph('[p]')}} hinzugefügt." + }, + { + "measure": "18", + "system": "Ges.", + "position": "Taktanfang
    bis 2. Note", + "comment": "Decrescendogabel hinzugefügt." + }, + { + "measure": "18", + "system": "Ges.", + "position": "", + "comment": "Drei Vierteltriolen geändert zu Viertel-, Achtelnote as1–ges1 unter einer Triolenklammer und Achtelpause, Viertelnote des1 unter einer Triolenklammer." + }, + { + "measure": "18", + "system": "Ges.", + "position": "3. Note", + "comment": "{{ref.getGlyph('[pp]')}} hinzugefügt." + }, + { + "measure": "18
    bis 21", + "system": "Ges.", + "position": "3. Note", + "comment": "Bogen hinzugefügt." + }, + { + "measure": "19", + "system": "Ges.", + "position": "", + "comment": "{{ref.getGlyph('[pp]')}} gestrichen." + }, + { + "measure": "19", + "system": "Ges.", + "position": "", + "comment": "Ansatz zu Bogen oder Crescendogabel (bis Taktende) gestrichen." + }, + { + "measure": "20", + "system": "Ges.", + "position": "2.–3. Note", + "comment": "Crescendogabel überschrieben zu Decrescendogabel." + }, + { + "measure": "21", + "system": "Klav.", + "position": "2/4", + "comment": "{{ref.getGlyph('[pp]')}} geändert zu {{ref.getGlyph('[p]')}}." + }, + { + "measure": "21
    bis 22", + "system": "Klav.", + "position": "2/4", + "comment": "Decrescendogabel hinzugefügt." + }, + { + "measure": "22", + "system": "Klav.", + "position": "2/4", + "comment": "{{ref.getGlyph('[ppp]')}} geändert zu {{ref.getGlyph('[pp]')}}." + } + ] + } + ] + } ] } }, @@ -2137,6 +2595,763 @@ } ] } + ], + "corrections": [ + { + "id": "source_F_corr", + "label": "Korrekturen in F", + "description": [ + "Die Beschreibung der Korrekturen bezieht sich auf die Textfassungen der Werkedition von Vier Lieder op. 12." + ], + "comments": [ + { + "blockHeader": "I „Der Tag ist vergangen“ M 212", + "blockComments": [ + { + "measure": "1", + "system": "Klav. o.", + "position": "Taktanfang", + "comment": "Rasur über dem System. Ante correcturam: Tempobezeichnung?" + }, + { + "measure": "2", + "system": "Klav. o.", + "position": "2. Note", + "comment": "Rasur über dem System. Ante correcturam: rit.?" + }, + { + "measure": "3", + "system": "Klav. o.", + "position": "Taktanfang", + "comment": "Rasur über dem System. Ante correcturam: tempo?" + }, + { + "measure": "4", + "system": "Klav. u.", + "position": "letzte Note", + "comment": "Auf Rasur." + }, + { + "measure": "5", + "system": "Klav. o.", + "position": "1. Note bis Taktende", + "comment": "Rasur unter dem System. Ante correcturam: Gabel?" + }, + { + "measure": "5
    bis 6", + "system": "Klav. u.", + "position": "1. Note", + "comment": "Rasur unter dem System. Ante correcturam: Gabel?" + }, + { + "measure": "5
    bis 7", + "system": "Ges.", + "position": "4/8
    1/4", + "comment": "Zwei Bögen von T. 5 4/8 bis T. 6 4/16 und von T. 6 3. Note bis T. 7 1/4 über dem System rasiert." + }, + { + "measure": "6", + "system": "Klav. o.", + "position": "1–2/4", + "comment": "Rasur unter dem System. Ante correcturam: Gabel?" + }, + { + "measure": "9", + "system": "Ges.", + "position": "1. Pause, letzte Note", + "comment": "Triolenklammer hinzugefügt mit rotem Buntstift." + }, + { + "measure": "10
    bis 11", + "system": "Klav. o.", + "position": "1. Note
    2. Note", + "comment": "Legatobogen auf Rasur." + }, + { + "measure": "10", + "system": "Klav. u.", + "position": "1/4", + "comment": "Rasur unter dem System. Ende des Bogen von T. 9 letzte Note?" + }, + { + "measure": "10
    bis 11", + "system": "Klav. o.", + "position": "2. Note
    2. Note", + "comment": "Decrescendogabel, {{ref.getGlyph('[pp]')}} auf Rasur." + }, + { + "measure": "11", + "system": "Klav. o.", + "position": "2. Note", + "comment": "Staccatopunkt hinzugefügt mit Bleistift." + }, + { + "measure": "12", + "system": "Ges.", + "position": "", + "comment": "Ganze Pause hinzugefügt mit Bleistift." + }, + { + "measure": "13", + "system": "Ges., Klav.", + "position": "", + "comment": "Fermaten rasiert über Ges. 1/8 und Klav. o. Ganze Pause. Fermaten über Taktstrich vor T. 13 vermutlich danach hinzugefügt." + }, + { + "measure": "15", + "system": "Klav. o.", + "position": "1.–2. Note", + "comment": "Decrescendogabel auf Rasur." + }, + { + "measure": "21", + "system": "Klav. o.", + "position": "", + "comment": "{{ref.getGlyph('[a]')}} zu e1 verändert zu {{ref.getGlyph('[b]')}} zu es1 und Verweislinie zu AW unter der Akkolade mit rotem Buntstift." + }, + { + "measure": "21", + "system": "Klav. u.", + "position": "", + "comment": "Rasur rechts neben g. Ante correcturam: Punktierung?" + }, + { + "measure": "21
    bis 22", + "system": "Klav. o.", + "position": "2/4", + "comment": "Bogen über dem System rasiert." + } + ] + }, + { + "blockHeader": "II Die geheimnisvolle Flöte („An einem Abend“) M 217", + "blockComments": [ + { + "measure": "5", + "system": "Klav. o.", + "position": "1. Note", + "comment": "{{ref.getGlyph('[p]')}} auf Rasur." + }, + { + "measure": "5", + "system": "Klav. o.", + "position": "2. Note", + "comment": "g2 auf Rasur.
    Ende der Decrescendogabel auf Rasur." + }, + { + "measure": "5", + "system": "Ges.", + "position": "4/8", + "comment": "{{ref.getGlyph('[p]')}} auf Rasur.
    Rasur am Notenhals." + }, + { + "measure": "5", + "system": "Ges.", + "position": "6/8", + "comment": "Auf Rasur. Ante correcturam: Untersatz angeglichen?" + }, + { + "measure": "6", + "system": "Klav. u.", + "position": "1. Note", + "comment": "Rasur unter der Note. Ante correcturam: Dynamik?" + }, + { + "measure": "6", + "system": "Klav.", + "position": "2/8–5/16", + "comment": "{{ref.getGlyph('[p]')}}, Decrescendogabel auf Rasur." + }, + { + "measure": "6", + "system": "Klav. u.", + "position": "2. Note", + "comment": "{{ref.getGlyph('[pp]')}} auf Rasur. Rasur unter dem System. Ante correcturam: Dynamik?" + }, + { + "measure": "6", + "system": "Klav. o.", + "position": "4/8", + "comment": "Rasur unter dem System. Ante correcturam: Dynamik?" + }, + { + "measure": "7", + "system": "Ges.", + "position": "1. Note", + "comment": "Rasur rechts neben dem Notenkopf. Ante correcturam: Augmentationspunkt?" + }, + { + "measure": "7", + "system": "Klav. u.", + "position": "2/4", + "comment": "Viertelpause hinzugefügt mit Bleistift." + }, + { + "measure": "7", + "system": "Klav. u.", + "position": "10/16", + "comment": "Rasur über dem System. Ante correcturam: Dynamik?" + }, + { + "measure": "8", + "system": "Klav. u.", + "position": "3/16–2/4", + "comment": "Decrescendogabel auf Rasur. Ante correcturam: Gabelende zuerst bis Taktende?" + }, + { + "measure": "9", + "system": "Klav. o.", + "position": "1/4", + "comment": "Decrescendogabel auf Rasur. Ante correcturam: Gabelanfang zuerst in T. 8 4/8?" + }, + { + "measure": "12
    bis 13", + "system": "Klav.", + "position": "letzte Note", + "comment": "{{ref.getGlyph('[pp]')}}, Decrescendogabel, {{ref.getGlyph('[ppp]')}} auf Rasur. Ante correcturam: Decrescendogabel zuerst über den Taktstrich?" + }, + { + "measure": "13", + "system": "Ges.", + "position": "", + "comment": "Gabeln auf Rasur." + }, + { + "measure": "14", + "system": "Klav. u.", + "position": "2/4", + "comment": "Notenhals auf Rasur." + }, + { + "measure": "14
    bis 16", + "system": "Klav. u.", + "position": "2/4
    2/4", + "comment": "Bogen schwach mit Bleistift: stehengelassene Vorzeichnung? (Siehe auch Korrektur in T. 16 bis 17.)" + }, + { + "measure": "16", + "system": "Ges.", + "position": "5/8 bis Taktende", + "comment": "{{ref.getGlyph('[mp]')}}, Crescendogabel auf Rasur." + }, + { + "measure": "16
    bis 17", + "system": "Klav. u.", + "position": "3/4
    2/4", + "comment": "Bogen schwach mit Bleistift: stehengelassene Vorzeichnung? (Siehe auch Korrektur in T. 14 bis 16.)" + }, + { + "measure": "17", + "system": "Ges.", + "position": "2–3/4", + "comment": "Decrescendogabel auf Rasur. Ante correcturam: Gabelanfang zuerst zu 1/4?" + }, + { + "measure": "17", + "system": "Klav. o.", + "position": "9/16", + "comment": "Rasur über dem System. Ante correcturam: Dynamik?" + }, + { + "measure": "17", + "system": "Klav. o.", + "position": "9–12/16", + "comment": "Rasur unter dem System. Ante correcturam: Gabel?" + }, + { + "measure": "17", + "system": "Klav. u.", + "position": "5–6/8", + "comment": "Rasur unter dem System. Ante correcturam: Dynamik und Gabel?" + }, + { + "measure": "18", + "system": "Ges.", + "position": "1/4", + "comment": "? mit rotem Buntstift: Text fehlt." + }, + { + "measure": "18
    bis 19", + "system": "Klav. u.", + "position": "1/16
    3/4", + "comment": "Rasur über dem System. Ante correcturam: Bogen?" + }, + { + "measure": "18", + "system": "Klav. o.", + "position": "3/4", + "comment": "{{ref.getGlyph('[p]')}} mit Bleistift, mit schwarzer Tinte nachgezogen." + }, + { + "measure": "18
    bis 19", + "system": "Klav. o.", + "position": "3/4
    3. Note", + "comment": "Decrescendogabel auf Rasur." + }, + { + "measure": "19", + "system": "Klav. o.", + "position": "3.–4. Note", + "comment": "{{ref.getGlyph('[pp]')}} und Decrescendogabel mit schwarzer Tinte überschreiben Decrescendogabel mit Bleitstift." + }, + { + "measure": "19
    bis 22", + "system": "Ges.", + "position": "3/4
    2/4", + "comment": "Rasuren über dem System. Ante correcturam: vermutlich Bogen von T. 20 1/4 bis T. 22 2/4.
    (Decrescendogabel in T. 22 auf dieser Rasur.)" + }, + { + "measure": "20", + "system": "Klav. o.", + "position": "1/16–3/8", + "comment": "Rasuren über dem System. Ante correcturam: vermutlich Bogen 1/16–3/8." + }, + { + "measure": "20", + "system": "Klav. u.", + "position": "1/8", + "comment": "Staccatopunkt auf Rasur." + }, + { + "measure": "21", + "system": "Klav. o.", + "position": "1.–4. Note", + "comment": "Crescendogabel mit Bleistift, nachgezogen mit schwarzer Tinte." + }, + { + "measure": "21", + "system": "Ges.", + "position": "letzte Note", + "comment": "des2 auf Rasur." + }, + { + "measure": "22", + "system": "Klav. o.", + "position": "1. Note", + "comment": "Auf Rasur. (Untersatz geändert.)
    {{ref.getGlyph('[p]')}} mit Bleistift, nachgezogen mit schwarzer Tinte." + }, + { + "measure": "22", + "system": "Klav. o.", + "position": "1.–3. Note", + "comment": "Rasur unter dem System. Ante correcturam: Decrescendogabel bereits ab 1. Note?" + }, + { + "measure": "22", + "system": "Ges.", + "position": "5/8", + "comment": "{{ref.getGlyph('[p]')}} mit Bleistift, mit schwarzer Tinte nachgezogen." + }, + { + "measure": "23
    bis 24", + "system": "Ges., Klav.", + "position": "Taktanfang", + "comment": "Auf Rasur. (Untersatzkorrektur?)" + }, + { + "measure": "25–27", + "system": "Klav. u.", + "position": "", + "comment": "Rasuren unter dem System." + }, + { + "measure": "25
    bis 26", + "system": "Klav. o.", + "position": "3/8
    2. Note", + "comment": "Rasuren über dem System. Ante correcturam: Bogen bis T. 26 2. Note?" + }, + { + "measure": "25
    bis 26", + "system": "Klav.", + "position": "2/4
    Taktende", + "comment": "{{ref.getGlyph('[pp]')}}, Decrescendogabel auf Rasur." + }, + { + "measure": "27", + "system": "Klav.", + "position": "", + "comment": "{{ref.getGlyph('[ppp]')}}, Decrescendogabel auf Rasur." + }, + { + "measure": "27", + "system": "Klav. u.", + "position": "", + "comment": "Augmentationspunkt hinzugefügt mit Bleistift." + } + ] + }, + { + "blockHeader": "III „Schien mir’s, als ich sah die Sonne“ M 213", + "blockComments": [ + { + "measure": "4", + "system": "Ges.", + "position": "5–6/16", + "comment": "Sechzehntelpause auf Rasur. Ante correcturam: Achtelnote d2." + }, + { + "measure": "5", + "system": "Klav. o.", + "position": "2/16–2/8", + "comment": "Decrescendogabel auf Rasur." + }, + { + "measure": "5", + "system": "Klav.", + "position": "3–6/16", + "comment": "Rasur über den Noten." + }, + { + "measure": "6", + "system": "Klav. u.", + "position": "", + "comment": "Rasuren neben den Notenköpfen. Ante correcturam: punktierte Viertelnote." + }, + { + "measure": "8", + "system": "Klav. u.", + "position": "2–3/8", + "comment": "{{ref.getGlyph('[pp]')}}, Decrescendogabel auf Rasur." + }, + { + "measure": "8", + "system": "Ges.", + "position": "6/16", + "comment": "[Son-]ne! geändert zu [Son-]ne,, ! rasiert, Komma mit Bleistift." + }, + { + "measure": "11", + "system": "Klav. o.", + "position": "2/8–6/16", + "comment": "Rasuren. Ante correcturam: vermutlich zwei zusammengebalkte Achtelnoten?" + }, + { + "measure": "11", + "system": "Ges.", + "position": "3/8", + "comment": ": (?) überschrieben zu ; mit Bleistift." + }, + { + "measure": "12", + "system": "", + "position": "Taktanfang", + "comment": "tempo auf Rasur. Ante correcturam: Geltungsstrichelung von rit. in T. 11 bis Ende T. 12?" + }, + { + "measure": "14", + "system": "Klav. o.", + "position": "1., 2. Note", + "comment": "Rasuren über den Noten." + }, + { + "measure": "15
    bis 16", + "system": "Ges.", + "position": "3/8
    Taktende", + "comment": "Rasur unter den Noten. Ante correcturam: Bogen unter den Noten." + }, + { + "measure": "16", + "system": "", + "position": "", + "comment": "Geltungsstrichelung von rit. auf Rasur." + }, + { + "measure": "16", + "system": "Klav. o.", + "position": "2. Note", + "comment": "Rasuren über der Note." + }, + { + "measure": "17–18", + "system": "", + "position": "", + "comment": "Taktartvorzeichnung vor T. 17: 5/8 überschrieben zu 2/8 sowie Taktstrich nach T. 17 und Taktartvorzeichnung vor T. 18 (3/8) hinzugefügt." + }, + { + "measure": "17", + "system": "Klav. o.", + "position": "Taktanfang", + "comment": "Bassschlüssel auf Rasur. Ante correcturam: Violinschlüssel." + }, + { + "measure": "20–21", + "system": "", + "position": "", + "comment": "Taktartvorzeichnung vor T. 20: 5/8 überschrieben zu 2/8 sowie Taktstrich nach T. 20 hinzugefügt und Untersatz am Anfang von T. 21 geändert auf Rasur." + }, + { + "measure": "21", + "system": "Klav. u.", + "position": "4/16", + "comment": "Rasur über dem System." + }, + { + "measure": "22", + "system": "Ges.", + "position": "2/16", + "comment": "dis2 auf Rasur." + }, + { + "measure": "23", + "system": "Klav. o.", + "position": "1–2/8", + "comment": "Crescendogabel auf Rasur." + }, + { + "measure": "23", + "system": "Ges.", + "position": "2/16–12/32", + "comment": "Gabeln auf Rasur." + }, + { + "measure": "24", + "system": "Klav. u.", + "position": "1. Note", + "comment": "{{ref.getGlyph('[p]')}} auf Rasur." + }, + { + "measure": "24
    bis 25", + "system": "Ges.", + "position": "1. Note
    letzte Note", + "comment": "Rasuren über dem System. Decrescendogabel in T. 25 3.–4. Note auf Rasur." + }, + { + "measure": "25", + "system": "Klav. u.", + "position": "1. Note", + "comment": "{{ref.getGlyph('[p]')}} auf Rasur." + }, + { + "measure": "25", + "system": "", + "position": "(2/8)", + "comment": "rit.- - - gestrichen mit Bleistift. (Siehe Korrektur in T. 26 Taktanfang.)" + }, + { + "measure": "25", + "system": "Klav. o.", + "position": "3/8", + "comment": "{{ref.getGlyph('[mf]')}} auf Rasur." + }, + { + "measure": "26", + "system": "", + "position": "Taktanfang", + "comment": "Taktartvorzeichnung 4/8 überschrieben zu 2/4.
    rit. hinzugefügt mit Bleistift. (Siehe Korrektur in T. 25 [2/8].)" + }, + { + "measure": "26", + "system": "Klav. u.", + "position": "1–2/8", + "comment": "Auf Rasur." + }, + { + "measure": "26", + "system": "Ges.", + "position": "1.–4. Note", + "comment": "Gabeln mit Bleistift, radiert und mit schwarzer Tinte nachgezogen." + }, + { + "measure": "26", + "system": "Klav. o.", + "position": "3.–4. Note", + "comment": "Ende der Decrescendogabel auf Rasur." + }, + { + "measure": "26", + "system": "Klav. u.", + "position": "8/16", + "comment": "{{ref.getGlyph('[p]')}} auf Rasur." + }, + { + "measure": "27
    bis 28", + "system": "Ges.", + "position": "2/16
    2/8", + "comment": "Rasur über den Noten. Ante correcturam: Bogen von T. 27 2/16 bis T. 28 2/8." + }, + { + "measure": "28", + "system": "Ges.", + "position": "1–2/8", + "comment": "Bogen auf Rasur." + }, + { + "measure": "28
    bis 29", + "system": "Ges.", + "position": "3. Note
    2. Note", + "comment": "Rasur über den Noten. Ante correcturam: Bogen von T. 28 3. Note bis T. 29 2. Note." + }, + { + "measure": "30", + "system": "", + "position": "Taktanfang", + "comment": "accell. auf Rasur. Ante correcturam: vermutlich durchgehende Geltungsstrichelung von rit. in T. 28 3/8 bis Ende T. 31?" + }, + { + "measure": "30", + "system": "Klav.", + "position": "1/8", + "comment": "Achtelpausen auf Rasur." + }, + { + "measure": "30", + "system": "Klav. o.", + "position": "vor 2/8", + "comment": "Violinschlüssel auf Rasur." + }, + { + "measure": "33", + "system": "Klav.", + "position": "4/32–4/16", + "comment": "Auf Rasur." + }, + { + "measure": "34", + "system": "", + "position": "Taktanfang", + "comment": "Taktartvorzeichnung 4/8 überschrieben zu 2/4.
    Geltungsstrichelung auf Rasur." + }, + { + "measure": "34", + "system": "Klav. o.", + "position": "1/4", + "comment": "Oberstimmenschicht: Viertelpause auf Rasur." + }, + { + "measure": "34–36", + "system": "Klav. o.", + "position": "", + "comment": "Rasur zwischen den Stimmenschichten. Ante correcturam: Trillerwellenlinie über a aus Unterstimmenschicht?" + }, + { + "measure": "35", + "system": "", + "position": "Taktanfang", + "comment": "sehr ruhig ([Achtel] = ca 100) auf Rasur." + }, + { + "measure": "38–40", + "system": "", + "position": "", + "comment": "rit. - - - mit Bleistift, nachgezogen mit schwarzer Tinte." + } + ] + }, + { + "blockHeader": "IV Gleich und Gleich („Ein Blumenglöckchen“) M 216", + "blockComments": [ + { + "measure": "2", + "system": "Klav. o.", + "position": "2.–4. Note", + "comment": "Decrescendogabel hinzugefügt mit Bleistift." + }, + { + "measure": "3", + "system": "Ges.", + "position": "1–2/4", + "comment": "Viertelpausen und Fermate zu 2/4 hinzugefügt mit Bleistift." + }, + { + "measure": "8
    bis 9", + "system": "Klav. u.", + "position": "1/4", + "comment": "e/g auf Rasur." + }, + { + "measure": "9
    bis 10", + "system": "Klav. o.", + "position": "2/8
    2/8", + "comment": "Notenköpfe mit Bleistift nachgezogen.
    Gabeln (über dem System) auf Rasur. Ante correcturam: Bogen über dem System. Post correcturam: Bogen unter dem System." + }, + { + "measure": "9
    bis 10", + "system": "Klav. u.", + "position": "2. Note", + "comment": "Bogen rasiert." + }, + { + "measure": "10
    bis 11", + "system": "Ges.", + "position": "2/4
    1. Note", + "comment": "Rasur über dem System. Ante correcturam: Bogen und Decrescendogabel überschneiden sich." + }, + { + "measure": "11", + "system": "Klav. u.", + "position": "1/8", + "comment": "Rasur über der Note." + }, + { + "measure": "11", + "system": "", + "position": "3/4", + "comment": "rit. vermutlich versetzt von Anfang T. 12. (Dort Geltungsstrichelung auf Rasur)." + }, + { + "measure": "12", + "system": "Klav. u.", + "position": "1/4", + "comment": "Auf Rasur." + }, + { + "measure": "13", + "system": "Klav. o.", + "position": "", + "comment": "g2/ges3/ais3, zweite Hilfslinie gestrichen und Tonnamen fis | es vor den beiden obersten Notenköpfen ergänzt mit Bleistift." + }, + { + "measure": "15", + "system": "Klav. o.", + "position": "1/4", + "comment": "Unterstimmenschicht: Viertelpause auf Rasur." + }, + { + "measure": "15", + "system": "Klav. o.", + "position": "2/8", + "comment": "{{ref.getGlyph('[f]')}} mit Bleistift, mit schwarzer Tinte nachgezogen." + }, + { + "measure": "15", + "system": "Klav. o.", + "position": "2–6/8", + "comment": "Rasur unter dem System." + }, + { + "measure": "16", + "system": "Ges.", + "position": "", + "comment": "Ganze Pause hinzugefügt mit Bleistift." + }, + { + "measure": "16", + "system": "Klav.", + "position": "1.–2. Note", + "comment": "{{ref.getGlyph('[p]')}}, Decrescendogabel auf Rasur." + }, + { + "measure": "16", + "system": "Klav.", + "position": "", + "comment": "Auf Rasur. Ante correcturam: Klav. u. und Klav. o. Unterstimmenschicht vermutlich Ligatur aus Viertelnote, punktierte Viertelnote C/A und e, Achtelpause. Klav. o. Oberstimmenschicht vermutlich Viertelnote cis1, Achtelpause" + }, + { + "measure": "18", + "system": "Klav. o.", + "position": "1/4", + "comment": "{{ref.getGlyph('[a]')}} zu g1 hinzugefügt mit Bleistift." + }, + { + "measure": "19", + "system": "Klav. o.", + "position": "2.–3. Note", + "comment": "Oberstimmenschicht auf Rasur." + } + ] + } + ] + } ] } }, diff --git a/src/assets/data/edition/series/1/section/5/op12/source-list.json b/src/assets/data/edition/series/1/section/5/op12/source-list.json index c39d54069..43d0a7f6b 100644 --- a/src/assets/data/edition/series/1/section/5/op12/source-list.json +++ b/src/assets/data/edition/series/1/section/5/op12/source-list.json @@ -36,7 +36,7 @@ "siglum": "E", "siglumAddendum": "", "type": "Druck von
    „Der Tag ist vergangen“ M 212: Textfassung 2.", - "location": "In: Musikblätter des Anbruch IV (Mai 1922).", + "location": "Beilage in: Musikblätter des Anbruch IV (Mai 1922).", "hasDescription": true, "linkTo": "source_E" }, @@ -78,7 +78,7 @@ "id": "text_Bethge_DchF", "siglum": "Bethge_DchF", "siglumAddendum": "", - "type": "Hans Bethge, Die chinesische Flöte, Leipzig: Inselverlag, 4[1914], S. 35 (Die geheimnisvolle Flöte).", + "type": "Hans Bethge, Die chinesische Flöte, Leipzig: Inselverlag, 4[1914], S. 35 (Die geheimnisvolle Flöte).", "location": "Weberns Exemplar befindet sich in CH-Bps, PSS AW B 1027." }, { diff --git a/src/assets/data/edition/series/1/section/5/op12/textcritics.json b/src/assets/data/edition/series/1/section/5/op12/textcritics.json index 8d0891c3c..1472b6ed4 100644 --- a/src/assets/data/edition/series/1/section/5/op12/textcritics.json +++ b/src/assets/data/edition/series/1/section/5/op12/textcritics.json @@ -8,102 +8,107 @@ ], "comments": [ { - "svgGroupId": "text200", - "measure": "1", - "system": "Klav.", - "position": "2/8 bis 2/4", - "comment": "Crescendogabel versetzt von über Klav. o." - }, - { - "svgGroupId": "text262", - "measure": "2", - "system": "Klav.", - "position": "1–4/8", - "comment": "Decrescendogabel versetzt von über Klav. o." - }, - { - "svgGroupId": "g5702", - "measure": "2", - "system": "Klav. o.", - "position": "1. Note", - "comment": "{{ref.getGlyph('[#]')}} zu gis1 ergänzt mit Blick auf Textfassung 2 und Textfassung 3 (op. 12/1)." - }, - { - "svgGroupId": "text748", - "measure": "5", - "system": "Klav. o.", - "position": "(1/4)", - "comment": "Triolenklammer versetzt von über Klav. u." - }, - { - "svgGroupId": "text766", - "measure": "5", - "system": "Klav.", - "position": "1. Note", - "comment": "{{ref.getGlyph('[pp]')}} versetzt von unter Klav. u." - }, - { - "svgGroupId": "g5708", - "measure": "5", - "system": "Ges.", - "position": "3/8", - "comment": "Text: Komma nach (ver-gan-)gen ergänzt mit Blick auf Rosegger_PM." - }, - { - "svgGroupId": "text902", - "measure": "6", - "system": "Klav.", - "position": "1. Note", - "comment": "Ende der Crescendogabel versetzt von Ende T. 5." - }, - { - "svgGroupId": "g5714", - "measure": "9", - "system": "Ges.", - "position": "2. Note", - "comment": "Text: Komma nach (Ma-ri-)a ergänzt mit Blick auf Rosegger_PM." - }, - { - "svgGroupId": "text318", - "measure": "13", - "system": "Ges.", - "position": "2/8", - "comment": "{{ref.getGlyph('[ppp]')}}: Entzifferung unsicher, Tinte stark verschmiert." - }, - { - "svgGroupId": "text484", - "measure": "14", - "system": "Klav. u.", - "position": "1/8", - "comment": "({{ref.getGlyph('[a]')}}) zu e/a als redundant weggelassen. B: Akkoladenwechsel nach T. 12." - }, - { - "svgGroupId": "g6096", - "measure": "14", - "system": "Ges.", - "position": "2. Note", - "comment": "Text: Komma nach (ver-gan-)gen ergänzt mit Blick auf Rosegger_PM." - }, - { - "svgGroupId": "", - "measure": "18", - "system": "Ges.", - "position": "1. Note", - "comment": "Text sic: (Ver-)storb(-nen) ohne Binnen-Apostroph. Rosegger_PM: Verstorb’nen." - }, - { - "svgGroupId": "text1556", - "measure": "22", - "system": "Klav. o.", - "position": "", - "comment": "Anfang der Ligaturbögen zu H/g ergänzt analog Fortsetzung der Bögen in T. 23. B: Akkoladenwechsel nach T. 22." - }, - { - "svgGroupId": "text1600", - "measure": "23", - "system": "Klav.", - "position": "1/8", - "comment": "({{ref.getGlyph('[#]')}}) zu Gis1/Cis und ({{ref.getGlyph('[a]')}}) zu H/g als redundant weggelassen. B: Akkoladenwechsel nach T. 22." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "text200", + "measure": "1", + "system": "Klav.", + "position": "2/8 bis 2/4", + "comment": "Crescendogabel versetzt von über Klav. o." + }, + { + "svgGroupId": "text262", + "measure": "2", + "system": "Klav.", + "position": "1–4/8", + "comment": "Decrescendogabel versetzt von über Klav. o." + }, + { + "svgGroupId": "g5702", + "measure": "2", + "system": "Klav. o.", + "position": "1. Note", + "comment": "{{ref.getGlyph('[#]')}} zu gis1 ergänzt mit Blick auf Textfassung 2 und Textfassung 3 (op. 12/1)." + }, + { + "svgGroupId": "text748", + "measure": "5", + "system": "Klav. o.", + "position": "(1/4)", + "comment": "Triolenklammer versetzt von über Klav. u." + }, + { + "svgGroupId": "text766", + "measure": "5", + "system": "Klav.", + "position": "1. Note", + "comment": "{{ref.getGlyph('[pp]')}} versetzt von unter Klav. u." + }, + { + "svgGroupId": "g5708", + "measure": "5", + "system": "Ges.", + "position": "3/8", + "comment": "Text: Komma nach (ver-gan-)gen ergänzt mit Blick auf Rosegger_PM." + }, + { + "svgGroupId": "text902", + "measure": "6", + "system": "Klav.", + "position": "1. Note", + "comment": "Ende der Crescendogabel versetzt von Ende T. 5." + }, + { + "svgGroupId": "g5714", + "measure": "9", + "system": "Ges.", + "position": "2. Note", + "comment": "Text: Komma nach (Ma-ri-)a ergänzt mit Blick auf Rosegger_PM." + }, + { + "svgGroupId": "text318", + "measure": "13", + "system": "Ges.", + "position": "2/8", + "comment": "{{ref.getGlyph('[ppp]')}}: Entzifferung unsicher, Tinte stark verschmiert." + }, + { + "svgGroupId": "text484", + "measure": "14", + "system": "Klav. u.", + "position": "1/8", + "comment": "({{ref.getGlyph('[a]')}}) zu e/a als redundant weggelassen. B: Akkoladenwechsel nach T. 12." + }, + { + "svgGroupId": "g6096", + "measure": "14", + "system": "Ges.", + "position": "2. Note", + "comment": "Text: Komma nach (ver-gan-)gen ergänzt mit Blick auf Rosegger_PM." + }, + { + "svgGroupId": "", + "measure": "18", + "system": "Ges.", + "position": "1. Note", + "comment": "Text sic: (Ver-)storb(-nen) ohne Binnen-Apostroph. Rosegger_PM: Verstorb’nen." + }, + { + "svgGroupId": "text1556", + "measure": "22", + "system": "Klav. o.", + "position": "", + "comment": "Anfang der Ligaturbögen zu H/g ergänzt analog Fortsetzung der Bögen in T. 23. B: Akkoladenwechsel nach T. 22." + }, + { + "svgGroupId": "text1600", + "measure": "23", + "system": "Klav.", + "position": "1/8", + "comment": "({{ref.getGlyph('[#]')}}) zu Gis1/Cis und ({{ref.getGlyph('[a]')}}) zu H/g als redundant weggelassen. B: Akkoladenwechsel nach T. 22." + } + ] } ] }, @@ -115,151 +120,156 @@ ], "comments": [ { - "svgGroupId": "g1141", - "measure": "1", - "system": "3", - "position": "2/8", - "comment": "{{ref.getGlyph('[a]')}}c2 überschreibt {{ref.getGlyph('[b]')}}b1 (oder {{ref.getGlyph('[b]')}}ces2?)." - }, - { - "svgGroupId": "g1153", - "measure": "2", - "system": "3", - "position": "4/8", - "comment": "{{ref.getGlyph('[#]')}} zu gis1 ergänzt mit Blick auf Textfassung 2 und Textfassung 3." - }, - { - "svgGroupId": "g1320", - "measure": "8", - "system": "6", - "position": "1/4", - "comment": "{{ref.getGlyph('[a]')}}g2 gestrichen und geändert zu {{ref.getGlyph('[a]')}}g1." - }, - { - "svgGroupId": "g1389", - "measure": "8", - "system": "6", - "position": "vorletzte und letzte Note", - "comment": "Text: Gute zusammengeschrieben." - }, - { - "svgGroupId": "g1306", - "measure": "11", - "system": "7", - "position": "1.–2. Note", - "comment": "Bogen gestrichen." - }, - { - "svgGroupId": "g1314", - "measure": "11", - "system": "9", - "position": "", - "comment": "Entzifferung und Bezug nicht eindeutig." - }, - { - "svgGroupId": "g1302", - "measure": "12", - "system": "8", - "position": "1.–3. Note", - "comment": "Bogen gestrichen." - }, - { - "svgGroupId": "g6001", - "measure": "13", - "system": "11", - "position": "2.–3. Note", - "comment": "Zwei triolische Achtelnoten {{ref.getGlyph('[a]')}}g1–{{ref.getGlyph('[a]')}}c2 gestrichen und geändert zu Achtelpause." - }, - { - "svgGroupId": "g5850", - "measure": "15", - "system": "11–12", - "position": "Taktanfang", - "comment": "Taktartvorzeichnung 2/4 gestrichen." - }, - { - "svgGroupId": "g2068", - "measure": "15", - "system": "10", - "position": "1.–2. Note", - "comment": "Text: [ver-]gangen zusammengeschrieben." - }, - { - "svgGroupId": "g6136", - "measure": "15", - "system": "11", - "position": "", - "comment": "{{ref.getGlyph('[b]')}}as2/{{ref.getGlyph('[a]')}}c3–{{ref.getGlyph('[a]')}}g1/{{ref.getGlyph('[#]')}}cis2 durch Einkreisung getilgt. Siehe Änderung in System 14." - }, - { - "svgGroupId": "g911", - "measure": "16", - "system": "10", - "position": "2/8", - "comment": "{{ref.getGlyph('[a]')}}a1 ersetzt {{ref.getGlyph('[a]')}}g2." - }, - { - "svgGroupId": "g5891", - "measure": "16", - "system": "11", - "position": "3–4/16", - "comment": "sic: {{ref.getGlyph('[a]')}} nach {{ref.getGlyph('[b]')}}es2. (Ansatz zu e2 bei 4/16?)" - }, - { - "svgGroupId": "g5905", - "measure": "16", - "system": "10", - "position": "3.–4. Note", - "comment": "Zwei Achtelnoten {{ref.getGlyph('[b]')}}as2–{{ref.getGlyph('[a]')}}g2 geändert zu punktierter Achtelnote und Sechzehntelnote." - }, - { - "svgGroupId": "g1256", - "measure": "20", - "system": "8", - "position": "", - "comment": "{{ref.getGlyph('[b]')}} überschreibt {{ref.getGlyph('[a]')}}." - }, - { - "svgGroupId": "g1276", - "measure": "21", - "system": "6", - "position": "3. Note", - "comment": "d1 gestrichen und geändert zu {{ref.getGlyph('[#]')}}fis1." - }, - { - "svgGroupId": "g1194", - "measure": "22", - "system": "9–10", - "position": "1. Note", - "comment": "Notenköpfe gestrichen und geändert zu Achtelpause (System 10)." - }, - { - "svgGroupId": "g1243", - "measure": "nach 22", - "system": "", - "position": "", - "comment": "Schlusstaktstrich gestrichen (siehe T. 23–24)." - }, - { - "svgGroupId": "g2767", - "measure": "23", - "system": "14", - "position": "1/4", - "comment": "Entzifferung nicht eindeutig. Zuerst: Halbe Note e/a überschreibt Viertelnote {{ref.getGlyph('[a]')}}H/g (?); dann: Halbe Note e/a gestrichen und geändert zu Viertelnote H/e sowie pauschale Ligaturbögen von T. 22 hinzugefügt." - }, - { - "svgGroupId": "g1094", - "measure": "23", - "system": "13", - "position": "2/4", - "comment": "{{ref.getGlyph('[#]')}}cis1/{{ref.getGlyph('[#]')}}gis1 gestrichen. Siehe Änderung in System 15." - }, - { - "svgGroupId": "g1104", - "measure": "24", - "system": "14", - "position": "", - "comment": "{{ref.getGlyph('[b]')}}B/{{ref.getGlyph('[a]')}}f/{{ref.getGlyph('[a]')}}h durch Einkreisung getilgt." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1141", + "measure": "1", + "system": "3", + "position": "2/8", + "comment": "{{ref.getGlyph('[a]')}}c2 überschreibt {{ref.getGlyph('[b]')}}b1 (oder {{ref.getGlyph('[b]')}}ces2?)." + }, + { + "svgGroupId": "g1153", + "measure": "2", + "system": "3", + "position": "4/8", + "comment": "{{ref.getGlyph('[#]')}} zu gis1 ergänzt mit Blick auf Textfassung 2 und Textfassung 3." + }, + { + "svgGroupId": "g1320", + "measure": "8", + "system": "6", + "position": "1/4", + "comment": "{{ref.getGlyph('[a]')}}g2 gestrichen und geändert zu {{ref.getGlyph('[a]')}}g1." + }, + { + "svgGroupId": "g1389", + "measure": "8", + "system": "6", + "position": "vorletzte und letzte Note", + "comment": "Text: Gute zusammengeschrieben." + }, + { + "svgGroupId": "g1306", + "measure": "11", + "system": "7", + "position": "1.–2. Note", + "comment": "Bogen gestrichen." + }, + { + "svgGroupId": "g1314", + "measure": "11", + "system": "9", + "position": "", + "comment": "Entzifferung und Bezug nicht eindeutig." + }, + { + "svgGroupId": "g1302", + "measure": "12", + "system": "8", + "position": "1.–3. Note", + "comment": "Bogen gestrichen." + }, + { + "svgGroupId": "g6001", + "measure": "13", + "system": "11", + "position": "2.–3. Note", + "comment": "Zwei triolische Achtelnoten {{ref.getGlyph('[a]')}}g1–{{ref.getGlyph('[a]')}}c2 gestrichen und geändert zu Achtelpause." + }, + { + "svgGroupId": "g5850", + "measure": "15", + "system": "11–12", + "position": "Taktanfang", + "comment": "Taktartvorzeichnung 2/4 gestrichen." + }, + { + "svgGroupId": "g2068", + "measure": "15", + "system": "10", + "position": "1.–2. Note", + "comment": "Text: [ver-]gangen zusammengeschrieben." + }, + { + "svgGroupId": "g6136", + "measure": "15", + "system": "11", + "position": "", + "comment": "{{ref.getGlyph('[b]')}}as2/{{ref.getGlyph('[a]')}}c3–{{ref.getGlyph('[a]')}}g1/{{ref.getGlyph('[#]')}}cis2 durch Einkreisung getilgt. Siehe Änderung in System 14." + }, + { + "svgGroupId": "g911", + "measure": "16", + "system": "10", + "position": "2/8", + "comment": "{{ref.getGlyph('[a]')}}a1 ersetzt {{ref.getGlyph('[a]')}}g2." + }, + { + "svgGroupId": "g5891", + "measure": "16", + "system": "11", + "position": "3–4/16", + "comment": "sic: {{ref.getGlyph('[a]')}} nach {{ref.getGlyph('[b]')}}es2. (Ansatz zu e2 bei 4/16?)" + }, + { + "svgGroupId": "g5905", + "measure": "16", + "system": "10", + "position": "3.–4. Note", + "comment": "Zwei Achtelnoten {{ref.getGlyph('[b]')}}as2–{{ref.getGlyph('[a]')}}g2 geändert zu punktierter Achtelnote und Sechzehntelnote." + }, + { + "svgGroupId": "g1256", + "measure": "20", + "system": "8", + "position": "", + "comment": "{{ref.getGlyph('[b]')}} überschreibt {{ref.getGlyph('[a]')}}." + }, + { + "svgGroupId": "g1276", + "measure": "21", + "system": "6", + "position": "3. Note", + "comment": "d1 gestrichen und geändert zu {{ref.getGlyph('[#]')}}fis1." + }, + { + "svgGroupId": "g1194", + "measure": "22", + "system": "9–10", + "position": "1. Note", + "comment": "Notenköpfe gestrichen und geändert zu Achtelpause (System 10)." + }, + { + "svgGroupId": "g1243", + "measure": "nach 22", + "system": "", + "position": "", + "comment": "Schlusstaktstrich gestrichen (siehe T. 23–24)." + }, + { + "svgGroupId": "g2767", + "measure": "23", + "system": "14", + "position": "1/4", + "comment": "Entzifferung nicht eindeutig. Zuerst: Halbe Note e/a überschreibt Viertelnote {{ref.getGlyph('[a]')}}H/g (?); dann: Halbe Note e/a gestrichen und geändert zu Viertelnote H/e sowie pauschale Ligaturbögen von T. 22 hinzugefügt." + }, + { + "svgGroupId": "g1094", + "measure": "23", + "system": "13", + "position": "2/4", + "comment": "{{ref.getGlyph('[#]')}}cis1/{{ref.getGlyph('[#]')}}gis1 gestrichen. Siehe Änderung in System 15." + }, + { + "svgGroupId": "g1104", + "measure": "24", + "system": "14", + "position": "", + "comment": "{{ref.getGlyph('[b]')}}B/{{ref.getGlyph('[a]')}}f/{{ref.getGlyph('[a]')}}h durch Einkreisung getilgt." + } + ] } ] }, @@ -271,32 +281,37 @@ ], "comments": [ { - "svgGroupId": "g1438", - "measure": "10", - "system": "12", - "position": "1. Note", - "comment": "Viertelnote überschreibt Halbe Note." - }, - { - "svgGroupId": "g1454", - "measure": "10", - "system": "12", - "position": "2. Note", - "comment": "{{ref.getGlyph('[a]')}}e oder {{ref.getGlyph('[b]')}}es (?). (Siehe auch System 13 2/4: e1/as1 oder [{{ref.getGlyph('[b]')}}]es1/as1?) Vorgeschlagene Entzifferung mit Blick auf eindeutig entzifferbare Akzidenzien an entsprechender Stelle in Sk1 T. 11, Sk3 und Sk5 sowie in den Reinschrift- bzw. Druckfassungen aus B, C, E, F und G." - }, - { - "svgGroupId": "g1006", - "measure": "11", - "system": "14", - "position": "(1/4)", - "comment": "Punktierte Achtelpause, Sechzehntelnote {{ref.getGlyph('[b]')}}b radiert." - }, - { - "svgGroupId": "g1405", - "measure": "12", - "system": "13", - "position": "", - "comment": "Radierte, nicht entzifferbare Schicht." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1438", + "measure": "10", + "system": "12", + "position": "1. Note", + "comment": "Viertelnote überschreibt Halbe Note." + }, + { + "svgGroupId": "g1454", + "measure": "10", + "system": "12", + "position": "2. Note", + "comment": "{{ref.getGlyph('[a]')}}e oder {{ref.getGlyph('[b]')}}es (?). (Siehe auch System 13 2/4: e1/as1 oder [{{ref.getGlyph('[b]')}}]es1/as1?) Vorgeschlagene Entzifferung mit Blick auf eindeutig entzifferbare Akzidenzien an entsprechender Stelle in Sk1 T. 11, Sk3 und Sk5 sowie in den Reinschrift- bzw. Druckfassungen aus B, C, E, F und G." + }, + { + "svgGroupId": "g1006", + "measure": "11", + "system": "14", + "position": "(1/4)", + "comment": "Punktierte Achtelpause, Sechzehntelnote {{ref.getGlyph('[b]')}}b radiert." + }, + { + "svgGroupId": "g1405", + "measure": "12", + "system": "13", + "position": "", + "comment": "Radierte, nicht entzifferbare Schicht." + } + ] } ], "linkBoxes": [ @@ -317,25 +332,30 @@ ], "comments": [ { - "svgGroupId": "g1477", - "measure": "10", - "system": "9", - "position": "2/4", - "comment": "c gestrichen; {{ref.getGlyph('[a]')}}e oder {{ref.getGlyph('[b]')}}es (?)." - }, - { - "svgGroupId": "g1543", - "measure": "11", - "system": "10", - "position": "1.–2. Note", - "comment": "Triole aus Viertelnote und Achtelnote überschreibt zwei zusammengebalkte Achtelnoten." - }, - { - "svgGroupId": "g1020", - "measure": "11", - "system": "10", - "position": "nach 2/4", - "comment": "Radierspuren." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1477", + "measure": "10", + "system": "9", + "position": "2/4", + "comment": "c gestrichen; {{ref.getGlyph('[a]')}}e oder {{ref.getGlyph('[b]')}}es (?)." + }, + { + "svgGroupId": "g1543", + "measure": "11", + "system": "10", + "position": "1.–2. Note", + "comment": "Triole aus Viertelnote und Achtelnote überschreibt zwei zusammengebalkte Achtelnoten." + }, + { + "svgGroupId": "g1020", + "measure": "11", + "system": "10", + "position": "nach 2/4", + "comment": "Radierspuren." + } + ] } ], "linkBoxes": [ @@ -363,18 +383,23 @@ ], "comments": [ { - "svgGroupId": "g1344", - "measure": "10", - "system": "6", - "position": "", - "comment": "Achtelfähnchen gestrichen." - }, - { - "svgGroupId": "g1422", - "measure": "10", - "system": "5", - "position": "3. Note", - "comment": "Ansatz zu Notenkopf c2 und f1(?)." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1344", + "measure": "10", + "system": "6", + "position": "", + "comment": "Achtelfähnchen gestrichen." + }, + { + "svgGroupId": "g1422", + "measure": "10", + "system": "5", + "position": "3. Note", + "comment": "Ansatz zu Notenkopf c2 und f1(?)." + } + ] } ], "linkBoxes": [ @@ -396,18 +421,23 @@ ], "comments": [ { - "svgGroupId": "g1447", - "measure": "10", - "system": "9", - "position": "3/8", - "comment": "{{ref.getGlyph('[b]')}} zu ces1 überschreibt {{ref.getGlyph('[a]')}} zu c1. (Oder: {{ref.getGlyph('[b]')}}ces1 überschreibt {{ref.getGlyph('[a]')}}h?)." - }, - { - "svgGroupId": "g1434", - "measure": "11", - "system": "9", - "position": "1/4", - "comment": "Text sic: dir (statt mir)." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1447", + "measure": "10", + "system": "9", + "position": "3/8", + "comment": "{{ref.getGlyph('[b]')}} zu ces1 überschreibt {{ref.getGlyph('[a]')}} zu c1. (Oder: {{ref.getGlyph('[b]')}}ces1 überschreibt {{ref.getGlyph('[a]')}}h?)." + }, + { + "svgGroupId": "g1434", + "measure": "11", + "system": "9", + "position": "1/4", + "comment": "Text sic: dir (statt mir)." + } + ] } ], "linkBoxes": [ diff --git a/src/assets/data/edition/series/1/section/5/op23/source-list.json b/src/assets/data/edition/series/1/section/5/op23/source-list.json index 8b845a75b..d11b0250a 100644 --- a/src/assets/data/edition/series/1/section/5/op23/source-list.json +++ b/src/assets/data/edition/series/1/section/5/op23/source-list.json @@ -3,7 +3,7 @@ { "siglum": "A", "siglumAddendum": "", - "type": "Skizzen (in Skizzenbuch 3).", + "type": "Skizzen (in: Skizzenbuch 3).", "location": "CH-Bps, Sammlung Anton Webern.", "hasDescription": true, "linkTo": "source_A" @@ -19,7 +19,7 @@ { "siglum": "C", "siglumAddendum": "", - "type": "Autograph von Drei Gesänge aus Viae Inviae von Hildegard Jone op. 23:
    I(„Das dunkle Herz“ M 314: einzige Textfassung)
    II(„Es stürzt aus Höhen Frische“ M 313: einzige Textfassung)
    III(„Herr Jesus mein“ M 312: einzige Textfassung).", + "type": "Autograph von Drei Gesänge aus Viae Inviae von Hildegard Jone op. 23:
    I„Das dunkle Herz“ M 314: einzige Textfassung
    II„Es stürzt aus Höhen Frische“ M 313: einzige Textfassung
    III„Herr Jesus mein“ M 312: einzige Textfassung.
    Stichvorlage für D.", "location": "US-NYpm, Dept. of Music Manuscripts and Books, Robert Owen Lehman Collection, W376.G389 / 115908.", "hasDescription": true, "linkTo": "source_C" @@ -27,10 +27,19 @@ { "siglum": "D", "siglumAddendum": "", - "type": "Druck von Drei Gesänge aus Viae Inviae von Hildegard Jone op. 23:
    I(„Das dunkle Herz“ M 314: einzige Textfassung)
    II(„Es stürzt aus Höhen Frische“ M 313: einzige Textfassung)
    III(„Herr Jesus mein“ M 312: einzige Textfassung).", + "type": "Druck von Drei Gesänge aus Viae Inviae von Hildegard Jone op. 23:
    I„Das dunkle Herz“ M 314: einzige Textfassung
    II„Es stürzt aus Höhen Frische“ M 313: einzige Textfassung
    III„Herr Jesus mein“ M 312: einzige Textfassung.", "location": "Wien: Universal Edition, 1936.", "hasDescription": true, "linkTo": "source_D" } + ], + "textSources": [ + { + "id": "text_Jone_Vi", + "siglum": "Jone_Vi", + "siglumAddendum": "", + "type": "Hildegard Jone, Viae inviae, in: Der Brenner 13 (1932), S. 60–74, hier S. 64 („Das dunkle Herz“) und 65 („Du stürzt aus Höhen“ und „Herr Jesus mein“).", + "location": "Webern bezieht sich in der Korrespondenz mit Hildegard Jone auf diese Druckausgabe der Gedichte (z. B. Webern an Jone, 3. September 1933 [A-Wn, HS 431/1–101]; siehe Einleitung). Ein Exemplar Weberns ist nicht überliefert." + } ] } diff --git a/src/assets/data/edition/series/1/section/5/op23/textcritics.json b/src/assets/data/edition/series/1/section/5/op23/textcritics.json index 84064e57d..ceea1feac 100644 --- a/src/assets/data/edition/series/1/section/5/op23/textcritics.json +++ b/src/assets/data/edition/series/1/section/5/op23/textcritics.json @@ -9,67 +9,72 @@ "rowtable": true, "comments": [ { - "svgGroupId": "text620", - "measure": "Bl. 1r", - "system": "1a", - "position": "Ggis", - "comment": "Reihennummerierung I mit rotem Buntstift." - }, - { - "svgGroupId": "text622", - "measure": "Bl. 1r", - "system": "1b", - "position": "Kh", - "comment": "Reihennummerierung II mit rotem Buntstift." - }, - { - "svgGroupId": "text624", - "measure": "Bl. 1r", - "system": "2a", - "position": "Ugis", - "comment": "Reihennummerierung III mit rotem Buntstift." - }, - { - "svgGroupId": "text626", - "measure": "Bl. 1r", - "system": "2b", - "position": "KUf", - "comment": "Reihennummerierung IV mit rotem Buntstift." - }, - { - "svgGroupId": "g998", - "measure": "Bl. 1r", - "system": "2b", - "position": "KUf: 8. Reihenton", - "comment": "{{ref.getGlyph('[#]')}}fis1 überschreibt {{ref.getGlyph('[b]')}} als Ansatz zu ges1." - }, - { - "svgGroupId": "text628", - "measure": "Bl. 1r", - "system": "3a", - "position": "Gd", - "comment": "Reihennummerierung V mit rotem Buntstift." - }, - { - "svgGroupId": "text630", - "measure": "Bl. 1r", - "system": "3b", - "position": "Kf", - "comment": "Reihennummerierung VI mit rotem Buntstift." - }, - { - "svgGroupId": "text632", - "measure": "Bl. 1r", - "system": "4a", - "position": "Ud", - "comment": "Reihennummerierung VII mit rotem Buntstift." - }, - { - "svgGroupId": "text634", - "measure": "Bl. 1r", - "system": "4b", - "position": "KUh", - "comment": "Reihennummerierung VIII mit rotem Buntstift." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "text620", + "measure": "Bl. 1r", + "system": "1a", + "position": "Ggis", + "comment": "Reihennummerierung I mit rotem Buntstift." + }, + { + "svgGroupId": "text622", + "measure": "Bl. 1r", + "system": "1b", + "position": "Kh", + "comment": "Reihennummerierung II mit rotem Buntstift." + }, + { + "svgGroupId": "text624", + "measure": "Bl. 1r", + "system": "2a", + "position": "Ugis", + "comment": "Reihennummerierung III mit rotem Buntstift." + }, + { + "svgGroupId": "text626", + "measure": "Bl. 1r", + "system": "2b", + "position": "KUf", + "comment": "Reihennummerierung IV mit rotem Buntstift." + }, + { + "svgGroupId": "g998", + "measure": "Bl. 1r", + "system": "2b", + "position": "KUf: 8. Reihenton", + "comment": "{{ref.getGlyph('[#]')}}fis1 überschreibt {{ref.getGlyph('[b]')}} als Ansatz zu ges1." + }, + { + "svgGroupId": "text628", + "measure": "Bl. 1r", + "system": "3a", + "position": "Gd", + "comment": "Reihennummerierung V mit rotem Buntstift." + }, + { + "svgGroupId": "text630", + "measure": "Bl. 1r", + "system": "3b", + "position": "Kf", + "comment": "Reihennummerierung VI mit rotem Buntstift." + }, + { + "svgGroupId": "text632", + "measure": "Bl. 1r", + "system": "4a", + "position": "Ud", + "comment": "Reihennummerierung VII mit rotem Buntstift." + }, + { + "svgGroupId": "text634", + "measure": "Bl. 1r", + "system": "4b", + "position": "KUh", + "comment": "Reihennummerierung VIII mit rotem Buntstift." + } + ] } ] } diff --git a/src/assets/data/edition/series/1/section/5/op25/source-description.json b/src/assets/data/edition/series/1/section/5/op25/source-description.json index 75ef7397c..3f7eb91d1 100644 --- a/src/assets/data/edition/series/1/section/5/op25/source-description.json +++ b/src/assets/data/edition/series/1/section/5/op25/source-description.json @@ -4,7 +4,7 @@ "id": "source_A", "siglum": "A", "siglumAddendum": "", - "type": "Skizzen und Reihentabelle zu „Wie bin ich froh!“ M 317 (in Skizzenbuch 3).", + "type": "Skizzen und Reihentabelle zu „Wie bin ich froh!“ M 317 (in: Skizzenbuch 3).", "location": "CH-Bps, Sammlung Anton Webern.", "description": { "desc": ["2 Seiten in Skizzenbuch 3: Bl. 38v–39r."], @@ -866,7 +866,7 @@ "id": "source_D", "siglum": "D", "siglumAddendum": "", - "type": "Skizzen zu „Sterne, Ihr silbernen Bienen“ M 321 und „Des Herzens Purpurvogel“ M 322 (in Skizzenbuch 4).", + "type": "Skizzen zu „Sterne, Ihr silbernen Bienen“ M 321 und „Des Herzens Purpurvogel“ M 322 (in: Skizzenbuch 4).", "location": "CH-Bps, Sammlung Anton Webern.", "description": { "desc": [ diff --git a/src/assets/data/edition/series/1/section/5/op25/source-list.json b/src/assets/data/edition/series/1/section/5/op25/source-list.json index f8dc5bfd8..acf1ff1df 100644 --- a/src/assets/data/edition/series/1/section/5/op25/source-list.json +++ b/src/assets/data/edition/series/1/section/5/op25/source-list.json @@ -3,7 +3,7 @@ { "siglum": "A", "siglumAddendum": "", - "type": "Skizzen und Reihentabelle zu „Wie bin ich froh!“ M 317 (in Skizzenbuch 3).", + "type": "Skizzen und Reihentabelle zu „Wie bin ich froh!“ M 317 (in: Skizzenbuch 3).", "location": "CH-Bps, Sammlung Anton Webern.", "hasDescription": true, "linkTo": "source_A" @@ -27,7 +27,7 @@ { "siglum": "D", "siglumAddendum": "", - "type": "Skizzen zu „Sterne, Ihr silbernen Bienen“ M 321 und „Des Herzens Purpurvogel“ M 322 (in Skizzenbuch 4).", + "type": "Skizzen zu „Sterne, Ihr silbernen Bienen“ M 321 und „Des Herzens Purpurvogel“ M 322 (in: Skizzenbuch 4).", "location": "CH-Bps, Sammlung Anton Webern.", "hasDescription": true, "linkTo": "source_D" @@ -42,7 +42,7 @@ }, { "siglum": "E", - "siglumAddendum": "F1–2", + "siglumAddendum": "F1–F2", "missing": true, "type": "Fotokopien von E.", "location": "Verschollen.", @@ -55,7 +55,7 @@ "id": "text_Jone_DF", "siglum": "Jone_DF", "siglumAddendum": "", - "type": "Hildegard Jone, Die Freude, in: Die Schildgenossen 13/1 (September/Oktober 1933), S. 16–26, hier S. 16 („Wie bin ich froh!“), 18 („Sterne, Ihr silbernen Bienen der Nacht“) und 24 („Des Herzens Pupurvogel“).", + "type": "Hildegard Jone, Die Freude, in: Die Schildgenossen 13/1 (September/Oktober 1933), S. 16–26, hier S. 16 („Wie bin ich froh!“), 18 („Sterne, Ihr silbernen Bienen der Nacht“) und 24 („Des Herzens Purpurvogel“).", "location": "Webern bezieht sich in der Korrespondenz mit Hildegard Jone auf diese Ausgabe (z. B. Webern an Jone, 21. September 1933 [A-Wn, HS 431/1–112]; siehe Einleitung). Ein Exemplar Weberns ist nicht überliefert." } ] diff --git a/src/assets/data/edition/series/1/section/5/op25/textcritics.json b/src/assets/data/edition/series/1/section/5/op25/textcritics.json index 6cd54e8de..3ea5c730f 100644 --- a/src/assets/data/edition/series/1/section/5/op25/textcritics.json +++ b/src/assets/data/edition/series/1/section/5/op25/textcritics.json @@ -8,25 +8,30 @@ ], "comments": [ { - "svgGroupId": "g1145", - "measure": "1", - "system": "", - "position": "4/8", - "comment": "rit. versetzt von ungenauer Position zwischen 4/8 und 5/8 mit Blick auf M 317 Sk4." - }, - { - "svgGroupId": "g1198", - "measure": "3", - "system": "Ges.", - "position": "1. Note", - "comment": "{{ref.getGlyph('[f]')}} versetzt von 1. Pause." - }, - { - "svgGroupId": "g1204", - "measure": "6", - "system": "Ges.", - "position": "1. Note", - "comment": "{{ref.getGlyph('[f]')}} versetzt von 3/8." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1145", + "measure": "1", + "system": "", + "position": "4/8", + "comment": "rit. versetzt von ungenauer Position zwischen 4/8 und 5/8 mit Blick auf M 317 Sk4." + }, + { + "svgGroupId": "g1198", + "measure": "3", + "system": "Ges.", + "position": "1. Note", + "comment": "{{ref.getGlyph('[f]')}} versetzt von 1. Pause." + }, + { + "svgGroupId": "g1204", + "measure": "6", + "system": "Ges.", + "position": "1. Note", + "comment": "{{ref.getGlyph('[f]')}} versetzt von 3/8." + } + ] } ] }, @@ -38,11 +43,16 @@ ], "comments": [ { - "svgGroupId": "g6494", - "measure": "1–2", - "system": "1", - "position": "", - "comment": "Durch Einklammerung rechts getilgt." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g6494", + "measure": "1–2", + "system": "1", + "position": "", + "comment": "Durch Einklammerung rechts getilgt." + } + ] } ], "linkBoxes": [ @@ -120,25 +130,30 @@ "rowtable": true, "comments": [ { - "svgGroupId": "g1055", - "measure": "A", - "system": "1", - "position": "1.–5. Reihenton", - "comment": "Durch Einklammerung rechts getilgt." - }, - { - "svgGroupId": "text74", - "measure": "A", - "system": "1", - "position": "2. Reihenton", - "comment": "{{ref.getGlyph('[a]')}} nachgezogen (überschreibt {{ref.getGlyph('[b]')}}?)." - }, - { - "svgGroupId": "g1065", - "measure": "B", - "system": "1", - "position": "4. Reihenton", - "comment": "{{ref.getGlyph('[#]')}}fis2 überschreibt {{ref.getGlyph('[a]')}}g2." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1055", + "measure": "A", + "system": "1", + "position": "1.–5. Reihenton", + "comment": "Durch Einklammerung rechts getilgt." + }, + { + "svgGroupId": "text74", + "measure": "A", + "system": "1", + "position": "2. Reihenton", + "comment": "{{ref.getGlyph('[a]')}} nachgezogen (überschreibt {{ref.getGlyph('[b]')}}?)." + }, + { + "svgGroupId": "g1065", + "measure": "B", + "system": "1", + "position": "4. Reihenton", + "comment": "{{ref.getGlyph('[#]')}}fis2 überschreibt {{ref.getGlyph('[a]')}}g2." + } + ] } ], "linkBoxes": [ @@ -215,60 +230,65 @@ ], "comments": [ { - "svgGroupId": "g1245", - "measure": "1–3", - "system": "1", - "position": "", - "comment": "Text in Kurrentschrift." - }, - { - "svgGroupId": "text164", - "measure": "1", - "system": "1", - "position": "6/8", - "comment": "{{ref.getGlyph('[b]')}} nachgezogen (überschreibt Ansatz von {{ref.getGlyph('[#]')}} zu dis2?)." - }, - { - "svgGroupId": "g1254", - "measure": "2", - "system": "1", - "position": "1. Note", - "comment": "Durch Einkreisung getilgt." - }, - { - "svgGroupId": "text194", - "measure": "2", - "system": "1", - "position": "3/8", - "comment": "{{ref.getGlyph('[#]')}} nachgezogen (überschreibt {{ref.getGlyph('[a]')}}?)." - }, - { - "svgGroupId": "text338", - "measure": "2", - "system": "3", - "position": "letzte Note", - "comment": "Punkt unter der Note: Fleck oder Ansatz zu Notenkopf f?" - }, - { - "svgGroupId": "g1281", - "measure": "2
    bis 3", - "system": "3", - "position": "letzte Note
    3. Note", - "comment": "Durch Einklammerung getilgt." - }, - { - "svgGroupId": "g242", - "measure": "3", - "system": "1", - "position": "3. Note", - "comment": "Klammerung rechts zeigt Tilgung an. Es ist nicht eindeutig, ob die so angezeigte Tilgung ab T. 2 4/8 beginnt (mit den Varianten in System 2–3) oder ob sie sich auch auf T. 1 ff. bezieht (mit den Varianten in Sk2.1.1 und Sk2.1.2." - }, - { - "svgGroupId": "g1295", - "measure": "3", - "system": "2", - "position": "4/8", - "comment": "Punktierte Achtelnote {{ref.getGlyph('[a]')}}c1 überschreibt radierte Achtelpause." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1245", + "measure": "1–3", + "system": "1", + "position": "", + "comment": "Text in Kurrentschrift." + }, + { + "svgGroupId": "text164", + "measure": "1", + "system": "1", + "position": "6/8", + "comment": "{{ref.getGlyph('[b]')}} nachgezogen (überschreibt Ansatz von {{ref.getGlyph('[#]')}} zu dis2?)." + }, + { + "svgGroupId": "g1254", + "measure": "2", + "system": "1", + "position": "1. Note", + "comment": "Durch Einkreisung getilgt." + }, + { + "svgGroupId": "text194", + "measure": "2", + "system": "1", + "position": "3/8", + "comment": "{{ref.getGlyph('[#]')}} nachgezogen (überschreibt {{ref.getGlyph('[a]')}}?)." + }, + { + "svgGroupId": "text338", + "measure": "2", + "system": "3", + "position": "letzte Note", + "comment": "Punkt unter der Note: Fleck oder Ansatz zu Notenkopf f?" + }, + { + "svgGroupId": "g1281", + "measure": "2
    bis 3", + "system": "3", + "position": "letzte Note
    3. Note", + "comment": "Durch Einklammerung getilgt." + }, + { + "svgGroupId": "g242", + "measure": "3", + "system": "1", + "position": "3. Note", + "comment": "Klammerung rechts zeigt Tilgung an. Es ist nicht eindeutig, ob die so angezeigte Tilgung ab T. 2 4/8 beginnt (mit den Varianten in System 2–3) oder ob sie sich auch auf T. 1 ff. bezieht (mit den Varianten in Sk2.1.1 und Sk2.1.2." + }, + { + "svgGroupId": "g1295", + "measure": "3", + "system": "2", + "position": "4/8", + "comment": "Punktierte Achtelnote {{ref.getGlyph('[a]')}}c1 überschreibt radierte Achtelpause." + } + ] } ], "linkBoxes": [ @@ -341,8 +361,7 @@ "id": "M_317_Sk2_1_1", "label": "M 317 Sk2.1.1", "description": [ - "Sk2.1.1 formuliert eine Variante des Anfangs von Sk2.1 auf der Grundlage des 1.–5. Reihentons von Reihe B in Sk2.", - "[Zu dieser Skizze gibt es keine textkritischen Kommentare.]" + "Sk2.1.1 formuliert eine Variante des Anfangs von Sk2.1 auf der Grundlage des 1.–5. Reihentons von Reihe B in Sk2." ], "comments": [], "linkBoxes": [ @@ -419,11 +438,16 @@ ], "comments": [ { - "svgGroupId": "g1105", - "measure": "3", - "system": "2", - "position": "", - "comment": "Durch Einklammerung getilgt." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1105", + "measure": "3", + "system": "2", + "position": "", + "comment": "Durch Einklammerung getilgt." + } + ] } ], "linkBoxes": [ @@ -496,8 +520,7 @@ "id": "M_317_Sk2_1_2_1", "label": "M 317 Sk2.1.2.1", "description": [ - "Sk2.1.2.1 formuliert eine rhythmisch-metrische Variante des Anfangs von Sk2.1.2.", - "[Zu dieser Skizze gibt es keine textkritischen Kommentare.]" + "Sk2.1.2.1 formuliert eine rhythmisch-metrische Variante des Anfangs von Sk2.1.2." ], "comments": [], "linkBoxes": [ @@ -570,8 +593,7 @@ "id": "M_317_Sk2_1_3", "label": "M 317 Sk2.1.3", "description": [ - "Die in Sk2.1.3 notierten Tonbuchstaben c, f, gis und a beziehen sich vermutlich auf noch fehlende Reihentöne bei der Niederschrift von Sk2 (Reihe B), Sk2.1 und Sk2.1.2.", - "[Zu dieser Skizze gibt es keine textkritischen Kommentare.]" + "Die in Sk2.1.3 notierten Tonbuchstaben c, f, gis und a beziehen sich vermutlich auf noch fehlende Reihentöne bei der Niederschrift von Sk2 (Reihe B), Sk2.1 und Sk2.1.2." ], "comments": [], "linkBoxes": [ @@ -648,25 +670,30 @@ ], "comments": [ { - "svgGroupId": "g1114", - "measure": "1
    bis 2", - "system": "3", - "position": "1. Note
    1. Note", - "comment": "Text in Kurrentschrift." - }, - { - "svgGroupId": "g1119", - "measure": "2", - "system": "3", - "position": "1. Note", - "comment": "Punktierung durch Einkreisung getilgt?" - }, - { - "svgGroupId": "g3069", - "measure": "2", - "system": "3", - "position": "1. Note", - "comment": "Pfeil zur Variante der Fortsetzung in Sk3.1." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1114", + "measure": "1
    bis 2", + "system": "3", + "position": "1. Note
    1. Note", + "comment": "Text in Kurrentschrift." + }, + { + "svgGroupId": "g1119", + "measure": "2", + "system": "3", + "position": "1. Note", + "comment": "Punktierung durch Einkreisung getilgt?" + }, + { + "svgGroupId": "g3069", + "measure": "2", + "system": "3", + "position": "1. Note", + "comment": "Pfeil zur Variante der Fortsetzung in Sk3.1." + } + ] } ], "linkBoxes": [ @@ -743,60 +770,65 @@ ], "comments": [ { - "svgGroupId": "g1203", - "measure": "vor 3
    bis 3", - "system": "4", - "position": "1. Note
    1. Note", - "comment": "Text in Kurrentschrift." - }, - { - "svgGroupId": "g1209", - "measure": "3", - "system": "4", - "position": "Taktanfang", - "comment": "Asterisk verweist auf Variante der Fortsetzung in Sk3.1.2." - }, - { - "svgGroupId": "g1213", - "measure": "{5–6}", - "system": "4", - "position": "", - "comment": "Durch Einklammerung getilgt. (Die Variante in System 3 wird allerdings nicht von der Einklammerung eingeschlossen.)" - }, - { - "svgGroupId": "g1218", - "measure": "{5}", - "system": "4", - "position": "1. Note", - "comment": "Ligaturbogen gestrichen." - }, - { - "svgGroupId": "g1206", - "measure": "{5}", - "system": "4", - "position": "1. Note", - "comment": "Pfeil unten rechts von Variante T. 4 in Sk3.1.1." - }, - { - "svgGroupId": "text228", - "measure": "{5}", - "system": "4", - "position": "6/8", - "comment": "I markiert hier als Reihenziffer vermutlich den wiederholten Beginn der in Sk3 T. 1–2 1. Note und in Sk3.1 fortgeführten Zwölftonreihe. Diese Reihe ist nicht identisch mit Gg in den Reihentabellen Sk3.1.3 und M 317 Sk5 / M 321 Sk1 / M 322 Sk1 in C (dort jeweils mit arabischer Ziffer 1 bezeichnet)." - }, - { - "svgGroupId": "g1241", - "measure": "{5}
    bis {6}", - "system": "4", - "position": "6/8
    3. Note", - "comment": "Text in Kurrentschrift." - }, - { - "svgGroupId": "g1225", - "measure": "{6}", - "system": "4", - "position": "1–2/8", - "comment": "Text: leuch[-]tet zusammengeschrieben." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1203", + "measure": "vor 3
    bis 3", + "system": "4", + "position": "1. Note
    1. Note", + "comment": "Text in Kurrentschrift." + }, + { + "svgGroupId": "g1209", + "measure": "3", + "system": "4", + "position": "Taktanfang", + "comment": "Asterisk verweist auf Variante der Fortsetzung in Sk3.1.2." + }, + { + "svgGroupId": "g1213", + "measure": "{5–6}", + "system": "4", + "position": "", + "comment": "Durch Einklammerung getilgt. (Die Variante in System 3 wird allerdings nicht von der Einklammerung eingeschlossen.)" + }, + { + "svgGroupId": "g1218", + "measure": "{5}", + "system": "4", + "position": "1. Note", + "comment": "Ligaturbogen gestrichen." + }, + { + "svgGroupId": "g1206", + "measure": "{5}", + "system": "4", + "position": "1. Note", + "comment": "Pfeil unten rechts von Variante T. 4 in Sk3.1.1." + }, + { + "svgGroupId": "text228", + "measure": "{5}", + "system": "4", + "position": "6/8", + "comment": "I markiert hier als Reihenziffer vermutlich den wiederholten Beginn der in Sk3 T. 1–2 1. Note und in Sk3.1 fortgeführten Zwölftonreihe. Diese Reihe ist nicht identisch mit Gg in den Reihentabellen Sk3.1.3 und M 317 Sk5 / M 321 Sk1 / M 322 Sk1 in C (dort jeweils mit arabischer Ziffer 1 bezeichnet)." + }, + { + "svgGroupId": "g1241", + "measure": "{5}
    bis {6}", + "system": "4", + "position": "6/8
    3. Note", + "comment": "Text in Kurrentschrift." + }, + { + "svgGroupId": "g1225", + "measure": "{6}", + "system": "4", + "position": "1–2/8", + "comment": "Text: leuch[-]tet zusammengeschrieben." + } + ] } ], "linkBoxes": [ @@ -887,11 +919,16 @@ ], "comments": [ { - "svgGroupId": "g312", - "measure": "5", - "system": "6", - "position": "", - "comment": "Halbe Note überschreibt Viertelnote." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g312", + "measure": "5", + "system": "6", + "position": "", + "comment": "Halbe Note überschreibt Viertelnote." + } + ] } ], "linkBoxes": [ @@ -926,39 +963,44 @@ ], "comments": [ { - "svgGroupId": "g798", - "measure": "3
    bis 5", - "system": "4", - "position": "1. Note
    1. Note", - "comment": "Text in Kurrentschrift." - }, - { - "svgGroupId": "g804", - "measure": "3", - "system": "4", - "position": "Taktanfang", - "comment": "Asterisk verweist auf Anschluss von Sk3.1." - }, - { - "svgGroupId": "g809", - "measure": "3", - "system": "4", - "position": "1. Note", - "comment": "Punktierung durch Einkreisung getilgt." - }, - { - "svgGroupId": "g929", - "measure": "5", - "system": "4", - "position": "1. Note", - "comment": "Punktierte Viertelnote überschreibt Halbe Note." - }, - { - "svgGroupId": "g1958", - "measure": "5", - "system": "4", - "position": "nach 1. Note", - "comment": "Durch Einklammerung abgegrenzt von Sk3.1." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g798", + "measure": "3
    bis 5", + "system": "4", + "position": "1. Note
    1. Note", + "comment": "Text in Kurrentschrift." + }, + { + "svgGroupId": "g804", + "measure": "3", + "system": "4", + "position": "Taktanfang", + "comment": "Asterisk verweist auf Anschluss von Sk3.1." + }, + { + "svgGroupId": "g809", + "measure": "3", + "system": "4", + "position": "1. Note", + "comment": "Punktierung durch Einkreisung getilgt." + }, + { + "svgGroupId": "g929", + "measure": "5", + "system": "4", + "position": "1. Note", + "comment": "Punktierte Viertelnote überschreibt Halbe Note." + }, + { + "svgGroupId": "g1958", + "measure": "5", + "system": "4", + "position": "nach 1. Note", + "comment": "Durch Einklammerung abgegrenzt von Sk3.1." + } + ] } ], "linkBoxes": [ @@ -1036,81 +1078,86 @@ "rowtable": true, "comments": [ { - "svgGroupId": "g4504", - "measure": "Bl. 38v", - "system": "5", - "position": "", - "comment": "Strich mit unklarer Bedeutung." - }, - { - "svgGroupId": "g310", - "measure": "Bl. 38v", - "system": "6", - "position": "Gg (1): vor 1. Reihenton", - "comment": "1 mit rotem Buntstift." - }, - { - "svgGroupId": "g104", - "measure": "Bl. 38v", - "system": "6", - "position": "Gg (1): 7. Reihenton", - "comment": "sic: kein {{ref.getGlyph('[a]')}}." - }, - { - "svgGroupId": "g1554", - "measure": "Bl. 38v", - "system": "6", - "position": "Gg (1): 10.–11. Reihenton", - "comment": "{{ref.getGlyph('[a]')}}a, {{ref.getGlyph('[a]')}}c1 durch Einkreisung getilgt und ersetzt durch c2 (sic: kein {{ref.getGlyph('[a]')}}), {{ref.getGlyph('[a]')}}a1." - }, - { - "svgGroupId": "g570", - "measure": "Bl. 38v", - "system": "6", - "position": "Kgis (2): vor 1. Reihenton", - "comment": "2 mit grünem Buntstift." - }, - { - "svgGroupId": "g1572", - "measure": "Bl. 38v", - "system": "6", - "position": "Kgis (2): 2.–3. Reihenton", - "comment": "{{ref.getGlyph('[a]')}}c1, {{ref.getGlyph('[a]')}}a durch Einkreisung getilgt und ersetzt durch a1, c2 (sic: keine {{ref.getGlyph('[a]')}})." - }, - { - "svgGroupId": "g318", - "measure": "Bl. 38v", - "system": "7", - "position": "Ug (3): vor 1. Reihenton", - "comment": "3 mit schwarzem Buntstift." - }, - { - "svgGroupId": "g1591", - "measure": "Bl. 38v", - "system": "7", - "position": "Ug (3): 10.–11. Reihenton", - "comment": "{{ref.getGlyph('[a]')}}f2, {{ref.getGlyph('[a]')}}d2 durch Einkreisung getilgt und ersetzt durch {{ref.getGlyph('[a]')}}d1, {{ref.getGlyph('[a]')}}f1." - }, - { - "svgGroupId": "g566", - "measure": "Bl. 38v", - "system": "7", - "position": "KUfis (4): vor 1. Reihenton", - "comment": "4 mit rotem Buntstift." - }, - { - "svgGroupId": "g1608", - "measure": "Bl. 38v", - "system": "7", - "position": "KUfis (4): 2.–3. Note", - "comment": "{{ref.getGlyph('[a]')}}d2, {{ref.getGlyph('[a]')}}f2 durch Einkreisung getilgt und ersetzt durch {{ref.getGlyph('[a]')}}f1, d1 (sic: kein {{ref.getGlyph('[a]')}})." - }, - { - "svgGroupId": "g1613", - "measure": "Bl. 38v", - "system": "6–7", - "position": "nach letzter Note", - "comment": "Klammer rechts mit rotem Buntstift." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g4504", + "measure": "Bl. 38v", + "system": "5", + "position": "", + "comment": "Strich mit unklarer Bedeutung." + }, + { + "svgGroupId": "g310", + "measure": "Bl. 38v", + "system": "6", + "position": "Gg (1): vor 1. Reihenton", + "comment": "1 mit rotem Buntstift." + }, + { + "svgGroupId": "g104", + "measure": "Bl. 38v", + "system": "6", + "position": "Gg (1): 7. Reihenton", + "comment": "sic: kein {{ref.getGlyph('[a]')}}." + }, + { + "svgGroupId": "g1554", + "measure": "Bl. 38v", + "system": "6", + "position": "Gg (1): 10.–11. Reihenton", + "comment": "{{ref.getGlyph('[a]')}}a, {{ref.getGlyph('[a]')}}c1 durch Einkreisung getilgt und ersetzt durch c2 (sic: kein {{ref.getGlyph('[a]')}}), {{ref.getGlyph('[a]')}}a1." + }, + { + "svgGroupId": "g570", + "measure": "Bl. 38v", + "system": "6", + "position": "Kgis (2): vor 1. Reihenton", + "comment": "2 mit grünem Buntstift." + }, + { + "svgGroupId": "g1572", + "measure": "Bl. 38v", + "system": "6", + "position": "Kgis (2): 2.–3. Reihenton", + "comment": "{{ref.getGlyph('[a]')}}c1, {{ref.getGlyph('[a]')}}a durch Einkreisung getilgt und ersetzt durch a1, c2 (sic: keine {{ref.getGlyph('[a]')}})." + }, + { + "svgGroupId": "g318", + "measure": "Bl. 38v", + "system": "7", + "position": "Ug (3): vor 1. Reihenton", + "comment": "3 mit schwarzem Buntstift." + }, + { + "svgGroupId": "g1591", + "measure": "Bl. 38v", + "system": "7", + "position": "Ug (3): 10.–11. Reihenton", + "comment": "{{ref.getGlyph('[a]')}}f2, {{ref.getGlyph('[a]')}}d2 durch Einkreisung getilgt und ersetzt durch {{ref.getGlyph('[a]')}}d1, {{ref.getGlyph('[a]')}}f1." + }, + { + "svgGroupId": "g566", + "measure": "Bl. 38v", + "system": "7", + "position": "KUfis (4): vor 1. Reihenton", + "comment": "4 mit rotem Buntstift." + }, + { + "svgGroupId": "g1608", + "measure": "Bl. 38v", + "system": "7", + "position": "KUfis (4): 2.–3. Note", + "comment": "{{ref.getGlyph('[a]')}}d2, {{ref.getGlyph('[a]')}}f2 durch Einkreisung getilgt und ersetzt durch {{ref.getGlyph('[a]')}}f1, d1 (sic: kein {{ref.getGlyph('[a]')}})." + }, + { + "svgGroupId": "g1613", + "measure": "Bl. 38v", + "system": "6–7", + "position": "nach letzter Note", + "comment": "Klammer rechts mit rotem Buntstift." + } + ] } ], "linkBoxes": [ @@ -1141,8 +1188,7 @@ "id": "M_317_Sk3_1_3_1", "label": "M 317 Sk3.1.3.1", "description": [ - "Sk3.1.3.1 notiert das Ergebnis der in Sk3.1.3 erkennbaren Änderung des 10.–11. Reihentons von Gg und Ug bzw. des 2.–3. Reihentons von Kgis und KUfis am Beispiel von Gg noch einmal in einem einheitlichen Oktavregister.", - "[Zu dieser Skizze gibt es keine textkritischen Kommentare.]" + "Sk3.1.3.1 notiert das Ergebnis der in Sk3.1.3 erkennbaren Änderung des 10.–11. Reihentons von Gg und Ug bzw. des 2.–3. Reihentons von Kgis und KUfis am Beispiel von Gg noch einmal in einem einheitlichen Oktavregister." ], "comments": [], "linkBoxes": [ @@ -1171,445 +1217,450 @@ ], "comments": [ { - "svgGroupId": "g678", - "measure": "{1A}", - "system": "10–12", - "position": "", - "comment": "Durch Einklammerung rechts getilgt." - }, - { - "svgGroupId": "g683", - "measure": "{1B}", - "system": "10–12", - "position": "", - "comment": "Durch Einklammerung rechts getilgt." - }, - { - "svgGroupId": "text334", - "measure": "vor 1C", - "system": "11", - "position": "1. Note", - "comment": "4 mit rotem Buntstift." - }, - { - "svgGroupId": "g687", - "measure": "1C", - "system": "11", - "position": "6/8", - "comment": "sic: Winkel markiert hier nicht das Ende, sondern den 11. Reihenton von KUfis (4). 12. Reihenton von KUfis (g) ist zugleich 1. Reihenton von Gg (1): siehe T. 2 System 10–11 jeweils 1. Note." - }, - { - "svgGroupId": "line20", - "measure": "nach 1C", - "system": "11–12", - "position": "", - "comment": "Taktstrich nachgezogen mit rotem Buntstift." - }, - { - "svgGroupId": "text580", - "measure": "2", - "system": "10", - "position": "1. Note", - "comment": "1 mit rotem Buntstift." - }, - { - "svgGroupId": "g1865", - "measure": "3B", - "system": "2", - "position": "1/8", - "comment": "zart gestrichen." - }, - { - "svgGroupId": "g1869", - "measure": "3B", - "system": "3", - "position": "3. Note", - "comment": "Winkel mit rotem Buntstift." - }, - { - "svgGroupId": "text1144", - "measure": "3B", - "system": "4", - "position": "2/8", - "comment": "3 mit rotem Buntstift." - }, - { - "svgGroupId": "g7843", - "measure": "3B", - "system": "3–4", - "position": "4.–6. Note", - "comment": "Durch Einkreisung getilgt." - }, - { - "svgGroupId": "text430", - "measure": "3B", - "system": "6", - "position": "1. Note", - "comment": "4 mit rotem Buntstift." - }, - { - "svgGroupId": "g8572", - "measure": "3B", - "system": "2", - "position": "5/8", - "comment": "Durch Einkreisung getilgt. Siehe Variante in System 1." - }, - { - "svgGroupId": "g1889", - "measure": "4", - "system": "2–4", - "position": "Taktanfang", - "comment": "Taktvorzeichnung 2/4 überschreibt 4/4." - }, - { - "svgGroupId": "g1899", - "measure": "5", - "system": "2", - "position": "1. Note", - "comment": "Punktierte Viertelnote überschreibt Halbe Note." - }, - { - "svgGroupId": "g1903", - "measure": "5", - "system": "2", - "position": "1. Note", - "comment": "Winkel mit rotem Buntstift." - }, - { - "svgGroupId": "g9301", - "measure": "5", - "system": "3–4", - "position": "(1–2/4)", - "comment": "Durch Einkreisung mit rotem Buntstift getilgt." - }, - { - "svgGroupId": "g1909", - "measure": "5", - "system": "5–6", - "position": "", - "comment": "Durch Streichung getilgt." - }, - { - "svgGroupId": "g1917", - "measure": "5", - "system": "3", - "position": "1. Note", - "comment": "u. 1 und Winkel mit rotem Buntstift." - }, - { - "svgGroupId": "g1925", - "measure": "5", - "system": "5", - "position": "1. Note", - "comment": "Beide Winkel und 1 mit rotem Buntstift." - }, - { - "svgGroupId": "g1929", - "measure": "5", - "system": "8", - "position": "3. Note", - "comment": "Winkel mit rotem Buntstift." - }, - { - "svgGroupId": "text806", - "measure": "5", - "system": "7", - "position": "1. Note", - "comment": "1 nachgezogen mit rotem Buntstift." - }, - { - "svgGroupId": "g1945", - "measure": "5", - "system": "2", - "position": "5/8", - "comment": "1 über dem System mit rotem Buntstift und radiert. 1 unter dem System mit rotem Buntstift. (Ziffern beziehen sich auf 6/8.)" - }, - { - "svgGroupId": "g2067", - "measure": "6", - "system": "2", - "position": "1.–2. Note", - "comment": "leuchtet zusammengeschrieben." - }, - { - "svgGroupId": "g10030", - "measure": "6", - "system": "3–4", - "position": "1. Pause bis
    1. Note", - "comment": "Durch Einkreisung getilgt." - }, - { - "svgGroupId": "g10759", - "measure": "6", - "system": "5", - "position": "1. Note", - "comment": "fis1 durch Einkreisung getilgt." - }, - { - "svgGroupId": "text1070", - "measure": "6", - "system": "4", - "position": "2. Note", - "comment": "[f] mit rotem Buntstift." - }, - { - "svgGroupId": "g11488", - "measure": "6", - "system": "5–6", - "position": "2.–6. Note", - "comment": "Durch Einkreisung getilgt." - }, - { - "svgGroupId": "text888", - "measure": "6", - "system": "3", - "position": "2.–4. Note", - "comment": "Triolenziffer nachgezogen mit rotem Buntstift." - }, - { - "svgGroupId": "g1871", - "measure": "6", - "system": "3", - "position": "letzte Note", - "comment": "Winkel mit rotem Buntstift." - }, - { - "svgGroupId": "text1078", - "measure": "6", - "system": "4", - "position": "8/8", - "comment": "3 nachgezogen mit schwarzem Buntstift." - }, - { - "svgGroupId": "g1165", - "measure": "7", - "system": "10–11", - "position": "Taktanfang", - "comment": "4/4 überschreibt 3/4." - }, - { - "svgGroupId": "text1148", - "measure": "7", - "system": "10", - "position": "3/8", - "comment": "3 nachgezogen mit schwarzem Buntstift. (Ziffer bezieht sich auf 1. Note.)" - }, - { - "svgGroupId": "g1228", - "measure": "7", - "system": "11", - "position": "8/8", - "comment": "Winkel nachgezogen mit schwarzem Buntstift." - }, - { - "svgGroupId": "g1233", - "measure": "vor 8", - "system": "12", - "position": "", - "comment": "Bassschlüssel gestrichen." - }, - { - "svgGroupId": "text1150", - "measure": "8", - "system": "11", - "position": "1. Note", - "comment": "2 mit grünem Buntstift." - }, - { - "svgGroupId": "g1236", - "measure": "9", - "system": "11", - "position": "(2/4)", - "comment": "Viertelpause über dem System durch Einkreisung getilgt?" - }, - { - "svgGroupId": "text1212", - "measure": "9", - "system": "11", - "position": "3. Note", - "comment": "sic: {{ref.getGlyph('[b]')}} (zu es2). Vermutlich Verschreibung für {{ref.getGlyph('[a]')}} (zu e2: 11. Reihenton von Kgis)." - }, - { - "svgGroupId": "g1247", - "measure": "9", - "system": "12", - "position": "2. Note", - "comment": "8–┐ nachgezogen mit grünem Buntstift." - }, - { - "svgGroupId": "text1152", - "measure": "9", - "system": "13", - "position": "1. Note", - "comment": "2 nachgezogen mit grünem Buntstift." - }, - { - "svgGroupId": "g1250", - "measure": "9", - "system": "11", - "position": "4.–5. Note", - "comment": "Durch Einkreisung getilgt." - }, - { - "svgGroupId": "g1254", - "measure": "9", - "system": "9", - "position": "letzte Note", - "comment": "Winkel mit schwarzem Buntstift und radiert." - }, - { - "svgGroupId": "g1445", - "measure": "9
    bis 10", - "system": "9", - "position": "letzte Note
    1. Note", - "comment": "einmal zusammengeschrieben." - }, - { - "svgGroupId": "g1264", - "measure": "10", - "system": "9", - "position": "1. Note", - "comment": "Winkel mit schwarzem Buntstift." - }, - { - "svgGroupId": "text1178", - "measure": "10", - "system": "9", - "position": "2. Note", - "comment": "1 mit rotem Buntstift." - }, - { - "svgGroupId": "g9931", - "measure": "10", - "system": "11–12", - "position": "1. Note", - "comment": "Durch Einkreisung getilgt." - }, - { - "svgGroupId": "g12115", - "measure": "12", - "system": "13–14", - "position": "Taktanfang", - "comment": "3/4 nachgezogen mit rotem Buntstift." - }, - { - "svgGroupId": "text1216", - "measure": "12", - "system": "8", - "position": "(1. Note)", - "comment": "molto [xx] radiert." - }, - { - "svgGroupId": "g1461", - "measure": "12", - "system": "9", - "position": "1/8", - "comment": "Text: Kleinschreibung wer[-den] überschrieben zu Großschreibung Wer[-den]." - }, - { - "svgGroupId": "g20105", - "measure": "12", - "system": "11", - "position": "1. Note", - "comment": "Winkel mit grünem Buntstift." - }, - { - "svgGroupId": "g1478", - "measure": "12", - "system": "9", - "position": "3.–5. Note", - "comment": "hingestellt zusammengeschrieben." - }, - { - "svgGroupId": "text1058", - "measure": "12", - "system": "13", - "position": "2. Note", - "comment": "4 nachgezogen mit rotem Buntstift." - }, - { - "svgGroupId": "text476", - "measure": "13", - "system": "16", - "position": "1. Note", - "comment": "gilt mit rotem Buntstift." - }, - { - "svgGroupId": "g12150", - "measure": "13", - "system": "15, 16", - "position": "1. Pause", - "comment": "Viertelpause überschreibt Achtelpause." - }, - { - "svgGroupId": "g12880", - "measure": "13", - "system": "14", - "position": "2. Note", - "comment": "Winkel mit rotem Buntstift." - }, - { - "svgGroupId": "g13611", - "measure": "13", - "system": "15", - "position": "(5/8)", - "comment": "Achtelpause gestrichen." - }, - { - "svgGroupId": "g14343", - "measure": "13", - "system": "14", - "position": "letzte Note", - "comment": "u. 4 gestrichen mit rotem Buntstift." - }, - { - "svgGroupId": "g15072", - "measure": "13", - "system": "14–15", - "position": "letzte Note", - "comment": "Pfeil mit rotem Buntstift." - }, - { - "svgGroupId": "g15803", - "measure": "13", - "system": "15", - "position": "letzte Note", - "comment": "Winkel gestrichen." - }, - { - "svgGroupId": "text474", - "measure": "14", - "system": "15–16", - "position": "Taktanfang", - "comment": "3 mit schwarzem Buntstift." - }, - { - "svgGroupId": "g17374", - "measure": "14", - "system": "15, 16", - "position": "1. Note", - "comment": "Achtelnote überschreibt Viertelnote." - }, - { - "svgGroupId": "g21745", - "measure": "14", - "system": "16", - "position": "1. Note", - "comment": "u. von u. 3 sowie Winkel mit rotem Buntstift." - }, - { - "svgGroupId": "g18830", - "measure": "14", - "system": "13", - "position": "2. Note", - "comment": "h (undeutlich, auch als c1 zu entziffern) durch Einklammerung getilgt und ersetzt durch h2." - }, - { - "svgGroupId": "g19559", - "measure": "14", - "system": "16", - "position": "letzte Note", - "comment": "Durch Einkreisung getilgt. Siehe Korrektur in T. 15." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g678", + "measure": "{1A}", + "system": "10–12", + "position": "", + "comment": "Durch Einklammerung rechts getilgt." + }, + { + "svgGroupId": "g683", + "measure": "{1B}", + "system": "10–12", + "position": "", + "comment": "Durch Einklammerung rechts getilgt." + }, + { + "svgGroupId": "text334", + "measure": "vor 1C", + "system": "11", + "position": "1. Note", + "comment": "4 mit rotem Buntstift." + }, + { + "svgGroupId": "g687", + "measure": "1C", + "system": "11", + "position": "6/8", + "comment": "sic: Winkel markiert hier nicht das Ende, sondern den 11. Reihenton von KUfis (4). 12. Reihenton von KUfis (g) ist zugleich 1. Reihenton von Gg (1): siehe T. 2 System 10–11 jeweils 1. Note." + }, + { + "svgGroupId": "line20", + "measure": "nach 1C", + "system": "11–12", + "position": "", + "comment": "Taktstrich nachgezogen mit rotem Buntstift." + }, + { + "svgGroupId": "text580", + "measure": "2", + "system": "10", + "position": "1. Note", + "comment": "1 mit rotem Buntstift." + }, + { + "svgGroupId": "g1865", + "measure": "3B", + "system": "2", + "position": "1/8", + "comment": "zart gestrichen." + }, + { + "svgGroupId": "g1869", + "measure": "3B", + "system": "3", + "position": "3. Note", + "comment": "Winkel mit rotem Buntstift." + }, + { + "svgGroupId": "text1144", + "measure": "3B", + "system": "4", + "position": "2/8", + "comment": "3 mit rotem Buntstift." + }, + { + "svgGroupId": "g7843", + "measure": "3B", + "system": "3–4", + "position": "4.–6. Note", + "comment": "Durch Einkreisung getilgt." + }, + { + "svgGroupId": "text430", + "measure": "3B", + "system": "6", + "position": "1. Note", + "comment": "4 mit rotem Buntstift." + }, + { + "svgGroupId": "g8572", + "measure": "3B", + "system": "2", + "position": "5/8", + "comment": "Durch Einkreisung getilgt. Siehe Variante in System 1." + }, + { + "svgGroupId": "g1889", + "measure": "4", + "system": "2–4", + "position": "Taktanfang", + "comment": "Taktvorzeichnung 2/4 überschreibt 4/4." + }, + { + "svgGroupId": "g1899", + "measure": "5", + "system": "2", + "position": "1. Note", + "comment": "Punktierte Viertelnote überschreibt Halbe Note." + }, + { + "svgGroupId": "g1903", + "measure": "5", + "system": "2", + "position": "1. Note", + "comment": "Winkel mit rotem Buntstift." + }, + { + "svgGroupId": "g9301", + "measure": "5", + "system": "3–4", + "position": "(1–2/4)", + "comment": "Durch Einkreisung mit rotem Buntstift getilgt." + }, + { + "svgGroupId": "g1909", + "measure": "5", + "system": "5–6", + "position": "", + "comment": "Durch Streichung getilgt." + }, + { + "svgGroupId": "g1917", + "measure": "5", + "system": "3", + "position": "1. Note", + "comment": "u. 1 und Winkel mit rotem Buntstift." + }, + { + "svgGroupId": "g1925", + "measure": "5", + "system": "5", + "position": "1. Note", + "comment": "Beide Winkel und 1 mit rotem Buntstift." + }, + { + "svgGroupId": "g1929", + "measure": "5", + "system": "8", + "position": "3. Note", + "comment": "Winkel mit rotem Buntstift." + }, + { + "svgGroupId": "text806", + "measure": "5", + "system": "7", + "position": "1. Note", + "comment": "1 nachgezogen mit rotem Buntstift." + }, + { + "svgGroupId": "g1945", + "measure": "5", + "system": "2", + "position": "5/8", + "comment": "1 über dem System mit rotem Buntstift und radiert. 1 unter dem System mit rotem Buntstift. (Ziffern beziehen sich auf 6/8.)" + }, + { + "svgGroupId": "g2067", + "measure": "6", + "system": "2", + "position": "1.–2. Note", + "comment": "leuchtet zusammengeschrieben." + }, + { + "svgGroupId": "g10030", + "measure": "6", + "system": "3–4", + "position": "1. Pause bis
    1. Note", + "comment": "Durch Einkreisung getilgt." + }, + { + "svgGroupId": "g10759", + "measure": "6", + "system": "5", + "position": "1. Note", + "comment": "fis1 durch Einkreisung getilgt." + }, + { + "svgGroupId": "text1070", + "measure": "6", + "system": "4", + "position": "2. Note", + "comment": "[f] mit rotem Buntstift." + }, + { + "svgGroupId": "g11488", + "measure": "6", + "system": "5–6", + "position": "2.–6. Note", + "comment": "Durch Einkreisung getilgt." + }, + { + "svgGroupId": "text888", + "measure": "6", + "system": "3", + "position": "2.–4. Note", + "comment": "Triolenziffer nachgezogen mit rotem Buntstift." + }, + { + "svgGroupId": "g1871", + "measure": "6", + "system": "3", + "position": "letzte Note", + "comment": "Winkel mit rotem Buntstift." + }, + { + "svgGroupId": "text1078", + "measure": "6", + "system": "4", + "position": "8/8", + "comment": "3 nachgezogen mit schwarzem Buntstift." + }, + { + "svgGroupId": "g1165", + "measure": "7", + "system": "10–11", + "position": "Taktanfang", + "comment": "4/4 überschreibt 3/4." + }, + { + "svgGroupId": "text1148", + "measure": "7", + "system": "10", + "position": "3/8", + "comment": "3 nachgezogen mit schwarzem Buntstift. (Ziffer bezieht sich auf 1. Note.)" + }, + { + "svgGroupId": "g1228", + "measure": "7", + "system": "11", + "position": "8/8", + "comment": "Winkel nachgezogen mit schwarzem Buntstift." + }, + { + "svgGroupId": "g1233", + "measure": "vor 8", + "system": "12", + "position": "", + "comment": "Bassschlüssel gestrichen." + }, + { + "svgGroupId": "text1150", + "measure": "8", + "system": "11", + "position": "1. Note", + "comment": "2 mit grünem Buntstift." + }, + { + "svgGroupId": "g1236", + "measure": "9", + "system": "11", + "position": "(2/4)", + "comment": "Viertelpause über dem System durch Einkreisung getilgt?" + }, + { + "svgGroupId": "text1212", + "measure": "9", + "system": "11", + "position": "3. Note", + "comment": "sic: {{ref.getGlyph('[b]')}} (zu es2). Vermutlich Verschreibung für {{ref.getGlyph('[a]')}} (zu e2: 11. Reihenton von Kgis)." + }, + { + "svgGroupId": "g1247", + "measure": "9", + "system": "12", + "position": "2. Note", + "comment": "8–┐ nachgezogen mit grünem Buntstift." + }, + { + "svgGroupId": "text1152", + "measure": "9", + "system": "13", + "position": "1. Note", + "comment": "2 nachgezogen mit grünem Buntstift." + }, + { + "svgGroupId": "g1250", + "measure": "9", + "system": "11", + "position": "4.–5. Note", + "comment": "Durch Einkreisung getilgt." + }, + { + "svgGroupId": "g1254", + "measure": "9", + "system": "9", + "position": "letzte Note", + "comment": "Winkel mit schwarzem Buntstift und radiert." + }, + { + "svgGroupId": "g1445", + "measure": "9
    bis 10", + "system": "9", + "position": "letzte Note
    1. Note", + "comment": "einmal zusammengeschrieben." + }, + { + "svgGroupId": "g1264", + "measure": "10", + "system": "9", + "position": "1. Note", + "comment": "Winkel mit schwarzem Buntstift." + }, + { + "svgGroupId": "text1178", + "measure": "10", + "system": "9", + "position": "2. Note", + "comment": "1 mit rotem Buntstift." + }, + { + "svgGroupId": "g9931", + "measure": "10", + "system": "11–12", + "position": "1. Note", + "comment": "Durch Einkreisung getilgt." + }, + { + "svgGroupId": "g12115", + "measure": "12", + "system": "13–14", + "position": "Taktanfang", + "comment": "3/4 nachgezogen mit rotem Buntstift." + }, + { + "svgGroupId": "text1216", + "measure": "12", + "system": "8", + "position": "(1. Note)", + "comment": "molto [xx] radiert." + }, + { + "svgGroupId": "g1461", + "measure": "12", + "system": "9", + "position": "1/8", + "comment": "Text: Kleinschreibung wer[-den] überschrieben zu Großschreibung Wer[-den]." + }, + { + "svgGroupId": "g20105", + "measure": "12", + "system": "11", + "position": "1. Note", + "comment": "Winkel mit grünem Buntstift." + }, + { + "svgGroupId": "g1478", + "measure": "12", + "system": "9", + "position": "3.–5. Note", + "comment": "hingestellt zusammengeschrieben." + }, + { + "svgGroupId": "text1058", + "measure": "12", + "system": "13", + "position": "2. Note", + "comment": "4 nachgezogen mit rotem Buntstift." + }, + { + "svgGroupId": "text476", + "measure": "13", + "system": "16", + "position": "1. Note", + "comment": "gilt mit rotem Buntstift." + }, + { + "svgGroupId": "g12150", + "measure": "13", + "system": "15, 16", + "position": "1. Pause", + "comment": "Viertelpause überschreibt Achtelpause." + }, + { + "svgGroupId": "g12880", + "measure": "13", + "system": "14", + "position": "2. Note", + "comment": "Winkel mit rotem Buntstift." + }, + { + "svgGroupId": "g13611", + "measure": "13", + "system": "15", + "position": "(5/8)", + "comment": "Achtelpause gestrichen." + }, + { + "svgGroupId": "g14343", + "measure": "13", + "system": "14", + "position": "letzte Note", + "comment": "u. 4 gestrichen mit rotem Buntstift." + }, + { + "svgGroupId": "g15072", + "measure": "13", + "system": "14–15", + "position": "letzte Note", + "comment": "Pfeil mit rotem Buntstift." + }, + { + "svgGroupId": "g15803", + "measure": "13", + "system": "15", + "position": "letzte Note", + "comment": "Winkel gestrichen." + }, + { + "svgGroupId": "text474", + "measure": "14", + "system": "15–16", + "position": "Taktanfang", + "comment": "3 mit schwarzem Buntstift." + }, + { + "svgGroupId": "g17374", + "measure": "14", + "system": "15, 16", + "position": "1. Note", + "comment": "Achtelnote überschreibt Viertelnote." + }, + { + "svgGroupId": "g21745", + "measure": "14", + "system": "16", + "position": "1. Note", + "comment": "u. von u. 3 sowie Winkel mit rotem Buntstift." + }, + { + "svgGroupId": "g18830", + "measure": "14", + "system": "13", + "position": "2. Note", + "comment": "h (undeutlich, auch als c1 zu entziffern) durch Einklammerung getilgt und ersetzt durch h2." + }, + { + "svgGroupId": "g19559", + "measure": "14", + "system": "16", + "position": "letzte Note", + "comment": "Durch Einkreisung getilgt. Siehe Korrektur in T. 15." + } + ] } ], "linkBoxes": [ @@ -1679,32 +1730,37 @@ ], "comments": [ { - "svgGroupId": "g25236", - "measure": "2", - "system": "14", - "position": "1. Note", - "comment": "Beide Winkel und 1 (Gg) mit rotem Buntstift. " - }, - { - "svgGroupId": "g1225", - "measure": "2", - "system": "13", - "position": "6/8–4/4", - "comment": "Decrescendogabel zu 4/4 überschrieben zu Decrescendogabel von 6/8–4/4." - }, - { - "svgGroupId": "g30323", - "measure": "{3}", - "system": "", - "position": "", - "comment": "Durch Einklammerung links und Streichung getilgt. Streichung mit rotem Buntstift." - }, - { - "svgGroupId": "g31053", - "measure": "{3}", - "system": "14", - "position": "letzte Note", - "comment": "Winkel mit rotem Buntstift." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g25236", + "measure": "2", + "system": "14", + "position": "1. Note", + "comment": "Beide Winkel und 1 (Gg) mit rotem Buntstift. " + }, + { + "svgGroupId": "g1225", + "measure": "2", + "system": "13", + "position": "6/8–4/4", + "comment": "Decrescendogabel zu 4/4 überschrieben zu Decrescendogabel von 6/8–4/4." + }, + { + "svgGroupId": "g30323", + "measure": "{3}", + "system": "", + "position": "", + "comment": "Durch Einklammerung links und Streichung getilgt. Streichung mit rotem Buntstift." + }, + { + "svgGroupId": "g31053", + "measure": "{3}", + "system": "14", + "position": "letzte Note", + "comment": "Winkel mit rotem Buntstift." + } + ] } ], "linkBoxes": [ @@ -1721,8 +1777,7 @@ "id": "M_317_Sk4_2", "label": "M 317 Sk4.2", "description": [ - "Sk4.2 formuliert vermutlich den Ansatz zu einer Variante der Singstimme in Sk4 T. 13.", - "[Zu dieser Skizze gibt es keine textkritischen Kommentare.]" + "Sk4.2 formuliert vermutlich den Ansatz zu einer Variante der Singstimme in Sk4 T. 13." ], "comments": [], "linkBoxes": [ @@ -1750,18 +1805,23 @@ ], "comments": [ { - "svgGroupId": "g35106", - "measure": "13", - "system": "16", - "position": "1. Note", - "comment": "sic: Verweisstrich führt zu Sk4 T. 14. Inhaltlich bezieht sich Sk4.3 jedoch auf Sk4 T. 13. " - }, - { - "svgGroupId": "g36576", - "measure": "13", - "system": "16", - "position": "letzte Note", - "comment": "Entzifferung von {{ref.getGlyph('[#]')}}ais unsicher: möglicherweise auch {{ref.getGlyph('[b]')}}b." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g35106", + "measure": "13", + "system": "16", + "position": "1. Note", + "comment": "sic: Verweisstrich führt zu Sk4 T. 14. Inhaltlich bezieht sich Sk4.3 jedoch auf Sk4 T. 13. " + }, + { + "svgGroupId": "g36576", + "measure": "13", + "system": "16", + "position": "letzte Note", + "comment": "Entzifferung von {{ref.getGlyph('[#]')}}ais unsicher: möglicherweise auch {{ref.getGlyph('[b]')}}b." + } + ] } ], "linkBoxes": [ @@ -1790,67 +1850,72 @@ "rowtable": true, "comments": [ { - "svgGroupId": "text440", - "measure": "Bl. 1r", - "system": "1", - "position": "Gg", - "comment": "Reihennummerierung 1 mit rotem Buntstift." - }, - { - "svgGroupId": "text682", - "measure": "Bl. 1r", - "system": "1", - "position": "Kgis", - "comment": "Reihennummerierung 2 mit rotem Buntstift." - }, - { - "svgGroupId": "text444", - "measure": "Bl. 1r", - "system": "2", - "position": "Ug", - "comment": "Reihennummerierung 3 mit rotem Buntstift." - }, - { - "svgGroupId": "text686", - "measure": "Bl. 1r", - "system": "2", - "position": "KUfis", - "comment": "Reihennummerierung 4 mit rotem Buntstift." - }, - { - "svgGroupId": "text450", - "measure": "Bl. 1r", - "system": "3", - "position": "Gc", - "comment": "Reihennummerierung 5 mit grünem Buntstift." - }, - { - "svgGroupId": "text688", - "measure": "Bl. 1r", - "system": "3", - "position": "Kcis", - "comment": "Reihennummerierung 6 mit grünem Buntstift." - }, - { - "svgGroupId": "text458", - "measure": "Bl. 1r", - "system": "4", - "position": "Uc", - "comment": "Reihennummerierung 7 mit grünem Buntstift." - }, - { - "svgGroupId": "text690", - "measure": "Bl. 1r", - "system": "4", - "position": "KUh", - "comment": "Reihennummerierung 8 mit grünem Buntstift." - }, - { - "svgGroupId": "g3291", - "measure": "Bl. 1r", - "system": "3–4", - "position": "", - "comment": "2. Lied mit blauem Buntstift. Akkoladenstrich mit blauem Buntstift nachgezogen." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "text440", + "measure": "Bl. 1r", + "system": "1", + "position": "Gg", + "comment": "Reihennummerierung 1 mit rotem Buntstift." + }, + { + "svgGroupId": "text682", + "measure": "Bl. 1r", + "system": "1", + "position": "Kgis", + "comment": "Reihennummerierung 2 mit rotem Buntstift." + }, + { + "svgGroupId": "text444", + "measure": "Bl. 1r", + "system": "2", + "position": "Ug", + "comment": "Reihennummerierung 3 mit rotem Buntstift." + }, + { + "svgGroupId": "text686", + "measure": "Bl. 1r", + "system": "2", + "position": "KUfis", + "comment": "Reihennummerierung 4 mit rotem Buntstift." + }, + { + "svgGroupId": "text450", + "measure": "Bl. 1r", + "system": "3", + "position": "Gc", + "comment": "Reihennummerierung 5 mit grünem Buntstift." + }, + { + "svgGroupId": "text688", + "measure": "Bl. 1r", + "system": "3", + "position": "Kcis", + "comment": "Reihennummerierung 6 mit grünem Buntstift." + }, + { + "svgGroupId": "text458", + "measure": "Bl. 1r", + "system": "4", + "position": "Uc", + "comment": "Reihennummerierung 7 mit grünem Buntstift." + }, + { + "svgGroupId": "text690", + "measure": "Bl. 1r", + "system": "4", + "position": "KUh", + "comment": "Reihennummerierung 8 mit grünem Buntstift." + }, + { + "svgGroupId": "g3291", + "measure": "Bl. 1r", + "system": "3–4", + "position": "", + "comment": "2. Lied mit blauem Buntstift. Akkoladenstrich mit blauem Buntstift nachgezogen." + } + ] } ] } diff --git a/src/assets/data/edition/series/1/section/5/op3/source-list.json b/src/assets/data/edition/series/1/section/5/op3/source-list.json index e631f3c36..38c1e2014 100644 --- a/src/assets/data/edition/series/1/section/5/op3/source-list.json +++ b/src/assets/data/edition/series/1/section/5/op3/source-list.json @@ -59,7 +59,7 @@ { "siglum": "H", "siglumAddendum": "", - "type": "Autograph von
    „An Bachesranft“ M 133: Textfassung 2.", + "type": "Autograph von
    „An Bachesranft“ M 135: Textfassung 2.", "location": "US-Wc, Moldenhauer Archives, Box-Folder: 58/9[b].", "hasDescription": true, "linkTo": "source_H" @@ -81,12 +81,13 @@ "linkTo": "source_J" }, { - "siglum": "[K]", + "siglum": "K", "siglumAddendum": "", + "missing": true, "type": "Stichvorlage für L.", "location": "Verschollen.", "hasDescription": false, - "linkTo": "source_K" + "linkTo": "" }, { "siglum": "L", diff --git a/src/assets/data/edition/series/1/section/5/op4/source-description.json b/src/assets/data/edition/series/1/section/5/op4/source-description.json index 124f4a996..37be3fe4b 100644 --- a/src/assets/data/edition/series/1/section/5/op4/source-description.json +++ b/src/assets/data/edition/series/1/section/5/op4/source-description.json @@ -780,6 +780,119 @@ ] } }, + { + "id": "source_G", + "siglum": "G", + "siglumAddendum": "", + "type": "Druck von „Ihr tratet zu dem Herde“ M 142: Textfassung 1.", + "location": "Beilage in: Der blaue Reiter, München: Piper, 1912.", + "description": { + "desc": [ + "Buch, 150 Seiten, Format (hoch) 296 × 215 mm, Einband: 305 × 320 mm. Beilagen mit Kompositionen von Arnold Schönberg, Alban Berg und Anton Webern zwischen S. [132] (vacat) und S. [133] (Inhaltsverzeichnis). (Es folgen: S. [134] vacat, S. [135]–140 Register der Reproduktionen, S. [141] vacat, S. [142–150] Werbeanzeigen.) Im konsultierten Exemplar (Berlin, Staatsbibliothek Preußischer Kulturbesitz, 1 B 20301) sind die Notenbeilagen (zusammen mit einer Anzeige „Moderne Galerie | Heinrich Tannhauser | MÜNCHEN THEATINERSTR. 7“) vermutlich nachträglich eingeheftet. Beilage Anton Webern: 1 Blatt, Format (hoch) 296 × ca. 222 mm, paginiert von 1 bis 2 recto oben rechts und verso oben links. Eine zweite Auflage des Buches von 1914 unterscheidet sich im Umfang (140 Seiten; die Werbeanzeigen fehlen) und Format ([hoch] 288 × 217 mm; Einband: 295 × 220 mm). Die Beilage mit der Komposition Anton Weberns unterscheidet sich in dieser Auflage ebenfalls im Format: (hoch) 280 × ca. 205 mm." + ], + "writingMaterialStrings": [], + "writingInstruments": { + "main": "", + "secondary": [] + }, + "titles": [ + "„Ihr tratet zu dem herde _ _ _ _“ aus dem „Jahr der Seele“ | von STEFAN GEORGE | Für eine Singstimme und Klavier von ANTON von WEBERN auf S. 1 oben Mitte" + ], + "dates": [], + "paginations": ["1 bis 2 auf S. 1–2 Außenecken oben"], + "measureNumbers": [], + "instrumentations": ["Gesang | Piano auf S. 1 System 1 | 2–3"], + "annotations": [], + "contents": [ + { + "item": "", + "itemLinkTo": "", + "itemDescription": "Druck von „Ihr tratet zu dem Herde“ M 142: Textfassung 1", + "folios": [ + { + "folio": "1", + "isPage": true, + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "1–3", + "measure": "1–2", + "linkTo": "" + } + ], + [ + { + "system": "4–6", + "measure": "3–5", + "linkTo": "" + } + ], + [ + { + "system": "7–9", + "measure": "6–8", + "linkTo": "" + } + ] + ] + }, + { + "folio": "2", + "isPage": true, + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "1–3", + "measure": "9–11", + "linkTo": "" + } + ], + [ + { + "system": "4–6", + "measure": "12–13", + "linkTo": "" + } + ], + [ + { + "system": "7–9", + "measure": "14–15", + "linkTo": "" + } + ] + ] + } + ] + } + ] + } + }, + { + "id": "source_GH", + "siglum": "G", + "siglumAddendum": "H", + "type": "Handexemplar von G mit Korrekturen Weberns: „Ihr tratet zu dem Herde“ M 142: Textfassung 1→2.", + "location": "US-NYpm, Dept. of Music Manuscripts and Books, PMM 21.", + "description": { + "desc": [ + "Siehe G. Format: hoch 296 × 219 mm. Rissspuren am linken Rand: von Bogen abgetrennt. Papierklebestreifen am rechten Rand von S. 2. Archivalische Eintragung PMM 21 auf S. 2 unten Mitte mit Bleistift." + ], + "titles": [ + "<I.> | „Ihr tratet zu dem herde _ _ _ _“ aus dem „Jahr der Seele“ | von STEFAN GEORGE | Für eine Singstimme und Klavier von ANTON von WEBERN <op[.] 2> auf S. 1 oben Mitte, <I.> mit schwarzer Tinte, <op[.] 2> mit roter Tinte" + ], + "dates": [], + "paginations": [], + "measureNumbers": [], + "instrumentations": [], + "annotations": [], + "contents": [] + } + }, { "id": "source_H", "siglum": "H", @@ -1566,119 +1679,6 @@ ] } }, - { - "id": "source_G", - "siglum": "G", - "siglumAddendum": "", - "type": "Druck von „Ihr tratet zu dem Herde“ M 142: Textfassung 1.", - "location": "Beilage in: Der blaue Reiter, München: Piper, 1912.", - "description": { - "desc": [ - "Buch, 150 Seiten, Format (hoch) 296 × 215 mm, Einband: 305 × 320 mm. Beilagen mit Kompositionen von Arnold Schönberg, Alban Berg und Anton Webern zwischen S. [132] (vacat) und S. [133] (Inhaltsverzeichnis). (Es folgen: S. [134] vacat, S. [135]–140 Register der Reproduktionen, S. [141] vacat, S. [142–150] Werbeanzeigen.) Im konsultierten Exemplar (Berlin, Staatsbibliothek Preußischer Kulturbesitz, 1 B 20301) sind die Notenbeilagen (zusammen mit einer Anzeige „Moderne Galerie | Heinrich Tannhauser | MÜNCHEN THEATINERSTR. 7“) vermutlich nachträglich eingeheftet. Beilage Anton Webern: 1 Blatt, Format (hoch) 296 × ca. 222 mm, paginiert von 1 bis 2 recto oben rechts und verso oben links. Eine zweite Auflage des Buches von 1914 unterscheidet sich im Umfang (140 Seiten; die Werbeanzeigen fehlen) und Format ([hoch] 288 × 217 mm; Einband: 295 × 220 mm). Die Beilage mit der Komposition Anton Weberns unterscheidet sich in dieser Auflage ebenfalls im Format: (hoch) 280 × ca. 205 mm." - ], - "writingMaterialStrings": [], - "writingInstruments": { - "main": "", - "secondary": [] - }, - "titles": [ - "„Ihr tratet zu dem herde _ _ _ _“ aus dem „Jahr der Seele“ | von STEFAN GEORGE | Für eine Singstimme und Klavier von ANTON von WEBERN auf S. 1 oben Mitte" - ], - "dates": [], - "paginations": ["1 bis 2 auf S. 1–2 Außenecken oben"], - "measureNumbers": [], - "instrumentations": ["Gesang | Piano auf S. 1 System 1 | 2–3"], - "annotations": [], - "contents": [ - { - "item": "", - "itemLinkTo": "", - "itemDescription": "Druck von „Ihr tratet zu dem Herde“ M 142: Textfassung 1", - "folios": [ - { - "folio": "1", - "isPage": true, - "folioLinkTo": "", - "folioDescription": "", - "systemGroups": [ - [ - { - "system": "1–3", - "measure": "1–2", - "linkTo": "" - } - ], - [ - { - "system": "4–6", - "measure": "3–5", - "linkTo": "" - } - ], - [ - { - "system": "7–9", - "measure": "6–8", - "linkTo": "" - } - ] - ] - }, - { - "folio": "2", - "isPage": true, - "folioLinkTo": "", - "folioDescription": "", - "systemGroups": [ - [ - { - "system": "1–3", - "measure": "9–11", - "linkTo": "" - } - ], - [ - { - "system": "4–6", - "measure": "12–13", - "linkTo": "" - } - ], - [ - { - "system": "7–9", - "measure": "14–15", - "linkTo": "" - } - ] - ] - } - ] - } - ] - } - }, - { - "id": "source_GH", - "siglum": "G", - "siglumAddendum": "H", - "type": "Handexemplar von G mit Korrekturen Weberns: „Ihr tratet zu dem Herde“ M 142: Textfassung 1→2.", - "location": "US-NYpm, Dept. of Music Manuscripts and Books, PMM 21.", - "description": { - "desc": [ - "Siehe G. Format: hoch 296 × 219 mm. Rissspuren am linken Rand: von Bogen abgetrennt. Papierklebestreifen am rechten Rand von S. 2. Archivalische Eintragung PMM 21 auf S. 2 unten Mitte mit Bleistift." - ], - "titles": [ - "<I.> | „Ihr tratet zu dem herde _ _ _ _“ aus dem „Jahr der Seele“ | von STEFAN GEORGE | Für eine Singstimme und Klavier von ANTON von WEBERN <op[.] 2> auf S. 1 oben Mitte, <I.> mit schwarzer Tinte, <op[.] 2> mit roter Tinte" - ], - "dates": [], - "paginations": [], - "measureNumbers": [], - "instrumentations": [], - "annotations": [], - "contents": [] - } - }, { "id": "source_J", "siglum": "J", diff --git a/src/assets/data/edition/series/1/section/5/op4/source-list.json b/src/assets/data/edition/series/1/section/5/op4/source-list.json index f09b7fae0..5d173422c 100644 --- a/src/assets/data/edition/series/1/section/5/op4/source-list.json +++ b/src/assets/data/edition/series/1/section/5/op4/source-list.json @@ -17,12 +17,13 @@ "linkTo": "source_B" }, { - "siglum": "[C]", + "siglum": "C", "siglumAddendum": "", + "missing": true, "type": "Autograph von
    „Ihr tratet zu dem Herde“ M 142: Textfassung 1.", "location": "Verschollen.", "hasDescription": false, - "linkTo": "source_C" + "linkTo": "" }, { "siglum": "D", @@ -33,26 +34,28 @@ "linkTo": "source_D" }, { - "siglum": "[E]", + "siglum": "E", "siglumAddendum": "", + "missing": true, "type": "Abschrift fremder Hand von
    „Ihr tratet zu dem Herde“ M 142: Textfassung 1.", "location": "Verschollen.", "hasDescription": false, - "linkTo": "source_E" + "linkTo": "" }, { - "siglum": "[F]", + "siglum": "F", "siglumAddendum": "", + "missing": true, "type": "Korrekturfahne von G.", "location": "Verschollen.", "hasDescription": false, - "linkTo": "source_F" + "linkTo": "" }, { "siglum": "G", "siglumAddendum": "", "type": "Druck von
    „Ihr tratet zu dem Herde“ M 142: Textfassung 1.", - "location": "Beilage in: Der blaue Reiter, München: Piper, 1912.", + "location": "Beilage in: Der blaue Reiter, München: Piper, 1912.", "hasDescription": true, "linkTo": "source_G" }, @@ -75,7 +78,7 @@ { "siglum": "I", "siglumAddendum": "", - "type": "Abschrift fremder Hand von Fünf Lieder nach Gedichten von Stefan George op. 4:
    IEingang („Welt der Gestalten“) M 138: Textfassung 3
    II„Noch zwingt mich Treue“ M 139: Textfassung 3
    III„Ja Heil und Dank dir“ M 140: Textfassung 2
    IV„So ich traurig bin“ M 141: Textfassung 2
    V„Ihr tratet zu dem Herde“ M 142: Textfassung 3.
    Stichvorlage für J.", + "type": "Abschrift fremder Hand von Fünf Lieder nach Gedichten von Stefan George op. 4:
    IEingang („Welt der Gestalten“) M 138: Textfassung 3
    II„Noch zwingt mich Treue“ M 139: Textfassung 3
    III„Ja Heil und Dank dir“ M 140: Textfassung 2
    IV„So ich traurig bin“ M 141: Textfassung 2
    V„Ihr tratet zu dem Herde“ M 142: Textfassung 3.
    Stichvorlage für J.", "location": "US-NYpm, Dept. of Music Manuscripts and Books, Robert Owen Lehman Collection, W376.L716.", "hasDescription": true, "linkTo": "source_I" diff --git a/src/assets/data/edition/series/2/section/2a/m22/source-description.json b/src/assets/data/edition/series/2/section/2a/m22/source-description.json index 0b4872e83..6f5e4ec6a 100644 --- a/src/assets/data/edition/series/2/section/2a/m22/source-description.json +++ b/src/assets/data/edition/series/2/section/2a/m22/source-description.json @@ -8,10 +8,10 @@ "location": "CH-Bps, Sammlung Anton Webern.", "description": { "desc": [ - "1 Blatt: Das Blatt ist Bestandteil (Bl. 4) eines größeren Konvolutes bestehend aus 1 Blatt (Bl. 1), 1 Bogen (Bl. 2/3) und 1 Blatt (Bl. 4). Horizontale Knickfalte. Stockflecken unten mittig-rechts. Ecke unten links abgerissen (inkl. Firmenzeichen auf 1r). Rissspuren am linken Rand: von Bogen abgetrennt." + "1 Blatt (Bl. 1). Horizontale Knickfalte. Stockflecken unten mittig-rechts. Ecke unten links abgerissen (vermutlich inkl. Firmenzeichen auf 1r). Rissspuren am linken Rand: von Bogen abgetrennt." ], "writingMaterialStrings": [ - "Notenpapier, 28 Systeme, Format: hoch 343 × 264 mm, Firmenzeichen abgerissen" + "Notenpapier, 28 Systeme, Format: hoch 343 × 264 mm. Firmenzeichen: vermutlich [J.E. & Co.] | No. 9 | 28 linig. unten links auf Bl. 1r" ], "writingInstruments": { "main": "schwarze Tinte", @@ -501,7 +501,7 @@ "location": "CH-Bps, Sammlung Anton Webern.", "description": { "desc": [ - "1 Blatt. Rissspuren am linken Rand: von Bogen abgetrennt. Horizontale und vertikale Knickfalte, diagonale Knickfalte unten rechts." + "1 Blatt (Bl. 1). Rissspuren am linken Rand: von Bogen abgetrennt. Horizontale und vertikale Knickfalte, diagonale Knickfalte unten rechts." ], "writingMaterialStrings": [ "Notenpapier, 18 Systeme, Format: hoch 347 × 267 mm, Firmenzeichen ### unten links auf Bl. 1r" @@ -855,7 +855,7 @@ { "item": "M 32", "itemLinkTo": {}, - "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M 32 Textfassung 2)", + "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M 32: Textfassung 2)", "folios": [ { "folio": "1v", @@ -890,7 +890,7 @@ { "item": "M 32 Sk3", "itemLinkTo": {}, - "itemDescription": "(Skizze zu Studienkomposition für Klavier M 32 Textfassung 3)", + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 32: Textfassung 3)", "folios": [ { "folio": "1v", @@ -911,7 +911,7 @@ { "item": "M 32 Sk4", "itemLinkTo": {}, - "itemDescription": "(Skizze zu Studienkomposition für Klavier M 32 Textfassung 3)", + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 32: Textfassung 3)", "folios": [ { "folio": "1v", @@ -953,7 +953,7 @@ { "item": "M 32 Sk5", "itemLinkTo": {}, - "itemDescription": "(Skizze zu Studienkomposition für Klavier M 32 Textfassung 3)", + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 32: Textfassung 3)", "folios": [ { "folio": "1v", @@ -974,7 +974,7 @@ { "item": "M 32 Sk4.1", "itemLinkTo": {}, - "itemDescription": "(Skizze zu Studienkomposition für Klavier M 32 Textfassung 3)", + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 32: Textfassung 3)", "folios": [ { "folio": "1v", @@ -1027,7 +1027,7 @@ "location": "CH-Bps, Sammlung Anton Webern.", "description": { "desc": [ - "1 Blatt. Horizontale Knickfalte. Zahlreiche Risse und Knicke am rechten, oberen und unteren Rand. Rötliche Verfärbung oben links und rechts. Rissspuren am linken Rand: von Bogen abgetrennt." + "1 Blatt (Bl. 1). Horizontale Knickfalte. Zahlreiche Risse und Knicke am rechten, oberen und unteren Rand. Rötliche Verfärbung oben links und rechts. Rissspuren am linken Rand: von Bogen abgetrennt." ], "writingMaterialStrings": [ "Notenpapier, 28 Systeme, Format: hoch 347 × 264 mm, Firmenzeichen ### unten links auf Bl. 1r" @@ -1345,7 +1345,7 @@ "location": "CH-Bps, Sammlung Anton Webern.", "description": { "desc": [ - "1 Blatt: Linke obere Ecke mit Bleistift eingefärbt. Rissspuren am rechten Rand: von Bogen abgetrennt. Horizontale und vertikale Knickfalte." + "1 Blatt (Bl. 1). Linke obere Ecke mit Bleistift eingefärbt. Rissspuren am rechten Rand: von Bogen abgetrennt. Horizontale und vertikale Knickfalte." ], "writingMaterialStrings": [ "Notenpapier, 18 Systeme, Format: hoch 347 × 266 mm, Firmenzeichen: [J.E. & Co.] | No. 5 | 18 linig. unten links auf Bl. 1v" @@ -1686,7 +1686,7 @@ "location": "CH-Bps, Sammlung Anton Webern.", "description": { "desc": [ - "1 Bogen (Bl. 1/2): Der Bogen ist Bestandteil (Bl. 1/2) eines größeren Konvoluts aus 2 Bögen (Bl. 1/2, 3/4), 1 Blatt (Bl. 5) und 1 Bogen (Bl. 6/7). Horizontale und vertikale Knickfalte, seitlich leicht eingerissen." + "1 Bogen (Bl. 1/2). Horizontale und vertikale Knickfalte, seitlich leicht eingerissen." ], "writingMaterialStrings": [ "Notenpapier, 28 Systeme, Format: hoch 342 × 264 mm, Firmenzeichen: [J.E. & Co.] | No. 9 | 28 linig. unten links auf Bl. 11–2r" @@ -3334,10 +3334,10 @@ "location": "CH-Bps, Sammlung Anton Webern.", "description": { "desc": [ - "1 Blatt (Bl. 1), 1 Bogen (Bl. 2/3): Blatt und Bogen sind Bestandteil (Bl. 1, 2/3) eines größeren Konvolutes bestehend aus 1 Blatt (Bl. 1), 1 Bogen (Bl. 2/3) und 1 Blatt (Bl. 4). Horizontale Knickfalte auf Blatt und Bogen. Kleiner Stockfleck oben rechts auf Blatt und Bogen. Ecke unten rechts von Bl. 1 abgerissen. Bogen unten in der Falte eingerissen." + "1 Blatt (Bl. 1), 1 Bogen (Bl. 2/3). Horizontale Knickfalte auf Blatt und Bogen. Kleiner Stockfleck oben rechts auf Blatt und Bogen. Ecke unten rechts von Bl. 1 abgerissen. Bogen unten in der Falte eingerissen." ], "writingMaterialStrings": [ - "Notenpapier, 28 Systeme, Format: hoch 343 × 264 mm, Firmenzeichen ### unten links auf Bl. 1r–3r" + "Notenpapier, 28 Systeme, Format: hoch 343 × 264 mm, Firmenzeichen ### unten links auf Bl. 1r, 2r und 3r" ], "writingInstruments": { "main": "schwarze Tinte", @@ -3353,7 +3353,7 @@ { "item": "M* 409", "itemLinkTo": {}, - "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M* 409 Textfassung 1)", + "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M* 409: Textfassung 1)", "folios": [ { "folio": "1r", @@ -3381,7 +3381,7 @@ { "item": "M* 409", "itemLinkTo": {}, - "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M* 409 Textfassung 2)", + "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M* 409: Textfassung 2)", "folios": [ { "folio": "1r", diff --git a/src/assets/data/edition/series/2/section/2a/m22/textcritics.json b/src/assets/data/edition/series/2/section/2a/m22/textcritics.json index afe5fb1cd..30e18e066 100644 --- a/src/assets/data/edition/series/2/section/2a/m22/textcritics.json +++ b/src/assets/data/edition/series/2/section/2a/m22/textcritics.json @@ -6,130 +6,114 @@ "description": [], "comments": [ { - "svgGroupId": "", - "measure": "Var. X", - "system": "", - "position": "", - "comment": "" - }, - { - "svgGroupId": "g1", - "measure": "8", - "system": "Klav.", - "position": "Taktende", - "comment": "Schlussstrich ergänzt. F: Einfacher Taktstrich." - }, - { - "svgGroupId": "", - "measure": "Var. XI", - "system": "", - "position": "", - "comment": "" - }, - { - "svgGroupId": "g2", - "measure": "1", - "system": "Klav. o.", - "position": "1. Note", - "comment": "Gemeinsamer Notenkopf für Ober- und Unterstimmenschicht korrigiert zu zwei separate Notenköpfe." - }, - { - "svgGroupId": "g3", - "measure": "2", - "system": "Klav. o.", - "position": "1. Note", - "comment": "Gemeinsamer Notenkopf für Ober- und Unterstimmenschicht korrigiert zu zwei separate Notenköpfe." - }, - { - "svgGroupId": "", - "measure": "Var. XIII", - "system": "", - "position": "", - "comment": "" - }, - { - "svgGroupId": "g4", - "measure": "6", - "system": "Klav. o.", - "position": "4/8", - "comment": "Viertelnote korrigiert zu Achtelnote mit Blick auf metrischen Kontext." - }, - { - "svgGroupId": "", - "measure": "Var. XVII", - "system": "", - "position": "", - "comment": "" - }, - { - "svgGroupId": "g5", - "measure": "3", - "system": "Klav. o.", - "position": "1. Note", - "comment": "Oberstimmenschicht: Augmentationspunkt weggelassen mit Blick auf metrischen Kontext." - }, - { - "svgGroupId": "", - "measure": "Var. XIX", - "system": "", - "position": "", - "comment": "" - }, - { - "svgGroupId": "g6", - "measure": "1", - "system": "Klav. u.", - "position": "1. Note", - "comment": "G korrigiert zu A mit Blick auf harmonischen Kontext." - }, - { - "svgGroupId": "g7", - "measure": "8", - "system": "Klav.", - "position": "Taktende", - "comment": "Schlussstrich ergänzt. F: Einfacher Taktstrich." - }, - { - "svgGroupId": "", - "measure": "Var. XX", - "system": "", - "position": "", - "comment": "" - }, - { - "svgGroupId": "g8", - "measure": "3", - "system": "Klav. u.", - "position": "3/4", - "comment": "G1 korrigiert zu H1 mit Blick auf harmonischen Kontext." - }, - { - "svgGroupId": "", - "measure": "Var. XXI", - "system": "", - "position": "", - "comment": "" - }, - { - "svgGroupId": "g3957", - "measure": "5", - "system": "2. Gg.", - "position": "letzte Note", - "comment": "Viertelnote korrigiert zu Achtelnote mit Blick auf metrischen Kontext." - }, - { - "svgGroupId": "", - "measure": "Var. XXII", - "system": "", - "position": "", - "comment": "" - }, - { - "svgGroupId": "g2199", - "measure": "8", - "system": "Vlc.", - "position": "1. Note", - "comment": "Augmentationspunkt weggelassen mit Blick auf metrischen Kontext." + "blockHeader": "Var. X", + "blockComments": [ + { + "svgGroupId": "g1", + "measure": "8", + "system": "Klav.", + "position": "Taktende", + "comment": "Schlussstrich ergänzt. F: Einfacher Taktstrich." + } + ] + }, + { + "blockHeader": "Var. XI", + "blockComments": [ + { + "svgGroupId": "g2", + "measure": "1", + "system": "Klav. o.", + "position": "1. Note", + "comment": "Gemeinsamer Notenkopf für Ober- und Unterstimmenschicht korrigiert zu zwei separate Notenköpfe." + }, + { + "svgGroupId": "g3", + "measure": "2", + "system": "Klav. o.", + "position": "1. Note", + "comment": "Gemeinsamer Notenkopf für Ober- und Unterstimmenschicht korrigiert zu zwei separate Notenköpfe." + } + ] + }, + { + "blockHeader": "Var. XIII", + "blockComments": [ + { + "svgGroupId": "g4", + "measure": "6", + "system": "Klav. o.", + "position": "4/8", + "comment": "Viertelnote korrigiert zu Achtelnote mit Blick auf metrischen Kontext." + } + ] + }, + { + "blockHeader": "Var. XVII", + "blockComments": [ + { + "svgGroupId": "g5", + "measure": "3", + "system": "Klav. o.", + "position": "1. Note", + "comment": "Oberstimmenschicht: Augmentationspunkt weggelassen mit Blick auf metrischen Kontext." + } + ] + }, + { + "blockHeader": "Var. XIX", + "blockComments": [ + { + "svgGroupId": "g6", + "measure": "1", + "system": "Klav. u.", + "position": "1. Note", + "comment": "G korrigiert zu A mit Blick auf harmonischen Kontext." + }, + { + "svgGroupId": "g7", + "measure": "8", + "system": "Klav.", + "position": "Taktende", + "comment": "Schlussstrich ergänzt. F: Einfacher Taktstrich." + } + ] + }, + { + "blockHeader": "Var. XX", + "blockComments": [ + { + "svgGroupId": "g8", + "measure": "3", + "system": "Klav. u.", + "position": "3/4", + "comment": "G1 korrigiert zu H1 mit Blick auf harmonischen Kontext." + } + ] + }, + { + "blockHeader": "Var. XXI", + "blockComments": [ + { + "svgGroupId": "g3957", + "measure": "5", + "system": "2. Gg.", + "position": "letzte Note", + "comment": "Viertelnote korrigiert zu Achtelnote mit Blick auf metrischen Kontext." + } + ] + }, + { + "blockHeader": "Var. XXII", + "blockComments": [ + { + "svgGroupId": "g2199", + "measure": "8", + "system": "Vlc.", + "position": "1. Note", + "comment": "Augmentationspunkt weggelassen mit Blick auf metrischen Kontext." + } + ] } ], "linkBoxes": [] @@ -140,32 +124,37 @@ "description": ["M 22 Sk1 entwirft das Thema der Variationen von M 22."], "comments": [ { - "svgGroupId": "g339", - "measure": "4", - "system": "23", - "position": "", - "comment": "Noten pauschal gestrichen." - }, - { - "svgGroupId": "g345", - "measure": "5", - "system": "22", - "position": "1. Pause", - "comment": "Punktierte Achtelpause überschreibt Viertelnote a1" - }, - { - "svgGroupId": "g350", - "measure": "7", - "system": "22", - "position": "1.–2. Note", - "comment": "Oberstimmenschicht: Balkierung überschreibt Achtelfähnchen." - }, - { - "svgGroupId": "g354", - "measure": "7", - "system": "22", - "position": "3/4", - "comment": "e2 gestrichen." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g339", + "measure": "4", + "system": "23", + "position": "", + "comment": "Noten pauschal gestrichen." + }, + { + "svgGroupId": "g345", + "measure": "5", + "system": "22", + "position": "1. Pause", + "comment": "Punktierte Achtelpause überschreibt Viertelnote a1" + }, + { + "svgGroupId": "g350", + "measure": "7", + "system": "22", + "position": "1.–2. Note", + "comment": "Oberstimmenschicht: Balkierung überschreibt Achtelfähnchen." + }, + { + "svgGroupId": "g354", + "measure": "7", + "system": "22", + "position": "3/4", + "comment": "e2 gestrichen." + } + ] } ] }, @@ -175,32 +164,37 @@ "description": ["M 22 Sk2 entwirft Var. I von M 22."], "comments": [ { - "svgGroupId": "g410", - "measure": "3", - "system": "28", - "position": "6/16", - "comment": "a1 überschreibt h1." - }, - { - "svgGroupId": "g416", - "measure": "5", - "system": "27", - "position": "3/4", - "comment": "Viertelnote cis gestrichen." - }, - { - "svgGroupId": "g420", - "measure": "5", - "system": "28", - "position": "12/16", - "comment": "cis2 gestrichen." - }, - { - "svgGroupId": "g425", - "measure": "7", - "system": "27", - "position": "2/4", - "comment": "Viertelpause überschreibt Viertelnote e." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g410", + "measure": "3", + "system": "28", + "position": "6/16", + "comment": "a1 überschreibt h1." + }, + { + "svgGroupId": "g416", + "measure": "5", + "system": "27", + "position": "3/4", + "comment": "Viertelnote cis gestrichen." + }, + { + "svgGroupId": "g420", + "measure": "5", + "system": "28", + "position": "12/16", + "comment": "cis2 gestrichen." + }, + { + "svgGroupId": "g425", + "measure": "7", + "system": "27", + "position": "2/4", + "comment": "Viertelpause überschreibt Viertelnote e." + } + ] } ] }, @@ -210,130 +204,135 @@ "description": ["M 22 Sk3 entwirft Var. II von M 22."], "comments": [ { - "svgGroupId": "g496", - "measure": "{1A}", - "system": "25", - "position": "", - "comment": "Noten pauschal gestrichen." - }, - { - "svgGroupId": "g502", - "measure": "1B", - "system": "26", - "position": "5/8", - "comment": "Notenkopf a1 radiert." - }, - { - "svgGroupId": "g507", - "measure": "3", - "system": "26", - "position": "1. Pause", - "comment": "Punktierte Achtelpause überschreibt Viertelpause." - }, - { - "svgGroupId": "g519", - "measure": "3", - "system": "25", - "position": "3–4/16", - "comment": "h–a gestrichen." - }, - { - "svgGroupId": "g514", - "measure": "3", - "system": "26", - "position": "4/8", - "comment": "Achtelnote gis1/h gestrichen." - }, - { - "svgGroupId": "g524", - "measure": "3", - "system": "25", - "position": "7–8/16", - "comment": "fis–e gestrichen." - }, - { - "svgGroupId": "g1476", - "measure": "3", - "system": "26", - "position": "5/8", - "comment": "h1/d2 überschreibt a1/c2." - }, - { - "svgGroupId": "g530", - "measure": "3", - "system": "25", - "position": "11/16", - "comment": "f überschreibt g." - }, - { - "svgGroupId": "g549", - "measure": "3", - "system": "25", - "position": "12/16", - "comment": "e gestrichen." - }, - { - "svgGroupId": "g8", - "measure": "4", - "system": "26", - "position": "1. Pause", - "comment": "Punktierte Achtelpause überschreibt Viertelpause." - }, - { - "svgGroupId": "g554", - "measure": "4", - "system": "26", - "position": "4/16", - "comment": "gis1 gestrichen." - }, - { - "svgGroupId": "g1328", - "measure": "4", - "system": "25", - "position": "5–7/16", - "comment": "gis–a–h überschreibt e–f–e." - }, - { - "svgGroupId": "g563", - "measure": "{5A}", - "system": "", - "position": "", - "comment": "Takt pauschal gestrichen." - }, - { - "svgGroupId": "g1341", - "measure": "5B", - "system": "26", - "position": "3/8", - "comment": "h2 überschreibt a2." - }, - { - "svgGroupId": "g584", - "measure": "5B", - "system": "26", - "position": "6/8", - "comment": "c2 gestrichen." - }, - { - "svgGroupId": "g580", - "measure": "6", - "system": "25", - "position": "2/16", - "comment": "d1 überschreibt e1." - }, - { - "svgGroupId": "g589", - "measure": "6", - "system": "26", - "position": "2/4", - "comment": "Unterstimmenschicht: Viertelnote f1 gestrichen." - }, - { - "svgGroupId": "g980", - "measure": "7", - "system": "24", - "position": "(5/8)", - "comment": "Notenkopf gis1 radiert." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g496", + "measure": "{1A}", + "system": "25", + "position": "", + "comment": "Noten pauschal gestrichen." + }, + { + "svgGroupId": "g502", + "measure": "1B", + "system": "26", + "position": "5/8", + "comment": "Notenkopf a1 radiert." + }, + { + "svgGroupId": "g507", + "measure": "3", + "system": "26", + "position": "1. Pause", + "comment": "Punktierte Achtelpause überschreibt Viertelpause." + }, + { + "svgGroupId": "g519", + "measure": "3", + "system": "25", + "position": "3–4/16", + "comment": "h–a gestrichen." + }, + { + "svgGroupId": "g514", + "measure": "3", + "system": "26", + "position": "4/8", + "comment": "Achtelnote gis1/h gestrichen." + }, + { + "svgGroupId": "g524", + "measure": "3", + "system": "25", + "position": "7–8/16", + "comment": "fis–e gestrichen." + }, + { + "svgGroupId": "g1476", + "measure": "3", + "system": "26", + "position": "5/8", + "comment": "h1/d2 überschreibt a1/c2." + }, + { + "svgGroupId": "g530", + "measure": "3", + "system": "25", + "position": "11/16", + "comment": "f überschreibt g." + }, + { + "svgGroupId": "g549", + "measure": "3", + "system": "25", + "position": "12/16", + "comment": "e gestrichen." + }, + { + "svgGroupId": "g8", + "measure": "4", + "system": "26", + "position": "1. Pause", + "comment": "Punktierte Achtelpause überschreibt Viertelpause." + }, + { + "svgGroupId": "g554", + "measure": "4", + "system": "26", + "position": "4/16", + "comment": "gis1 gestrichen." + }, + { + "svgGroupId": "g1328", + "measure": "4", + "system": "25", + "position": "5–7/16", + "comment": "gis–a–h überschreibt e–f–e." + }, + { + "svgGroupId": "g563", + "measure": "{5A}", + "system": "", + "position": "", + "comment": "Takt pauschal gestrichen." + }, + { + "svgGroupId": "g1341", + "measure": "5B", + "system": "26", + "position": "3/8", + "comment": "h2 überschreibt a2." + }, + { + "svgGroupId": "g584", + "measure": "5B", + "system": "26", + "position": "6/8", + "comment": "c2 gestrichen." + }, + { + "svgGroupId": "g580", + "measure": "6", + "system": "25", + "position": "2/16", + "comment": "d1 überschreibt e1." + }, + { + "svgGroupId": "g589", + "measure": "6", + "system": "26", + "position": "2/4", + "comment": "Unterstimmenschicht: Viertelnote f1 gestrichen." + }, + { + "svgGroupId": "g980", + "measure": "7", + "system": "24", + "position": "(5/8)", + "comment": "Notenkopf gis1 radiert." + } + ] } ] }, @@ -343,95 +342,100 @@ "description": ["M 22 Sk4 entwirft Var. III von M 22."], "comments": [ { - "svgGroupId": "g1460", - "measure": "1", - "system": "21", - "position": "3/16", - "comment": "h überschreibt gis." - }, - { - "svgGroupId": "g1468", - "measure": "1", - "system": "21", - "position": "4/16", - "comment": "a überschreibt e1." - }, - { - "svgGroupId": "g1474", - "measure": "3", - "system": "21", - "position": "7/16", - "comment": "g überschreibt h." - }, - { - "svgGroupId": "g1488", - "measure": "3", - "system": "22", - "position": "10–12/16", - "comment": "h1–c2–d2 überschreibt c2–d2–e2." - }, - { - "svgGroupId": "g1505", - "measure": "4", - "system": "21", - "position": "1–2/16", - "comment": "e–f und c1 gestrichen. " - }, - { - "svgGroupId": "g1517", - "measure": "{5A}", - "system": "", - "position": "", - "comment": "Takt pauschal gestrichen." - }, - { - "svgGroupId": "g1512", - "measure": "{5A}", - "system": "21", - "position": "4/16", - "comment": "h überschreibt cis1." - }, - { - "svgGroupId": "g5", - "measure": "{5A}", - "system": "21", - "position": "6–7/16", - "comment": "h–cis1 gestrichen." - }, - { - "svgGroupId": "g1524", - "measure": "5B", - "system": "21", - "position": "4/16", - "comment": "d1 überschreibt cis1." - }, - { - "svgGroupId": "g1085", - "measure": "7", - "system": "19", - "position": "5/16", - "comment": "a gestrichen." - }, - { - "svgGroupId": "g1089", - "measure": "7", - "system": "19", - "position": "6/16", - "comment": "d gestrichen." - }, - { - "svgGroupId": "g1066", - "measure": "7", - "system": "19", - "position": "10/16", - "comment": "fis überschreibt e1." - }, - { - "svgGroupId": "g4", - "measure": "8", - "system": "19", - "position": "(2/4)", - "comment": "Sechzehntelnoten {{ref.getGlyph('[#]')}}gis–e–a–gis überschreiben Achtelnoten gis–E." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1460", + "measure": "1", + "system": "21", + "position": "3/16", + "comment": "h überschreibt gis." + }, + { + "svgGroupId": "g1468", + "measure": "1", + "system": "21", + "position": "4/16", + "comment": "a überschreibt e1." + }, + { + "svgGroupId": "g1474", + "measure": "3", + "system": "21", + "position": "7/16", + "comment": "g überschreibt h." + }, + { + "svgGroupId": "g1488", + "measure": "3", + "system": "22", + "position": "10–12/16", + "comment": "h1–c2–d2 überschreibt c2–d2–e2." + }, + { + "svgGroupId": "g1505", + "measure": "4", + "system": "21", + "position": "1–2/16", + "comment": "e–f und c1 gestrichen. " + }, + { + "svgGroupId": "g1517", + "measure": "{5A}", + "system": "", + "position": "", + "comment": "Takt pauschal gestrichen." + }, + { + "svgGroupId": "g1512", + "measure": "{5A}", + "system": "21", + "position": "4/16", + "comment": "h überschreibt cis1." + }, + { + "svgGroupId": "g5", + "measure": "{5A}", + "system": "21", + "position": "6–7/16", + "comment": "h–cis1 gestrichen." + }, + { + "svgGroupId": "g1524", + "measure": "5B", + "system": "21", + "position": "4/16", + "comment": "d1 überschreibt cis1." + }, + { + "svgGroupId": "g1085", + "measure": "7", + "system": "19", + "position": "5/16", + "comment": "a gestrichen." + }, + { + "svgGroupId": "g1089", + "measure": "7", + "system": "19", + "position": "6/16", + "comment": "d gestrichen." + }, + { + "svgGroupId": "g1066", + "measure": "7", + "system": "19", + "position": "10/16", + "comment": "fis überschreibt e1." + }, + { + "svgGroupId": "g4", + "measure": "8", + "system": "19", + "position": "(2/4)", + "comment": "Sechzehntelnoten {{ref.getGlyph('[#]')}}gis–e–a–gis überschreiben Achtelnoten gis–E." + } + ] } ] }, @@ -441,11 +445,16 @@ "description": ["M 22 Sk5 entwirft die unvollständig gebliebene Var. IV von M 22."], "comments": [ { - "svgGroupId": "g1104", - "measure": "3", - "system": "17", - "position": "5/8", - "comment": "f überschreibt e." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1104", + "measure": "3", + "system": "17", + "position": "5/8", + "comment": "f überschreibt e." + } + ] } ], "linkBoxes": [ @@ -464,53 +473,58 @@ "description": ["M 22 Sk6 entwirft Var. V von M 22."], "comments": [ { - "svgGroupId": "g1201", - "measure": "1", - "system": "16", - "position": "(4/16)", - "comment": "Ansatz zu Achtelnote e2 gestrichen." - }, - { - "svgGroupId": "g5", - "measure": "1", - "system": "15", - "position": "2/4", - "comment": "Notenkopf a radiert." - }, - { - "svgGroupId": "g1185", - "measure": "4", - "system": "15", - "position": "1. Note", - "comment": "e1 gestrichen." - }, - { - "svgGroupId": "g1213", - "measure": "4", - "system": "16", - "position": "3–4/8", - "comment": "gis2–f2 überschreibt f2–e2." - }, - { - "svgGroupId": "g1218", - "measure": "5", - "system": "15", - "position": "1/4", - "comment": "Viertelnote g gestrichen." - }, - { - "svgGroupId": "g1222", - "measure": "5", - "system": "15", - "position": "2/4", - "comment": "c1 gestrichen." - }, - { - "svgGroupId": "g1237", - "measure": "7", - "system": "16", - "position": "2–4/8", - "comment": "gis1–a1–e2 überschreibt e2–c2–d2." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1201", + "measure": "1", + "system": "16", + "position": "(4/16)", + "comment": "Ansatz zu Achtelnote e2 gestrichen." + }, + { + "svgGroupId": "g5", + "measure": "1", + "system": "15", + "position": "2/4", + "comment": "Notenkopf a radiert." + }, + { + "svgGroupId": "g1185", + "measure": "4", + "system": "15", + "position": "1. Note", + "comment": "e1 gestrichen." + }, + { + "svgGroupId": "g1213", + "measure": "4", + "system": "16", + "position": "3–4/8", + "comment": "gis2–f2 überschreibt f2–e2." + }, + { + "svgGroupId": "g1218", + "measure": "5", + "system": "15", + "position": "1/4", + "comment": "Viertelnote g gestrichen." + }, + { + "svgGroupId": "g1222", + "measure": "5", + "system": "15", + "position": "2/4", + "comment": "c1 gestrichen." + }, + { + "svgGroupId": "g1237", + "measure": "7", + "system": "16", + "position": "2–4/8", + "comment": "gis1–a1–e2 überschreibt e2–c2–d2." + } + ] } ], "linkBoxes": [ @@ -546,11 +560,16 @@ ], "comments": [ { - "svgGroupId": "g917", - "measure": "1", - "system": "12", - "position": "1. Note", - "comment": "Halbe Note der Unterstimmenschicht überschreibt mit Oberstimmenschicht zusammengehalste Viertelnote." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g917", + "measure": "1", + "system": "12", + "position": "1. Note", + "comment": "Halbe Note der Unterstimmenschicht überschreibt mit Oberstimmenschicht zusammengehalste Viertelnote." + } + ] } ], "linkBoxes": [ @@ -569,88 +588,93 @@ "description": ["M 22 Sk9 entwirft Var. VII von M 22."], "comments": [ { - "svgGroupId": "g1345", - "measure": "{1A–2A}", - "system": "", - "position": "", - "comment": "Takte pauschal gestrichen." - }, - { - "svgGroupId": "g1367", - "measure": "{2A}", - "system": "10", - "position": "4/8", - "comment": "{{ref.getGlyph('[#]')}} zu a1 gestrichen." - }, - { - "svgGroupId": "g1305", - "measure": "3", - "system": "9", - "position": "2/4", - "comment": "F/f überschreibt A/a." - }, - { - "svgGroupId": "g1381", - "measure": "3", - "system": "10", - "position": "6. Note", - "comment": "e1 überschreibt h1." - }, - { - "svgGroupId": "g1387", - "measure": "3", - "system": "10", - "position": "8. Note", - "comment": "a1 überschreibt h1." - }, - { - "svgGroupId": "g1164", - "measure": "5", - "system": "7", - "position": "1. Note", - "comment": "e2 überschreibt f2." - }, - { - "svgGroupId": "g1170", - "measure": "5", - "system": "7", - "position": "5. Note", - "comment": "dis2 überschreibt f2." - }, - { - "svgGroupId": "g1174", - "measure": "6", - "system": "7", - "position": "3. Note", - "comment": "{{ref.getGlyph('[#]')}} zu g2 gestrichen." - }, - { - "svgGroupId": "g1178", - "measure": "6", - "system": "7", - "position": "4. Note", - "comment": "{{ref.getGlyph('[#]')}} zu f2 gestrichen." - }, - { - "svgGroupId": "g1191", - "measure": "6", - "system": "6", - "position": "3/4", - "comment": "c/c1 überschreibt d/d1. D: sic. " - }, - { - "svgGroupId": "g1200", - "measure": "7", - "system": "6", - "position": "2/4", - "comment": "E/e überschreibt A/a." - }, - { - "svgGroupId": "g1212", - "measure": "8", - "system": "6", - "position": "2/4", - "comment": "Viertelnote überschreibt Halbe Note." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1345", + "measure": "{1A–2A}", + "system": "", + "position": "", + "comment": "Takte pauschal gestrichen." + }, + { + "svgGroupId": "g1367", + "measure": "{2A}", + "system": "10", + "position": "4/8", + "comment": "{{ref.getGlyph('[#]')}} zu a1 gestrichen." + }, + { + "svgGroupId": "g1305", + "measure": "3", + "system": "9", + "position": "2/4", + "comment": "F/f überschreibt A/a." + }, + { + "svgGroupId": "g1381", + "measure": "3", + "system": "10", + "position": "6. Note", + "comment": "e1 überschreibt h1." + }, + { + "svgGroupId": "g1387", + "measure": "3", + "system": "10", + "position": "8. Note", + "comment": "a1 überschreibt h1." + }, + { + "svgGroupId": "g1164", + "measure": "5", + "system": "7", + "position": "1. Note", + "comment": "e2 überschreibt f2." + }, + { + "svgGroupId": "g1170", + "measure": "5", + "system": "7", + "position": "5. Note", + "comment": "dis2 überschreibt f2." + }, + { + "svgGroupId": "g1174", + "measure": "6", + "system": "7", + "position": "3. Note", + "comment": "{{ref.getGlyph('[#]')}} zu g2 gestrichen." + }, + { + "svgGroupId": "g1178", + "measure": "6", + "system": "7", + "position": "4. Note", + "comment": "{{ref.getGlyph('[#]')}} zu f2 gestrichen." + }, + { + "svgGroupId": "g1191", + "measure": "6", + "system": "6", + "position": "3/4", + "comment": "c/c1 überschreibt d/d1. D: sic. " + }, + { + "svgGroupId": "g1200", + "measure": "7", + "system": "6", + "position": "2/4", + "comment": "E/e überschreibt A/a." + }, + { + "svgGroupId": "g1212", + "measure": "8", + "system": "6", + "position": "2/4", + "comment": "Viertelnote überschreibt Halbe Note." + } + ] } ], "linkBoxes": [ @@ -678,11 +702,16 @@ ], "comments": [ { - "svgGroupId": "g1066", - "measure": "{1–3}", - "system": "", - "position": "", - "comment": "Takte pauschal gestrichen." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1066", + "measure": "{1–3}", + "system": "", + "position": "", + "comment": "Takte pauschal gestrichen." + } + ] } ], "linkBoxes": [ @@ -701,81 +730,86 @@ "description": ["M 22 Sk11 entwirft Var. IX von M 22."], "comments": [ { - "svgGroupId": "g1309", - "measure": "2", - "system": "5", - "position": "2/4", - "comment": "gis2 überschreibt fis2." - }, - { - "svgGroupId": "g4", - "measure": "2", - "system": "4", - "position": "3–4/8", - "comment": "Achtelnoten h/d1–cis1/e1 gestrichen." - }, - { - "svgGroupId": "g1314", - "measure": "2", - "system": "5", - "position": "5–6/8", - "comment": "e1–d1 gestrichen." - }, - { - "svgGroupId": "g1337", - "measure": "3", - "system": "5", - "position": "1/4", - "comment": "Oberstimmenschicht: cis1/cis2 überschreibt a/a1." - }, - { - "svgGroupId": "g1342", - "measure": "3", - "system": "4", - "position": "1. Note", - "comment": "Achtelnote gis in Oberstimmenschicht überschreibt mit Unterstimmenschicht zusammengehalste Viertelnote a." - }, - { - "svgGroupId": "g1292", - "measure": "3", - "system": "5", - "position": "2/4", - "comment": "Oberstimmenschicht: sic: cis1." - }, - { - "svgGroupId": "g1346", - "measure": "{5A}", - "system": "", - "position": "", - "comment": "Takt pauschal gestrichen." - }, - { - "svgGroupId": "g1352", - "measure": "6", - "system": "5", - "position": "6/8", - "comment": "Oberstimmenschicht: h2 überschreibt a2." - }, - { - "svgGroupId": "g1357", - "measure": "{7A–8A}", - "system": "", - "position": "", - "comment": "Takte pauschal gestrichen." - }, - { - "svgGroupId": "g1365", - "measure": "7B", - "system": "5", - "position": "3/4", - "comment": "fis1/fis2 überschreibt gis1/gis2." - }, - { - "svgGroupId": "g1374", - "measure": "8B", - "system": "4", - "position": "1. Note", - "comment": "Punktierte Achtelnote überschreibt Halbe Note." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1309", + "measure": "2", + "system": "5", + "position": "2/4", + "comment": "gis2 überschreibt fis2." + }, + { + "svgGroupId": "g4", + "measure": "2", + "system": "4", + "position": "3–4/8", + "comment": "Achtelnoten h/d1–cis1/e1 gestrichen." + }, + { + "svgGroupId": "g1314", + "measure": "2", + "system": "5", + "position": "5–6/8", + "comment": "e1–d1 gestrichen." + }, + { + "svgGroupId": "g1337", + "measure": "3", + "system": "5", + "position": "1/4", + "comment": "Oberstimmenschicht: cis1/cis2 überschreibt a/a1." + }, + { + "svgGroupId": "g1342", + "measure": "3", + "system": "4", + "position": "1. Note", + "comment": "Achtelnote gis in Oberstimmenschicht überschreibt mit Unterstimmenschicht zusammengehalste Viertelnote a." + }, + { + "svgGroupId": "g1292", + "measure": "3", + "system": "5", + "position": "2/4", + "comment": "Oberstimmenschicht: sic: cis1." + }, + { + "svgGroupId": "g1346", + "measure": "{5A}", + "system": "", + "position": "", + "comment": "Takt pauschal gestrichen." + }, + { + "svgGroupId": "g1352", + "measure": "6", + "system": "5", + "position": "6/8", + "comment": "Oberstimmenschicht: h2 überschreibt a2." + }, + { + "svgGroupId": "g1357", + "measure": "{7A–8A}", + "system": "", + "position": "", + "comment": "Takte pauschal gestrichen." + }, + { + "svgGroupId": "g1365", + "measure": "7B", + "system": "5", + "position": "3/4", + "comment": "fis1/fis2 überschreibt gis1/gis2." + }, + { + "svgGroupId": "g1374", + "measure": "8B", + "system": "4", + "position": "1. Note", + "comment": "Punktierte Achtelnote überschreibt Halbe Note." + } + ] } ] }, @@ -785,102 +819,107 @@ "description": ["M 22 Sk12 entwirft Var. X von M 22."], "comments": [ { - "svgGroupId": "g1619", - "measure": "1", - "system": "3", - "position": "1. Note", - "comment": "e2 (und möglicherweise weitere Akkordtöne) in Bleistift überschrieben durch Notenhals zu a/c1/e1/a1 in Tinte." - }, - { - "svgGroupId": "g1362", - "measure": "2", - "system": "2", - "position": "1. Note", - "comment": "c1 gestrichen." - }, - { - "svgGroupId": "g1578", - "measure": "3", - "system": "3", - "position": "1. Note", - "comment": "a2 mit Tinte gestrichen." - }, - { - "svgGroupId": "g1390", - "measure": "3", - "system": "3", - "position": "3–4/8", - "comment": "Zwei Achtelnoten überschreiben punktierte Achtelnote und Sechzehntelnote." - }, - { - "svgGroupId": "g1419", - "measure": "3", - "system": "3", - "position": "(3/4)", - "comment": "Triolenachtelnoten d3–c3–h2 überschreiben Achtelnoten c3–d3." - }, - { - "svgGroupId": "g1570", - "measure": "3", - "system": "2", - "position": "4. Note", - "comment": "G/g überschreibt Fis/fis." - }, - { - "svgGroupId": "g1547", - "measure": "4", - "system": "2", - "position": "1/8", - "comment": "Achtelpause überschreibt Notenkopf g." - }, - { - "svgGroupId": "g1552", - "measure": "4", - "system": "2", - "position": "(2/8–2/4)", - "comment": "Achtelnote G/g und Viertelnote E/e gestrichen." - }, - { - "svgGroupId": "g1451", - "measure": "5", - "system": "3", - "position": "4/8", - "comment": "h1 überschreibt h2." - }, - { - "svgGroupId": "g1631", - "measure": "6", - "system": "3", - "position": "(1/4)", - "comment": "Achtelnote a1 und Sechzehntelnote a1 bzw. a2 gestrichen." - }, - { - "svgGroupId": "g1530", - "measure": "6", - "system": "2", - "position": "(1/4)", - "comment": "Viertelnote d1 gestrichen." - }, - { - "svgGroupId": "g1636", - "measure": "6", - "system": "3", - "position": "(2/4)", - "comment": "Viertelnote f2 gestrichen." - }, - { - "svgGroupId": "g1514", - "measure": "7", - "system": "2", - "position": "1. Pause", - "comment": "Achtelpause überschreibt Viertelnote e." - }, - { - "svgGroupId": "g1524", - "measure": "7", - "system": "2", - "position": "2/4", - "comment": "d/d1 überschreibt c/e/g." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1619", + "measure": "1", + "system": "3", + "position": "1. Note", + "comment": "e2 (und möglicherweise weitere Akkordtöne) in Bleistift überschrieben durch Notenhals zu a/c1/e1/a1 in Tinte." + }, + { + "svgGroupId": "g1362", + "measure": "2", + "system": "2", + "position": "1. Note", + "comment": "c1 gestrichen." + }, + { + "svgGroupId": "g1578", + "measure": "3", + "system": "3", + "position": "1. Note", + "comment": "a2 mit Tinte gestrichen." + }, + { + "svgGroupId": "g1390", + "measure": "3", + "system": "3", + "position": "3–4/8", + "comment": "Zwei Achtelnoten überschreiben punktierte Achtelnote und Sechzehntelnote." + }, + { + "svgGroupId": "g1419", + "measure": "3", + "system": "3", + "position": "(3/4)", + "comment": "Triolenachtelnoten d3–c3–h2 überschreiben Achtelnoten c3–d3." + }, + { + "svgGroupId": "g1570", + "measure": "3", + "system": "2", + "position": "4. Note", + "comment": "G/g überschreibt Fis/fis." + }, + { + "svgGroupId": "g1547", + "measure": "4", + "system": "2", + "position": "1/8", + "comment": "Achtelpause überschreibt Notenkopf g." + }, + { + "svgGroupId": "g1552", + "measure": "4", + "system": "2", + "position": "(2/8–2/4)", + "comment": "Achtelnote G/g und Viertelnote E/e gestrichen." + }, + { + "svgGroupId": "g1451", + "measure": "5", + "system": "3", + "position": "4/8", + "comment": "h1 überschreibt h2." + }, + { + "svgGroupId": "g1631", + "measure": "6", + "system": "3", + "position": "(1/4)", + "comment": "Achtelnote a1 und Sechzehntelnote a1 bzw. a2 gestrichen." + }, + { + "svgGroupId": "g1530", + "measure": "6", + "system": "2", + "position": "(1/4)", + "comment": "Viertelnote d1 gestrichen." + }, + { + "svgGroupId": "g1636", + "measure": "6", + "system": "3", + "position": "(2/4)", + "comment": "Viertelnote f2 gestrichen." + }, + { + "svgGroupId": "g1514", + "measure": "7", + "system": "2", + "position": "1. Pause", + "comment": "Achtelpause überschreibt Viertelnote e." + }, + { + "svgGroupId": "g1524", + "measure": "7", + "system": "2", + "position": "2/4", + "comment": "d/d1 überschreibt c/e/g." + } + ] } ] }, @@ -890,18 +929,23 @@ "description": ["M 22 Sk13 entwirft die unvollständig gebliebene Var. XI von M 22."], "comments": [ { - "svgGroupId": "g1038", - "measure": "{1A}", - "system": "1", - "position": "", - "comment": "Noten gestrichen." - }, - { - "svgGroupId": "g1042", - "measure": "2", - "system": "2", - "position": "4. Note", - "comment": "h gestrichen." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1038", + "measure": "{1A}", + "system": "1", + "position": "", + "comment": "Noten gestrichen." + }, + { + "svgGroupId": "g1042", + "measure": "2", + "system": "2", + "position": "4. Note", + "comment": "h gestrichen." + } + ] } ] }, @@ -935,25 +979,30 @@ "description": ["M 22 Sk15 entwirft Var. XII von M 22."], "comments": [ { - "svgGroupId": "g1158", - "measure": "4", - "system": "5", - "position": "1. Note", - "comment": "Oberstimmenschicht: Halbe Note überschreibt Viertelnote." - }, - { - "svgGroupId": "g1164", - "measure": "3B", - "system": "5", - "position": "2/4", - "comment": "a1 überschreibt e1." - }, - { - "svgGroupId": "g1170", - "measure": "3B", - "system": "5", - "position": "3/4", - "comment": "Viertelpause überschreibt Viertelnote e1/cis2." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1158", + "measure": "4", + "system": "5", + "position": "1. Note", + "comment": "Oberstimmenschicht: Halbe Note überschreibt Viertelnote." + }, + { + "svgGroupId": "g1164", + "measure": "3B", + "system": "5", + "position": "2/4", + "comment": "a1 überschreibt e1." + }, + { + "svgGroupId": "g1170", + "measure": "3B", + "system": "5", + "position": "3/4", + "comment": "Viertelpause überschreibt Viertelnote e1/cis2." + } + ] } ], "linkBoxes": [ @@ -974,32 +1023,37 @@ ], "comments": [ { - "svgGroupId": "g1082", - "measure": "1", - "system": "11", - "position": "1–2/8", - "comment": "Achtelnoten cis2–a1 gestrichen." - }, - { - "svgGroupId": "g1089", - "measure": "4B", - "system": "11", - "position": "1. Note", - "comment": "e2 überschreibt a2." - }, - { - "svgGroupId": "g1095", - "measure": "4B", - "system": "12", - "position": "1/4", - "comment": "Viertelnote gis gestrichen." - }, - { - "svgGroupId": "g1102", - "measure": "5", - "system": "11", - "position": "(2–3/4)", - "comment": "Möglicherweise Viertelnoten gis2–h2 radiert. Entzifferung unsicher." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1082", + "measure": "1", + "system": "11", + "position": "1–2/8", + "comment": "Achtelnoten cis2–a1 gestrichen." + }, + { + "svgGroupId": "g1089", + "measure": "4B", + "system": "11", + "position": "1. Note", + "comment": "e2 überschreibt a2." + }, + { + "svgGroupId": "g1095", + "measure": "4B", + "system": "12", + "position": "1/4", + "comment": "Viertelnote gis gestrichen." + }, + { + "svgGroupId": "g1102", + "measure": "5", + "system": "11", + "position": "(2–3/4)", + "comment": "Möglicherweise Viertelnoten gis2–h2 radiert. Entzifferung unsicher." + } + ] } ] }, @@ -1011,53 +1065,58 @@ ], "comments": [ { - "svgGroupId": "g1245", - "measure": "1", - "system": "14", - "position": "4/16", - "comment": "A/a überschreibt c/c1; Notenkopf c1 gestrichen." - }, - { - "svgGroupId": "g1255", - "measure": "1", - "system": "14", - "position": "3/8", - "comment": "A/a überschreibt c/c1." - }, - { - "svgGroupId": "g1309", - "measure": "2", - "system": "14", - "position": "1. Note", - "comment": "gis gestrichen." - }, - { - "svgGroupId": "g1269", - "measure": "4", - "system": "14", - "position": "1. Note", - "comment": "E überschreibt A1." - }, - { - "svgGroupId": "g1273", - "measure": "4", - "system": "13", - "position": "(2/4)", - "comment": "Viertelpause gestrichen." - }, - { - "svgGroupId": "g1277", - "measure": "5", - "system": "13", - "position": "1/4", - "comment": "h1 gestrichen." - }, - { - "svgGroupId": "g1489", - "measure": "5", - "system": "14", - "position": "1.–2. Note", - "comment": "E–E/e überschreibt {{ref.getGlyph('[#]')}}Gis1/{{ref.getGlyph('[#]')}}Gis–Gis/[{{ref.getGlyph('[#]')}}]gis. " + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1245", + "measure": "1", + "system": "14", + "position": "4/16", + "comment": "A/a überschreibt c/c1; Notenkopf c1 gestrichen." + }, + { + "svgGroupId": "g1255", + "measure": "1", + "system": "14", + "position": "3/8", + "comment": "A/a überschreibt c/c1." + }, + { + "svgGroupId": "g1309", + "measure": "2", + "system": "14", + "position": "1. Note", + "comment": "gis gestrichen." + }, + { + "svgGroupId": "g1269", + "measure": "4", + "system": "14", + "position": "1. Note", + "comment": "E überschreibt A1." + }, + { + "svgGroupId": "g1273", + "measure": "4", + "system": "13", + "position": "(2/4)", + "comment": "Viertelpause gestrichen." + }, + { + "svgGroupId": "g1277", + "measure": "5", + "system": "13", + "position": "1/4", + "comment": "h1 gestrichen." + }, + { + "svgGroupId": "g1489", + "measure": "5", + "system": "14", + "position": "1.–2. Note", + "comment": "E–E/e überschreibt {{ref.getGlyph('[#]')}}Gis1/{{ref.getGlyph('[#]')}}Gis–Gis/[{{ref.getGlyph('[#]')}}]gis. " + } + ] } ], "linkBoxes": [ @@ -1076,25 +1135,30 @@ "description": ["M 22 Sk18 entwirft die gültige Version von Var. XIII von M 22."], "comments": [ { - "svgGroupId": "g1143", - "measure": "2", - "system": "16", - "position": "1. Note", - "comment": "E überschreibt C." - }, - { - "svgGroupId": "g1122", - "measure": "6", - "system": "16", - "position": "7. Note", - "comment": "a überschreibt c1." - }, - { - "svgGroupId": "g925", - "measure": "7", - "system": "13", - "position": "2.–3. Note", - "comment": "Unterstimmenschicht: a1–f1 überschreibt d2–a1." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1143", + "measure": "2", + "system": "16", + "position": "1. Note", + "comment": "E überschreibt C." + }, + { + "svgGroupId": "g1122", + "measure": "6", + "system": "16", + "position": "7. Note", + "comment": "a überschreibt c1." + }, + { + "svgGroupId": "g925", + "measure": "7", + "system": "13", + "position": "2.–3. Note", + "comment": "Unterstimmenschicht: a1–f1 überschreibt d2–a1." + } + ] } ], "linkBoxes": [ @@ -1130,32 +1194,37 @@ "description": ["M 22 Sk20 entwirft Var. XIV von M 22."], "comments": [ { - "svgGroupId": "g1079", - "measure": "{1A}", - "system": "16", - "position": "", - "comment": "Noten gestrichen." - }, - { - "svgGroupId": "g1091", - "measure": "2", - "system": "17", - "position": "4/8", - "comment": "Balkierung überschreibt Achtelfähnchen." - }, - { - "svgGroupId": "g1084", - "measure": "2", - "system": "16", - "position": "(3/4)", - "comment": "Viertelnote e1 gestrichen." - }, - { - "svgGroupId": "g1097", - "measure": "2", - "system": "17", - "position": "6/8", - "comment": "e überschreibt fis." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1079", + "measure": "{1A}", + "system": "16", + "position": "", + "comment": "Noten gestrichen." + }, + { + "svgGroupId": "g1091", + "measure": "2", + "system": "17", + "position": "4/8", + "comment": "Balkierung überschreibt Achtelfähnchen." + }, + { + "svgGroupId": "g1084", + "measure": "2", + "system": "16", + "position": "(3/4)", + "comment": "Viertelnote e1 gestrichen." + }, + { + "svgGroupId": "g1097", + "measure": "2", + "system": "17", + "position": "6/8", + "comment": "e überschreibt fis." + } + ] } ], "linkBoxes": [ @@ -1181,81 +1250,86 @@ "description": ["M 22 Sk21 entwirft Var. XV von M 22."], "comments": [ { - "svgGroupId": "g1052", - "measure": "{1A}", - "system": "17", - "position": "1. Note", - "comment": "Achtelnote c2/e2 gestrichen." - }, - { - "svgGroupId": "g5", - "measure": "{1A}", - "system": "17–18", - "position": "", - "comment": "Takt pauschal gestrichen." - }, - { - "svgGroupId": "g1084", - "measure": "1B", - "system": "17", - "position": "5–6/8", - "comment": "Noten gestrichen." - }, - { - "svgGroupId": "g1094", - "measure": "1B", - "system": "18", - "position": "5/8", - "comment": "a überschreibt c1." - }, - { - "svgGroupId": "g1108", - "measure": "2", - "system": "18", - "position": "1–2/8", - "comment": "E–[{{ref.getGlyph('[#]')}}]gis überschreibt {{ref.getGlyph('[#]')}}Gis–h." - }, - { - "svgGroupId": "g1115", - "measure": "2", - "system": "18", - "position": "5/8", - "comment": "gis überschreibt h." - }, - { - "svgGroupId": "g1131", - "measure": "3", - "system": "17", - "position": "3–4/8", - "comment": "a1/c2 überschreibt h1/d2." - }, - { - "svgGroupId": "g1138", - "measure": "3", - "system": "18", - "position": "5/8", - "comment": "g überschreibt h." - }, - { - "svgGroupId": "g977", - "measure": "5", - "system": "16", - "position": "1/4", - "comment": "Viertelpause überschreibt Achtelpause." - }, - { - "svgGroupId": "g984", - "measure": "5", - "system": "17", - "position": "2/8", - "comment": "c1 überschreibt a." - }, - { - "svgGroupId": "g988", - "measure": "6", - "system": "16", - "position": "1/4", - "comment": "Viertelpause überschreibt Achtelpause." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1052", + "measure": "{1A}", + "system": "17", + "position": "1. Note", + "comment": "Achtelnote c2/e2 gestrichen." + }, + { + "svgGroupId": "g5", + "measure": "{1A}", + "system": "17–18", + "position": "", + "comment": "Takt pauschal gestrichen." + }, + { + "svgGroupId": "g1084", + "measure": "1B", + "system": "17", + "position": "5–6/8", + "comment": "Noten gestrichen." + }, + { + "svgGroupId": "g1094", + "measure": "1B", + "system": "18", + "position": "5/8", + "comment": "a überschreibt c1." + }, + { + "svgGroupId": "g1108", + "measure": "2", + "system": "18", + "position": "1–2/8", + "comment": "E–[{{ref.getGlyph('[#]')}}]gis überschreibt {{ref.getGlyph('[#]')}}Gis–h." + }, + { + "svgGroupId": "g1115", + "measure": "2", + "system": "18", + "position": "5/8", + "comment": "gis überschreibt h." + }, + { + "svgGroupId": "g1131", + "measure": "3", + "system": "17", + "position": "3–4/8", + "comment": "a1/c2 überschreibt h1/d2." + }, + { + "svgGroupId": "g1138", + "measure": "3", + "system": "18", + "position": "5/8", + "comment": "g überschreibt h." + }, + { + "svgGroupId": "g977", + "measure": "5", + "system": "16", + "position": "1/4", + "comment": "Viertelpause überschreibt Achtelpause." + }, + { + "svgGroupId": "g984", + "measure": "5", + "system": "17", + "position": "2/8", + "comment": "c1 überschreibt a." + }, + { + "svgGroupId": "g988", + "measure": "6", + "system": "16", + "position": "1/4", + "comment": "Viertelpause überschreibt Achtelpause." + } + ] } ], "linkBoxes": [ @@ -1295,60 +1369,65 @@ "description": ["M 22 Sk22 entwirft die vollständige Version von Var. VIII von M 22."], "comments": [ { - "svgGroupId": "g1169", - "measure": "1", - "system": "13", - "position": "7. Note", - "comment": "fis gestrichen." - }, - { - "svgGroupId": "g1219", - "measure": "2", - "system": "13", - "position": "4. Note", - "comment": "h überschreibt d1." - }, - { - "svgGroupId": "g1176", - "measure": "2", - "system": "13", - "position": "7. Note", - "comment": "h gestrichen und ersetzt durch gis." - }, - { - "svgGroupId": "g1236", - "measure": "3", - "system": "14", - "position": "1.–3. Note", - "comment": "Nach unten gehalste, gebalkte Achtelnoten e2–a1–e1 überschreiben nach oben gehalste, gebalkte Achtelnoten cis2–a1–e1." - }, - { - "svgGroupId": "g1253", - "measure": "3", - "system": "14", - "position": "4.–6. Note", - "comment": "a1–fis1–cis1 überschreibt cis2–a1–fis1." - }, - { - "svgGroupId": "g1259", - "measure": "3", - "system": "14", - "position": "8. Note", - "comment": "fis1 überschreibt a1." - }, - { - "svgGroupId": "g1013", - "measure": "6", - "system": "15", - "position": "7. Note", - "comment": "Fis überschreibt a." - }, - { - "svgGroupId": "g1018", - "measure": "8", - "system": "17", - "position": "1. Note", - "comment": "cis gestrichen." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1169", + "measure": "1", + "system": "13", + "position": "7. Note", + "comment": "fis gestrichen." + }, + { + "svgGroupId": "g1219", + "measure": "2", + "system": "13", + "position": "4. Note", + "comment": "h überschreibt d1." + }, + { + "svgGroupId": "g1176", + "measure": "2", + "system": "13", + "position": "7. Note", + "comment": "h gestrichen und ersetzt durch gis." + }, + { + "svgGroupId": "g1236", + "measure": "3", + "system": "14", + "position": "1.–3. Note", + "comment": "Nach unten gehalste, gebalkte Achtelnoten e2–a1–e1 überschreiben nach oben gehalste, gebalkte Achtelnoten cis2–a1–e1." + }, + { + "svgGroupId": "g1253", + "measure": "3", + "system": "14", + "position": "4.–6. Note", + "comment": "a1–fis1–cis1 überschreibt cis2–a1–fis1." + }, + { + "svgGroupId": "g1259", + "measure": "3", + "system": "14", + "position": "8. Note", + "comment": "fis1 überschreibt a1." + }, + { + "svgGroupId": "g1013", + "measure": "6", + "system": "15", + "position": "7. Note", + "comment": "Fis überschreibt a." + }, + { + "svgGroupId": "g1018", + "measure": "8", + "system": "17", + "position": "1. Note", + "comment": "cis gestrichen." + } + ] } ], "linkBoxes": [ @@ -1381,67 +1460,72 @@ "description": ["M 22 Sk23 entwirft eine erste Version von Var. XVI von M 22."], "comments": [ { - "svgGroupId": "g1028", - "measure": "1", - "system": "4", - "position": "2/4", - "comment": "a gestrichen." - }, - { - "svgGroupId": "g1033", - "measure": "2", - "system": "3", - "position": "2. Note", - "comment": "gis gestrichen." - }, - { - "svgGroupId": "g992", - "measure": "3", - "system": "5", - "position": "1/4", - "comment": "e1 gestrichen." - }, - { - "svgGroupId": "g1010", - "measure": "3", - "system": "5", - "position": "2. Note", - "comment": "d und f1 gestrichen." - }, - { - "svgGroupId": "g987", - "measure": "4", - "system": "6", - "position": "2–3/4", - "comment": "F/f–E/e überschreibt E/e–D/d." - }, - { - "svgGroupId": "g970", - "measure": "7", - "system": "4", - "position": "1. Note", - "comment": "Viertelnote H/h gestrichen." - }, - { - "svgGroupId": "g9", - "measure": "7", - "system": "3", - "position": "1/4", - "comment": "A radiert." - }, - { - "svgGroupId": "g978", - "measure": "7", - "system": "4", - "position": "3/8", - "comment": "f überschreibt e." - }, - { - "svgGroupId": "g4", - "measure": "7", - "system": "4", - "position": "3–4/8", - "comment": "sic: Zwei Achtelnoten statt zwei Viertelnoten." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1028", + "measure": "1", + "system": "4", + "position": "2/4", + "comment": "a gestrichen." + }, + { + "svgGroupId": "g1033", + "measure": "2", + "system": "3", + "position": "2. Note", + "comment": "gis gestrichen." + }, + { + "svgGroupId": "g992", + "measure": "3", + "system": "5", + "position": "1/4", + "comment": "e1 gestrichen." + }, + { + "svgGroupId": "g1010", + "measure": "3", + "system": "5", + "position": "2. Note", + "comment": "d und f1 gestrichen." + }, + { + "svgGroupId": "g987", + "measure": "4", + "system": "6", + "position": "2–3/4", + "comment": "F/f–E/e überschreibt E/e–D/d." + }, + { + "svgGroupId": "g970", + "measure": "7", + "system": "4", + "position": "1. Note", + "comment": "Viertelnote H/h gestrichen." + }, + { + "svgGroupId": "g9", + "measure": "7", + "system": "3", + "position": "1/4", + "comment": "A radiert." + }, + { + "svgGroupId": "g978", + "measure": "7", + "system": "4", + "position": "3/8", + "comment": "f überschreibt e." + }, + { + "svgGroupId": "g4", + "measure": "7", + "system": "4", + "position": "3–4/8", + "comment": "sic: Zwei Achtelnoten statt zwei Viertelnoten." + } + ] } ], "linkBoxes": [ @@ -1495,46 +1579,51 @@ "description": ["M 22 Sk24 entwirft die gültige Version von Var. XIV von M 22."], "comments": [ { - "svgGroupId": "g1163", - "measure": "1", - "system": "1", - "position": "Taktanfang", - "comment": "Bassschlüssel überschreibt Violinschlüssel." - }, - { - "svgGroupId": "g1229", - "measure": "3", - "system": "1", - "position": "2. Note", - "comment": "cis1 gestrichen." - }, - { - "svgGroupId": "g1234", - "measure": "4", - "system": "1", - "position": "1/4", - "comment": "e1 gestrichen." - }, - { - "svgGroupId": "g1224", - "measure": "4", - "system": "2", - "position": "2/4", - "comment": "H1/D/H gestrichen." - }, - { - "svgGroupId": "g1202", - "measure": "6", - "system": "2", - "position": "2/4", - "comment": "e überschreibt f." - }, - { - "svgGroupId": "g1215", - "measure": "7", - "system": "1", - "position": "2. Note", - "comment": "Halbe Note e/gis/h/e1 gestrichen und ersetzt durch Tonbuchstaben über dem System: g[sic. Lies: gis]/d/e." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1163", + "measure": "1", + "system": "1", + "position": "Taktanfang", + "comment": "Bassschlüssel überschreibt Violinschlüssel." + }, + { + "svgGroupId": "g1229", + "measure": "3", + "system": "1", + "position": "2. Note", + "comment": "cis1 gestrichen." + }, + { + "svgGroupId": "g1234", + "measure": "4", + "system": "1", + "position": "1/4", + "comment": "e1 gestrichen." + }, + { + "svgGroupId": "g1224", + "measure": "4", + "system": "2", + "position": "2/4", + "comment": "H1/D/H gestrichen." + }, + { + "svgGroupId": "g1202", + "measure": "6", + "system": "2", + "position": "2/4", + "comment": "e überschreibt f." + }, + { + "svgGroupId": "g1215", + "measure": "7", + "system": "1", + "position": "2. Note", + "comment": "Halbe Note e/gis/h/e1 gestrichen und ersetzt durch Tonbuchstaben über dem System: g[sic. Lies: gis]/d/e." + } + ] } ], "linkBoxes": [ @@ -1555,46 +1644,51 @@ ], "comments": [ { - "svgGroupId": "g1175", - "measure": "{1–5}", - "system": "4–5", - "position": "", - "comment": "Takte pauschal gestrichen." - }, - { - "svgGroupId": "g1199", - "measure": "{1}", - "system": "5", - "position": "1–2/8", - "comment": "c1/e1–h/dis1 überschreibt h–g." - }, - { - "svgGroupId": "g1205", - "measure": "{1}", - "system": "4", - "position": "3/16", - "comment": "f2 überschreibt e2." - }, - { - "svgGroupId": "g1227", - "measure": "{3}", - "system": "4", - "position": "1–2/16", - "comment": "a2–e3 überschreibt c3–f3." - }, - { - "svgGroupId": "g1234", - "measure": "{3}", - "system": "5", - "position": "(4/8)", - "comment": "Viertelnote h/d1 gestrichen." - }, - { - "svgGroupId": "g2", - "measure": "{6–8}", - "system": "6–7", - "position": "", - "comment": "Takte pauschal gestrichen." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1175", + "measure": "{1–5}", + "system": "4–5", + "position": "", + "comment": "Takte pauschal gestrichen." + }, + { + "svgGroupId": "g1199", + "measure": "{1}", + "system": "5", + "position": "1–2/8", + "comment": "c1/e1–h/dis1 überschreibt h–g." + }, + { + "svgGroupId": "g1205", + "measure": "{1}", + "system": "4", + "position": "3/16", + "comment": "f2 überschreibt e2." + }, + { + "svgGroupId": "g1227", + "measure": "{3}", + "system": "4", + "position": "1–2/16", + "comment": "a2–e3 überschreibt c3–f3." + }, + { + "svgGroupId": "g1234", + "measure": "{3}", + "system": "5", + "position": "(4/8)", + "comment": "Viertelnote h/d1 gestrichen." + }, + { + "svgGroupId": "g2", + "measure": "{6–8}", + "system": "6–7", + "position": "", + "comment": "Takte pauschal gestrichen." + } + ] } ], "linkBoxes": [ @@ -1620,53 +1714,58 @@ "description": ["M 22 Sk26 entwirft Var. XVII von M 22."], "comments": [ { - "svgGroupId": "g1316", - "measure": "1", - "system": "8", - "position": "5/8", - "comment": "h1 überschreibt c2." - }, - { - "svgGroupId": "g1328", - "measure": "3", - "system": "8", - "position": "5–6/16", - "comment": "f1–e1 überschreibt e1–d1." - }, - { - "svgGroupId": "g1335", - "measure": "3", - "system": "8", - "position": "5/8", - "comment": "e1 überschreibt f1." - }, - { - "svgGroupId": "g1339", - "measure": "5", - "system": "8", - "position": "", - "comment": "Noten pauschal gestrichen." - }, - { - "svgGroupId": "g1121", - "measure": "6", - "system": "11", - "position": "Taktanfang", - "comment": "Bassschlüssel überschreibt Violinschlüssel." - }, - { - "svgGroupId": "g1117", - "measure": "6", - "system": "11", - "position": "1. Note", - "comment": "Viertelnote D gestrichen? Entzifferung unklar." - }, - { - "svgGroupId": "g1111", - "measure": "8", - "system": "11", - "position": "6–7/16", - "comment": "e–f überschreibt d–e." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1316", + "measure": "1", + "system": "8", + "position": "5/8", + "comment": "h1 überschreibt c2." + }, + { + "svgGroupId": "g1328", + "measure": "3", + "system": "8", + "position": "5–6/16", + "comment": "f1–e1 überschreibt e1–d1." + }, + { + "svgGroupId": "g1335", + "measure": "3", + "system": "8", + "position": "5/8", + "comment": "e1 überschreibt f1." + }, + { + "svgGroupId": "g1339", + "measure": "5", + "system": "8", + "position": "", + "comment": "Noten pauschal gestrichen." + }, + { + "svgGroupId": "g1121", + "measure": "6", + "system": "11", + "position": "Taktanfang", + "comment": "Bassschlüssel überschreibt Violinschlüssel." + }, + { + "svgGroupId": "g1117", + "measure": "6", + "system": "11", + "position": "1. Note", + "comment": "Viertelnote D gestrichen? Entzifferung unklar." + }, + { + "svgGroupId": "g1111", + "measure": "8", + "system": "11", + "position": "6–7/16", + "comment": "e–f überschreibt d–e." + } + ] } ], "linkBoxes": [ @@ -1692,18 +1791,23 @@ "description": ["M 22 Sk27 entwirft die T. 1–6 von Var. XVIII von M 22."], "comments": [ { - "svgGroupId": "g1194", - "measure": "3", - "system": "14", - "position": "3/4", - "comment": "a überschreibt cis1." - }, - { - "svgGroupId": "g1199", - "measure": "5", - "system": "10", - "position": "1. Note", - "comment": "cis2 gestrichen." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1194", + "measure": "3", + "system": "14", + "position": "3/4", + "comment": "a überschreibt cis1." + }, + { + "svgGroupId": "g1199", + "measure": "5", + "system": "10", + "position": "1. Note", + "comment": "cis2 gestrichen." + } + ] } ], "linkBoxes": [ @@ -1724,46 +1828,51 @@ ], "comments": [ { - "svgGroupId": "g980", - "measure": "5", - "system": "1", - "position": "6/8", - "comment": "gis1 überschreibt e1." - }, - { - "svgGroupId": "g976", - "measure": "6", - "system": "1", - "position": "1. Note", - "comment": "Halbe Note überschreibt Viertelnote." - }, - { - "svgGroupId": "g1012", - "measure": "7", - "system": "3", - "position": "(1/4)", - "comment": "Viertelnote h gestrichen." - }, - { - "svgGroupId": "g1020", - "measure": "7", - "system": "3", - "position": "1. Note", - "comment": "h/fis1 gestrichen." - }, - { - "svgGroupId": "g1029", - "measure": "7", - "system": "4", - "position": "2/4", - "comment": "Viertelnote cis gestrichen." - }, - { - "svgGroupId": "g1024", - "measure": "7", - "system": "3", - "position": "4/8", - "comment": "d1 gestrichen." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g980", + "measure": "5", + "system": "1", + "position": "6/8", + "comment": "gis1 überschreibt e1." + }, + { + "svgGroupId": "g976", + "measure": "6", + "system": "1", + "position": "1. Note", + "comment": "Halbe Note überschreibt Viertelnote." + }, + { + "svgGroupId": "g1012", + "measure": "7", + "system": "3", + "position": "(1/4)", + "comment": "Viertelnote h gestrichen." + }, + { + "svgGroupId": "g1020", + "measure": "7", + "system": "3", + "position": "1. Note", + "comment": "h/fis1 gestrichen." + }, + { + "svgGroupId": "g1029", + "measure": "7", + "system": "4", + "position": "2/4", + "comment": "Viertelnote cis gestrichen." + }, + { + "svgGroupId": "g1024", + "measure": "7", + "system": "3", + "position": "4/8", + "comment": "d1 gestrichen." + } + ] } ], "linkBoxes": [ @@ -1789,95 +1898,100 @@ "description": ["M 22 Sk28 entwirft Var. XIX von M 22."], "comments": [ { - "svgGroupId": "g1573", - "measure": "{1A–2A}", - "system": "14–13", - "position": "", - "comment": "Takte pauschal gestrichen." - }, - { - "svgGroupId": "g1425", - "measure": "{2A}", - "system": "14", - "position": "1. Note", - "comment": "Oberstimmenschicht: Halbe Note überschreibt Viertelnote." - }, - { - "svgGroupId": "g1419", - "measure": "{2A}", - "system": "14", - "position": "1/4", - "comment": "Unterstimmenschicht: Viertelnote überschreibt Halbe Note." - }, - { - "svgGroupId": "g1332", - "measure": "1B", - "system": "14", - "position": "2. Note", - "comment": "e2 überschreibt a2." - }, - { - "svgGroupId": "g1350", - "measure": "1B", - "system": "13", - "position": "2.–4. Note", - "comment": "Noten gestrichen." - }, - { - "svgGroupId": "g1284", - "measure": "2B", - "system": "14", - "position": "1. Pause", - "comment": "Punktierte Achtelpause überschreibt Viertelpause." - }, - { - "svgGroupId": "g1295", - "measure": "3", - "system": "13", - "position": "4/16", - "comment": "d/d1 überschreibt A/a." - }, - { - "svgGroupId": "g1588", - "measure": "3", - "system": "14", - "position": "2.–3. Note", - "comment": "Noten gestrichen." - }, - { - "svgGroupId": "g1314", - "measure": "3", - "system": "14", - "position": "12/16", - "comment": "Sechzehntelbalken gestrichen und ersetzt durch Sechzehntelfähnchen (siehe auch Korrektur zuvor)." - }, - { - "svgGroupId": "g1604", - "measure": "5", - "system": "14", - "position": "1. Pause", - "comment": "Punktierte Achtelpause überschreibt Viertelnote a2/a3. Entzifferung von a3 jedoch unsicher und auch als e3 lesbar." - }, - { - "svgGroupId": "g975", - "measure": "7", - "system": "10", - "position": "2/4", - "comment": "Viertelpause überschreibt Achtelpause." - }, - { - "svgGroupId": "g992", - "measure": "7", - "system": "9", - "position": "(2/4)", - "comment": "c1–a überschreibt a–e." - }, - { - "svgGroupId": "g979", - "measure": "8", - "system": "10", - "position": "2/4", - "comment": "a/a1 überschreibt c1/c2." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1573", + "measure": "{1A–2A}", + "system": "14–13", + "position": "", + "comment": "Takte pauschal gestrichen." + }, + { + "svgGroupId": "g1425", + "measure": "{2A}", + "system": "14", + "position": "1. Note", + "comment": "Oberstimmenschicht: Halbe Note überschreibt Viertelnote." + }, + { + "svgGroupId": "g1419", + "measure": "{2A}", + "system": "14", + "position": "1/4", + "comment": "Unterstimmenschicht: Viertelnote überschreibt Halbe Note." + }, + { + "svgGroupId": "g1332", + "measure": "1B", + "system": "14", + "position": "2. Note", + "comment": "e2 überschreibt a2." + }, + { + "svgGroupId": "g1350", + "measure": "1B", + "system": "13", + "position": "2.–4. Note", + "comment": "Noten gestrichen." + }, + { + "svgGroupId": "g1284", + "measure": "2B", + "system": "14", + "position": "1. Pause", + "comment": "Punktierte Achtelpause überschreibt Viertelpause." + }, + { + "svgGroupId": "g1295", + "measure": "3", + "system": "13", + "position": "4/16", + "comment": "d/d1 überschreibt A/a." + }, + { + "svgGroupId": "g1588", + "measure": "3", + "system": "14", + "position": "2.–3. Note", + "comment": "Noten gestrichen." + }, + { + "svgGroupId": "g1314", + "measure": "3", + "system": "14", + "position": "12/16", + "comment": "Sechzehntelbalken gestrichen und ersetzt durch Sechzehntelfähnchen (siehe auch Korrektur zuvor)." + }, + { + "svgGroupId": "g1604", + "measure": "5", + "system": "14", + "position": "1. Pause", + "comment": "Punktierte Achtelpause überschreibt Viertelnote a2/a3. Entzifferung von a3 jedoch unsicher und auch als e3 lesbar." + }, + { + "svgGroupId": "g975", + "measure": "7", + "system": "10", + "position": "2/4", + "comment": "Viertelpause überschreibt Achtelpause." + }, + { + "svgGroupId": "g992", + "measure": "7", + "system": "9", + "position": "(2/4)", + "comment": "c1–a überschreibt a–e." + }, + { + "svgGroupId": "g979", + "measure": "8", + "system": "10", + "position": "2/4", + "comment": "a/a1 überschreibt c1/c2." + } + ] } ] }, @@ -1889,18 +2003,23 @@ ], "comments": [ { - "svgGroupId": "g4431", - "measure": "7", - "system": "3", - "position": "2/4", - "comment": "Viertelnote gestrichen und ersetzt durch Achtelnote auf 4/8." - }, - { - "svgGroupId": "g4444", - "measure": "7", - "system": "4", - "position": "2.–3. Note", - "comment": "c1–a überschreibt a–e." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g4431", + "measure": "7", + "system": "3", + "position": "2/4", + "comment": "Viertelnote gestrichen und ersetzt durch Achtelnote auf 4/8." + }, + { + "svgGroupId": "g4444", + "measure": "7", + "system": "4", + "position": "2.–3. Note", + "comment": "c1–a überschreibt a–e." + } + ] } ], "linkBoxes": [ @@ -1919,102 +2038,107 @@ "description": ["M 22 Sk29 entwirft Var. XX von M 22."], "comments": [ { - "svgGroupId": "g1259", - "measure": "1", - "system": "1", - "position": "(2/4)", - "comment": "Unterstimmenschicht: Metrisch falsch positionierte Viertelnote e1 gestrichen." - }, - { - "svgGroupId": "g1273", - "measure": "2", - "system": "1", - "position": "5/8", - "comment": "Unterstimmenschicht: Metrisch falsch positionierte Achtelnote e1 gestrichen." - }, - { - "svgGroupId": "g1279", - "measure": "3", - "system": "1", - "position": "5/8", - "comment": "Unterstimmenschicht: Achtelnote d1 gestrichen." - }, - { - "svgGroupId": "g1289", - "measure": "4", - "system": "1", - "position": "(2/8–5/8)", - "comment": "Zwei Viertelnoten c2–c2 radiert." - }, - { - "svgGroupId": "g7", - "measure": "4", - "system": "1–2", - "position": "zwischen 4/8 und 5/8", - "comment": "Taktstrich radiert." - }, - { - "svgGroupId": "g1295", - "measure": "5", - "system": "1", - "position": "1. Pause", - "comment": "Unterstimmenschicht: Achtelpause überschreibt Halbe Note e1/e2." - }, - { - "svgGroupId": "g1307", - "measure": "5", - "system": "1", - "position": "1. Note", - "comment": "Oberstimmenschicht: Viertelnote überschreibt punktierte Halbe Note." - }, - { - "svgGroupId": "g4", - "measure": "5", - "system": "2", - "position": "(2/8–5/8)", - "comment": "Metrisch falsch positionierte Viertelnoten gestrichen und versetzt auf 2–3/4." - }, - { - "svgGroupId": "g1325", - "measure": "5", - "system": "1", - "position": "3/4", - "comment": "c2/c3 gestrichen und ersetzt durch h1/h2 am Ende des Takts." - }, - { - "svgGroupId": "g1292", - "measure": "7", - "system": "1", - "position": "1. Note", - "comment": "Oberstimmenschicht: Viertelnote d2/d3 überschreibt Halbe Note d2/d3, die wiederum Halbe Note f1/f2 überschreibt." - }, - { - "svgGroupId": "g1343", - "measure": "7", - "system": "1", - "position": "2/4", - "comment": "Unterstimmenschicht: Viertelnote h1 gestrichen." - }, - { - "svgGroupId": "g1357", - "measure": "8", - "system": "1", - "position": "1. Note", - "comment": "Oberstimmenschicht: Halbe Note a/a1/a2 überschreibt Viertelnote a1/a2." - }, - { - "svgGroupId": "g6", - "measure": "8", - "system": "2", - "position": "1–3/4", - "comment": "Oberstimmenschicht: Noten gestrichen." - }, - { - "svgGroupId": "g5", - "measure": "8", - "system": "1", - "position": "1.–3. Note", - "comment": "Unterstimmenschicht: Noten gestrichen und um eine Oktave nach oben versetzt." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1259", + "measure": "1", + "system": "1", + "position": "(2/4)", + "comment": "Unterstimmenschicht: Metrisch falsch positionierte Viertelnote e1 gestrichen." + }, + { + "svgGroupId": "g1273", + "measure": "2", + "system": "1", + "position": "5/8", + "comment": "Unterstimmenschicht: Metrisch falsch positionierte Achtelnote e1 gestrichen." + }, + { + "svgGroupId": "g1279", + "measure": "3", + "system": "1", + "position": "5/8", + "comment": "Unterstimmenschicht: Achtelnote d1 gestrichen." + }, + { + "svgGroupId": "g1289", + "measure": "4", + "system": "1", + "position": "(2/8–5/8)", + "comment": "Zwei Viertelnoten c2–c2 radiert." + }, + { + "svgGroupId": "g7", + "measure": "4", + "system": "1–2", + "position": "zwischen 4/8 und 5/8", + "comment": "Taktstrich radiert." + }, + { + "svgGroupId": "g1295", + "measure": "5", + "system": "1", + "position": "1. Pause", + "comment": "Unterstimmenschicht: Achtelpause überschreibt Halbe Note e1/e2." + }, + { + "svgGroupId": "g1307", + "measure": "5", + "system": "1", + "position": "1. Note", + "comment": "Oberstimmenschicht: Viertelnote überschreibt punktierte Halbe Note." + }, + { + "svgGroupId": "g4", + "measure": "5", + "system": "2", + "position": "(2/8–5/8)", + "comment": "Metrisch falsch positionierte Viertelnoten gestrichen und versetzt auf 2–3/4." + }, + { + "svgGroupId": "g1325", + "measure": "5", + "system": "1", + "position": "3/4", + "comment": "c2/c3 gestrichen und ersetzt durch h1/h2 am Ende des Takts." + }, + { + "svgGroupId": "g1292", + "measure": "7", + "system": "1", + "position": "1. Note", + "comment": "Oberstimmenschicht: Viertelnote d2/d3 überschreibt Halbe Note d2/d3, die wiederum Halbe Note f1/f2 überschreibt." + }, + { + "svgGroupId": "g1343", + "measure": "7", + "system": "1", + "position": "2/4", + "comment": "Unterstimmenschicht: Viertelnote h1 gestrichen." + }, + { + "svgGroupId": "g1357", + "measure": "8", + "system": "1", + "position": "1. Note", + "comment": "Oberstimmenschicht: Halbe Note a/a1/a2 überschreibt Viertelnote a1/a2." + }, + { + "svgGroupId": "g6", + "measure": "8", + "system": "2", + "position": "1–3/4", + "comment": "Oberstimmenschicht: Noten gestrichen." + }, + { + "svgGroupId": "g5", + "measure": "8", + "system": "1", + "position": "1.–3. Note", + "comment": "Unterstimmenschicht: Noten gestrichen und um eine Oktave nach oben versetzt." + } + ] } ] }, @@ -2030,53 +2154,58 @@ "description": ["M 22 Sk31 entwirft Var. XXI von M 22."], "comments": [ { - "svgGroupId": "g1308", - "measure": "3", - "system": "1", - "position": "2.–3. Note", - "comment": "Oberstimmenschicht: f2–a2 überschreibt a2–f2." - }, - { - "svgGroupId": "g1302", - "measure": "4", - "system": "2", - "position": "(6/8)", - "comment": "Zwei Sechzehntelnoten a–h radiert." - }, - { - "svgGroupId": "g1306", - "measure": "5", - "system": "2", - "position": "1/4", - "comment": "Unterstimmenschicht: Viertelpause überschreibt Achtelpause." - }, - { - "svgGroupId": "g1310", - "measure": "6", - "system": "1", - "position": "(2/4)", - "comment": "Notenkopf a2 radiert." - }, - { - "svgGroupId": "g1317", - "measure": "6", - "system": "1", - "position": "5/8", - "comment": "d2 überschreibt f2." - }, - { - "svgGroupId": "g951", - "measure": "8", - "system": "4", - "position": "5/16", - "comment": "Sechzehntelpause gestrichen." - }, - { - "svgGroupId": "g4", - "measure": "8", - "system": "3–4", - "position": "zwischen 4/8 und 12/16", - "comment": "Schlussstrich gestrichen." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1308", + "measure": "3", + "system": "1", + "position": "2.–3. Note", + "comment": "Oberstimmenschicht: f2–a2 überschreibt a2–f2." + }, + { + "svgGroupId": "g1302", + "measure": "4", + "system": "2", + "position": "(6/8)", + "comment": "Zwei Sechzehntelnoten a–h radiert." + }, + { + "svgGroupId": "g1306", + "measure": "5", + "system": "2", + "position": "1/4", + "comment": "Unterstimmenschicht: Viertelpause überschreibt Achtelpause." + }, + { + "svgGroupId": "g1310", + "measure": "6", + "system": "1", + "position": "(2/4)", + "comment": "Notenkopf a2 radiert." + }, + { + "svgGroupId": "g1317", + "measure": "6", + "system": "1", + "position": "5/8", + "comment": "d2 überschreibt f2." + }, + { + "svgGroupId": "g951", + "measure": "8", + "system": "4", + "position": "5/16", + "comment": "Sechzehntelpause gestrichen." + }, + { + "svgGroupId": "g4", + "measure": "8", + "system": "3–4", + "position": "zwischen 4/8 und 12/16", + "comment": "Schlussstrich gestrichen." + } + ] } ], "linkBoxes": [ @@ -2095,67 +2224,72 @@ "description": ["M 22 Sk32 entwirft Var. XXII von M 22."], "comments": [ { - "svgGroupId": "g1226", - "measure": "3", - "system": "10", - "position": "1/4", - "comment": "Unterstimmenschicht: Viertelnote c1 gestrichen." - }, - { - "svgGroupId": "g1283", - "measure": "4", - "system": "11", - "position": "1–2/8", - "comment": "Unterstimmenschicht: Balkierung überschreibt Achtelfähnchen zu 1/8." - }, - { - "svgGroupId": "g1234", - "measure": "5", - "system": "10", - "position": "1. Note", - "comment": "Oberstimmenschicht: Viertelnote cis2 überschreibt Halbe Note fis2." - }, - { - "svgGroupId": "g1273", - "measure": "5", - "system": "11", - "position": "1. Note", - "comment": "Viertelnote überschreibt Halbe Note." - }, - { - "svgGroupId": "g1279", - "measure": "5", - "system": "11", - "position": "2/4", - "comment": "Viertelnote c1 gestrichen." - }, - { - "svgGroupId": "g1236", - "measure": "6", - "system": "10", - "position": "2/8", - "comment": "Unterstimmenschicht: f1 überschreibt d1; h1 gestrichen." - }, - { - "svgGroupId": "g1248", - "measure": "7", - "system": "11", - "position": "1/4", - "comment": "Viertelnote H/e gestrichen." - }, - { - "svgGroupId": "g1259", - "measure": "7", - "system": "10", - "position": "2/4", - "comment": "Viertelnoten a/fis1 und a1 gestrichen." - }, - { - "svgGroupId": "g1267", - "measure": "8", - "system": "11", - "position": "1. Note", - "comment": "Oberstimmenschicht: Halbe Note überschreibt Viertelnote." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1226", + "measure": "3", + "system": "10", + "position": "1/4", + "comment": "Unterstimmenschicht: Viertelnote c1 gestrichen." + }, + { + "svgGroupId": "g1283", + "measure": "4", + "system": "11", + "position": "1–2/8", + "comment": "Unterstimmenschicht: Balkierung überschreibt Achtelfähnchen zu 1/8." + }, + { + "svgGroupId": "g1234", + "measure": "5", + "system": "10", + "position": "1. Note", + "comment": "Oberstimmenschicht: Viertelnote cis2 überschreibt Halbe Note fis2." + }, + { + "svgGroupId": "g1273", + "measure": "5", + "system": "11", + "position": "1. Note", + "comment": "Viertelnote überschreibt Halbe Note." + }, + { + "svgGroupId": "g1279", + "measure": "5", + "system": "11", + "position": "2/4", + "comment": "Viertelnote c1 gestrichen." + }, + { + "svgGroupId": "g1236", + "measure": "6", + "system": "10", + "position": "2/8", + "comment": "Unterstimmenschicht: f1 überschreibt d1; h1 gestrichen." + }, + { + "svgGroupId": "g1248", + "measure": "7", + "system": "11", + "position": "1/4", + "comment": "Viertelnote H/e gestrichen." + }, + { + "svgGroupId": "g1259", + "measure": "7", + "system": "10", + "position": "2/4", + "comment": "Viertelnoten a/fis1 und a1 gestrichen." + }, + { + "svgGroupId": "g1267", + "measure": "8", + "system": "11", + "position": "1. Note", + "comment": "Oberstimmenschicht: Halbe Note überschreibt Viertelnote." + } + ] } ] }, @@ -2167,39 +2301,44 @@ ], "comments": [ { - "svgGroupId": "g1097", - "measure": "6", - "system": "12", - "position": "4/8", - "comment": "Achtelnote e2 gestrichen." - }, - { - "svgGroupId": "g5", - "measure": "{7A}", - "system": "12–13", - "position": "", - "comment": "Takt pauschal gestrichen." - }, - { - "svgGroupId": "g1103", - "measure": "{7A}", - "system": "13", - "position": "2/8", - "comment": "Achtelnote e gestrichen." - }, - { - "svgGroupId": "g1122", - "measure": "{7A}", - "system": "13", - "position": "4–5/8", - "comment": "h–e überschreibt c1–h." - }, - { - "svgGroupId": "g1123", - "measure": "{8A}", - "system": "12", - "position": "", - "comment": "Noten gestrichen." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1097", + "measure": "6", + "system": "12", + "position": "4/8", + "comment": "Achtelnote e2 gestrichen." + }, + { + "svgGroupId": "g5", + "measure": "{7A}", + "system": "12–13", + "position": "", + "comment": "Takt pauschal gestrichen." + }, + { + "svgGroupId": "g1103", + "measure": "{7A}", + "system": "13", + "position": "2/8", + "comment": "Achtelnote e gestrichen." + }, + { + "svgGroupId": "g1122", + "measure": "{7A}", + "system": "13", + "position": "4–5/8", + "comment": "h–e überschreibt c1–h." + }, + { + "svgGroupId": "g1123", + "measure": "{8A}", + "system": "12", + "position": "", + "comment": "Noten gestrichen." + } + ] } ], "linkBoxes": [ @@ -2235,102 +2374,107 @@ "description": ["M 22 Sk33 entwirft Var. XXIII von M 22."], "comments": [ { - "svgGroupId": "g1237", - "measure": "3", - "system": "14", - "position": "1. Note", - "comment": "Mittelstimmenschicht: Halbe Note überschreibt Viertelnote." - }, - { - "svgGroupId": "g1243", - "measure": "3", - "system": "15", - "position": "2/4", - "comment": "Viertelnote überschreibt Halbe Note." - }, - { - "svgGroupId": "g1249", - "measure": "4", - "system": "14", - "position": "1/4", - "comment": "Mittelstimmenschicht: Viertelnote überschreibt Halbe Note." - }, - { - "svgGroupId": "g1254", - "measure": "4", - "system": "14", - "position": "1. Note", - "comment": "Oberstimmenschicht: Halbe Note g2 gestrichen." - }, - { - "svgGroupId": "g1260", - "measure": "5", - "system": "14", - "position": "1/4", - "comment": "Mittelstimmenschicht: Viertelnote überschreibt Halbe Note." - }, - { - "svgGroupId": "g1266", - "measure": "5", - "system": "14", - "position": "2. Note", - "comment": "Mittelstimmenschicht: Halbe Note überschreibt Viertelnote." - }, - { - "svgGroupId": "g1271", - "measure": "5", - "system": "15", - "position": "3/4", - "comment": "Viertelnote c gestrichen." - }, - { - "svgGroupId": "g1244", - "measure": "5
    bis 6", - "system": "14", - "position": "letzte Note
    1. Note", - "comment": "Unterstimmenschicht: f1 ersetzt gestrichenes g1 in T. 6; Ligatur zu g1 in T. 5 gestrichen." - }, - { - "svgGroupId": "g1229", - "measure": "6", - "system": "14", - "position": "3/4", - "comment": "Mittelstimmenschicht: f2 überschreibt {{ref.getGlyph('[a]')}}h1." - }, - { - "svgGroupId": "g1290", - "measure": "7", - "system": "14", - "position": "1. Note", - "comment": "Oberstimmenschicht: Halbe Note überschreibt Viertelnote." - }, - { - "svgGroupId": "g1250", - "measure": "7", - "system": "14", - "position": "1. Note", - "comment": "Mittelstimmenschicht: f2 überschreibt a1." - }, - { - "svgGroupId": "g1299", - "measure": "7", - "system": "14", - "position": "2/4", - "comment": "Mittelstimmenschicht: e2 überschreibt e3." - }, - { - "svgGroupId": "g1310", - "measure": "8", - "system": "14", - "position": "1. Note", - "comment": "Oberstimmenschicht: Augmentationspunkt zu a2 gestrichen." - }, - { - "svgGroupId": "g1286", - "measure": "8", - "system": "14", - "position": "3/4", - "comment": "Mittelstimmenschicht: Viertelnote c2 überschreibt Halbe Note e2." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1237", + "measure": "3", + "system": "14", + "position": "1. Note", + "comment": "Mittelstimmenschicht: Halbe Note überschreibt Viertelnote." + }, + { + "svgGroupId": "g1243", + "measure": "3", + "system": "15", + "position": "2/4", + "comment": "Viertelnote überschreibt Halbe Note." + }, + { + "svgGroupId": "g1249", + "measure": "4", + "system": "14", + "position": "1/4", + "comment": "Mittelstimmenschicht: Viertelnote überschreibt Halbe Note." + }, + { + "svgGroupId": "g1254", + "measure": "4", + "system": "14", + "position": "1. Note", + "comment": "Oberstimmenschicht: Halbe Note g2 gestrichen." + }, + { + "svgGroupId": "g1260", + "measure": "5", + "system": "14", + "position": "1/4", + "comment": "Mittelstimmenschicht: Viertelnote überschreibt Halbe Note." + }, + { + "svgGroupId": "g1266", + "measure": "5", + "system": "14", + "position": "2. Note", + "comment": "Mittelstimmenschicht: Halbe Note überschreibt Viertelnote." + }, + { + "svgGroupId": "g1271", + "measure": "5", + "system": "15", + "position": "3/4", + "comment": "Viertelnote c gestrichen." + }, + { + "svgGroupId": "g1244", + "measure": "5
    bis 6", + "system": "14", + "position": "letzte Note
    1. Note", + "comment": "Unterstimmenschicht: f1 ersetzt gestrichenes g1 in T. 6; Ligatur zu g1 in T. 5 gestrichen." + }, + { + "svgGroupId": "g1229", + "measure": "6", + "system": "14", + "position": "3/4", + "comment": "Mittelstimmenschicht: f2 überschreibt {{ref.getGlyph('[a]')}}h1." + }, + { + "svgGroupId": "g1290", + "measure": "7", + "system": "14", + "position": "1. Note", + "comment": "Oberstimmenschicht: Halbe Note überschreibt Viertelnote." + }, + { + "svgGroupId": "g1250", + "measure": "7", + "system": "14", + "position": "1. Note", + "comment": "Mittelstimmenschicht: f2 überschreibt a1." + }, + { + "svgGroupId": "g1299", + "measure": "7", + "system": "14", + "position": "2/4", + "comment": "Mittelstimmenschicht: e2 überschreibt e3." + }, + { + "svgGroupId": "g1310", + "measure": "8", + "system": "14", + "position": "1. Note", + "comment": "Oberstimmenschicht: Augmentationspunkt zu a2 gestrichen." + }, + { + "svgGroupId": "g1286", + "measure": "8", + "system": "14", + "position": "3/4", + "comment": "Mittelstimmenschicht: Viertelnote c2 überschreibt Halbe Note e2." + } + ] } ] } diff --git a/src/assets/data/edition/series/2/section/2a/m30/textcritics.json b/src/assets/data/edition/series/2/section/2a/m30/textcritics.json index 26549d0c6..9fc64d183 100644 --- a/src/assets/data/edition/series/2/section/2a/m30/textcritics.json +++ b/src/assets/data/edition/series/2/section/2a/m30/textcritics.json @@ -8,46 +8,51 @@ ], "comments": [ { - "svgGroupId": "g2815", - "measure": "8", - "system": "Klav. u.", - "position": "2/8", - "comment": "Oberstimmenschicht: Augmentationspunkt weggelassen mit Blick auf metrischen Kontext." - }, - { - "svgGroupId": "g6275", - "measure": "14", - "system": "Klav. o.", - "position": "6/8", - "comment": "Unterstimmenschicht: Hilfslinie unter dem Notenkopf weggelassen (vgl. auch Korrekturen mit Bleistift)." - }, - { - "svgGroupId": "g6279", - "measure": "15", - "system": "Klav. u.", - "position": "4/8", - "comment": "Gemeinsamer Notenkopf für Ober- und Unterstimmenschicht korrigiert zu zwei separate Notenköpfe." - }, - { - "svgGroupId": "g6283", - "measure": "20", - "system": "Klav. u.", - "position": "1–2/8", - "comment": "Oberstimmenschicht: Viertelnoten b/es1–a/es1 korrigiert zu Achtelnoten mit Blick auf metrischen Kontext." - }, - { - "svgGroupId": "g6318", - "measure": "22", - "system": "Klav. u.", - "position": "1–3/8", - "comment": "sic." - }, - { - "svgGroupId": "g6321", - "measure": "24", - "system": "Klav.", - "position": "Taktende", - "comment": "sic. B: Kein Schlussstrich vorhanden (vgl. auch Sk1)." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g2815", + "measure": "8", + "system": "Klav. u.", + "position": "2/8", + "comment": "Oberstimmenschicht: Augmentationspunkt weggelassen mit Blick auf metrischen Kontext." + }, + { + "svgGroupId": "g6275", + "measure": "14", + "system": "Klav. o.", + "position": "6/8", + "comment": "Unterstimmenschicht: Hilfslinie unter dem Notenkopf weggelassen (vgl. auch Korrekturen mit Bleistift)." + }, + { + "svgGroupId": "g6279", + "measure": "15", + "system": "Klav. u.", + "position": "4/8", + "comment": "Gemeinsamer Notenkopf für Ober- und Unterstimmenschicht korrigiert zu zwei separate Notenköpfe." + }, + { + "svgGroupId": "g6283", + "measure": "20", + "system": "Klav. u.", + "position": "1–2/8", + "comment": "Oberstimmenschicht: Viertelnoten b/es1–a/es1 korrigiert zu Achtelnoten mit Blick auf metrischen Kontext." + }, + { + "svgGroupId": "g6318", + "measure": "22", + "system": "Klav. u.", + "position": "1–3/8", + "comment": "sic." + }, + { + "svgGroupId": "g6321", + "measure": "24", + "system": "Klav.", + "position": "Taktende", + "comment": "sic. B: Kein Schlussstrich vorhanden (vgl. auch Sk1)." + } + ] } ] }, @@ -59,403 +64,408 @@ ], "comments": [ { - "svgGroupId": "g1187", - "measure": "2", - "system": "2", - "position": "5/8", - "comment": "Oberstimmenschicht: sic. Hilfslinien unterhalb von vermutlich als b/d1 gedachter Viertelnote." - }, - { - "svgGroupId": "g1186", - "measure": "4", - "system": "1", - "position": "3. Note", - "comment": "Oberstimmenschicht: Augmentationspunkt gestrichen." - }, - { - "svgGroupId": "g1174", - "measure": "5", - "system": "2", - "position": "1. Note", - "comment": "Oberstimmenschicht: es überschreibt f." - }, - { - "svgGroupId": "g1178", - "measure": "6", - "system": "1", - "position": "letzte Note", - "comment": "{{ref.getGlyph('[a]')}} zu e2 überschreibt {{ref.getGlyph('[b]')}}." - }, - { - "svgGroupId": "g1182", - "measure": "6", - "system": "2", - "position": "4/8", - "comment": "Oberstimmenschicht: Achtelpause überschreibt {{ref.getGlyph('[b]')}} zu b." - }, - { - "svgGroupId": "g1058", - "measure": "{7A–10B}", - "system": "4–5", - "position": "", - "comment": "Akkolade pauschal gestrichen." - }, - { - "svgGroupId": "g1067", - "measure": "{8A}", - "system": "5", - "position": "3/8", - "comment": "e überschreibt c." - }, - { - "svgGroupId": "g1075", - "measure": "{8A}", - "system": "5", - "position": "2. Note", - "comment": "Unterstimmenschicht: C radiert und ersetzt durch c." - }, - { - "svgGroupId": "g1062", - "measure": "{9A–10B}", - "system": "4–5", - "position": "1–3/4", - "comment": "Takte pauschal gestrichen." - }, - { - "svgGroupId": "g827", - "measure": "{11A–16A}", - "system": "7–8", - "position": "", - "comment": "Akkolade pauschal gestrichen." - }, - { - "svgGroupId": "g1116", - "measure": "7B", - "system": "10", - "position": "3/8", - "comment": "as2 gestrichen und ersetzt durch f2." - }, - { - "svgGroupId": "text1949", - "measure": "7B", - "system": "10", - "position": "(3/8)", - "comment": "Nicht entzifferbare, gestrichene Schicht über dem System." - }, - { - "svgGroupId": "g1122", - "measure": "7B", - "system": "10", - "position": "4/8", - "comment": "Oberstimmenschicht: Viertelnote as1 überschreibt Achtelnote f2 (oder {{ref.getGlyph('[b]')}} zu b1 oder as1?)." - }, - { - "svgGroupId": "g1137", - "measure": "8B", - "system": "11", - "position": "1–3/8", - "comment": "Oberstimmenschicht: b–a–g überschreibt as–g–f." - }, - { - "svgGroupId": "g1151", - "measure": "8B", - "system": "11", - "position": "4–6/8", - "comment": "Unterstimmenschicht: As–G überschreibt B–As und punktierte Viertelnote F." - }, - { - "svgGroupId": "g1161", - "measure": "9C", - "system": "10", - "position": "(1/4)", - "comment": "{{ref.getGlyph('[b]')}} zu des2 überschreibt Viertelnote as1." - }, - { - "svgGroupId": "g1157", - "measure": "9C", - "system": "11", - "position": "1. Note", - "comment": "Des gestrichen." - }, - { - "svgGroupId": "g998", - "measure": "9D", - "system": "13", - "position": "", - "comment": "{{ref.getGlyph('[b]')}}des2–f2 überschreibt {{ref.getGlyph('[a]')}}f2–{{ref.getGlyph('[b]')}}b2." - }, - { - "svgGroupId": "g2571", - "measure": "{9D–12B}", - "system": "13", - "position": "", - "comment": "Takte pauschal gestrichen." - }, - { - "svgGroupId": "g1132", - "measure": "9E–10E", - "system": "14", - "position": "letzte Note bis 1. Note", - "comment": "Ligatur gestrichen." - }, - { - "svgGroupId": "g1140", - "measure": "10E", - "system": "14", - "position": "1/8", - "comment": "Unterstimmenschicht: ges1 überschreibt f1." - }, - { - "svgGroupId": "g1156", - "measure": "10E", - "system": "14", - "position": "4–6/8", - "comment": "ges1–b1–ges1 überschreibt b1–ges1–b1." - }, - { - "svgGroupId": "g1179", - "measure": "12C", - "system": "14", - "position": "3/8", - "comment": "des3/f3 überschreibt c2/es2." - }, - { - "svgGroupId": "g1162", - "measure": "12C", - "system": "15", - "position": "3/8", - "comment": "b überschreibt B." - }, - { - "svgGroupId": "g1188", - "measure": "12C", - "system": "14", - "position": "3. Note", - "comment": "d2 überschreibt es2." - }, - { - "svgGroupId": "g1166", - "measure": "12C", - "system": "15", - "position": "4–6/8", - "comment": "Noten gestrichen." - }, - { - "svgGroupId": "g1197", - "measure": "{13B–15B}", - "system": "14–15", - "position": "", - "comment": "Takte pauschal gestrichen." - }, - { - "svgGroupId": "g1193", - "measure": "{13B}", - "system": "14", - "position": "1/8", - "comment": "Unterstimmenschicht: h1 überschreibt f1." - }, - { - "svgGroupId": "g1213", - "measure": "{14B}", - "system": "15", - "position": "4–6/8", - "comment": "Unterstimmenschicht: c2–es2–c2 überschreibt es2–c2–es2." - }, - { - "svgGroupId": "g1123", - "measure": "16B", - "system": "17", - "position": "3. Note", - "comment": "g1 ersetzt durch b1/g2/b2." - }, - { - "svgGroupId": "g1117", - "measure": "{13C}", - "system": "16–17", - "position": "", - "comment": "Takt pauschal gestrichen." - }, - { - "svgGroupId": "g1112", - "measure": "{13C}", - "system": "16", - "position": "3. Note", - "comment": "f2 überschreibt des2." - }, - { - "svgGroupId": "g1134", - "measure": "14C", - "system": "16", - "position": "5–6/8", - "comment": "dis1–h überschreibt dis2–h1." - }, - { - "svgGroupId": "g1120", - "measure": "18", - "system": "1", - "position": "2. Note", - "comment": "Augmentationspunkt gestrichen." - }, - { - "svgGroupId": "g1135", - "measure": "19", - "system": "2", - "position": "3.–4. Note", - "comment": "Unterstimmenschicht: Ligatur gestrichen." - }, - { - "svgGroupId": "g1131", - "measure": "19", - "system": "1", - "position": "6/8", - "comment": "{{ref.getGlyph('[b]')}}b2 überschreibt {{ref.getGlyph('[a]')}}g2." - }, - { - "svgGroupId": "g1172", - "measure": "21", - "system": "1", - "position": "1. Note", - "comment": "b über dem System gestrichen." - }, - { - "svgGroupId": "g1233", - "measure": "21", - "system": "1", - "position": "(1/4)", - "comment": "Viertelnote gestrichen (Tonhöhe undeutlich)." - }, - { - "svgGroupId": "g1167", - "measure": "21", - "system": "2", - "position": "1/8", - "comment": "{{ref.getGlyph('[b]')}}B ersetzt durch B1." - }, - { - "svgGroupId": "g1160", - "measure": "21", - "system": "1", - "position": "2. Note", - "comment": "g1 gestrichen und ersetzt durch b1." - }, - { - "svgGroupId": "g1121", - "measure": "22", - "system": "5", - "position": "4. Note", - "comment": "Viertelnote {{ref.getGlyph('[b]')}}des gestrichen." - }, - { - "svgGroupId": "g1129", - "measure": "{23A}", - "system": "4", - "position": "", - "comment": "Noten gestrichen." - }, - { - "svgGroupId": "g1107", - "measure": "23B", - "system": "4", - "position": "2/8", - "comment": "f1 überschreibt des1." - }, - { - "svgGroupId": "g1113", - "measure": "23B", - "system": "4", - "position": "3/8", - "comment": "es1 überschreibt c1." - }, - { - "svgGroupId": "g1144", - "measure": "{24A}", - "system": "4", - "position": "1. Note", - "comment": "heses1 überschreibt as1." - }, - { - "svgGroupId": "g1148", - "measure": "{24A}", - "system": "24–5", - "position": "Taktmitte", - "comment": "Taktstrich gestrichen." - }, - { - "svgGroupId": "g1155", - "measure": "{24A}", - "system": "4", - "position": "letzte Note", - "comment": "Viertelnote überschreibt Achtelnote." - }, - { - "svgGroupId": "g1159", - "measure": "{24A}", - "system": "", - "position": "", - "comment": "Takt pauschal gestrichen." - }, - { - "svgGroupId": "g1164", - "measure": "24B", - "system": "4", - "position": "1. Note", - "comment": "e2 gestrichen." - }, - { - "svgGroupId": "g1168", - "measure": "24B", - "system": "5", - "position": "2/8", - "comment": "Notenkopf c1 radiert." - }, - { - "svgGroupId": "g1071", - "measure": "25(4–6/8)", - "system": "7", - "position": "1.–2. Note", - "comment": "ges2–fes2 überschreibt b2–as2. " - }, - { - "svgGroupId": "g1101", - "measure": "27", - "system": "7", - "position": "1/8", - "comment": " c2 gestrichen." - }, - { - "svgGroupId": "g1108", - "measure": "27", - "system": "7", - "position": "4. Note", - "comment": "a1 überschreibt ges1." - }, - { - "svgGroupId": "g1114", - "measure": "27", - "system": "7", - "position": "6/8", - "comment": "h1 gestrichen." - }, - { - "svgGroupId": "g37", - "measure": "{28A–29A}", - "system": "7", - "position": "", - "comment": "Noten pauschal gestrichen." - }, - { - "svgGroupId": "g1118", - "measure": "{28A}", - "system": "7", - "position": "4/8", - "comment": "{{ref.getGlyph('[bb]')}} gestrichen." - }, - { - "svgGroupId": "g1125", - "measure": "28B", - "system": "8", - "position": "(1/4)", - "comment": "Viertelnote As/es gestrichen." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1187", + "measure": "2", + "system": "2", + "position": "5/8", + "comment": "Oberstimmenschicht: sic. Hilfslinien unterhalb von vermutlich als b/d1 gedachter Viertelnote." + }, + { + "svgGroupId": "g1186", + "measure": "4", + "system": "1", + "position": "3. Note", + "comment": "Oberstimmenschicht: Augmentationspunkt gestrichen." + }, + { + "svgGroupId": "g1174", + "measure": "5", + "system": "2", + "position": "1. Note", + "comment": "Oberstimmenschicht: es überschreibt f." + }, + { + "svgGroupId": "g1178", + "measure": "6", + "system": "1", + "position": "letzte Note", + "comment": "{{ref.getGlyph('[a]')}} zu e2 überschreibt {{ref.getGlyph('[b]')}}." + }, + { + "svgGroupId": "g1182", + "measure": "6", + "system": "2", + "position": "4/8", + "comment": "Oberstimmenschicht: Achtelpause überschreibt {{ref.getGlyph('[b]')}} zu b." + }, + { + "svgGroupId": "g1058", + "measure": "{7A–10B}", + "system": "4–5", + "position": "", + "comment": "Akkolade pauschal gestrichen." + }, + { + "svgGroupId": "g1067", + "measure": "{8A}", + "system": "5", + "position": "3/8", + "comment": "e überschreibt c." + }, + { + "svgGroupId": "g1075", + "measure": "{8A}", + "system": "5", + "position": "2. Note", + "comment": "Unterstimmenschicht: C radiert und ersetzt durch c." + }, + { + "svgGroupId": "g1062", + "measure": "{9A–10B}", + "system": "4–5", + "position": "1–3/4", + "comment": "Takte pauschal gestrichen." + }, + { + "svgGroupId": "g827", + "measure": "{11A–16A}", + "system": "7–8", + "position": "", + "comment": "Akkolade pauschal gestrichen." + }, + { + "svgGroupId": "g1116", + "measure": "7B", + "system": "10", + "position": "3/8", + "comment": "as2 gestrichen und ersetzt durch f2." + }, + { + "svgGroupId": "text1949", + "measure": "7B", + "system": "10", + "position": "(3/8)", + "comment": "Nicht entzifferbare, gestrichene Schicht über dem System." + }, + { + "svgGroupId": "g1122", + "measure": "7B", + "system": "10", + "position": "4/8", + "comment": "Oberstimmenschicht: Viertelnote as1 überschreibt Achtelnote f2 (oder {{ref.getGlyph('[b]')}} zu b1 oder as1?)." + }, + { + "svgGroupId": "g1137", + "measure": "8B", + "system": "11", + "position": "1–3/8", + "comment": "Oberstimmenschicht: b–a–g überschreibt as–g–f." + }, + { + "svgGroupId": "g1151", + "measure": "8B", + "system": "11", + "position": "4–6/8", + "comment": "Unterstimmenschicht: As–G überschreibt B–As und punktierte Viertelnote F." + }, + { + "svgGroupId": "g1161", + "measure": "9C", + "system": "10", + "position": "(1/4)", + "comment": "{{ref.getGlyph('[b]')}} zu des2 überschreibt Viertelnote as1." + }, + { + "svgGroupId": "g1157", + "measure": "9C", + "system": "11", + "position": "1. Note", + "comment": "Des gestrichen." + }, + { + "svgGroupId": "g998", + "measure": "9D", + "system": "13", + "position": "", + "comment": "{{ref.getGlyph('[b]')}}des2–f2 überschreibt {{ref.getGlyph('[a]')}}f2–{{ref.getGlyph('[b]')}}b2." + }, + { + "svgGroupId": "g2571", + "measure": "{9D–12B}", + "system": "13", + "position": "", + "comment": "Takte pauschal gestrichen." + }, + { + "svgGroupId": "g1132", + "measure": "9E–10E", + "system": "14", + "position": "letzte Note bis 1. Note", + "comment": "Ligatur gestrichen." + }, + { + "svgGroupId": "g1140", + "measure": "10E", + "system": "14", + "position": "1/8", + "comment": "Unterstimmenschicht: ges1 überschreibt f1." + }, + { + "svgGroupId": "g1156", + "measure": "10E", + "system": "14", + "position": "4–6/8", + "comment": "ges1–b1–ges1 überschreibt b1–ges1–b1." + }, + { + "svgGroupId": "g1179", + "measure": "12C", + "system": "14", + "position": "3/8", + "comment": "des3/f3 überschreibt c2/es2." + }, + { + "svgGroupId": "g1162", + "measure": "12C", + "system": "15", + "position": "3/8", + "comment": "b überschreibt B." + }, + { + "svgGroupId": "g1188", + "measure": "12C", + "system": "14", + "position": "3. Note", + "comment": "d2 überschreibt es2." + }, + { + "svgGroupId": "g1166", + "measure": "12C", + "system": "15", + "position": "4–6/8", + "comment": "Noten gestrichen." + }, + { + "svgGroupId": "g1197", + "measure": "{13B–15B}", + "system": "14–15", + "position": "", + "comment": "Takte pauschal gestrichen." + }, + { + "svgGroupId": "g1193", + "measure": "{13B}", + "system": "14", + "position": "1/8", + "comment": "Unterstimmenschicht: h1 überschreibt f1." + }, + { + "svgGroupId": "g1213", + "measure": "{14B}", + "system": "15", + "position": "4–6/8", + "comment": "Unterstimmenschicht: c2–es2–c2 überschreibt es2–c2–es2." + }, + { + "svgGroupId": "g1123", + "measure": "16B", + "system": "17", + "position": "3. Note", + "comment": "g1 ersetzt durch b1/g2/b2." + }, + { + "svgGroupId": "g1117", + "measure": "{13C}", + "system": "16–17", + "position": "", + "comment": "Takt pauschal gestrichen." + }, + { + "svgGroupId": "g1112", + "measure": "{13C}", + "system": "16", + "position": "3. Note", + "comment": "f2 überschreibt des2." + }, + { + "svgGroupId": "g1134", + "measure": "14C", + "system": "16", + "position": "5–6/8", + "comment": "dis1–h überschreibt dis2–h1." + }, + { + "svgGroupId": "g1120", + "measure": "18", + "system": "1", + "position": "2. Note", + "comment": "Augmentationspunkt gestrichen." + }, + { + "svgGroupId": "g1135", + "measure": "19", + "system": "2", + "position": "3.–4. Note", + "comment": "Unterstimmenschicht: Ligatur gestrichen." + }, + { + "svgGroupId": "g1131", + "measure": "19", + "system": "1", + "position": "6/8", + "comment": "{{ref.getGlyph('[b]')}}b2 überschreibt {{ref.getGlyph('[a]')}}g2." + }, + { + "svgGroupId": "g1172", + "measure": "21", + "system": "1", + "position": "1. Note", + "comment": "b über dem System gestrichen." + }, + { + "svgGroupId": "g1233", + "measure": "21", + "system": "1", + "position": "(1/4)", + "comment": "Viertelnote gestrichen (Tonhöhe undeutlich)." + }, + { + "svgGroupId": "g1167", + "measure": "21", + "system": "2", + "position": "1/8", + "comment": "{{ref.getGlyph('[b]')}}B ersetzt durch B1." + }, + { + "svgGroupId": "g1160", + "measure": "21", + "system": "1", + "position": "2. Note", + "comment": "g1 gestrichen und ersetzt durch b1." + }, + { + "svgGroupId": "g1121", + "measure": "22", + "system": "5", + "position": "4. Note", + "comment": "Viertelnote {{ref.getGlyph('[b]')}}des gestrichen." + }, + { + "svgGroupId": "g1129", + "measure": "{23A}", + "system": "4", + "position": "", + "comment": "Noten gestrichen." + }, + { + "svgGroupId": "g1107", + "measure": "23B", + "system": "4", + "position": "2/8", + "comment": "f1 überschreibt des1." + }, + { + "svgGroupId": "g1113", + "measure": "23B", + "system": "4", + "position": "3/8", + "comment": "es1 überschreibt c1." + }, + { + "svgGroupId": "g1144", + "measure": "{24A}", + "system": "4", + "position": "1. Note", + "comment": "heses1 überschreibt as1." + }, + { + "svgGroupId": "g1148", + "measure": "{24A}", + "system": "24–5", + "position": "Taktmitte", + "comment": "Taktstrich gestrichen." + }, + { + "svgGroupId": "g1155", + "measure": "{24A}", + "system": "4", + "position": "letzte Note", + "comment": "Viertelnote überschreibt Achtelnote." + }, + { + "svgGroupId": "g1159", + "measure": "{24A}", + "system": "", + "position": "", + "comment": "Takt pauschal gestrichen." + }, + { + "svgGroupId": "g1164", + "measure": "24B", + "system": "4", + "position": "1. Note", + "comment": "e2 gestrichen." + }, + { + "svgGroupId": "g1168", + "measure": "24B", + "system": "5", + "position": "2/8", + "comment": "Notenkopf c1 radiert." + }, + { + "svgGroupId": "g1071", + "measure": "25(4–6/8)", + "system": "7", + "position": "1.–2. Note", + "comment": "ges2–fes2 überschreibt b2–as2. " + }, + { + "svgGroupId": "g1101", + "measure": "27", + "system": "7", + "position": "1/8", + "comment": " c2 gestrichen." + }, + { + "svgGroupId": "g1108", + "measure": "27", + "system": "7", + "position": "4. Note", + "comment": "a1 überschreibt ges1." + }, + { + "svgGroupId": "g1114", + "measure": "27", + "system": "7", + "position": "6/8", + "comment": "h1 gestrichen." + }, + { + "svgGroupId": "g37", + "measure": "{28A–29A}", + "system": "7", + "position": "", + "comment": "Noten pauschal gestrichen." + }, + { + "svgGroupId": "g1118", + "measure": "{28A}", + "system": "7", + "position": "4/8", + "comment": "{{ref.getGlyph('[bb]')}} gestrichen." + }, + { + "svgGroupId": "g1125", + "measure": "28B", + "system": "8", + "position": "(1/4)", + "comment": "Viertelnote As/es gestrichen." + } + ] } ], "linkBoxes": [ diff --git a/src/assets/data/edition/series/2/section/2a/m31/textcritics.json b/src/assets/data/edition/series/2/section/2a/m31/textcritics.json index a20eac0d8..7c3906c0e 100644 --- a/src/assets/data/edition/series/2/section/2a/m31/textcritics.json +++ b/src/assets/data/edition/series/2/section/2a/m31/textcritics.json @@ -8,60 +8,65 @@ ], "comments": [ { - "svgGroupId": "g3298", - "measure": "1", - "system": "Klav.", - "position": "4/16", - "comment": "{{ref.getGlyph('[pp]')}} versetzt von 3/8." - }, - { - "svgGroupId": "g3302", - "measure": "5", - "system": "Klav. u.", - "position": "3/16", - "comment": "Augmentationspunkt weggelassen mit Blick auf metrischen Kontext." - }, - { - "svgGroupId": "g3306", - "measure": "6", - "system": "Klav.", - "position": "4/16", - "comment": "{{ref.getGlyph('[pp]')}} versetzt von 3/8." - }, - { - "svgGroupId": "g2028", - "measure": "15", - "system": "Klav.", - "position": "Taktende", - "comment": "Taktstrich ergänzt (vgl. Korrekturen 2)." - }, - { - "svgGroupId": "g3042", - "measure": "16", - "system": "Klav.", - "position": "Taktende", - "comment": "Taktstrich ergänzt (vgl. Korrekturen 2)." - }, - { - "svgGroupId": "g3046", - "measure": "18", - "system": "Klav.", - "position": "4/16", - "comment": "{{ref.getGlyph('[pp]')}} versetzt von zwischen 3/8 und 4/8." - }, - { - "svgGroupId": "g3050", - "measure": "23", - "system": "Klav.", - "position": "4/16", - "comment": "{{ref.getGlyph('[p]')}} versetzt von 3/8." - }, - { - "svgGroupId": "g3054", - "measure": "28", - "system": "Klav.", - "position": "8/16", - "comment": "{{ref.getGlyph('[pp]')}} versetzt von 5/8." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g3298", + "measure": "1", + "system": "Klav.", + "position": "4/16", + "comment": "{{ref.getGlyph('[pp]')}} versetzt von 3/8." + }, + { + "svgGroupId": "g3302", + "measure": "5", + "system": "Klav. u.", + "position": "3/16", + "comment": "Augmentationspunkt weggelassen mit Blick auf metrischen Kontext." + }, + { + "svgGroupId": "g3306", + "measure": "6", + "system": "Klav.", + "position": "4/16", + "comment": "{{ref.getGlyph('[pp]')}} versetzt von 3/8." + }, + { + "svgGroupId": "g2028", + "measure": "15", + "system": "Klav.", + "position": "Taktende", + "comment": "Taktstrich ergänzt (vgl. Korrekturen 2)." + }, + { + "svgGroupId": "g3042", + "measure": "16", + "system": "Klav.", + "position": "Taktende", + "comment": "Taktstrich ergänzt (vgl. Korrekturen 2)." + }, + { + "svgGroupId": "g3046", + "measure": "18", + "system": "Klav.", + "position": "4/16", + "comment": "{{ref.getGlyph('[pp]')}} versetzt von zwischen 3/8 und 4/8." + }, + { + "svgGroupId": "g3050", + "measure": "23", + "system": "Klav.", + "position": "4/16", + "comment": "{{ref.getGlyph('[p]')}} versetzt von 3/8." + }, + { + "svgGroupId": "g3054", + "measure": "28", + "system": "Klav.", + "position": "8/16", + "comment": "{{ref.getGlyph('[pp]')}} versetzt von 5/8." + } + ] } ] }, @@ -73,11 +78,16 @@ ], "comments": [ { - "svgGroupId": "g964", - "measure": "1", - "system": "10", - "position": "(2/4)", - "comment": "Zwei Achtelnoten überschreiben Viertelnote." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g964", + "measure": "1", + "system": "10", + "position": "(2/4)", + "comment": "Zwei Achtelnoten überschreiben Viertelnote." + } + ] } ], "linkBoxes": [ @@ -105,11 +115,16 @@ ], "comments": [ { - "svgGroupId": "g952", - "measure": "x+2", - "system": "10", - "position": "1. Note", - "comment": "Halbe Note überschreibt Viertelnote." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g952", + "measure": "x+2", + "system": "10", + "position": "1. Note", + "comment": "Halbe Note überschreibt Viertelnote." + } + ] } ] }, @@ -121,74 +136,79 @@ ], "comments": [ { - "svgGroupId": "g1140", - "measure": "2", - "system": "16", - "position": "1/4", - "comment": "Im Bassschlüssel zu lesende Viertelnote as/c1 gestrichen." - }, - { - "svgGroupId": "g1146", - "measure": "3", - "system": "16", - "position": "1. Note", - "comment": "Viertelnote überschreibt Halbe Note." - }, - { - "svgGroupId": "g1150", - "measure": "3", - "system": "16", - "position": "2/4", - "comment": "g gestrichen." - }, - { - "svgGroupId": "g1169", - "measure": "4", - "system": "15", - "position": "1. Note", - "comment": "[a] überschreibt [b]." - }, - { - "svgGroupId": "g1164", - "measure": "4", - "system": "15", - "position": "letzte Note", - "comment": "g1/c2/e2 überschreibt f2." - }, - { - "svgGroupId": "g1090", - "measure": "8", - "system": "17", - "position": "2/8", - "comment": "a2 gestrichen." - }, - { - "svgGroupId": "g1166", - "measure": "10", - "system": "18", - "position": "(2–3/4)", - "comment": "Punktierte Viertelnote G/d mit Achtelnote g überschreibt Halbe Note G/d; Augmentationspunkte gestrichen und Achtelnote d auf 5/8 hinzugefügt und mit g auf 6/8 zusammengebalkt." - }, - { - "svgGroupId": "g1131", - "measure": "10", - "system": "17", - "position": "3/4", - "comment": "h1 gestrichen." - }, - { - "svgGroupId": "g1155", - "measure": "11", - "system": "2", - "position": "", - "comment": "Violinschlüssel und Noten radiert." - }, - { - "svgGroupId": "g1128", - "measure": "15", - "system": "1", - "position": "3–6/8", - "comment": "d2–c2–h1–gis1 überschreibt f2–e2–d2–h1." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1140", + "measure": "2", + "system": "16", + "position": "1/4", + "comment": "Im Bassschlüssel zu lesende Viertelnote as/c1 gestrichen." + }, + { + "svgGroupId": "g1146", + "measure": "3", + "system": "16", + "position": "1. Note", + "comment": "Viertelnote überschreibt Halbe Note." + }, + { + "svgGroupId": "g1150", + "measure": "3", + "system": "16", + "position": "2/4", + "comment": "g gestrichen." + }, + { + "svgGroupId": "g1169", + "measure": "4", + "system": "15", + "position": "1. Note", + "comment": "[a] überschreibt [b]." + }, + { + "svgGroupId": "g1164", + "measure": "4", + "system": "15", + "position": "letzte Note", + "comment": "g1/c2/e2 überschreibt f2." + }, + { + "svgGroupId": "g1090", + "measure": "8", + "system": "17", + "position": "2/8", + "comment": "a2 gestrichen." + }, + { + "svgGroupId": "g1166", + "measure": "10", + "system": "18", + "position": "(2–3/4)", + "comment": "Punktierte Viertelnote G/d mit Achtelnote g überschreibt Halbe Note G/d; Augmentationspunkte gestrichen und Achtelnote d auf 5/8 hinzugefügt und mit g auf 6/8 zusammengebalkt." + }, + { + "svgGroupId": "g1131", + "measure": "10", + "system": "17", + "position": "3/4", + "comment": "h1 gestrichen." + }, + { + "svgGroupId": "g1155", + "measure": "11", + "system": "2", + "position": "", + "comment": "Violinschlüssel und Noten radiert." + }, + { + "svgGroupId": "g1128", + "measure": "15", + "system": "1", + "position": "3–6/8", + "comment": "d2–c2–h1–gis1 überschreibt f2–e2–d2–h1." + } + ] } ], "linkBoxes": [ @@ -216,11 +236,16 @@ ], "comments": [ { - "svgGroupId": "g961", - "measure": "10+1", - "system": "6", - "position": "1. Note", - "comment": "Punktierte Viertelnote überschreibt Halbe Note." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g961", + "measure": "10+1", + "system": "6", + "position": "1. Note", + "comment": "Punktierte Viertelnote überschreibt Halbe Note." + } + ] } ], "linkBoxes": [ @@ -248,11 +273,16 @@ ], "comments": [ { - "svgGroupId": "g963", - "measure": "17", - "system": "5", - "position": "3/4", - "comment": "e1 überschreibt f1." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g963", + "measure": "17", + "system": "5", + "position": "3/4", + "comment": "e1 überschreibt f1." + } + ] } ], "linkBoxes": [ @@ -280,95 +310,100 @@ ], "comments": [ { - "svgGroupId": "g1170", - "measure": "12", - "system": "9", - "position": "4–5/8", - "comment": "H–H überschreibt e–gis." - }, - { - "svgGroupId": "g1203", - "measure": "15", - "system": "8", - "position": "1–6/8", - "comment": "Sechs Achtelnoten durch Streichung der Balkierung aufgelöst und geändert zu drei Achtelnoten, Viertelnote und Achtelnote; Achtelnote e2 auf 5/8 aufgrund der Änderung getilgt." - }, - { - "svgGroupId": "g1202", - "measure": "{16A–18A}", - "system": "8–9", - "position": "", - "comment": "Takte zusammen mit T. {{ '{' }}19B{{ '}' }} und T. {{ '{' }}16B–18B{{ '}' }} durch Einkreisung getilgt." - }, - { - "svgGroupId": "g1222", - "measure": "{17A}", - "system": "8", - "position": "2/4", - "comment": "f3 überschreibt c3." - }, - { - "svgGroupId": "g1227", - "measure": "{17A}", - "system": "8", - "position": "2/4–6/8", - "comment": "Drei Achtelnoten durch Streichung der Balkierung aufgelöst und geändert zu Viertelnote und zwei Achtelnoten." - }, - { - "svgGroupId": "g1259", - "measure": "{18A}", - "system": "8", - "position": "", - "comment": "Noten gestrichen." - }, - { - "svgGroupId": "g2", - "measure": "{19A}", - "system": "11", - "position": "", - "comment": "Noten gestrichen." - }, - { - "svgGroupId": "g3", - "measure": "{19B}", - "system": "", - "position": "", - "comment": "Takt zusammen mit T. {{ '{' }}16A–18A{{ '}' }} und T. {{ '{' }}16B–18B{{ '}' }} durch Einkreisung getilgt." - }, - { - "svgGroupId": "g956", - "measure": "{19B}", - "system": "11", - "position": "5/8", - "comment": "d2 überschreibt c2." - }, - { - "svgGroupId": "g1003", - "measure": "{16B–18B}", - "system": "13–14", - "position": "", - "comment": "Takte pauschal gestrichen." - }, - { - "svgGroupId": "g1002", - "measure": "{16B–18B}", - "system": "13–14", - "position": "", - "comment": "Takte zusammen mit T. {{ '{' }}16A–18A{{ '}' }} und T. {{ '{' }}19B{{ '}' }} durch Einkreisung getilgt." - }, - { - "svgGroupId": "g1066", - "measure": "16C", - "system": "13", - "position": "4/8", - "comment": "f1 überschreibt d1." - }, - { - "svgGroupId": "g1079", - "measure": "16C", - "system": "14", - "position": "5–6/8", - "comment": "a–d überschreibt F–D." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1170", + "measure": "12", + "system": "9", + "position": "4–5/8", + "comment": "H–H überschreibt e–gis." + }, + { + "svgGroupId": "g1203", + "measure": "15", + "system": "8", + "position": "1–6/8", + "comment": "Sechs Achtelnoten durch Streichung der Balkierung aufgelöst und geändert zu drei Achtelnoten, Viertelnote und Achtelnote; Achtelnote e2 auf 5/8 aufgrund der Änderung getilgt." + }, + { + "svgGroupId": "g1202", + "measure": "{16A–18A}", + "system": "8–9", + "position": "", + "comment": "Takte zusammen mit T. {{ '{' }}19B{{ '}' }} und T. {{ '{' }}16B–18B{{ '}' }} durch Einkreisung getilgt." + }, + { + "svgGroupId": "g1222", + "measure": "{17A}", + "system": "8", + "position": "2/4", + "comment": "f3 überschreibt c3." + }, + { + "svgGroupId": "g1227", + "measure": "{17A}", + "system": "8", + "position": "2/4–6/8", + "comment": "Drei Achtelnoten durch Streichung der Balkierung aufgelöst und geändert zu Viertelnote und zwei Achtelnoten." + }, + { + "svgGroupId": "g1259", + "measure": "{18A}", + "system": "8", + "position": "", + "comment": "Noten gestrichen." + }, + { + "svgGroupId": "g2", + "measure": "{19A}", + "system": "11", + "position": "", + "comment": "Noten gestrichen." + }, + { + "svgGroupId": "g3", + "measure": "{19B}", + "system": "", + "position": "", + "comment": "Takt zusammen mit T. {{ '{' }}16A–18A{{ '}' }} und T. {{ '{' }}16B–18B{{ '}' }} durch Einkreisung getilgt." + }, + { + "svgGroupId": "g956", + "measure": "{19B}", + "system": "11", + "position": "5/8", + "comment": "d2 überschreibt c2." + }, + { + "svgGroupId": "g1003", + "measure": "{16B–18B}", + "system": "13–14", + "position": "", + "comment": "Takte pauschal gestrichen." + }, + { + "svgGroupId": "g1002", + "measure": "{16B–18B}", + "system": "13–14", + "position": "", + "comment": "Takte zusammen mit T. {{ '{' }}16A–18A{{ '}' }} und T. {{ '{' }}19B{{ '}' }} durch Einkreisung getilgt." + }, + { + "svgGroupId": "g1066", + "measure": "16C", + "system": "13", + "position": "4/8", + "comment": "f1 überschreibt d1." + }, + { + "svgGroupId": "g1079", + "measure": "16C", + "system": "14", + "position": "5–6/8", + "comment": "a–d überschreibt F–D." + } + ] } ], "linkBoxes": [ @@ -417,60 +452,65 @@ ], "comments": [ { - "svgGroupId": "g1068", - "measure": "{20–24}", - "system": "1–2", - "position": "6/8", - "comment": "Takte pauschal gestrichen." - }, - { - "svgGroupId": "g1073", - "measure": "{21}", - "system": "2", - "position": "1/4", - "comment": "Viertelnote G gestrichen." - }, - { - "svgGroupId": "g1090", - "measure": "{25–29}", - "system": "4–5", - "position": "", - "comment": "Takte pauschal gestrichen." - }, - { - "svgGroupId": "g1081", - "measure": "{25}", - "system": "5", - "position": "1/4", - "comment": "Viertelnote d1 gestrichen." - }, - { - "svgGroupId": "g1086", - "measure": "{27A}", - "system": "4–5", - "position": "", - "comment": "Takt pauschal gestrichen." - }, - { - "svgGroupId": "g1094", - "measure": "{27B}", - "system": "5", - "position": "1. Pause", - "comment": "Achtelpause gestrichen." - }, - { - "svgGroupId": "g1115", - "measure": "{28}", - "system": "4", - "position": "1/4", - "comment": "Oberstimmenschicht: Viertelpause überschreibt Achtelpause." - }, - { - "svgGroupId": "g1111", - "measure": "{28}", - "system": "4", - "position": "5–6/8", - "comment": "f1/a1–d1/f1 überschreibt e1/g1–c1/e1." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1068", + "measure": "{20–24}", + "system": "1–2", + "position": "6/8", + "comment": "Takte pauschal gestrichen." + }, + { + "svgGroupId": "g1073", + "measure": "{21}", + "system": "2", + "position": "1/4", + "comment": "Viertelnote G gestrichen." + }, + { + "svgGroupId": "g1090", + "measure": "{25–29}", + "system": "4–5", + "position": "", + "comment": "Takte pauschal gestrichen." + }, + { + "svgGroupId": "g1081", + "measure": "{25}", + "system": "5", + "position": "1/4", + "comment": "Viertelnote d1 gestrichen." + }, + { + "svgGroupId": "g1086", + "measure": "{27A}", + "system": "4–5", + "position": "", + "comment": "Takt pauschal gestrichen." + }, + { + "svgGroupId": "g1094", + "measure": "{27B}", + "system": "5", + "position": "1. Pause", + "comment": "Achtelpause gestrichen." + }, + { + "svgGroupId": "g1115", + "measure": "{28}", + "system": "4", + "position": "1/4", + "comment": "Oberstimmenschicht: Viertelpause überschreibt Achtelpause." + }, + { + "svgGroupId": "g1111", + "measure": "{28}", + "system": "4", + "position": "5–6/8", + "comment": "f1/a1–d1/f1 überschreibt e1/g1–c1/e1." + } + ] } ] } diff --git a/src/assets/data/edition/series/2/section/2a/m34/folio-convolute.json b/src/assets/data/edition/series/2/section/2a/m34/folio-convolute.json index bae510c45..322ff2d87 100644 --- a/src/assets/data/edition/series/2/section/2a/m34/folio-convolute.json +++ b/src/assets/data/edition/series/2/section/2a/m34/folio-convolute.json @@ -61,7 +61,7 @@ "sections": [ { "position": 2, - "startSystem": 7, + "startSystem": 6, "endSystem": 8 } ] @@ -79,6 +79,20 @@ } ] }, + { + "complexId": "m36", + "sheetId": "M_36_Sk1d", + "sigle": "M 36 Sk1", + "sigleAddendum": "T. 12", + "sectionPartition": 7, + "sections": [ + { + "position": 6, + "startSystem": 12, + "endSystem": 12 + } + ] + }, { "complexId": "m35_42", "sheetId": "M_35_42_Sk1b", @@ -92,6 +106,61 @@ "endSystem": 14 } ] + }, + { + "complexId": "m36", + "sheetId": "M_36_Sk1c", + "sigle": "M 36 Sk1", + "sigleAddendum": "T. 8–11", + "sectionPartition": 2, + "sections": [ + { + "position": 2, + "startSystem": 13, + "endSystem": 14 + } + ] + }, + { + "complexId": "m36", + "sheetId": "M_36_Sk1b", + "sigle": "M 36 Sk1", + "sigleAddendum": "T. 7", + "sectionPartition": 7, + "sections": [ + { + "position": 6, + "startSystem": 14, + "endSystem": 15 + } + ] + }, + { + "complexId": "m36", + "sheetId": "M_36_Sk1e", + "sigle": "M 36 Sk1", + "sigleAddendum": "T. 16", + "sectionPartition": 7, + "sections": [ + { + "position": 4, + "startSystem": 15, + "endSystem": 15 + } + ] + }, + { + "complexId": "m36", + "sheetId": "M_36_Sk1a", + "sigle": "M 36 Sk1", + "sigleAddendum": "T. 1–6", + "sectionPartition": 1, + "sections": [ + { + "startSystem": 16, + "endSystem": 17 + } + ] } ] }, @@ -102,7 +171,50 @@ "height": 349, "width": 265 }, - "content": [] + "content": [ + { + "complexId": "m38", + "sheetId": "M_38_Sk3b", + "sigle": "M 38 Sk3", + "sigleAddendum": "T. 5", + "sectionPartition": 4, + "sections": [ + { + "position": 4, + "startSystem": 13, + "endSystem": 14 + } + ] + }, + { + "complexId": "m38", + "sheetId": "M_38_Sk3a", + "sigle": "M 38 Sk3", + "sigleAddendum": "T. 1–4", + "sectionPartition": 3, + "sections": [ + { + "position": 3, + "startSystem": 15, + "endSystem": 16 + } + ] + }, + { + "complexId": "m38", + "sheetId": "M_38_Sk3c", + "sigle": "M 38 Sk3", + "sigleAddendum": "T. 6–8", + "sectionPartition": 3, + "sections": [ + { + "position": 3, + "startSystem": 17, + "endSystem": 18 + } + ] + } + ] }, { "folioId": "2r", @@ -139,6 +251,34 @@ "endSystem": 18 } ] + }, + { + "complexId": "m38", + "sheetId": "M_38_Sk2", + "sigle": "M 38 Sk2", + "sigleAddendum": "", + "sectionPartition": 3, + "sections": [ + { + "position": 3, + "startSystem": 18, + "endSystem": 18 + } + ] + }, + { + "complexId": "m38", + "sheetId": "M_38_Sk1", + "sigle": "M 38 Sk1", + "sigleAddendum": "", + "sectionPartition": 1, + "sections": [ + { + "startSystem": 18, + "endSystem": 18, + "relativeToSystem": "below" + } + ] } ] }, @@ -150,6 +290,32 @@ "width": 265 }, "content": [ + { + "complexId": "m38", + "sheetId": "M_38_Sk3d", + "sigle": "M 38 Sk3", + "sigleAddendum": "T. 9–12B", + "sectionPartition": 1, + "sections": [ + { + "startSystem": 1, + "endSystem": 2 + } + ] + }, + { + "complexId": "m38", + "sheetId": "M_38_Sk3e", + "sigle": "M 38 Sk3", + "sigleAddendum": "T. 13–17", + "sectionPartition": 1, + "sections": [ + { + "startSystem": 4, + "endSystem": 5 + } + ] + }, { "complexId": "m37", "sheetId": "M_37_Sk3a", diff --git a/src/assets/data/edition/series/2/section/2a/m34/source-description.json b/src/assets/data/edition/series/2/section/2a/m34/source-description.json index b5c817b2a..ce6523db8 100644 --- a/src/assets/data/edition/series/2/section/2a/m34/source-description.json +++ b/src/assets/data/edition/series/2/section/2a/m34/source-description.json @@ -4,14 +4,12 @@ "id": "source_A", "siglum": "A", "siglumAddendum": "", - "type": "Skizzen zu
    Studienkomposition für Klavier M 34.
    Enthält auch Skizzen zu Studienkomposition für Klavier M 35–38, M 39 Textfassung 1→2 und M* 404.", + "type": "Skizzen zu
    Studienkomposition für Klavier M 34.
    Enthält auch Skizzen zu Studienkompositionen für Klavier M 35/42, M 36–39 und M* 404.", "location": "CH-Bps, Sammlung Anton Webern.", "description": { - "desc": [ - "1 Bogen (Bl. 1/2): Der Bogen ist Bestandteil (Bl. 1/2) eines größeren Konvoluts aus 2 Bögen (Bl. 1/2, 3/4), 2 Blättern (Bl. 5–6) und 1 Bogen (Bl. 7/8)." - ], + "desc": ["1 Bogen (Bl. 1/2)."], "writingMaterialStrings": [ - "Notenpapier, 18 Systeme, Format: hoch 349 × 265 mm, Firmenzeichen:

    unten links auf Bl. 1r und 2r" + "Notenpapier, 18 Systeme, Format: hoch 349 × 265 mm, Firmenzeichen: ##[JE]## | Protokoll. Schutzmarke | No. 5 | 18 linig. unten links auf Bl. 1r und 2r" ], "writingMaterials": [ { @@ -152,7 +150,10 @@ }, { "item": "M 36 Sk1", - "itemLinkTo": {}, + "itemLinkTo": { + "complexId": "m36", + "sheetId": "M_36_Sk1a" + }, "itemDescription": "(Skizze zu Studienkomposition für Klavier M 36)", "folios": [ { @@ -164,35 +165,35 @@ { "system": "16–17", "measure": "1–6", - "linkTo": "" + "linkTo": "M_36_Sk1a" } ], [ { "system": "14c–15b", "measure": "7", - "linkTo": "" + "linkTo": "M_36_Sk1b" } ], [ { "system": "13b–14b", "measure": "8–11", - "linkTo": "" + "linkTo": "M_36_Sk1c" } ], [ { "system": "12", "measure": "12", - "linkTo": "" + "linkTo": "M_36_Sk1d" } ], [ { "system": "15a", "measure": "16", - "linkTo": "" + "linkTo": "M_36_Sk1e" } ] ] @@ -334,7 +335,10 @@ }, { "item": "M 38 Sk3", - "itemLinkTo": {}, + "itemLinkTo": { + "complexId": "m38", + "sheetId": "M_38_Sk3a" + }, "itemDescription": "(Skizze zu Studienkomposition für Klavier M 38)", "folios": [ { @@ -346,21 +350,21 @@ { "system": "15–16c", "measure": "1–4", - "linkTo": "" + "linkTo": "M_38_Sk3a" } ], [ { "system": "13b–14b", "measure": "5", - "linkTo": "" + "linkTo": "M_38_Sk3b" } ], [ { "system": "17c–18", "measure": "6–8", - "linkTo": "" + "linkTo": "M_38_Sk3c" } ] ] @@ -374,14 +378,14 @@ { "system": "1–2", "measure": "9–10, {11A–12A}, 11B–12B", - "linkTo": "" + "linkTo": "M_38_Sk3d" } ], [ { "system": "4–5", "measure": "13–17", - "linkTo": "" + "linkTo": "M_38_Sk3e" } ] ] @@ -543,7 +547,10 @@ }, { "item": "M 38 Sk2", - "itemLinkTo": {}, + "itemLinkTo": { + "complexId": "m38", + "sheetId": "M_38_Sk2" + }, "itemDescription": "(Skizze zu Studienkomposition für Klavier M 38)", "folios": [ { @@ -564,7 +571,10 @@ }, { "item": "M 38 Sk1", - "itemLinkTo": {}, + "itemLinkTo": { + "complexId": "m38", + "sheetId": "M_38_Sk1" + }, "itemDescription": "(Skizze zu Studienkomposition für Klavier M 38)", "folios": [ { @@ -628,14 +638,12 @@ "id": "source_B", "siglum": "B", "siglumAddendum": "", - "type": "Tintenniederschrift von
    Studienkomposition für Klavier M 34.
    Enthält auch Tintenniederschrift von Studienkomposition für Klavier M 35–38, M 39 Textfassung 1→2 und M 41 sowie Skizzen zu Studienkomposition für Klavier M 35/42 und M 39 Textfassung 2.", + "type": "Tintenniederschrift von
    Studienkomposition für Klavier M 34.
    Enthält auch Tintenniederschrift zu Studienkompositionen für Klavier M 35/42, M 36–38, M 39 Textfassung 1→2 und M 41 sowie Skizzen zu Studienkomposition für Klavier M 35/42 und M 39 Textfassung 2.", "location": "CH-Bps, Sammlung Anton Webern.", "description": { - "desc": [ - "1 Bogen (Bl. 1/2): Der Bogen ist Bestandteil (Bl. 3/4) eines größeren Konvoluts aus 2 Bögen (Bl. 1/2, 3/4), 2 Blättern (Bl. 5–6) und 1 Bogen (Bl. 7/8). Stockfleck und rötliche Verfärbung mittig am oberen Rand des Bogens." - ], + "desc": ["1 Bogen (Bl. 1/2). Stockfleck und rötliche Verfärbung mittig am oberen Rand des Bogens."], "writingMaterialStrings": [ - "Notenpapier, 18 Systeme, Format: hoch 349 × 267 mm, Firmenzeichen:

    unten links auf Bl. 1r und 2r" + "Notenpapier, 18 Systeme, Format: hoch 349 × 267 mm, Firmenzeichen: ##[JE]## | Protokoll. Schutzmarke | No. 5 | 18 linig. unten links auf Bl. 1r und 2r" ], "writingMaterials": [ { @@ -769,7 +777,10 @@ }, { "item": "M 36", - "itemLinkTo": {}, + "itemLinkTo": { + "complexId": "m36", + "sheetId": "M_36_TF1" + }, "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M 36)", "folios": [ { @@ -849,7 +860,10 @@ }, { "item": "M 38", - "itemLinkTo": {}, + "itemLinkTo": { + "complexId": "m38", + "sheetId": "M_38_TF1" + }, "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M 38)", "folios": [ { diff --git a/src/assets/data/edition/series/2/section/2a/m34/source-list.json b/src/assets/data/edition/series/2/section/2a/m34/source-list.json index 911d49cf4..744a57eaa 100644 --- a/src/assets/data/edition/series/2/section/2a/m34/source-list.json +++ b/src/assets/data/edition/series/2/section/2a/m34/source-list.json @@ -3,7 +3,7 @@ { "siglum": "A", "siglumAddendum": "", - "type": "Skizzen zu
    Studienkomposition für Klavier M 34.
    Enthält auch Skizzen zu Studienkompositionen für Klavier M 35/42, M 36–38, M 39 Textfassung 1→2 und M* 404.", + "type": "Skizzen zu
    Studienkomposition für Klavier M 34.
    Enthält auch Skizzen zu Studienkompositionen für Klavier M 35/42, M 36–39 und M* 404.", "location": "CH-Bps, Sammlung Anton Webern.", "hasDescription": true, "linkTo": "source_A" diff --git a/src/assets/data/edition/series/2/section/2a/m34/textcritics.json b/src/assets/data/edition/series/2/section/2a/m34/textcritics.json index 517724469..b51a3b9d3 100644 --- a/src/assets/data/edition/series/2/section/2a/m34/textcritics.json +++ b/src/assets/data/edition/series/2/section/2a/m34/textcritics.json @@ -8,11 +8,16 @@ ], "comments": [ { - "svgGroupId": "g5789", - "measure": "7", - "system": "Klav. o.", - "position": "1. Note", - "comment": "Achtelnote g1 aufgrund des horizontal verschobenen Notenhalses auch als Viertelnote lesbar (vgl. Korrekturschicht 1). Eine Deutung als Viertelnote ist mit Blick auf Sk1 und Sk1.1 aber sehr unwahrscheinlich." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g5789", + "measure": "7", + "system": "Klav. o.", + "position": "1. Note", + "comment": "Achtelnote g1 aufgrund des horizontal verschobenen Notenhalses auch als Viertelnote lesbar (vgl. Korrekturschicht 1). Eine Deutung als Viertelnote ist mit Blick auf Sk1 und Sk1.1 aber sehr unwahrscheinlich." + } + ] } ] }, @@ -24,95 +29,100 @@ ], "comments": [ { - "svgGroupId": "g1130", - "measure": "1", - "system": "2", - "position": "2/4", - "comment": "B1 überschreibt f." - }, - { - "svgGroupId": "g1446", - "measure": "1", - "system": "2", - "position": "3/4", - "comment": "Viertelnote gestrichen." - }, - { - "svgGroupId": "g1798", - "measure": "4", - "system": "1", - "position": "", - "comment": "Oberstimmenschicht: Halbe Note c3 und Viertelnote a1/f2 überschreiben punktierte Viertelnote a2/c3 und Achtelnoten f2/a2–f2–e2." - }, - { - "svgGroupId": "g1812", - "measure": "4", - "system": "1", - "position": "1–2/4", - "comment": "Unterstimmenschicht: Achtelnoten a1/c2–g1/b2 und Viertelnote f1/a1 gestrichen." - }, - { - "svgGroupId": "g1445", - "measure": "4", - "system": "2", - "position": "3/4", - "comment": "Viertelnote f/c1 gestrichen und ersetzt durch f/a." - }, - { - "svgGroupId": "g2414", - "measure": "8–16", - "system": "4–5, 7–8", - "position": "", - "comment": "Takte pauschal gestrichen." - }, - { - "svgGroupId": "g2418", - "measure": "13", - "system": "5", - "position": "1. Pause", - "comment": "Viertelpause überschreibt Achtelpause." - }, - { - "svgGroupId": "g2427", - "measure": "14", - "system": "4", - "position": "3/8", - "comment": "b überscheibt es1." - }, - { - "svgGroupId": "g9346", - "measure": "15–16", - "system": "7–8", - "position": "", - "comment": "Takte pauschal gestrichen." - }, - { - "svgGroupId": "g7144", - "measure": "15", - "system": "7", - "position": "4/8", - "comment": "f1 radiert." - }, - { - "svgGroupId": "g7873", - "measure": "15", - "system": "8", - "position": "3/4", - "comment": "Notenkopf F radiert." - }, - { - "svgGroupId": "g220", - "measure": "15", - "system": "7", - "position": "6/8", - "comment": "f2 gestrichen." - }, - { - "svgGroupId": "g8617", - "measure": "16", - "system": "7–8", - "position": "1. Note", - "comment": "Halbe Note überschreibt Viertelnote." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1130", + "measure": "1", + "system": "2", + "position": "2/4", + "comment": "B1 überschreibt f." + }, + { + "svgGroupId": "g1446", + "measure": "1", + "system": "2", + "position": "3/4", + "comment": "Viertelnote gestrichen." + }, + { + "svgGroupId": "g1798", + "measure": "4", + "system": "1", + "position": "", + "comment": "Oberstimmenschicht: Halbe Note c3 und Viertelnote a1/f2 überschreiben punktierte Viertelnote a2/c3 und Achtelnoten f2/a2–f2–e2." + }, + { + "svgGroupId": "g1812", + "measure": "4", + "system": "1", + "position": "1–2/4", + "comment": "Unterstimmenschicht: Achtelnoten a1/c2–g1/b2 und Viertelnote f1/a1 gestrichen." + }, + { + "svgGroupId": "g1445", + "measure": "4", + "system": "2", + "position": "3/4", + "comment": "Viertelnote f/c1 gestrichen und ersetzt durch f/a." + }, + { + "svgGroupId": "g2414", + "measure": "8–16", + "system": "4–5, 7–8", + "position": "", + "comment": "Takte pauschal gestrichen." + }, + { + "svgGroupId": "g2418", + "measure": "13", + "system": "5", + "position": "1. Pause", + "comment": "Viertelpause überschreibt Achtelpause." + }, + { + "svgGroupId": "g2427", + "measure": "14", + "system": "4", + "position": "3/8", + "comment": "b überscheibt es1." + }, + { + "svgGroupId": "g9346", + "measure": "15–16", + "system": "7–8", + "position": "", + "comment": "Takte pauschal gestrichen." + }, + { + "svgGroupId": "g7144", + "measure": "15", + "system": "7", + "position": "4/8", + "comment": "f1 radiert." + }, + { + "svgGroupId": "g7873", + "measure": "15", + "system": "8", + "position": "3/4", + "comment": "Notenkopf F radiert." + }, + { + "svgGroupId": "g220", + "measure": "15", + "system": "7", + "position": "6/8", + "comment": "f2 gestrichen." + }, + { + "svgGroupId": "g8617", + "measure": "16", + "system": "7–8", + "position": "1. Note", + "comment": "Halbe Note überschreibt Viertelnote." + } + ] } ], "linkBoxes": [ @@ -133,32 +143,37 @@ ], "comments": [ { - "svgGroupId": "g1149", - "measure": "5", - "system": "7", - "position": "3/4", - "comment": "f2 überschreibt g2." - }, - { - "svgGroupId": "g1156", - "measure": "5", - "system": "8", - "position": "3/4", - "comment": "D überschreibt G." - }, - { - "svgGroupId": "g1171", - "measure": "6", - "system": "8", - "position": "3–4/8", - "comment": "Oberstimmenschicht: Zwei Achtelnoten überschreiben punktierte Viertelnote und Achtelnote? Entzifferung unklar." - }, - { - "svgGroupId": "g1143", - "measure": "7", - "system": "6", - "position": "", - "comment": "Korrektur in Tinte." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1149", + "measure": "5", + "system": "7", + "position": "3/4", + "comment": "f2 überschreibt g2." + }, + { + "svgGroupId": "g1156", + "measure": "5", + "system": "8", + "position": "3/4", + "comment": "D überschreibt G." + }, + { + "svgGroupId": "g1171", + "measure": "6", + "system": "8", + "position": "3–4/8", + "comment": "Oberstimmenschicht: Zwei Achtelnoten überschreiben punktierte Viertelnote und Achtelnote? Entzifferung unklar." + }, + { + "svgGroupId": "g1143", + "measure": "7", + "system": "6", + "position": "", + "comment": "Korrektur in Tinte." + } + ] } ], "linkBoxes": [ diff --git a/src/assets/data/edition/series/2/section/2a/m35_42/folio-convolute.json b/src/assets/data/edition/series/2/section/2a/m35_42/folio-convolute.json index 8abe27630..92a62ce91 100644 --- a/src/assets/data/edition/series/2/section/2a/m35_42/folio-convolute.json +++ b/src/assets/data/edition/series/2/section/2a/m35_42/folio-convolute.json @@ -61,7 +61,7 @@ "sections": [ { "position": 2, - "startSystem": 7, + "startSystem": 6, "endSystem": 8 } ] @@ -79,6 +79,20 @@ } ] }, + { + "complexId": "m36", + "sheetId": "M_36_Sk1d", + "sigle": "M 36 Sk1", + "sigleAddendum": "T. 12", + "sectionPartition": 7, + "sections": [ + { + "position": 6, + "startSystem": 12, + "endSystem": 12 + } + ] + }, { "complexId": "m35_42", "sheetId": "M_35_42_Sk1b", @@ -92,6 +106,61 @@ "endSystem": 14 } ] + }, + { + "complexId": "m36", + "sheetId": "M_36_Sk1c", + "sigle": "M 36 Sk1", + "sigleAddendum": "T. 8–11", + "sectionPartition": 2, + "sections": [ + { + "position": 2, + "startSystem": 13, + "endSystem": 14 + } + ] + }, + { + "complexId": "m36", + "sheetId": "M_36_Sk1b", + "sigle": "M 36 Sk1", + "sigleAddendum": "T. 7", + "sectionPartition": 7, + "sections": [ + { + "position": 6, + "startSystem": 14, + "endSystem": 15 + } + ] + }, + { + "complexId": "m36", + "sheetId": "M_36_Sk1e", + "sigle": "M 36 Sk1", + "sigleAddendum": "T. 16", + "sectionPartition": 7, + "sections": [ + { + "position": 4, + "startSystem": 15, + "endSystem": 15 + } + ] + }, + { + "complexId": "m36", + "sheetId": "M_36_Sk1a", + "sigle": "M 36 Sk1", + "sigleAddendum": "T. 1–6", + "sectionPartition": 1, + "sections": [ + { + "startSystem": 16, + "endSystem": 17 + } + ] } ] }, @@ -102,7 +171,50 @@ "height": 349, "width": 265 }, - "content": [] + "content": [ + { + "complexId": "m38", + "sheetId": "M_38_Sk3b", + "sigle": "M 38 Sk3", + "sigleAddendum": "T. 5", + "sectionPartition": 4, + "sections": [ + { + "position": 4, + "startSystem": 13, + "endSystem": 14 + } + ] + }, + { + "complexId": "m38", + "sheetId": "M_38_Sk3a", + "sigle": "M 38 Sk3", + "sigleAddendum": "T. 1–4", + "sectionPartition": 3, + "sections": [ + { + "position": 3, + "startSystem": 15, + "endSystem": 16 + } + ] + }, + { + "complexId": "m38", + "sheetId": "M_38_Sk3c", + "sigle": "M 38 Sk3", + "sigleAddendum": "T. 6–8", + "sectionPartition": 3, + "sections": [ + { + "position": 3, + "startSystem": 17, + "endSystem": 18 + } + ] + } + ] }, { "folioId": "2r", @@ -139,6 +251,34 @@ "endSystem": 18 } ] + }, + { + "complexId": "m38", + "sheetId": "M_38_Sk2", + "sigle": "M 38 Sk2", + "sigleAddendum": "", + "sectionPartition": 3, + "sections": [ + { + "position": 3, + "startSystem": 18, + "endSystem": 18 + } + ] + }, + { + "complexId": "m38", + "sheetId": "M_38_Sk1", + "sigle": "M 38 Sk1", + "sigleAddendum": "", + "sectionPartition": 1, + "sections": [ + { + "startSystem": 18, + "endSystem": 18, + "relativeToSystem": "below" + } + ] } ] }, @@ -150,6 +290,32 @@ "width": 265 }, "content": [ + { + "complexId": "m38", + "sheetId": "M_38_Sk3d", + "sigle": "M 38 Sk3", + "sigleAddendum": "T. 9–12B", + "sectionPartition": 1, + "sections": [ + { + "startSystem": 1, + "endSystem": 2 + } + ] + }, + { + "complexId": "m38", + "sheetId": "M_38_Sk3e", + "sigle": "M 38 Sk3", + "sigleAddendum": "T. 13–17", + "sectionPartition": 1, + "sections": [ + { + "startSystem": 4, + "endSystem": 5 + } + ] + }, { "complexId": "m37", "sheetId": "M_37_Sk3a", @@ -195,7 +361,49 @@ }, { "convoluteId": "B", - "convoluteLabel": "B Skizzen (CH-Bps)", + "convoluteLabel": "B Tintenniederschrift (CH-Bps)", + "folios": [ + { + "folioId": "1r", + "systems": "18", + "format": { + "height": 349, + "width": 267 + }, + "content": [] + }, + { + "folioId": "1v", + "systems": "18", + "format": { + "height": 349, + "width": 267 + }, + "content": [] + }, + { + "folioId": "2r", + "systems": "18", + "format": { + "height": 349, + "width": 267 + }, + "content": [] + }, + { + "folioId": "2v", + "systems": "18", + "format": { + "height": 349, + "width": 267 + }, + "content": [] + } + ] + }, + { + "convoluteId": "C", + "convoluteLabel": "C Skizzen (CH-Bps)", "folios": [ { "folioId": "1r", @@ -304,48 +512,7 @@ } ] }, - { - "convoluteId": "C", - "convoluteLabel": "C Tintenniederschrift (CH-Bps)", - "folios": [ - { - "folioId": "1r", - "systems": "18", - "format": { - "height": 349, - "width": 267 - }, - "content": [] - }, - { - "folioId": "1v", - "systems": "18", - "format": { - "height": 349, - "width": 267 - }, - "content": [] - }, - { - "folioId": "2r", - "systems": "18", - "format": { - "height": 349, - "width": 267 - }, - "content": [] - }, - { - "folioId": "2v", - "systems": "18", - "format": { - "height": 349, - "width": 267 - }, - "content": [] - } - ] - }, + { "convoluteId": "D", "convoluteLabel": "D Tintenniederschrift (CH-Bps)", diff --git a/src/assets/data/edition/series/2/section/2a/m35_42/source-description.json b/src/assets/data/edition/series/2/section/2a/m35_42/source-description.json index 46cfec86c..a27e35987 100644 --- a/src/assets/data/edition/series/2/section/2a/m35_42/source-description.json +++ b/src/assets/data/edition/series/2/section/2a/m35_42/source-description.json @@ -4,14 +4,12 @@ "id": "source_A", "siglum": "A", "siglumAddendum": "", - "type": "Skizzen zu
    Studienkomposition für Klavier M 35/42.
    Enthält auch Skizzen zu Studienkomposition für Klavier M 34, M 36–38, M 39 Textfassung 1→2 und M* 404.", + "type": "Skizzen zu
    Studienkomposition für Klavier M 35/42.
    Enthält auch Skizzen zu Studienkomposition für Klavier M 34, M 36–39 und M* 404.", "location": "CH-Bps, Sammlung Anton Webern.", "description": { - "desc": [ - "1 Bogen (Bl. 1/2): Der Bogen ist Bestandteil (Bl. 1/2) eines größeren Konvoluts aus 2 Bögen (Bl. 1/2, 3/4), 2 Blättern (Bl. 5–6) und 1 Bogen (Bl. 7/8)." - ], + "desc": ["1 Bogen (Bl. 1/2)."], "writingMaterialStrings": [ - "Notenpapier, 18 Systeme, Format: hoch 349 × 265 mm, Firmenzeichen:

    unten links auf Bl. 1r und 2r" + "Notenpapier, 18 Systeme, Format: hoch 349 × 265 mm, Firmenzeichen: ##[JE]## | Protokoll. Schutzmarke | No. 5 | 18 linig. unten links auf Bl. 1r und 2r" ], "writingMaterials": [ { @@ -152,7 +150,10 @@ }, { "item": "M 36 Sk1", - "itemLinkTo": {}, + "itemLinkTo": { + "complexId": "m36", + "sheetId": "M_36_Sk1a" + }, "itemDescription": "(Skizze zu Studienkomposition für Klavier M 36)", "folios": [ { @@ -164,35 +165,35 @@ { "system": "16–17", "measure": "1–6", - "linkTo": "" + "linkTo": "M_36_Sk1a" } ], [ { "system": "14c–15b", "measure": "7", - "linkTo": "" + "linkTo": "M_36_Sk1b" } ], [ { "system": "13b–14b", "measure": "8–11", - "linkTo": "" + "linkTo": "M_36_Sk1c" } ], [ { "system": "12", "measure": "12", - "linkTo": "" + "linkTo": "M_36_Sk1d" } ], [ { "system": "15a", "measure": "16", - "linkTo": "" + "linkTo": "M_36_Sk1e" } ] ] @@ -334,7 +335,10 @@ }, { "item": "M 38 Sk3", - "itemLinkTo": {}, + "itemLinkTo": { + "complexId": "m38", + "sheetId": "M_38_Sk3a" + }, "itemDescription": "(Skizze zu Studienkomposition für Klavier M 38)", "folios": [ { @@ -346,21 +350,21 @@ { "system": "15–16c", "measure": "1–4", - "linkTo": "" + "linkTo": "M_38_Sk3a" } ], [ { "system": "13b–14b", "measure": "5", - "linkTo": "" + "linkTo": "M_38_Sk3b" } ], [ { "system": "17c–18", "measure": "6–8", - "linkTo": "" + "linkTo": "M_38_Sk3c" } ] ] @@ -374,14 +378,14 @@ { "system": "1–2", "measure": "9–10, {11A–12A}, 11B–12B", - "linkTo": "" + "linkTo": "M_38_Sk3d" } ], [ { "system": "4–5", "measure": "13–17", - "linkTo": "" + "linkTo": "M_38_Sk3e" } ] ] @@ -543,7 +547,10 @@ }, { "item": "M 38 Sk2", - "itemLinkTo": {}, + "itemLinkTo": { + "complexId": "m38", + "sheetId": "M_38_Sk2" + }, "itemDescription": "(Skizze zu Studienkomposition für Klavier M 38)", "folios": [ { @@ -564,7 +571,10 @@ }, { "item": "M 38 Sk1", - "itemLinkTo": {}, + "itemLinkTo": { + "complexId": "m38", + "sheetId": "M_38_Sk1" + }, "itemDescription": "(Skizze zu Studienkomposition für Klavier M 38)", "folios": [ { @@ -628,14 +638,12 @@ "id": "source_B", "siglum": "B", "siglumAddendum": "", - "type": "Skizzen zu
    Studienkomposition für Klavier M 35/42.
    Enthält auch Skizzen zu Studienkomposition für Klavier M 39 Textfassung 2, M 40–41 und M* 405–406.", + "type": "Tintenniederschrift von
    Studienkomposition für Klavier M 35/42.
    Enthält auch Tintenniederschrift von Studienkomposition für Klavier M 34, M 36–38 und M 39 Textfassung 1→2 sowie Skizzen zu Studienkomposition für Klavier M 39 Textfassung 2.", "location": "CH-Bps, Sammlung Anton Webern.", "description": { - "desc": [ - "1 Bogen (Bl. 1/2): Der Bogen ist Bestandteil (Bl. 7/8) eines größeren Konvoluts aus 2 Bögen (Bl. 1/2, 3/4), 2 Blättern (Bl. 5–6) und 1 Bogen (Bl. 7/8). Kleiner Riss am rechten Rand von Bl. 2." - ], + "desc": ["1 Bogen (Bl. 1/2). Stockfleck und rötliche Verfärbung mittig am oberen Rand des Bogens."], "writingMaterialStrings": [ - "Notenpapier, 18 Systeme, Format: hoch 348 × 266 mm, Firmenzeichen:

    unten links auf Bl. 1r und 2r" + "Notenpapier, 18 Systeme, Format: hoch 349 × 267 mm, Firmenzeichen: ##[JE]## | Protokoll. Schutzmarke | No. 5 | 18 linig. unten links auf Bl. 1r und 2r" ], "writingMaterials": [ { @@ -649,15 +657,15 @@ "orientation": "hoch", "height": { "uncertainty": "", - "value": "348" + "value": "349" }, "width": { "uncertainty": "", - "value": "266" + "value": "267" } }, "firmSign": { - "variant": "FIRM_JE_NO_5_LIN_18_C", + "variant": "FIRM_JE_NO_5_LIN_18_D", "alt": "", "location": [ { @@ -671,8 +679,8 @@ } ], "writingInstruments": { - "main": "Bleistift", - "secondary": [] + "main": "schwarze Tinte", + "secondary": ["Bleistift"] }, "titles": [], "dates": [], @@ -682,9 +690,12 @@ "annotations": [], "contents": [ { - "item": "M 41 Sk 1", - "itemLinkTo": {}, - "itemDescription": "(Skizze zu Studienkomposition für Klavier M 41)", + "item": "M 34", + "itemLinkTo": { + "complexId": "m34", + "sheetId": "M_34_TF1" + }, + "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M 34)", "folios": [ { "folio": "1r", @@ -694,42 +705,14 @@ [ { "system": "1–2", - "measure": "1, {2A–3A}, 2B–3B, 4", - "linkTo": "" - } - ], - [ - { - "system": "4–6", - "measure": "5–11", - "linkTo": "" - } - ], - [ - { - "system": "7–8", - "measure": "12–17", - "linkTo": "" - } - ], - [ - { - "system": "10–11", - "measure": "18–23", - "linkTo": "" - } - ], - [ - { - "system": "13–14", - "measure": "24A, 24B, 25–28", + "measure": "1–5", "linkTo": "" } ], [ { - "system": "17a", - "measure": "29–31", + "system": "4–5", + "measure": "6–8", "linkTo": "" } ] @@ -738,9 +721,12 @@ ] }, { - "item": "M 41 Sk1.1", - "itemLinkTo": {}, - "itemDescription": "(Skizze zu Studienkomposition für Klavier M 41)", + "item": "M 35/42", + "itemLinkTo": { + "complexId": "m35_42", + "sheetId": "M_35_42_TF1" + }, + "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M 35/42)", "folios": [ { "folio": "1r", @@ -749,15 +735,15 @@ "systemGroups": [ [ { - "system": "12", - "measure": "24–28", + "system": "7–8", + "measure": "1–7", "linkTo": "" } ], [ { - "system": "16a", - "measure": "29", + "system": "10a–11a", + "measure": "8–9", "linkTo": "" } ] @@ -766,9 +752,12 @@ ] }, { - "item": "M 41 Sk1.2", - "itemLinkTo": {}, - "itemDescription": "(Skizze zu Studienkomposition für Klavier M 41)", + "item": "M 35/42 Sk2", + "itemLinkTo": { + "complexId": "m35_42", + "sheetId": "M_35_42_Sk2" + }, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 35/42)", "folios": [ { "folio": "1r", @@ -777,8 +766,8 @@ "systemGroups": [ [ { - "system": "16b–18", - "measure": "29–31", + "system": "10b–11b (Bleistift)", + "measure": "7(2–3/4)–9", "linkTo": "" } ] @@ -787,45 +776,34 @@ ] }, { - "item": "M 40 Sk1", - "itemLinkTo": {}, - "itemDescription": "(Skizze zu Studienkomposition für Klavier M 40)", + "item": "M 36", + "itemLinkTo": { + "complexId": "m36", + "sheetId": "M_36_TF1" + }, + "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M 36)", "folios": [ { - "folio": "1v", + "folio": "1r", "folioLinkTo": "", "folioDescription": "", "systemGroups": [ [ { - "system": "1–2", - "measure": "1–7, {8A}, 8B, 9", - "linkTo": "" - } - ], - [ - { - "system": "4–7b", - "measure": "10–12, {13A}, 13B, 14–15", + "system": "13–14", + "measure": "1–6", "linkTo": "" } ], [ { - "system": "7a–8", - "measure": "16A–17A, 16B–17B", + "system": "16–17", + "measure": "7–13", "linkTo": "" } ] ] - } - ] - }, - { - "item": "M 40 Sk1.1", - "itemLinkTo": {}, - "itemDescription": "(Skizze zu Studienkomposition für Klavier M 40)", - "folios": [ + }, { "folio": "1v", "folioLinkTo": "", @@ -833,8 +811,8 @@ "systemGroups": [ [ { - "system": "9–10c", - "measure": "24–25", + "system": "1–2", + "measure": "14–16", "linkTo": "" } ] @@ -843,12 +821,12 @@ ] }, { - "item": "M 35/42 Sk1.1", + "item": "M 37", "itemLinkTo": { - "complexId": "m35_42", - "sheetId": "M_35_42_Sk1.1" + "complexId": "m37", + "sheetId": "M_37_TF1" }, - "itemDescription": "(Skizze zu Studienkomposition für Klavier M 35/42)", + "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M 37)", "folios": [ { "folio": "1v", @@ -857,8 +835,22 @@ "systemGroups": [ [ { - "system": "10b–11b", - "measure": "22, 22+1", + "system": "4–5", + "measure": "1–7", + "linkTo": "" + } + ], + [ + { + "system": "7–8", + "measure": "8–15", + "linkTo": "" + } + ], + [ + { + "system": "10–11", + "measure": "16–21", "linkTo": "" } ] @@ -867,12 +859,12 @@ ] }, { - "item": "M 35/42 Sk1", + "item": "M 38", "itemLinkTo": { - "complexId": "m35_42", - "sheetId": "M_35_42_Sk1" + "complexId": "m38", + "sheetId": "M_38_TF1" }, - "itemDescription": "(Skizze zu Studienkomposition für Klavier M 35/42)", + "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M 38)", "folios": [ { "folio": "1v", @@ -881,30 +873,23 @@ "systemGroups": [ [ { - "system": "12a–13a", - "measure": "10–15", - "linkTo": "M_35_42_Sk1c" + "system": "13–14", + "measure": "1–6", + "linkTo": "" } ], [ { - "system": "12b–16", - "measure": "{16A–17A}, 16B, {17B}, 17C, 18", - "linkTo": "M_35_42_Sk1d" + "system": "15–16", + "measure": "7–12", + "linkTo": "" } ], [ { "system": "17–18", - "measure": "19–21, {22}, 23–26", - "linkTo": "M_35_42_Sk1e" - } - ], - [ - { - "system": "10a–11a", - "measure": "27", - "linkTo": "M_35_42_Sk1f" + "measure": "13–20", + "linkTo": "" } ] ] @@ -912,9 +897,9 @@ ] }, { - "item": "M 39 Sk2", + "item": "M 39", "itemLinkTo": {}, - "itemDescription": "(Skizze zu Studienkomposition für Klavier M 39 Textfassung 2)", + "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M 39: Textfassung 1→2)", "folios": [ { "folio": "2r", @@ -924,56 +909,35 @@ [ { "system": "1–2", - "measure": "11–13", + "measure": "1–3", "linkTo": "" } - ] - ] - } - ] - }, - { - "item": "M* 405 Sk1", - "itemLinkTo": {}, - "itemDescription": "(Skizze zu Studienkomposition für Klavier M* 405)", - "folios": [ - { - "folio": "2r", - "folioLinkTo": "", - "folioDescription": "", - "systemGroups": [ + ], [ { "system": "4–5", - "measure": "1–6", + "measure": "4–7", "linkTo": "" } ], [ { - "system": "6–8", - "measure": "7–10, {11A}", + "system": "7–8", + "measure": "8–12 → T. 8, {9–12}", "linkTo": "" } ], [ { "system": "10–11", - "measure": "11B, {12A}, 12B, 13–14", + "measure": "13–16 → T. {13–14}, 13–14", "linkTo": "" } ], [ { "system": "13–14", - "measure": "15A, {16A}, 15B(3–4/4), 16B", - "linkTo": "" - } - ], - [ - { - "system": "16–17", - "measure": "17–18", + "measure": "17–19 → T. 15–17", "linkTo": "" } ] @@ -982,41 +946,123 @@ ] }, { - "item": "M* 406 Sk1", + "item": "M 39 Sk2", "itemLinkTo": {}, - "itemDescription": "(Skizze zu Studienkomposition für Klavier M* 406)", + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 39: Textfassung 2)", "folios": [ { - "folio": "2v", + "folio": "2r", "folioLinkTo": "", "folioDescription": "", "systemGroups": [ [ { - "system": "1–2", - "measure": "1–4", + "system": "16a–17a (Bleistift)", + "measure": "9–10", "linkTo": "" } ] ] } ] - } - ] - } - }, - { - "id": "source_C", + }, + { + "item": "M 39 Sk3", + "itemLinkTo": {}, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 39: Textfassung 2)", + "folios": [ + { + "folio": "2r", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "13b–14b (Bleistift)", + "measure": "16–17(1–2/4)", + "linkTo": "" + } + ], + [ + { + "system": "16b–17b (Bleistift)", + "measure": "17(3–4/4)–19", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M 41", + "itemLinkTo": {}, + "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M 41)", + "folios": [ + { + "folio": "2v", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "1–2", + "measure": "1–6", + "linkTo": "" + } + ], + [ + { + "system": "4–5", + "measure": "7–12", + "linkTo": "" + } + ], + [ + { + "system": "7–8", + "measure": "13–18", + "linkTo": "" + } + ], + [ + { + "system": "10–11", + "measure": "19–25", + "linkTo": "" + } + ], + [ + { + "system": "13–14", + "measure": "26–30", + "linkTo": "" + } + ], + [ + { + "system": "16–17", + "measure": "31", + "linkTo": "" + } + ] + ] + } + ] + } + ] + } + }, + { + "id": "source_C", "siglum": "C", "siglumAddendum": "", - "type": "Tintenniederschrift von
    Studienkomposition für Klavier M 35/42.
    Enthält auch Tintenniederschrift von Studienkomposition für Klavier M 34, M 36–38 und M 39 Textfassung 1→2 sowie Skizzen zu Studienkomposition für Klavier M 39 Textfassung 2.", + "type": "Skizzen zu
    Studienkomposition für Klavier M 35/42.
    Enthält auch Skizzen zu Studienkomposition für Klavier M 39 Textfassung 2, M 40–41 und M* 405–406.", "location": "CH-Bps, Sammlung Anton Webern.", "description": { - "desc": [ - "1 Bogen (Bl. 1/2): Der Bogen ist Bestandteil (Bl. 3/4) eines größeren Konvoluts aus 2 Bögen (Bl. 1/2, 3/4), 2 Blättern (Bl. 5–6) und 1 Bogen (Bl. 7/8). Stockfleck und rötliche Verfärbung mittig am oberen Rand des Bogens." - ], + "desc": ["1 Bogen (Bl. 1/2). Kleiner Riss am rechten Rand von Bl. 2."], "writingMaterialStrings": [ - "Notenpapier, 18 Systeme, Format: hoch 349 × 267 mm, Firmenzeichen:

    unten links auf Bl. 1r und 2r" + "Notenpapier, 18 Systeme, Format: hoch 348 × 266 mm, Firmenzeichen:

    unten links auf Bl. 1r und 2r" ], "writingMaterials": [ { @@ -1030,15 +1076,15 @@ "orientation": "hoch", "height": { "uncertainty": "", - "value": "349" + "value": "348" }, "width": { "uncertainty": "", - "value": "267" + "value": "266" } }, "firmSign": { - "variant": "FIRM_JE_NO_5_LIN_18_D", + "variant": "FIRM_JE_NO_5_LIN_18_C", "alt": "", "location": [ { @@ -1052,8 +1098,8 @@ } ], "writingInstruments": { - "main": "schwarze Tinte", - "secondary": ["Bleistift"] + "main": "Bleistift", + "secondary": [] }, "titles": [], "dates": [], @@ -1063,12 +1109,9 @@ "annotations": [], "contents": [ { - "item": "M 34", - "itemLinkTo": { - "complexId": "m34", - "sheetId": "M_34_TF1" - }, - "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M 34)", + "item": "M 41 Sk 1", + "itemLinkTo": {}, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 41)", "folios": [ { "folio": "1r", @@ -1078,14 +1121,42 @@ [ { "system": "1–2", - "measure": "1–5", + "measure": "1, {2A–3A}, 2B–3B, 4", "linkTo": "" } ], [ { - "system": "4–5", - "measure": "6–8", + "system": "4–6", + "measure": "5–11", + "linkTo": "" + } + ], + [ + { + "system": "7–8", + "measure": "12–17", + "linkTo": "" + } + ], + [ + { + "system": "10–11", + "measure": "18–23", + "linkTo": "" + } + ], + [ + { + "system": "13–14", + "measure": "24A, 24B, 25–28", + "linkTo": "" + } + ], + [ + { + "system": "17a", + "measure": "29–31", "linkTo": "" } ] @@ -1094,12 +1165,9 @@ ] }, { - "item": "M 35/42", - "itemLinkTo": { - "complexId": "m35_42", - "sheetId": "M_35_42_TF1" - }, - "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M 35/42)", + "item": "M 41 Sk1.1", + "itemLinkTo": {}, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 41)", "folios": [ { "folio": "1r", @@ -1108,15 +1176,15 @@ "systemGroups": [ [ { - "system": "7–8", - "measure": "1–7", + "system": "12", + "measure": "24–28", "linkTo": "" } ], [ { - "system": "10a–11a", - "measure": "8–9", + "system": "16a", + "measure": "29", "linkTo": "" } ] @@ -1125,12 +1193,9 @@ ] }, { - "item": "M 35/42 Sk2", - "itemLinkTo": { - "complexId": "m35_42", - "sheetId": "M_35_42_Sk2" - }, - "itemDescription": "(Skizze zu Studienkomposition für Klavier M 35/42)", + "item": "M 41 Sk1.2", + "itemLinkTo": {}, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 41)", "folios": [ { "folio": "1r", @@ -1139,8 +1204,8 @@ "systemGroups": [ [ { - "system": "10b–11b (Bleistift)", - "measure": "7(2–3/4)–9", + "system": "16b–18", + "measure": "29–31", "linkTo": "" } ] @@ -1149,40 +1214,33 @@ ] }, { - "item": "M 36", + "item": "M 40 Sk1", "itemLinkTo": {}, - "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M 36)", + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 40)", "folios": [ { - "folio": "1r", + "folio": "1v", "folioLinkTo": "", "folioDescription": "", "systemGroups": [ [ { - "system": "13–14", - "measure": "1–6", + "system": "1–2", + "measure": "1–7, {8A}, 8B, 9", "linkTo": "" } ], [ { - "system": "16–17", - "measure": "7–13", + "system": "4–7b", + "measure": "10–12, {13A}, 13B, 14–15", "linkTo": "" } - ] - ] - }, - { - "folio": "1v", - "folioLinkTo": "", - "folioDescription": "", - "systemGroups": [ + ], [ { - "system": "1–2", - "measure": "14–16", + "system": "7a–8", + "measure": "16A–17A, 16B–17B", "linkTo": "" } ] @@ -1191,12 +1249,9 @@ ] }, { - "item": "M 37", - "itemLinkTo": { - "complexId": "m37", - "sheetId": "M_37_TF1" - }, - "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M 37)", + "item": "M 40 Sk1.1", + "itemLinkTo": {}, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 40)", "folios": [ { "folio": "1v", @@ -1205,22 +1260,8 @@ "systemGroups": [ [ { - "system": "4–5", - "measure": "1–7", - "linkTo": "" - } - ], - [ - { - "system": "7–8", - "measure": "8–15", - "linkTo": "" - } - ], - [ - { - "system": "10–11", - "measure": "16–21", + "system": "9–10c", + "measure": "24–25", "linkTo": "" } ] @@ -1229,9 +1270,12 @@ ] }, { - "item": "M 38", - "itemLinkTo": {}, - "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M 38)", + "item": "M 35/42 Sk1.1", + "itemLinkTo": { + "complexId": "m35_42", + "sheetId": "M_35_42_Sk1.1" + }, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 35/42)", "folios": [ { "folio": "1v", @@ -1240,22 +1284,8 @@ "systemGroups": [ [ { - "system": "13–14", - "measure": "1–6", - "linkTo": "" - } - ], - [ - { - "system": "15–16", - "measure": "7–12", - "linkTo": "" - } - ], - [ - { - "system": "17–18", - "measure": "13–20", + "system": "10b–11b", + "measure": "22, 22+1", "linkTo": "" } ] @@ -1264,48 +1294,44 @@ ] }, { - "item": "M 39", - "itemLinkTo": {}, - "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M 39: Textfassung 1→2)", + "item": "M 35/42 Sk1", + "itemLinkTo": { + "complexId": "m35_42", + "sheetId": "M_35_42_Sk1" + }, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 35/42)", "folios": [ { - "folio": "2r", + "folio": "1v", "folioLinkTo": "", "folioDescription": "", "systemGroups": [ [ { - "system": "1–2", - "measure": "1–3", - "linkTo": "" - } - ], - [ - { - "system": "4–5", - "measure": "4–7", - "linkTo": "" + "system": "12a–13a", + "measure": "10–15", + "linkTo": "M_35_42_Sk1c" } ], [ { - "system": "7–8", - "measure": "8–12 → T. 8, {9–12}", - "linkTo": "" + "system": "12b–16", + "measure": "{16A–17A}, 16B, {17B}, 17C, 18", + "linkTo": "M_35_42_Sk1d" } ], [ { - "system": "10–11", - "measure": "13–16 → T. {13–14}, 13–14", - "linkTo": "" + "system": "17–18", + "measure": "19–21, {22}, 23–26", + "linkTo": "M_35_42_Sk1e" } ], [ { - "system": "13–14", - "measure": "17–19 → T. 15–17", - "linkTo": "" + "system": "10a–11a", + "measure": "27", + "linkTo": "M_35_42_Sk1f" } ] ] @@ -1324,8 +1350,8 @@ "systemGroups": [ [ { - "system": "16a–17a (Bleistift)", - "measure": "9–10", + "system": "1–2", + "measure": "11–13", "linkTo": "" } ] @@ -1334,9 +1360,9 @@ ] }, { - "item": "M 39 Sk3", + "item": "M* 405 Sk1", "itemLinkTo": {}, - "itemDescription": "(Skizze zu Studienkomposition für Klavier M 39: Textfassung 2)", + "itemDescription": "(Skizze zu Studienkomposition für Klavier M* 405)", "folios": [ { "folio": "2r", @@ -1345,71 +1371,57 @@ "systemGroups": [ [ { - "system": "13b–14b (Bleistift)", - "measure": "16–17(1–2/4)", - "linkTo": "" - } - ], - [ - { - "system": "16b–17b (Bleistift)", - "measure": "17(3–4/4)–19", - "linkTo": "" - } - ] - ] - } - ] - }, - { - "item": "M 41", - "itemLinkTo": {}, - "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M 41)", - "folios": [ - { - "folio": "2v", - "folioLinkTo": "", - "folioDescription": "", - "systemGroups": [ - [ - { - "system": "1–2", + "system": "4–5", "measure": "1–6", "linkTo": "" } ], [ { - "system": "4–5", - "measure": "7–12", + "system": "6–8", + "measure": "7–10, {11A}", "linkTo": "" } ], [ { - "system": "7–8", - "measure": "13–18", + "system": "10–11", + "measure": "11B, {12A}, 12B, 13–14", "linkTo": "" } ], [ { - "system": "10–11", - "measure": "19–25", + "system": "13–14", + "measure": "15A, {16A}, 15B(3–4/4), 16B", "linkTo": "" } ], [ { - "system": "13–14", - "measure": "26–30", + "system": "16–17", + "measure": "17–18", "linkTo": "" } - ], + ] + ] + } + ] + }, + { + "item": "M* 406 Sk1", + "itemLinkTo": {}, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M* 406)", + "folios": [ + { + "folio": "2v", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ [ { - "system": "16–17", - "measure": "31", + "system": "1–2", + "measure": "1–4", "linkTo": "" } ] @@ -1427,8 +1439,9 @@ "type": "Tintenniederschrift von
    Studienkomposition für Klavier M 35/42.
    Enthält auch Tintenniederschrift von Studienkomposition für Klavier M 39 Textfassung 2 und M 40.", "location": "CH-Bps, Sammlung Anton Webern.", "description": { - "desc": [ - "1 Blatt (Bl. 1): Das Blatt ist Bestandteil (Bl. 5) eines größeren Konvoluts aus 2 Bögen (Bl. 1/2, 3/4), 2 Blättern (Bl. 5–6) und 1 Bogen (Bl. 7/8). Rissspuren am linken Rand: von Bogen abgetrennt." + "desc": ["1 Blatt (Bl. 1). Rissspuren am linken Rand: von Bogen abgetrennt."], + "writingMaterialStrings": [ + "Notenpapier, 18 Systeme, Format: hoch 347 × 265 mm, Firmenzeichen:

    unten links auf Bl. 1r" ], "writingMaterials": [ { @@ -1550,7 +1563,7 @@ { "item": "M 39", "itemLinkTo": {}, - "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M 39 Textfassung 2)", + "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M 39: Textfassung 2)", "folios": [ { "folio": "1v", diff --git a/src/assets/data/edition/series/2/section/2a/m35_42/source-list.json b/src/assets/data/edition/series/2/section/2a/m35_42/source-list.json index 04781cca9..5a2813fa3 100644 --- a/src/assets/data/edition/series/2/section/2a/m35_42/source-list.json +++ b/src/assets/data/edition/series/2/section/2a/m35_42/source-list.json @@ -2,21 +2,21 @@ "sources": [ { "siglum": "A", - "type": "Skizzen zu
    Studienkomposition für Klavier M 35/42.
    Enthält auch Skizzen zu Studienkomposition für Klavier M 34, M 36–38, M 39 Textfassung 1→2 und M* 404.", + "type": "Skizzen zu
    Studienkomposition für Klavier M 35/42.
    Enthält auch Skizzen zu Studienkomposition für Klavier M 34, M 36–39 und M* 404.", "location": "CH-Bps, Sammlung Anton Webern.", "hasDescription": true, "linkTo": "source_A" }, { "siglum": "B", - "type": "Skizzen zu
    Studienkomposition für Klavier M 35/42.
    Enthält auch Skizzen zu Studienkomposition für Klavier M 39 Textfassung 2, M 40–41 und M* 405–406.", + "type": "Tintenniederschrift von
    Studienkomposition für Klavier M 35/42.
    Enthält auch Tintenniederschrift von Studienkomposition für Klavier M 34, M 36–38 und M 39 Textfassung 1→2 sowie Skizzen zu Studienkomposition für Klavier M 39 Textfassung 2.", "location": "CH-Bps, Sammlung Anton Webern.", "hasDescription": true, "linkTo": "source_B" }, { "siglum": "C", - "type": "Tintenniederschrift von
    Studienkomposition für Klavier M 35/42.
    Enthält auch Tintenniederschrift von Studienkomposition für Klavier M 34, M 36–38 und M 39 Textfassung 1→2 sowie Skizzen zu Studienkomposition für Klavier M 39 Textfassung 2.", + "type": "Skizzen zu
    Studienkomposition für Klavier M 35/42.
    Enthält auch Skizzen zu Studienkomposition für Klavier M 39 Textfassung 2, M 40–41 und M* 405–406.", "location": "CH-Bps, Sammlung Anton Webern.", "hasDescription": true, "linkTo": "source_C" diff --git a/src/assets/data/edition/series/2/section/2a/m35_42/textcritics.json b/src/assets/data/edition/series/2/section/2a/m35_42/textcritics.json index 061f2c282..0bb250e1a 100644 --- a/src/assets/data/edition/series/2/section/2a/m35_42/textcritics.json +++ b/src/assets/data/edition/series/2/section/2a/m35_42/textcritics.json @@ -8,39 +8,44 @@ ], "comments": [ { - "svgGroupId": "g3402", - "measure": "23
    bis 24", - "system": "Klav. o.", - "position": "3/4
    1. Note", - "comment": "Ligatur zu T. 23 3/4 ergänzt. D: Seitenwechsel nach T. 23." - }, - { - "svgGroupId": "g3405", - "measure": "25", - "system": "Klav. u.", - "position": "1. Note", - "comment": "Ces1/Es korrigiert zu Es1/Es mit Blick auf harmonischen Kontext." - }, - { - "svgGroupId": "g3408", - "measure": "25", - "system": "Klav. u.", - "position": "3/4", - "comment": "H2/D korrigiert zu D1/D mit Blick auf harmonischen Kontext." - }, - { - "svgGroupId": "g3411", - "measure": "26", - "system": "Klav. u.", - "position": "1/4", - "comment": "E1/G korrigiert zu G1/G mit Blick auf harmonischen Kontext." - }, - { - "svgGroupId": "g7117", - "measure": "26", - "system": "Klav. o.", - "position": "3/4", - "comment": "Staccatopunkt: sic. Staccatopunkt vermutlich für Unterstimme gedacht." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g3402", + "measure": "23
    bis 24", + "system": "Klav. o.", + "position": "3/4
    1. Note", + "comment": "Ligatur zu T. 23 3/4 ergänzt. D: Seitenwechsel nach T. 23." + }, + { + "svgGroupId": "g3405", + "measure": "25", + "system": "Klav. u.", + "position": "1. Note", + "comment": "Ces1/Es korrigiert zu Es1/Es mit Blick auf harmonischen Kontext." + }, + { + "svgGroupId": "g3408", + "measure": "25", + "system": "Klav. u.", + "position": "3/4", + "comment": "H2/D korrigiert zu D1/D mit Blick auf harmonischen Kontext." + }, + { + "svgGroupId": "g3411", + "measure": "26", + "system": "Klav. u.", + "position": "1/4", + "comment": "E1/G korrigiert zu G1/G mit Blick auf harmonischen Kontext." + }, + { + "svgGroupId": "g7117", + "measure": "26", + "system": "Klav. o.", + "position": "3/4", + "comment": "Staccatopunkt: sic. Staccatopunkt vermutlich für Unterstimme gedacht." + } + ] } ] }, @@ -50,175 +55,187 @@ "description": ["Sk1 ist die Verlaufsskizze zur Studienkomposition für Klavier M 35/42."], "comments": [ { - "svgGroupId": "g5408", - "measure": "4", - "system": "11", - "position": "2/4", - "comment": "e1 radiert." - }, - { - "svgGroupId": "g5399", - "measure": "4", - "system": "10", - "position": "3/4", - "comment": "a2 gestrichen." - }, - { - "svgGroupId": "g5166", - "measure": "8(1–2/4)", - "system": "14", - "position": "1/4", - "comment": "{{ref.getGlyph('[b]')}}es überschreibt {{ref.getGlyph('[#]')}}dis." - }, - { - "svgGroupId": "g5183", - "measure": "{8(3/4)A–10}", - "system": "13–14", - "position": "", - "comment": "Takte pauschal gestrichen." - }, - { - "svgGroupId": "g5172", - "measure": "{8(3/4)A}", - "system": "14", - "position": "3/4", - "comment": "{{ref.getGlyph('[b]')}}es überschreibt d." - }, - { - "svgGroupId": "g5177", - "measure": "{9A}", - "system": "14", - "position": "1/4", - "comment": "D gestrichen." - }, - { - "svgGroupId": "g5201", - "measure": "{10}", - "system": "13", - "position": "1. Note", - "comment": "Halbe Note h/g1 überscheibt Viertelnote h/d1/h1." - }, - { - "svgGroupId": "g5190", - "measure": "9B", - "system": "13", - "position": "1. Note", - "comment": "Halbe Note g1/h1 überschreibt Viertelnote h1." - }, - { - "svgGroupId": "g35163", - "measure": "11", - "system": "13", - "position": "1. Note", - "comment": "Halbe Note a/c1 überschreibt Viertelnoten a–H." - }, - { - "svgGroupId": "g35181", - "measure": "14", - "system": "13", - "position": "1/4", - "comment": "Viertelnote überschreibt Halbe Note." - }, - { - "svgGroupId": "g35206", - "measure": "15", - "system": "12", - "position": "1. Note", - "comment": "Halbe Note [{{ref.getGlyph('[#]')}}]dis1 überschreibt Viertelnoten [{{ref.getGlyph('[#]')}}]dis1/{{ref.getGlyph('[a]')}}f1–{{ref.getGlyph('[#]')}}ais1/c2." - }, - { - "svgGroupId": "g37650", - "measure": "{16A–17A}", - "system": "15–16", - "position": "", - "comment": "Takte pauschal gestrichen." - }, - { - "svgGroupId": "g1508", - "measure": "{16A}", - "system": "15", - "position": "1. Note", - "comment": "Achtelpause überschreibt Viertelnote [{{ref.getGlyph('[#]')}}]dis1/{{ref.getGlyph('[#]')}}fis1." - }, - { - "svgGroupId": "g1629", - "measure": "16B", - "system": "15", - "position": "1. Pause", - "comment": "Achtelpause überschreibt Achtelnote h1/[{{ref.getGlyph('[#]')}}]dis2." - }, - { - "svgGroupId": "g37705", - "measure": "16B", - "system": "15", - "position": "1. Note", - "comment": "h1/{{ref.getGlyph('[#]')}}dis2 überschreibt {{ref.getGlyph('[b]')}}b/d1." - }, - { - "svgGroupId": "g37731", - "measure": "{17B}", - "system": "15", - "position": "1/4", - "comment": "Viertelpause überschreibt gestrichene Viertelnote h/g1." - }, - { - "svgGroupId": "g2798", - "measure": "{17B}", - "system": "15–16", - "position": "", - "comment": "Takt pauschal gestrichen." - }, - { - "svgGroupId": "g38561", - "measure": "17C", - "system": "15", - "position": "3/4", - "comment": "g1/e2 überschreibt a1/g2." - }, - { - "svgGroupId": "g37753", - "measure": "18", - "system": "15–16", - "position": "", - "comment": "Takt pauschal gestrichen und in System 12–13 neu gesetzt." - }, - { - "svgGroupId": "g42457", - "measure": "19", - "system": "17", - "position": "1. Note", - "comment": "h1/d2 überschreibt g1/h1." - }, - { - "svgGroupId": "g42480", - "measure": "21", - "system": "17", - "position": "3/4", - "comment": "[{{ref.getGlyph('[#]')}}]ais/{{ref.getGlyph('[#]')}}fis1 überschreibt g1/h1." - }, - { - "svgGroupId": "g42786", - "measure": "{22}", - "system": "17–18", - "position": "", - "comment": "Takt pauschal gestrichen." - }, - { - "svgGroupId": "g42497", - "measure": "{22}", - "system": "17", - "position": "2/4", - "comment": "fis1 gestrichen." - }, - { - "svgGroupId": "g4507", - "measure": "{22}", - "system": "17", - "position": "3/4", - "comment": "Entzifferung nicht eindeutig. g1/h1 überschreibt c1/{{ref.getGlyph('[b]')}}es1 sowie e2?" + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g5408", + "measure": "4", + "system": "11", + "position": "2/4", + "comment": "e1 radiert." + }, + { + "svgGroupId": "g5399", + "measure": "4", + "system": "10", + "position": "3/4", + "comment": "a2 gestrichen." + }, + { + "svgGroupId": "g5166", + "measure": "8(1–2/4)", + "system": "14", + "position": "1/4", + "comment": "{{ref.getGlyph('[b]')}}es überschreibt {{ref.getGlyph('[#]')}}dis." + }, + { + "svgGroupId": "g5183", + "measure": "{8(3/4)A–10}", + "system": "13–14", + "position": "", + "comment": "Takte pauschal gestrichen." + }, + { + "svgGroupId": "g5172", + "measure": "{8(3/4)A}", + "system": "14", + "position": "3/4", + "comment": "{{ref.getGlyph('[b]')}}es überschreibt d." + }, + { + "svgGroupId": "g5177", + "measure": "{9A}", + "system": "14", + "position": "1/4", + "comment": "D gestrichen." + }, + { + "svgGroupId": "g5201", + "measure": "{10}", + "system": "13", + "position": "1. Note", + "comment": "Halbe Note h/g1 überscheibt Viertelnote h/d1/h1." + }, + { + "svgGroupId": "g5190", + "measure": "9B", + "system": "13", + "position": "1. Note", + "comment": "Halbe Note g1/h1 überschreibt Viertelnote h1." + }, + { + "svgGroupId": "g35163", + "measure": "11", + "system": "13", + "position": "1. Note", + "comment": "Halbe Note a/c1 überschreibt Viertelnoten a–H." + }, + { + "svgGroupId": "g35181", + "measure": "14", + "system": "13", + "position": "1/4", + "comment": "Viertelnote überschreibt Halbe Note." + }, + { + "svgGroupId": "g35206", + "measure": "15", + "system": "12", + "position": "1. Note", + "comment": "Halbe Note [{{ref.getGlyph('[#]')}}]dis1 überschreibt Viertelnoten [{{ref.getGlyph('[#]')}}]dis1/{{ref.getGlyph('[a]')}}f1–{{ref.getGlyph('[#]')}}ais1/c2." + }, + { + "svgGroupId": "g37650", + "measure": "{16A–17A}", + "system": "15–16", + "position": "", + "comment": "Takte pauschal gestrichen." + }, + { + "svgGroupId": "g1508", + "measure": "{16A}", + "system": "15", + "position": "1. Note", + "comment": "Achtelpause überschreibt Viertelnote [{{ref.getGlyph('[#]')}}]dis1/{{ref.getGlyph('[#]')}}fis1." + }, + { + "svgGroupId": "g1629", + "measure": "16B", + "system": "15", + "position": "1. Pause", + "comment": "Achtelpause überschreibt Achtelnote h1/[{{ref.getGlyph('[#]')}}]dis2." + }, + { + "svgGroupId": "g37705", + "measure": "16B", + "system": "15", + "position": "1. Note", + "comment": "h1/{{ref.getGlyph('[#]')}}dis2 überschreibt {{ref.getGlyph('[b]')}}b/d1." + }, + { + "svgGroupId": "g37731", + "measure": "{17B}", + "system": "15", + "position": "1/4", + "comment": "Viertelpause überschreibt gestrichene Viertelnote h/g1." + }, + { + "svgGroupId": "g2798", + "measure": "{17B}", + "system": "15–16", + "position": "", + "comment": "Takt pauschal gestrichen." + }, + { + "svgGroupId": "g38561", + "measure": "17C", + "system": "15", + "position": "3/4", + "comment": "g1/e2 überschreibt a1/g2." + }, + { + "svgGroupId": "g37753", + "measure": "18", + "system": "15–16", + "position": "", + "comment": "Takt pauschal gestrichen und in System 12–13 neu gesetzt." + }, + { + "svgGroupId": "g42457", + "measure": "19", + "system": "17", + "position": "1. Note", + "comment": "h1/d2 überschreibt g1/h1." + }, + { + "svgGroupId": "g42480", + "measure": "21", + "system": "17", + "position": "3/4", + "comment": "[{{ref.getGlyph('[#]')}}]ais/{{ref.getGlyph('[#]')}}fis1 überschreibt g1/h1." + }, + { + "svgGroupId": "g42786", + "measure": "{22}", + "system": "17–18", + "position": "", + "comment": "Takt pauschal gestrichen." + }, + { + "svgGroupId": "g42497", + "measure": "{22}", + "system": "17", + "position": "2/4", + "comment": "fis1 gestrichen." + }, + { + "svgGroupId": "g4507", + "measure": "{22}", + "system": "17", + "position": "3/4", + "comment": "Entzifferung nicht eindeutig. g1/h1 überschreibt c1/{{ref.getGlyph('[b]')}}es1 sowie e2?" + } + ] } ], "linkBoxes": [ + { + "svgGroupId": "g1", + "linkTo": { + "complexId": "m36", + "sheetId": "M_36_Sk1c" + } + }, { "svgGroupId": "g2", "linkTo": { @@ -264,18 +281,23 @@ ], "comments": [ { - "svgGroupId": "g44424", - "measure": "22", - "system": "10", - "position": "1/4", - "comment": "Viertelnote fis1 gestrichen." - }, - { - "svgGroupId": "g6997", - "measure": "22", - "system": "10", - "position": "4/8", - "comment": "Balkierung überschreibt Achtelfähnchen." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g44424", + "measure": "22", + "system": "10", + "position": "1/4", + "comment": "Viertelnote fis1 gestrichen." + }, + { + "svgGroupId": "g6997", + "measure": "22", + "system": "10", + "position": "4/8", + "comment": "Balkierung überschreibt Achtelfähnchen." + } + ] } ], "linkBoxes": [ @@ -301,18 +323,23 @@ "description": ["Sk2 notiert eine alternative Schlussformel für den ersten A-Teil."], "comments": [ { - "svgGroupId": "g50343", - "measure": "9", - "system": "10", - "position": "1. Note", - "comment": "Augmentationspunkte gestrichen." - }, - { - "svgGroupId": "g50355", - "measure": "9", - "system": "11", - "position": "2/4", - "comment": "Viertelnote überschreibt Halbe Note." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g50343", + "measure": "9", + "system": "10", + "position": "1. Note", + "comment": "Augmentationspunkte gestrichen." + }, + { + "svgGroupId": "g50355", + "measure": "9", + "system": "11", + "position": "2/4", + "comment": "Viertelnote überschreibt Halbe Note." + } + ] } ], "linkBoxes": [ diff --git a/src/assets/data/edition/series/2/section/2a/m36/folio-convolute.json b/src/assets/data/edition/series/2/section/2a/m36/folio-convolute.json new file mode 100644 index 000000000..322ff2d87 --- /dev/null +++ b/src/assets/data/edition/series/2/section/2a/m36/folio-convolute.json @@ -0,0 +1,405 @@ +{ + "convolutes": [ + { + "convoluteId": "A", + "convoluteLabel": "A Skizzen (CH-Bps)", + "folios": [ + { + "folioId": "1r", + "systems": "18", + "format": { + "height": 349, + "width": 265 + }, + "content": [ + { + "complexId": "m34", + "sheetId": "M_34_Sk1a", + "sigle": "M 34 Sk1", + "sigleAddendum": "T. 1–7", + "sectionPartition": 1, + "sections": [ + { + "startSystem": 1, + "endSystem": 2 + } + ] + }, + { + "complexId": "m34", + "sheetId": "M_34_Sk1b", + "sigle": "M 34 Sk1", + "sigleAddendum": "T. 8–14", + "sectionPartition": 1, + "sections": [ + { + "startSystem": 4, + "endSystem": 5 + } + ] + }, + { + "complexId": "m34", + "sheetId": "M_34_Sk1c", + "sigle": "M 34 Sk1", + "sigleAddendum": "T. 15–16", + "sectionPartition": 2, + "sections": [ + { + "position": 1, + "startSystem": 7, + "endSystem": 8 + } + ] + }, + { + "complexId": "m34", + "sheetId": "M_34_Sk1_1", + "sigle": "M 34 Sk1.1", + "sigleAddendum": "", + "sectionPartition": 2, + "sections": [ + { + "position": 2, + "startSystem": 6, + "endSystem": 8 + } + ] + }, + { + "complexId": "m35_42", + "sheetId": "M_35_42_Sk1a", + "sigle": "M 35/42 Sk1", + "sigleAddendum": "T. 1–7", + "sectionPartition": 1, + "sections": [ + { + "startSystem": 10, + "endSystem": 11 + } + ] + }, + { + "complexId": "m36", + "sheetId": "M_36_Sk1d", + "sigle": "M 36 Sk1", + "sigleAddendum": "T. 12", + "sectionPartition": 7, + "sections": [ + { + "position": 6, + "startSystem": 12, + "endSystem": 12 + } + ] + }, + { + "complexId": "m35_42", + "sheetId": "M_35_42_Sk1b", + "sigle": "M 35/42 Sk1", + "sigleAddendum": "T. 8(1–2/4)–9B", + "sectionPartition": 2, + "sections": [ + { + "position": 1, + "startSystem": 13, + "endSystem": 14 + } + ] + }, + { + "complexId": "m36", + "sheetId": "M_36_Sk1c", + "sigle": "M 36 Sk1", + "sigleAddendum": "T. 8–11", + "sectionPartition": 2, + "sections": [ + { + "position": 2, + "startSystem": 13, + "endSystem": 14 + } + ] + }, + { + "complexId": "m36", + "sheetId": "M_36_Sk1b", + "sigle": "M 36 Sk1", + "sigleAddendum": "T. 7", + "sectionPartition": 7, + "sections": [ + { + "position": 6, + "startSystem": 14, + "endSystem": 15 + } + ] + }, + { + "complexId": "m36", + "sheetId": "M_36_Sk1e", + "sigle": "M 36 Sk1", + "sigleAddendum": "T. 16", + "sectionPartition": 7, + "sections": [ + { + "position": 4, + "startSystem": 15, + "endSystem": 15 + } + ] + }, + { + "complexId": "m36", + "sheetId": "M_36_Sk1a", + "sigle": "M 36 Sk1", + "sigleAddendum": "T. 1–6", + "sectionPartition": 1, + "sections": [ + { + "startSystem": 16, + "endSystem": 17 + } + ] + } + ] + }, + { + "folioId": "1v", + "systems": "18", + "format": { + "height": 349, + "width": 265 + }, + "content": [ + { + "complexId": "m38", + "sheetId": "M_38_Sk3b", + "sigle": "M 38 Sk3", + "sigleAddendum": "T. 5", + "sectionPartition": 4, + "sections": [ + { + "position": 4, + "startSystem": 13, + "endSystem": 14 + } + ] + }, + { + "complexId": "m38", + "sheetId": "M_38_Sk3a", + "sigle": "M 38 Sk3", + "sigleAddendum": "T. 1–4", + "sectionPartition": 3, + "sections": [ + { + "position": 3, + "startSystem": 15, + "endSystem": 16 + } + ] + }, + { + "complexId": "m38", + "sheetId": "M_38_Sk3c", + "sigle": "M 38 Sk3", + "sigleAddendum": "T. 6–8", + "sectionPartition": 3, + "sections": [ + { + "position": 3, + "startSystem": 17, + "endSystem": 18 + } + ] + } + ] + }, + { + "folioId": "2r", + "systems": "18", + "format": { + "height": 349, + "width": 265 + }, + "content": [ + { + "complexId": "m37", + "sheetId": "M_37_Sk1", + "sigle": "M 37 Sk1", + "sigleAddendum": "", + "sectionPartition": 3, + "sections": [ + { + "position": 1, + "startSystem": 18, + "endSystem": 18 + } + ] + }, + { + "complexId": "m37", + "sheetId": "M_37_Sk2", + "sigle": "M 37 Sk2", + "sigleAddendum": "", + "sectionPartition": 3, + "sections": [ + { + "position": 2, + "startSystem": 18, + "endSystem": 18 + } + ] + }, + { + "complexId": "m38", + "sheetId": "M_38_Sk2", + "sigle": "M 38 Sk2", + "sigleAddendum": "", + "sectionPartition": 3, + "sections": [ + { + "position": 3, + "startSystem": 18, + "endSystem": 18 + } + ] + }, + { + "complexId": "m38", + "sheetId": "M_38_Sk1", + "sigle": "M 38 Sk1", + "sigleAddendum": "", + "sectionPartition": 1, + "sections": [ + { + "startSystem": 18, + "endSystem": 18, + "relativeToSystem": "below" + } + ] + } + ] + }, + { + "folioId": "2v", + "systems": "18", + "format": { + "height": 349, + "width": 265 + }, + "content": [ + { + "complexId": "m38", + "sheetId": "M_38_Sk3d", + "sigle": "M 38 Sk3", + "sigleAddendum": "T. 9–12B", + "sectionPartition": 1, + "sections": [ + { + "startSystem": 1, + "endSystem": 2 + } + ] + }, + { + "complexId": "m38", + "sheetId": "M_38_Sk3e", + "sigle": "M 38 Sk3", + "sigleAddendum": "T. 13–17", + "sectionPartition": 1, + "sections": [ + { + "startSystem": 4, + "endSystem": 5 + } + ] + }, + { + "complexId": "m37", + "sheetId": "M_37_Sk3a", + "sigle": "M 37 Sk3", + "sigleAddendum": "T. 1–6", + "sectionPartition": 1, + "sections": [ + { + "startSystem": 7, + "endSystem": 8 + } + ] + }, + { + "complexId": "m37", + "sheetId": "M_37_Sk3b", + "sigle": "M 37 Sk3", + "sigleAddendum": "T. 7–14", + "sectionPartition": 1, + "sections": [ + { + "startSystem": 10, + "endSystem": 11 + } + ] + }, + { + "complexId": "m37", + "sheetId": "M_37_Sk3c", + "sigle": "M 37 Sk3", + "sigleAddendum": "T. 15–21", + "sectionPartition": 1, + "sections": [ + { + "startSystem": 13, + "endSystem": 14 + } + ] + } + ] + } + ] + }, + { + "convoluteId": "B", + "convoluteLabel": "B Tintenniederschrift (CH-Bps)", + "folios": [ + { + "folioId": "1r", + "systems": "18", + "format": { + "height": 349, + "width": 267 + }, + "content": [] + }, + { + "folioId": "1v", + "systems": "18", + "format": { + "height": 349, + "width": 267 + }, + "content": [] + }, + { + "folioId": "2r", + "systems": "18", + "format": { + "height": 349, + "width": 267 + }, + "content": [] + }, + { + "folioId": "2v", + "systems": "18", + "format": { + "height": 349, + "width": 267 + }, + "content": [] + } + ] + } + ] +} diff --git a/src/assets/data/edition/series/2/section/2a/m36/graph.json b/src/assets/data/edition/series/2/section/2a/m36/graph.json new file mode 100644 index 000000000..b6944f634 --- /dev/null +++ b/src/assets/data/edition/series/2/section/2a/m36/graph.json @@ -0,0 +1,13 @@ +{ + "graph": [ + { + "id": "m36", + "title": "Skizzengraph M 36", + "description": [], + "rdfData": { + "queryList": [], + "triples": "" + } + } + ] +} diff --git a/src/assets/data/edition/series/2/section/2a/m36/intro.json b/src/assets/data/edition/series/2/section/2a/m36/intro.json new file mode 100644 index 000000000..6ee4bc2fa --- /dev/null +++ b/src/assets/data/edition/series/2/section/2a/m36/intro.json @@ -0,0 +1,8 @@ +{ + "intro": [ + { + "id": "m36", + "content": [] + } + ] +} diff --git a/src/assets/data/edition/series/2/section/2a/m36/source-description.json b/src/assets/data/edition/series/2/section/2a/m36/source-description.json new file mode 100644 index 000000000..81c499727 --- /dev/null +++ b/src/assets/data/edition/series/2/section/2a/m36/source-description.json @@ -0,0 +1,1057 @@ +{ + "sources": [ + { + "id": "source_A", + "siglum": "A", + "siglumAddendum": "", + "type": "Skizzen zu
    Studienkomposition für Klavier M 36.
    Enthält auch Skizzen zu Studienkomposition für Klavier M 34, M 35/42, M 37–39 und M* 404.", + "location": "CH-Bps, Sammlung Anton Webern.", + "description": { + "desc": ["1 Bogen (Bl. 1/2)."], + "writingMaterialStrings": [ + "Notenpapier, 18 Systeme, Format: hoch 349 × 265 mm, Firmenzeichen: ##[JE]## | Protokoll. Schutzmarke | No. 5 | 18 linig. unten links auf Bl. 1r und 2r" + ], + "writingMaterials": [ + { + "paperType": "Notenpapier", + "systems": { + "number": 18, + "info": "", + "addendum": "" + }, + "format": { + "orientation": "hoch", + "height": { + "uncertainty": "", + "value": "349" + }, + "width": { + "uncertainty": "", + "value": "265" + } + }, + "firmSign": { + "variant": "FIRM_JE_NO_5_LIN_18_C", + "alt": "", + "location": [ + { + "info": "", + "folios": ["1r", "2r"], + "position": "unten links" + } + ] + }, + "folioAddendum": "1/2" + } + ], + "writingInstruments": { + "main": "Bleistift", + "secondary": [] + }, + "titles": [], + "dates": [], + "paginations": [], + "measureNumbers": [], + "instrumentations": [], + "annotations": [], + "contents": [ + { + "item": "M 34 Sk1", + "itemLinkTo": { + "complexId": "m34", + "sheetId": "M_34_Sk1a" + }, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 34)", + "folios": [ + { + "folio": "1r", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "1–2", + "measure": "1–7", + "linkTo": "M_34_Sk1a" + } + ], + [ + { + "system": "4–5", + "measure": "8–14", + "linkTo": "M_34_Sk1b" + } + ], + [ + { + "system": "7a–8a", + "measure": "15–16", + "linkTo": "M_34_Sk1c" + } + ] + ] + } + ] + }, + { + "item": "M 34 Sk1.1", + "itemLinkTo": { + "complexId": "m34", + "sheetId": "M_34_Sk1_1" + }, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 34)", + "folios": [ + { + "folio": "1r", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "6–8b", + "measure": "5–8", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M 35/42 Sk1", + "itemLinkTo": { + "complexId": "m35_42", + "sheetId": "M_35_42_Sk1" + }, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 35/42)", + "folios": [ + { + "folio": "1r", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "10–11", + "measure": "1–7", + "linkTo": "M_35_42_Sk1a" + } + ], + [ + { + "system": "13a–14a", + "measure": "8(1–2/4), {8(3/4)A–9A, 10}, 8(3/4)B–9B", + "linkTo": "M_35_42_Sk1b" + } + ] + ] + } + ] + }, + { + "item": "M 36 Sk1", + "itemLinkTo": { + "complexId": "m36", + "sheetId": "M_36_Sk1a" + }, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 36)", + "folios": [ + { + "folio": "1r", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "16–17", + "measure": "1–6", + "linkTo": "M_36_Sk1a" + } + ], + [ + { + "system": "14c–15b", + "measure": "7", + "linkTo": "M_36_Sk1b" + } + ], + [ + { + "system": "13b–14b", + "measure": "8–11", + "linkTo": "M_36_Sk1c" + } + ], + [ + { + "system": "12", + "measure": "12", + "linkTo": "M_36_Sk1d" + } + ], + [ + { + "system": "15a", + "measure": "16", + "linkTo": "M_36_Sk1e" + } + ] + ] + } + ] + }, + { + "item": "M* 404 Sk1", + "itemLinkTo": {}, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M* 404)", + "folios": [ + { + "folio": "1v", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "1–2", + "measure": "1–4, {5A}", + "linkTo": "" + } + ], + [ + { + "system": "4–5", + "measure": "5B, {6A–7A}, 6B–7B", + "linkTo": "" + } + ], + [ + { + "system": "10–11", + "measure": "8A–9A, 8B(3/4)–9B, 10–11", + "linkTo": "" + } + ], + [ + { + "system": "13a–14a", + "measure": "12–15", + "linkTo": "" + } + ], + [ + { + "system": "16a–17a", + "measure": "16", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M* 404 Sk1.1", + "itemLinkTo": {}, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M* 404)", + "folios": [ + { + "folio": "1v", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "7a–8a", + "measure": "1–2", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M* 404 Sk1.2", + "itemLinkTo": {}, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M* 404)", + "folios": [ + { + "folio": "1v", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "7b–8b", + "measure": "1–2", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M* 404 Sk1.3", + "itemLinkTo": {}, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M* 404)", + "folios": [ + { + "folio": "1v", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "7c–8c", + "measure": "x+1", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M* 404 Sk1.4", + "itemLinkTo": {}, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M* 404)", + "folios": [ + { + "folio": "1v", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "16b–17b", + "measure": "16–17", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M 38 Sk3", + "itemLinkTo": { + "complexId": "m38", + "sheetId": "M_38_Sk3a" + }, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 38)", + "folios": [ + { + "folio": "1v", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "15–16c", + "measure": "1–4", + "linkTo": "M_38_Sk3a" + } + ], + [ + { + "system": "13b–14b", + "measure": "5", + "linkTo": "M_38_Sk3b" + } + ], + [ + { + "system": "17c–18", + "measure": "6–8", + "linkTo": "M_38_Sk3c" + } + ] + ] + }, + { + "folio": "2v", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "1–2", + "measure": "9–10, {11A–12A}, 11B–12B", + "linkTo": "M_38_Sk3d" + } + ], + [ + { + "system": "4–5", + "measure": "13–17", + "linkTo": "M_38_Sk3e" + } + ] + ] + } + ] + }, + { + "item": "M 39 Sk1", + "itemLinkTo": {}, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 39)", + "folios": [ + { + "folio": "2r", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "2a–3a", + "measure": "1, {2A}", + "linkTo": "" + } + ], + [ + { + "system": "5–6", + "measure": "{2B}, 3–4, 5A", + "linkTo": "" + } + ], + [ + { + "system": "8a–9a", + "measure": "5B", + "linkTo": "" + } + ], + [ + { + "system": "11a–12a", + "measure": "6A, {7A–8A}", + "linkTo": "" + } + ], + [ + { + "system": "13a–14a", + "measure": "6B–8B", + "linkTo": "" + } + ], + [ + { + "system": "16–17", + "measure": "{9A–13A}", + "linkTo": "" + } + ], + [ + { + "system": "9c–10", + "measure": "{9B}", + "linkTo": "" + } + ], + [ + { + "system": "11b–12b", + "measure": "9C, 10B", + "linkTo": "" + } + ], + [ + { + "system": "13b–14b", + "measure": "11C, 12B", + "linkTo": "" + } + ], + [ + { + "system": "7–8c", + "measure": "13B, 14", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M 39 Sk1.1", + "itemLinkTo": {}, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 39)", + "folios": [ + { + "folio": "2r", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "8b–9b", + "measure": "2", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M 37 Sk1", + "itemLinkTo": { + "complexId": "m37", + "sheetId": "M_37_Sk1" + }, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 37)", + "folios": [ + { + "folio": "2r", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "18a", + "measure": "1–4", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M 37 Sk2", + "itemLinkTo": { + "complexId": "m37", + "sheetId": "M_37_Sk2" + }, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 37)", + "folios": [ + { + "folio": "2r", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "18b", + "measure": "1, {2A}, 2B, 3–5", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M 38 Sk2", + "itemLinkTo": { + "complexId": "m38", + "sheetId": "M_38_Sk2" + }, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 38)", + "folios": [ + { + "folio": "2r", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "18c", + "measure": "9–11", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M 38 Sk1", + "itemLinkTo": { + "complexId": "m38", + "sheetId": "M_38_Sk1" + }, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 38)", + "folios": [ + { + "folio": "2r", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "nach 18", + "measure": "1–12", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M 37 Sk3", + "itemLinkTo": { + "complexId": "m37", + "sheetId": "M_37_Sk3" + }, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 37)", + "folios": [ + { + "folio": "2v", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "7–8", + "measure": "1–6", + "linkTo": "M_37_Sk3a" + } + ], + [ + { + "system": "10–11", + "measure": "7–14", + "linkTo": "M_37_Sk3b" + } + ], + [ + { + "system": "13–14", + "measure": "15–21", + "linkTo": "M_37_Sk3c" + } + ] + ] + } + ] + } + ] + } + }, + { + "id": "source_B", + "siglum": "B", + "siglumAddendum": "", + "type": "Tintenniederschrift von
    Studienkomposition für Klavier M 36.
    Enthält auch Tintenniederschrift von Studienkomposition für Klavier M 34, M 35/42, M 37–38, M 39 Textfassung 1→2 und M 41 sowie Skizzen zu Studienkomposition für Klavier M 35/42 und M 39 Textfassung 2.", + "location": "CH-Bps, Sammlung Anton Webern.", + "description": { + "desc": ["1 Bogen (Bl. 1/2). Stockfleck und rötliche Verfärbung mittig am oberen Rand des Bogens."], + "writingMaterialStrings": [ + "Notenpapier, 18 Systeme, Format: hoch 349 × 267 mm, Firmenzeichen: ##[JE]## | Protokoll. Schutzmarke | No. 5 | 18 linig. unten links auf Bl. 1r und 2r" + ], + "writingMaterials": [ + { + "paperType": "Notenpapier", + "systems": { + "number": 18, + "info": "", + "addendum": "" + }, + "format": { + "orientation": "hoch", + "height": { + "uncertainty": "", + "value": "349" + }, + "width": { + "uncertainty": "", + "value": "267" + } + }, + "firmSign": { + "variant": "FIRM_JE_NO_5_LIN_18_D", + "alt": "", + "location": [ + { + "info": "", + "folios": ["1r", "2r"], + "position": "unten links" + } + ] + }, + "folioAddendum": "1/2" + } + ], + "writingInstruments": { + "main": "schwarze Tinte, Bleistift", + "secondary": [] + }, + "titles": [], + "dates": [], + "paginations": [], + "measureNumbers": [], + "instrumentations": [], + "annotations": [], + "contents": [ + { + "item": "M 34", + "itemLinkTo": { + "complexId": "m34", + "sheetId": "M_34_TF1" + }, + "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M 34)", + "folios": [ + { + "folio": "1r", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "1–2", + "measure": "1–5", + "linkTo": "" + } + ], + [ + { + "system": "4–5", + "measure": "6–8", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M 35/42", + "itemLinkTo": { + "complexId": "m35_42", + "sheetId": "M_35_42_TF1" + }, + "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M 35/42)", + "folios": [ + { + "folio": "1r", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "7–8", + "measure": "1–7", + "linkTo": "" + } + ], + [ + { + "system": "10a–11a", + "measure": "8–9", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M 35/42 Sk2", + "itemLinkTo": { + "complexId": "m35_42", + "sheetId": "M_35_42_Sk2" + }, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 35/42)", + "folios": [ + { + "folio": "1r", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "10b–11b (Bleistift)", + "measure": "7(2–3/4)–9", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M 36", + "itemLinkTo": { + "complexId": "m36", + "sheetId": "M_36_TF1" + }, + "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M 36)", + "folios": [ + { + "folio": "1r", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "13–14", + "measure": "1–6", + "linkTo": "" + } + ], + [ + { + "system": "16–17", + "measure": "7–13", + "linkTo": "" + } + ] + ] + }, + { + "folio": "1v", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "1–2", + "measure": "14–16", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M 37", + "itemLinkTo": { + "complexId": "m37", + "sheetId": "M_37_TF1" + }, + "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M 37)", + "folios": [ + { + "folio": "1v", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "4–5", + "measure": "1–7", + "linkTo": "" + } + ], + [ + { + "system": "7–8", + "measure": "8–15", + "linkTo": "" + } + ], + [ + { + "system": "10–11", + "measure": "16–21", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M 38", + "itemLinkTo": { + "complexId": "m38", + "sheetId": "M_38_TF1" + }, + "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M 38)", + "folios": [ + { + "folio": "1v", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "13–14", + "measure": "1–6", + "linkTo": "" + } + ], + [ + { + "system": "15–16", + "measure": "7–12", + "linkTo": "" + } + ], + [ + { + "system": "17–18", + "measure": "13–20", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M 39", + "itemLinkTo": {}, + "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M 39: Textfassung 1→2)", + "folios": [ + { + "folio": "2r", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "1–2", + "measure": "1–3", + "linkTo": "" + } + ], + [ + { + "system": "4–5", + "measure": "4–7", + "linkTo": "" + } + ], + [ + { + "system": "7–8", + "measure": "8–12 → T. 8, {9–12}", + "linkTo": "" + } + ], + [ + { + "system": "10–11", + "measure": "13–16 → T. {13–14}, 13–14", + "linkTo": "" + } + ], + [ + { + "system": "13–14", + "measure": "17–19 → T. 15–17", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M 39 Sk2", + "itemLinkTo": {}, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 39: Textfassung 2)", + "folios": [ + { + "folio": "2r", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "16a–17a (Bleistift)", + "measure": "9–10", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M 39 Sk3", + "itemLinkTo": {}, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 39: Textfassung 2)", + "folios": [ + { + "folio": "2r", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "13b–14b (Bleistift)", + "measure": "16–17(1–2/4)", + "linkTo": "" + } + ], + [ + { + "system": "16b–17b (Bleistift)", + "measure": "17(3–4/4)–19", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M 41", + "itemLinkTo": {}, + "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M 41)", + "folios": [ + { + "folio": "2v", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "1–2", + "measure": "1–6", + "linkTo": "" + } + ], + [ + { + "system": "4–5", + "measure": "7–12", + "linkTo": "" + } + ], + [ + { + "system": "7–8", + "measure": "13–18", + "linkTo": "" + } + ], + [ + { + "system": "10–11", + "measure": "19–25", + "linkTo": "" + } + ], + [ + { + "system": "13–14", + "measure": "26–30", + "linkTo": "" + } + ], + [ + { + "system": "16–17", + "measure": "31", + "linkTo": "" + } + ] + ] + } + ] + } + ] + } + } + ] +} diff --git a/src/assets/data/edition/series/2/section/2a/m36/source-evaluation.json b/src/assets/data/edition/series/2/section/2a/m36/source-evaluation.json new file mode 100644 index 000000000..363094bbc --- /dev/null +++ b/src/assets/data/edition/series/2/section/2a/m36/source-evaluation.json @@ -0,0 +1,8 @@ +{ + "sources": [ + { + "id": "m36", + "content": [] + } + ] +} diff --git a/src/assets/data/edition/series/2/section/2a/m36/source-list.json b/src/assets/data/edition/series/2/section/2a/m36/source-list.json index 81b22f1aa..51b4c39fb 100644 --- a/src/assets/data/edition/series/2/section/2a/m36/source-list.json +++ b/src/assets/data/edition/series/2/section/2a/m36/source-list.json @@ -3,7 +3,7 @@ { "siglum": "A", "siglumAddendum": "", - "type": "Skizzen zu
    Studienkomposition für Klavier M 36.
    Enthält auch Skizzen zu Studienkomposition für Klavier M 34–35, M 37–38, M 39 Textfassung 1→2 und M* 404.", + "type": "Skizzen zu
    Studienkomposition für Klavier M 36.
    Enthält auch Skizzen zu Studienkomposition für Klavier M 34, M 35/42, M 37–39 und M* 404.", "location": "CH-Bps, Sammlung Anton Webern.", "hasDescription": true, "linkTo": "source_A" @@ -11,7 +11,7 @@ { "siglum": "B", "siglumAddendum": "", - "type": "Tintenniederschrift von
    Studienkomposition für Klavier M 36.
    Enthält auch Tintenniederschrift von Studienkomposition für Klavier M 34–35, M 37–38, M 39 Textfassung 1→2 und M 41 sowie Skizzen zu Studienkomposition für Klavier M 35 und 39 Textfassung 2.", + "type": "Tintenniederschrift von
    Studienkomposition für Klavier M 36.
    Enthält auch Tintenniederschrift von Studienkomposition für Klavier M 34, M 35/42, M 37–38, M 39 Textfassung 1→2 und M 41 sowie Skizzen zu Studienkomposition für Klavier M 35/42 und M 39 Textfassung 2.", "location": "CH-Bps, Sammlung Anton Webern.", "hasDescription": true, "linkTo": "source_B" diff --git a/src/assets/data/edition/series/2/section/2a/m36/svg-sheets.json b/src/assets/data/edition/series/2/section/2a/m36/svg-sheets.json new file mode 100644 index 000000000..42df98df9 --- /dev/null +++ b/src/assets/data/edition/series/2/section/2a/m36/svg-sheets.json @@ -0,0 +1,57 @@ +{ + "sheets": { + "workEditions": [], + "textEditions": [ + { + "id": "M_36_TF1", + "label": "M 36 einzige Textfassung", + "content": [ + { + "svg": "assets/img/edition/series/2/section/2a/m36/M36_Textfassung1-1von1-final.svg", + "image": "", + "partial": "", + "convolute": "B" + } + ] + } + ], + "sketchEditions": [ + { + "id": "M_36_Sk1", + "label": "M 36 Sk1", + "content": [ + { + "svg": "assets/img/edition/series/2/section/2a/m36/M36_Sk1-1von5-final.svg", + "image": "", + "partial": "a", + "convolute": "A" + }, + { + "svg": "assets/img/edition/series/2/section/2a/m36/M36_Sk1-2von5-final.svg", + "image": "", + "partial": "b", + "convolute": "A" + }, + { + "svg": "assets/img/edition/series/2/section/2a/m36/M36_Sk1-3von5-final.svg", + "image": "", + "partial": "c", + "convolute": "A" + }, + { + "svg": "assets/img/edition/series/2/section/2a/m36/M36_Sk1-4von5-final.svg", + "image": "", + "partial": "d", + "convolute": "A" + }, + { + "svg": "assets/img/edition/series/2/section/2a/m36/M36_Sk1-5von5-final.svg", + "image": "", + "partial": "e", + "convolute": "A" + } + ] + } + ] + } +} diff --git a/src/assets/data/edition/series/2/section/2a/m36/textcritics.json b/src/assets/data/edition/series/2/section/2a/m36/textcritics.json new file mode 100644 index 000000000..d37365505 --- /dev/null +++ b/src/assets/data/edition/series/2/section/2a/m36/textcritics.json @@ -0,0 +1,146 @@ +{ + "textcritics": [ + { + "id": "M_36_TF1", + "label": "M 36 einzige Textfassung", + "description": [ + "Für die Textedition der Studienkomposition für Klavier M 36 ist B relevante Quelle. A enthält Skizzen.
    B weist zwei unterscheidbare Korrekturschichten auf: Korrekturen 1 mit Tinte sowie die später entstandenen Korrekturen 2 mit Bleistift. Der Zustand vor Korrekturen 1 ist nicht immer zu entziffern.
    Hauptquelle für die Textedition der Studienkomposition für Klavier M 36 ist B nach Korrekturen 1." + ], + "comments": [ + { + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g820", + "measure": "11", + "system": "Klav.", + "position": "3/4", + "comment": "Diastematisch undefinierter Notenkopf zwischen den Systemen weggelassen." + } + ] + } + ] + }, + { + "id": "M_36_Sk1", + "label": "M 36 Sk1", + "description": [ + "Sk1 ist die Verlaufsskizze zu der Studienkomposition für Klavier M 36, bei der die Reprise mit Ausnahme des neuen Schlussakkords (T. 16) nicht ausnotiert ist." + ], + "comments": [ + { + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g1046", + "measure": "3", + "system": "16", + "position": "1. Note", + "comment": "Halbe Note g1/c2/e2 überschreibt Viertelnote c2/e2." + }, + { + "svgGroupId": "g1058", + "measure": "5", + "system": "16", + "position": "1. Note", + "comment": "Punktierte Halbe Note überschreibt Viertelnote." + }, + { + "svgGroupId": "g3", + "measure": "6", + "system": "17", + "position": "3/4", + "comment": "Metrisch falsch gesetzter Notenkopf e gestrichen." + }, + { + "svgGroupId": "g975", + "measure": "7", + "system": "14", + "position": "1. Note", + "comment": "{{ref.getGlyph('[#]')}}cis1 überschreibt d1." + }, + { + "svgGroupId": "g13", + "measure": "7", + "system": "15", + "position": "(2/4)", + "comment": "Viertelnote e gstrichen? Entzifferung unsicher." + }, + { + "svgGroupId": "g1040", + "measure": "8 bis
    9", + "system": "13", + "position": "3/4
    1/4", + "comment": "a1–a1 überschreibt h1–h1." + }, + { + "svgGroupId": "g9", + "measure": "11", + "system": "13", + "position": "1/4", + "comment": "Oberstimmenschicht: Viertelnote überschreibt Halbe Note." + }, + { + "svgGroupId": "g10", + "measure": "12", + "system": "12", + "position": "1. Note", + "comment": "h überschreibt a." + }, + { + "svgGroupId": "g111", + "measure": "12", + "system": "12", + "position": "2/4", + "comment": "Entzifferung unsicher. Die Viertelnote mit Hilfslinien ist vergleichsweise tief gesetzt und möglicherweise auch lesbar als H1 im Bassschlüssel analog Tintenniederschrift." + } + ] + } + ], + "linkBoxes": [ + { + "svgGroupId": "g2", + "linkTo": { + "complexId": "m36", + "sheetId": "M_36_Sk1d" + } + }, + { + "svgGroupId": "g5", + "linkTo": { + "complexId": "m36", + "sheetId": "M_36_Sk1e" + } + }, + { + "svgGroupId": "g6", + "linkTo": { + "complexId": "m36", + "sheetId": "M_36_Sk1a" + } + }, + { + "svgGroupId": "g8", + "linkTo": { + "complexId": "m36", + "sheetId": "M_36_Sk1b" + } + }, + { + "svgGroupId": "g11", + "linkTo": { + "complexId": "m35_42", + "sheetId": "M_35_42_Sk1b" + } + }, + { + "svgGroupId": "g12", + "linkTo": { + "complexId": "m36", + "sheetId": "M_36_Sk1c" + } + } + ] + } + ] +} diff --git a/src/assets/data/edition/series/2/section/2a/m37/folio-convolute.json b/src/assets/data/edition/series/2/section/2a/m37/folio-convolute.json index bae510c45..322ff2d87 100644 --- a/src/assets/data/edition/series/2/section/2a/m37/folio-convolute.json +++ b/src/assets/data/edition/series/2/section/2a/m37/folio-convolute.json @@ -61,7 +61,7 @@ "sections": [ { "position": 2, - "startSystem": 7, + "startSystem": 6, "endSystem": 8 } ] @@ -79,6 +79,20 @@ } ] }, + { + "complexId": "m36", + "sheetId": "M_36_Sk1d", + "sigle": "M 36 Sk1", + "sigleAddendum": "T. 12", + "sectionPartition": 7, + "sections": [ + { + "position": 6, + "startSystem": 12, + "endSystem": 12 + } + ] + }, { "complexId": "m35_42", "sheetId": "M_35_42_Sk1b", @@ -92,6 +106,61 @@ "endSystem": 14 } ] + }, + { + "complexId": "m36", + "sheetId": "M_36_Sk1c", + "sigle": "M 36 Sk1", + "sigleAddendum": "T. 8–11", + "sectionPartition": 2, + "sections": [ + { + "position": 2, + "startSystem": 13, + "endSystem": 14 + } + ] + }, + { + "complexId": "m36", + "sheetId": "M_36_Sk1b", + "sigle": "M 36 Sk1", + "sigleAddendum": "T. 7", + "sectionPartition": 7, + "sections": [ + { + "position": 6, + "startSystem": 14, + "endSystem": 15 + } + ] + }, + { + "complexId": "m36", + "sheetId": "M_36_Sk1e", + "sigle": "M 36 Sk1", + "sigleAddendum": "T. 16", + "sectionPartition": 7, + "sections": [ + { + "position": 4, + "startSystem": 15, + "endSystem": 15 + } + ] + }, + { + "complexId": "m36", + "sheetId": "M_36_Sk1a", + "sigle": "M 36 Sk1", + "sigleAddendum": "T. 1–6", + "sectionPartition": 1, + "sections": [ + { + "startSystem": 16, + "endSystem": 17 + } + ] } ] }, @@ -102,7 +171,50 @@ "height": 349, "width": 265 }, - "content": [] + "content": [ + { + "complexId": "m38", + "sheetId": "M_38_Sk3b", + "sigle": "M 38 Sk3", + "sigleAddendum": "T. 5", + "sectionPartition": 4, + "sections": [ + { + "position": 4, + "startSystem": 13, + "endSystem": 14 + } + ] + }, + { + "complexId": "m38", + "sheetId": "M_38_Sk3a", + "sigle": "M 38 Sk3", + "sigleAddendum": "T. 1–4", + "sectionPartition": 3, + "sections": [ + { + "position": 3, + "startSystem": 15, + "endSystem": 16 + } + ] + }, + { + "complexId": "m38", + "sheetId": "M_38_Sk3c", + "sigle": "M 38 Sk3", + "sigleAddendum": "T. 6–8", + "sectionPartition": 3, + "sections": [ + { + "position": 3, + "startSystem": 17, + "endSystem": 18 + } + ] + } + ] }, { "folioId": "2r", @@ -139,6 +251,34 @@ "endSystem": 18 } ] + }, + { + "complexId": "m38", + "sheetId": "M_38_Sk2", + "sigle": "M 38 Sk2", + "sigleAddendum": "", + "sectionPartition": 3, + "sections": [ + { + "position": 3, + "startSystem": 18, + "endSystem": 18 + } + ] + }, + { + "complexId": "m38", + "sheetId": "M_38_Sk1", + "sigle": "M 38 Sk1", + "sigleAddendum": "", + "sectionPartition": 1, + "sections": [ + { + "startSystem": 18, + "endSystem": 18, + "relativeToSystem": "below" + } + ] } ] }, @@ -150,6 +290,32 @@ "width": 265 }, "content": [ + { + "complexId": "m38", + "sheetId": "M_38_Sk3d", + "sigle": "M 38 Sk3", + "sigleAddendum": "T. 9–12B", + "sectionPartition": 1, + "sections": [ + { + "startSystem": 1, + "endSystem": 2 + } + ] + }, + { + "complexId": "m38", + "sheetId": "M_38_Sk3e", + "sigle": "M 38 Sk3", + "sigleAddendum": "T. 13–17", + "sectionPartition": 1, + "sections": [ + { + "startSystem": 4, + "endSystem": 5 + } + ] + }, { "complexId": "m37", "sheetId": "M_37_Sk3a", diff --git a/src/assets/data/edition/series/2/section/2a/m37/source-description.json b/src/assets/data/edition/series/2/section/2a/m37/source-description.json index 4c6948bdf..9e392e188 100644 --- a/src/assets/data/edition/series/2/section/2a/m37/source-description.json +++ b/src/assets/data/edition/series/2/section/2a/m37/source-description.json @@ -4,14 +4,12 @@ "id": "source_A", "siglum": "A", "siglumAddendum": "", - "type": "Skizzen zu
    Studienkomposition für Klavier M 37.
    Enthält auch Skizzen zu Studienkomposition für Klavier M 34–36, M 38, M 39 Textfassung 1→2 und M* 404.", + "type": "Skizzen zu
    Studienkomposition für Klavier M 37.
    Enthält auch Skizzen zu Studienkomposition für Klavier M 34, M 35/42, M 36, M 38–39 und M* 404.", "location": "CH-Bps, Sammlung Anton Webern.", "description": { - "desc": [ - "1 Bogen (Bl. 1/2): Der Bogen ist Bestandteil (Bl. 1/2) eines größeren Konvoluts aus 2 Bögen (Bl. 1/2, 3/4), 2 Blättern (Bl. 5–6) und 1 Bogen (Bl. 7/8)." - ], + "desc": ["1 Bogen (Bl. 1/2)."], "writingMaterialStrings": [ - "Notenpapier, 18 Systeme, Format: hoch 349 × 265 mm, Firmenzeichen:

    unten links auf Bl. 1r und 2r" + "Notenpapier, 18 Systeme, Format: hoch 349 × 265 mm, Firmenzeichen: ##[JE]## | Protokoll. Schutzmarke | No. 5 | 18 linig. unten links auf Bl. 1r und 2r" ], "writingMaterials": [ { @@ -152,7 +150,10 @@ }, { "item": "M 36 Sk1", - "itemLinkTo": {}, + "itemLinkTo": { + "complexId": "m36", + "sheetId": "M_36_Sk1a" + }, "itemDescription": "(Skizze zu Studienkomposition für Klavier M 36)", "folios": [ { @@ -164,35 +165,35 @@ { "system": "16–17", "measure": "1–6", - "linkTo": "" + "linkTo": "M_36_Sk1a" } ], [ { "system": "14c–15b", "measure": "7", - "linkTo": "" + "linkTo": "M_36_Sk1b" } ], [ { "system": "13b–14b", "measure": "8–11", - "linkTo": "" + "linkTo": "M_36_Sk1c" } ], [ { "system": "12", "measure": "12", - "linkTo": "" + "linkTo": "M_36_Sk1d" } ], [ { "system": "15a", "measure": "16", - "linkTo": "" + "linkTo": "M_36_Sk1e" } ] ] @@ -334,7 +335,10 @@ }, { "item": "M 38 Sk3", - "itemLinkTo": {}, + "itemLinkTo": { + "complexId": "m38", + "sheetId": "M_38_Sk3a" + }, "itemDescription": "(Skizze zu Studienkomposition für Klavier M 38)", "folios": [ { @@ -346,21 +350,21 @@ { "system": "15–16c", "measure": "1–4", - "linkTo": "" + "linkTo": "M_38_Sk3a" } ], [ { "system": "13b–14b", "measure": "5", - "linkTo": "" + "linkTo": "M_38_Sk3b" } ], [ { "system": "17c–18", "measure": "6–8", - "linkTo": "" + "linkTo": "M_38_Sk3c" } ] ] @@ -374,14 +378,14 @@ { "system": "1–2", "measure": "9–10, {11A–12A}, 11B–12B", - "linkTo": "" + "linkTo": "M_38_Sk3d" } ], [ { "system": "4–5", "measure": "13–17", - "linkTo": "" + "linkTo": "M_38_Sk3e" } ] ] @@ -543,7 +547,10 @@ }, { "item": "M 38 Sk2", - "itemLinkTo": {}, + "itemLinkTo": { + "complexId": "m38", + "sheetId": "M_38_Sk2" + }, "itemDescription": "(Skizze zu Studienkomposition für Klavier M 38)", "folios": [ { @@ -564,7 +571,10 @@ }, { "item": "M 38 Sk1", - "itemLinkTo": {}, + "itemLinkTo": { + "complexId": "m38", + "sheetId": "M_38_Sk1" + }, "itemDescription": "(Skizze zu Studienkomposition für Klavier M 38)", "folios": [ { @@ -628,14 +638,12 @@ "id": "source_B", "siglum": "B", "siglumAddendum": "", - "type": "Tintenniederschrift von
    Studienkomposition für Klavier M 37.
    Enthält auch Tintenniederschrift von Studienkomposition für Klavier M 34–36, M 38, M 39 Textfassung 1→2 und M 41 sowie Skizzen zu Studienkomposition für Klavier M 35/42 und 39 Textfassung 2.", + "type": "Tintenniederschrift von
    Studienkomposition für Klavier M 37.
    Enthält auch Tintenniederschrift von Studienkomposition für Klavier M 34, M 35/42, M 36, M 38, M 39 Textfassung 1→2 und M 41 sowie Skizzen zu Studienkomposition für Klavier M 35/42 und 39 Textfassung 2.", "location": "CH-Bps, Sammlung Anton Webern.", "description": { - "desc": [ - "1 Bogen (Bl. 1/2): Der Bogen ist Bestandteil (Bl. 3/4) eines größeren Konvoluts aus 2 Bögen (Bl. 1/2, 3/4), 2 Blättern (Bl. 5–6) und 1 Bogen (Bl. 7/8). Stockfleck und rötliche Verfärbung mittig am oberen Rand des Bogens." - ], + "desc": ["1 Bogen (Bl. 1/2). Stockfleck und rötliche Verfärbung mittig am oberen Rand des Bogens."], "writingMaterialStrings": [ - "Notenpapier, 18 Systeme, Format: hoch 349 × 267 mm, Firmenzeichen:

    unten links auf Bl. 1r und 2r" + "Notenpapier, 18 Systeme, Format: hoch 349 × 267 mm, Firmenzeichen: ##[JE]## | Protokoll. Schutzmarke | No. 5 | 18 linig. unten links auf Bl. 1r und 2r" ], "writingMaterials": [ { @@ -769,7 +777,10 @@ }, { "item": "M 36", - "itemLinkTo": {}, + "itemLinkTo": { + "complexId": "m36", + "sheetId": "M_36_TF1" + }, "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M 36)", "folios": [ { @@ -849,7 +860,10 @@ }, { "item": "M 38", - "itemLinkTo": {}, + "itemLinkTo": { + "complexId": "m38", + "sheetId": "M_38_TF1" + }, "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M 38)", "folios": [ { diff --git a/src/assets/data/edition/series/2/section/2a/m37/source-list.json b/src/assets/data/edition/series/2/section/2a/m37/source-list.json index e7f2d9e0d..f706873d2 100644 --- a/src/assets/data/edition/series/2/section/2a/m37/source-list.json +++ b/src/assets/data/edition/series/2/section/2a/m37/source-list.json @@ -3,7 +3,7 @@ { "siglum": "A", "siglumAddendum": "", - "type": "Skizzen zu
    Studienkomposition für Klavier M 37.
    Enthält auch Skizzen zu Studienkomposition für Klavier M 34–36, M 38, M 39 Textfassung 1→2 und M* 404.", + "type": "Skizzen zu
    Studienkomposition für Klavier M 37.
    Enthält auch Skizzen zu Studienkomposition für Klavier M 34, M 35/42, M 36, M 38–39 und M* 404.", "location": "CH-Bps, Sammlung Anton Webern.", "hasDescription": true, "linkTo": "source_A" @@ -11,7 +11,7 @@ { "siglum": "B", "siglumAddendum": "", - "type": "Tintenniederschrift von
    Studienkomposition für Klavier M 37.
    Enthält auch Tintenniederschrift von Studienkomposition für Klavier M 34–36, M 38, M 39 Textfassung 1→2 und M 41 sowie Skizzen zu Studienkomposition für Klavier M 35/42 und 39 Textfassung 2.", + "type": "Tintenniederschrift von
    Studienkomposition für Klavier M 37.
    Enthält auch Tintenniederschrift von Studienkomposition für Klavier M 34, M 35/42, M 36, M 38, M 39 Textfassung 1→2 und M 41 sowie Skizzen zu Studienkomposition für Klavier M 35/42 und 39 Textfassung 2.", "location": "CH-Bps, Sammlung Anton Webern.", "hasDescription": true, "linkTo": "source_B" diff --git a/src/assets/data/edition/series/2/section/2a/m37/textcritics.json b/src/assets/data/edition/series/2/section/2a/m37/textcritics.json index 46a53e1e9..d57554d9c 100644 --- a/src/assets/data/edition/series/2/section/2a/m37/textcritics.json +++ b/src/assets/data/edition/series/2/section/2a/m37/textcritics.json @@ -8,32 +8,37 @@ ], "comments": [ { - "svgGroupId": "g4640", - "measure": "6", - "system": "Klav. u.", - "position": "3/4", - "comment": "Notenhals und nur im Ansatz vorhandenes {{ref.getGlyph('[#]')}} ergänzt." - }, - { - "svgGroupId": "g4643", - "measure": "10", - "system": "Klav.", - "position": "(2/4)", - "comment": "Gestrichelte Linie zwischen den Systemen zur Verdeutlichung des in B verschobenen Untersatzes weggelassen.###Grafik###." - }, - { - "svgGroupId": "g4646", - "measure": "19", - "system": "Klav. u.", - "position": "2/4", - "comment": "Augmentationspunkt weggelassen mit Blick auf metrischen Kontext." - }, - { - "svgGroupId": "g4649", - "measure": "21", - "system": "Klav. u.", - "position": "1. Note", - "comment": "g korrigiert zu a mit Blick auf harmonischen Kontext." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g4640", + "measure": "6", + "system": "Klav. u.", + "position": "3/4", + "comment": "Notenhals und nur im Ansatz vorhandenes {{ref.getGlyph('[#]')}} ergänzt." + }, + { + "svgGroupId": "g4643", + "measure": "10", + "system": "Klav.", + "position": "(2/4)", + "comment": "Gestrichelte Linie zwischen den Systemen zur Verdeutlichung des in B verschobenen Untersatzes weggelassen.###Grafik###." + }, + { + "svgGroupId": "g4646", + "measure": "19", + "system": "Klav. u.", + "position": "2/4", + "comment": "Augmentationspunkt weggelassen mit Blick auf metrischen Kontext." + }, + { + "svgGroupId": "g4649", + "measure": "21", + "system": "Klav. u.", + "position": "1. Note", + "comment": "g korrigiert zu a mit Blick auf harmonischen Kontext." + } + ] } ] }, @@ -43,6 +48,7 @@ "description": [ "Sk1 skizziert möglicherweise eine erste melodische Linie für M 37. Die Zugehörigkeit zur Studienkomposition für Klavier M 37 ist allerdings nicht eindeutig." ], + "comments": [], "linkBoxes": [ { "svgGroupId": "g1365", @@ -68,18 +74,23 @@ ], "comments": [ { - "svgGroupId": "g19564", - "measure": "{2A}", - "system": "18", - "position": "1/4", - "comment": "Viertelnote c2 gestrichen." - }, - { - "svgGroupId": "g22497", - "measure": "4", - "system": "18", - "position": "1. Note", - "comment": "Oberstimmenschicht: a überschreibt {{ref.getGlyph('[#]')}}gis." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g19564", + "measure": "{2A}", + "system": "18", + "position": "1/4", + "comment": "Viertelnote c2 gestrichen." + }, + { + "svgGroupId": "g22497", + "measure": "4", + "system": "18", + "position": "1. Note", + "comment": "Oberstimmenschicht: a überschreibt {{ref.getGlyph('[#]')}}gis." + } + ] } ], "linkBoxes": [ @@ -105,123 +116,128 @@ "description": ["Sk3 ist die Verlaufsskizze zur Studienkomposition für Klavier M 37."], "comments": [ { - "svgGroupId": "g56588", - "measure": "2", - "system": "8", - "position": "2/4", - "comment": "H/f/g überschreibt d/h." - }, - { - "svgGroupId": "g57322", - "measure": "3", - "system": "7", - "position": "1. Note", - "comment": "Punktierte Viertelnote überschreibt Halbe Note." - }, - { - "svgGroupId": "g58053", - "measure": "3", - "system": "7", - "position": "2. Note", - "comment": "c2 überschreibt d2." - }, - { - "svgGroupId": "g58784", - "measure": "3", - "system": "7", - "position": "letzte Note", - "comment": "g1 überschreibt c2." - }, - { - "svgGroupId": "g59524", - "measure": "4", - "system": "7", - "position": "2/4", - "comment": "Viertelnote überschreibt Halbe Note." - }, - { - "svgGroupId": "g60259", - "measure": "5", - "system": "7", - "position": "2. Note", - "comment": "h1/h2 überschreibt a1/a2." - }, - { - "svgGroupId": "g61719", - "measure": "6", - "system": "8", - "position": "2/4", - "comment": "A/f überschreibt cis/a." - }, - { - "svgGroupId": "g8097", - "measure": "7", - "system": "10", - "position": "1. Note", - "comment": "Halbe Note überschreibt Viertelnote; d2 überschreibt f2." - }, - { - "svgGroupId": "g8829", - "measure": "10", - "system": "10", - "position": "1/4", - "comment": "Viertelpause überschreibt Viertelnote d1/h1." - }, - { - "svgGroupId": "g9564", - "measure": "12", - "system": "10", - "position": "1. Note", - "comment": "Viertelnote {{ref.getGlyph('[b]')}}b2 überschreibt Halbe Note {{ref.getGlyph('[b]')}}b2." - }, - { - "svgGroupId": "g10298", - "measure": "12", - "system": "10", - "position": "2. Note", - "comment": "a1/a2 überschreibt e1/e2." - }, - { - "svgGroupId": "g11033", - "measure": "13", - "system": "10", - "position": "2/4", - "comment": "{{ref.getGlyph('[#]')}}cis1/{{ref.getGlyph('[#]')}}cis2 überschreibt e1/e2." - }, - { - "svgGroupId": "g11767", - "measure": "13", - "system": "11", - "position": "3/4", - "comment": "c/a überschreibt f/d1." - }, - { - "svgGroupId": "g19964", - "measure": "17", - "system": "13", - "position": "1. Note", - "comment": "e1 überschreibt g1." - }, - { - "svgGroupId": "g20694", - "measure": "18", - "system": "13", - "position": "3/4", - "comment": "{{ref.getGlyph('[a]')}} überschreibt {{ref.getGlyph('[#]')}}." - }, - { - "svgGroupId": "g21427", - "measure": "19", - "system": "13", - "position": "1. Note", - "comment": "Punktierte Viertelnote {{ref.getGlyph('[#]')}}gis1 der Oberstimmenschicht überschreibt Halbe Note {{ref.getGlyph('[#]')}}gis1 der Unterstimmenschicht." - }, - { - "svgGroupId": "g22161", - "measure": "20", - "system": "13", - "position": "2/4", - "comment": "Viertelnote überschreibt Halbe Note." + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g56588", + "measure": "2", + "system": "8", + "position": "2/4", + "comment": "H/f/g überschreibt d/h." + }, + { + "svgGroupId": "g57322", + "measure": "3", + "system": "7", + "position": "1. Note", + "comment": "Punktierte Viertelnote überschreibt Halbe Note." + }, + { + "svgGroupId": "g58053", + "measure": "3", + "system": "7", + "position": "2. Note", + "comment": "c2 überschreibt d2." + }, + { + "svgGroupId": "g58784", + "measure": "3", + "system": "7", + "position": "letzte Note", + "comment": "g1 überschreibt c2." + }, + { + "svgGroupId": "g59524", + "measure": "4", + "system": "7", + "position": "2/4", + "comment": "Viertelnote überschreibt Halbe Note." + }, + { + "svgGroupId": "g60259", + "measure": "5", + "system": "7", + "position": "2. Note", + "comment": "h1/h2 überschreibt a1/a2." + }, + { + "svgGroupId": "g61719", + "measure": "6", + "system": "8", + "position": "2/4", + "comment": "A/f überschreibt cis/a." + }, + { + "svgGroupId": "g8097", + "measure": "7", + "system": "10", + "position": "1. Note", + "comment": "Halbe Note überschreibt Viertelnote; d2 überschreibt f2." + }, + { + "svgGroupId": "g8829", + "measure": "10", + "system": "10", + "position": "1/4", + "comment": "Viertelpause überschreibt Viertelnote d1/h1." + }, + { + "svgGroupId": "g9564", + "measure": "12", + "system": "10", + "position": "1. Note", + "comment": "Viertelnote {{ref.getGlyph('[b]')}}b2 überschreibt Halbe Note {{ref.getGlyph('[b]')}}b2." + }, + { + "svgGroupId": "g10298", + "measure": "12", + "system": "10", + "position": "2. Note", + "comment": "a1/a2 überschreibt e1/e2." + }, + { + "svgGroupId": "g11033", + "measure": "13", + "system": "10", + "position": "2/4", + "comment": "{{ref.getGlyph('[#]')}}cis1/{{ref.getGlyph('[#]')}}cis2 überschreibt e1/e2." + }, + { + "svgGroupId": "g11767", + "measure": "13", + "system": "11", + "position": "3/4", + "comment": "c/a überschreibt f/d1." + }, + { + "svgGroupId": "g19964", + "measure": "17", + "system": "13", + "position": "1. Note", + "comment": "e1 überschreibt g1." + }, + { + "svgGroupId": "g20694", + "measure": "18", + "system": "13", + "position": "3/4", + "comment": "{{ref.getGlyph('[a]')}} überschreibt {{ref.getGlyph('[#]')}}." + }, + { + "svgGroupId": "g21427", + "measure": "19", + "system": "13", + "position": "1. Note", + "comment": "Punktierte Viertelnote {{ref.getGlyph('[#]')}}gis1 der Oberstimmenschicht überschreibt Halbe Note {{ref.getGlyph('[#]')}}gis1 der Unterstimmenschicht." + }, + { + "svgGroupId": "g22161", + "measure": "20", + "system": "13", + "position": "2/4", + "comment": "Viertelnote überschreibt Halbe Note." + } + ] } ] } diff --git a/src/assets/data/edition/series/2/section/2a/m38/folio-convolute.json b/src/assets/data/edition/series/2/section/2a/m38/folio-convolute.json new file mode 100644 index 000000000..322ff2d87 --- /dev/null +++ b/src/assets/data/edition/series/2/section/2a/m38/folio-convolute.json @@ -0,0 +1,405 @@ +{ + "convolutes": [ + { + "convoluteId": "A", + "convoluteLabel": "A Skizzen (CH-Bps)", + "folios": [ + { + "folioId": "1r", + "systems": "18", + "format": { + "height": 349, + "width": 265 + }, + "content": [ + { + "complexId": "m34", + "sheetId": "M_34_Sk1a", + "sigle": "M 34 Sk1", + "sigleAddendum": "T. 1–7", + "sectionPartition": 1, + "sections": [ + { + "startSystem": 1, + "endSystem": 2 + } + ] + }, + { + "complexId": "m34", + "sheetId": "M_34_Sk1b", + "sigle": "M 34 Sk1", + "sigleAddendum": "T. 8–14", + "sectionPartition": 1, + "sections": [ + { + "startSystem": 4, + "endSystem": 5 + } + ] + }, + { + "complexId": "m34", + "sheetId": "M_34_Sk1c", + "sigle": "M 34 Sk1", + "sigleAddendum": "T. 15–16", + "sectionPartition": 2, + "sections": [ + { + "position": 1, + "startSystem": 7, + "endSystem": 8 + } + ] + }, + { + "complexId": "m34", + "sheetId": "M_34_Sk1_1", + "sigle": "M 34 Sk1.1", + "sigleAddendum": "", + "sectionPartition": 2, + "sections": [ + { + "position": 2, + "startSystem": 6, + "endSystem": 8 + } + ] + }, + { + "complexId": "m35_42", + "sheetId": "M_35_42_Sk1a", + "sigle": "M 35/42 Sk1", + "sigleAddendum": "T. 1–7", + "sectionPartition": 1, + "sections": [ + { + "startSystem": 10, + "endSystem": 11 + } + ] + }, + { + "complexId": "m36", + "sheetId": "M_36_Sk1d", + "sigle": "M 36 Sk1", + "sigleAddendum": "T. 12", + "sectionPartition": 7, + "sections": [ + { + "position": 6, + "startSystem": 12, + "endSystem": 12 + } + ] + }, + { + "complexId": "m35_42", + "sheetId": "M_35_42_Sk1b", + "sigle": "M 35/42 Sk1", + "sigleAddendum": "T. 8(1–2/4)–9B", + "sectionPartition": 2, + "sections": [ + { + "position": 1, + "startSystem": 13, + "endSystem": 14 + } + ] + }, + { + "complexId": "m36", + "sheetId": "M_36_Sk1c", + "sigle": "M 36 Sk1", + "sigleAddendum": "T. 8–11", + "sectionPartition": 2, + "sections": [ + { + "position": 2, + "startSystem": 13, + "endSystem": 14 + } + ] + }, + { + "complexId": "m36", + "sheetId": "M_36_Sk1b", + "sigle": "M 36 Sk1", + "sigleAddendum": "T. 7", + "sectionPartition": 7, + "sections": [ + { + "position": 6, + "startSystem": 14, + "endSystem": 15 + } + ] + }, + { + "complexId": "m36", + "sheetId": "M_36_Sk1e", + "sigle": "M 36 Sk1", + "sigleAddendum": "T. 16", + "sectionPartition": 7, + "sections": [ + { + "position": 4, + "startSystem": 15, + "endSystem": 15 + } + ] + }, + { + "complexId": "m36", + "sheetId": "M_36_Sk1a", + "sigle": "M 36 Sk1", + "sigleAddendum": "T. 1–6", + "sectionPartition": 1, + "sections": [ + { + "startSystem": 16, + "endSystem": 17 + } + ] + } + ] + }, + { + "folioId": "1v", + "systems": "18", + "format": { + "height": 349, + "width": 265 + }, + "content": [ + { + "complexId": "m38", + "sheetId": "M_38_Sk3b", + "sigle": "M 38 Sk3", + "sigleAddendum": "T. 5", + "sectionPartition": 4, + "sections": [ + { + "position": 4, + "startSystem": 13, + "endSystem": 14 + } + ] + }, + { + "complexId": "m38", + "sheetId": "M_38_Sk3a", + "sigle": "M 38 Sk3", + "sigleAddendum": "T. 1–4", + "sectionPartition": 3, + "sections": [ + { + "position": 3, + "startSystem": 15, + "endSystem": 16 + } + ] + }, + { + "complexId": "m38", + "sheetId": "M_38_Sk3c", + "sigle": "M 38 Sk3", + "sigleAddendum": "T. 6–8", + "sectionPartition": 3, + "sections": [ + { + "position": 3, + "startSystem": 17, + "endSystem": 18 + } + ] + } + ] + }, + { + "folioId": "2r", + "systems": "18", + "format": { + "height": 349, + "width": 265 + }, + "content": [ + { + "complexId": "m37", + "sheetId": "M_37_Sk1", + "sigle": "M 37 Sk1", + "sigleAddendum": "", + "sectionPartition": 3, + "sections": [ + { + "position": 1, + "startSystem": 18, + "endSystem": 18 + } + ] + }, + { + "complexId": "m37", + "sheetId": "M_37_Sk2", + "sigle": "M 37 Sk2", + "sigleAddendum": "", + "sectionPartition": 3, + "sections": [ + { + "position": 2, + "startSystem": 18, + "endSystem": 18 + } + ] + }, + { + "complexId": "m38", + "sheetId": "M_38_Sk2", + "sigle": "M 38 Sk2", + "sigleAddendum": "", + "sectionPartition": 3, + "sections": [ + { + "position": 3, + "startSystem": 18, + "endSystem": 18 + } + ] + }, + { + "complexId": "m38", + "sheetId": "M_38_Sk1", + "sigle": "M 38 Sk1", + "sigleAddendum": "", + "sectionPartition": 1, + "sections": [ + { + "startSystem": 18, + "endSystem": 18, + "relativeToSystem": "below" + } + ] + } + ] + }, + { + "folioId": "2v", + "systems": "18", + "format": { + "height": 349, + "width": 265 + }, + "content": [ + { + "complexId": "m38", + "sheetId": "M_38_Sk3d", + "sigle": "M 38 Sk3", + "sigleAddendum": "T. 9–12B", + "sectionPartition": 1, + "sections": [ + { + "startSystem": 1, + "endSystem": 2 + } + ] + }, + { + "complexId": "m38", + "sheetId": "M_38_Sk3e", + "sigle": "M 38 Sk3", + "sigleAddendum": "T. 13–17", + "sectionPartition": 1, + "sections": [ + { + "startSystem": 4, + "endSystem": 5 + } + ] + }, + { + "complexId": "m37", + "sheetId": "M_37_Sk3a", + "sigle": "M 37 Sk3", + "sigleAddendum": "T. 1–6", + "sectionPartition": 1, + "sections": [ + { + "startSystem": 7, + "endSystem": 8 + } + ] + }, + { + "complexId": "m37", + "sheetId": "M_37_Sk3b", + "sigle": "M 37 Sk3", + "sigleAddendum": "T. 7–14", + "sectionPartition": 1, + "sections": [ + { + "startSystem": 10, + "endSystem": 11 + } + ] + }, + { + "complexId": "m37", + "sheetId": "M_37_Sk3c", + "sigle": "M 37 Sk3", + "sigleAddendum": "T. 15–21", + "sectionPartition": 1, + "sections": [ + { + "startSystem": 13, + "endSystem": 14 + } + ] + } + ] + } + ] + }, + { + "convoluteId": "B", + "convoluteLabel": "B Tintenniederschrift (CH-Bps)", + "folios": [ + { + "folioId": "1r", + "systems": "18", + "format": { + "height": 349, + "width": 267 + }, + "content": [] + }, + { + "folioId": "1v", + "systems": "18", + "format": { + "height": 349, + "width": 267 + }, + "content": [] + }, + { + "folioId": "2r", + "systems": "18", + "format": { + "height": 349, + "width": 267 + }, + "content": [] + }, + { + "folioId": "2v", + "systems": "18", + "format": { + "height": 349, + "width": 267 + }, + "content": [] + } + ] + } + ] +} diff --git a/src/assets/data/edition/series/2/section/2a/m38/graph.json b/src/assets/data/edition/series/2/section/2a/m38/graph.json new file mode 100644 index 000000000..d7c11099c --- /dev/null +++ b/src/assets/data/edition/series/2/section/2a/m38/graph.json @@ -0,0 +1,13 @@ +{ + "graph": [ + { + "id": "m38", + "title": "Skizzengraph M 38", + "description": [], + "rdfData": { + "queryList": [], + "triples": "" + } + } + ] +} diff --git a/src/assets/data/edition/series/2/section/2a/m38/intro.json b/src/assets/data/edition/series/2/section/2a/m38/intro.json new file mode 100644 index 000000000..1afb18ff0 --- /dev/null +++ b/src/assets/data/edition/series/2/section/2a/m38/intro.json @@ -0,0 +1,8 @@ +{ + "intro": [ + { + "id": "m38", + "content": [] + } + ] +} diff --git a/src/assets/data/edition/series/2/section/2a/m38/source-description.json b/src/assets/data/edition/series/2/section/2a/m38/source-description.json new file mode 100644 index 000000000..032f11d5d --- /dev/null +++ b/src/assets/data/edition/series/2/section/2a/m38/source-description.json @@ -0,0 +1,1053 @@ +{ + "sources": [ + { + "id": "source_A", + "siglum": "A", + "siglumAddendum": "", + "type": "Skizzen zu
    Studienkomposition für Klavier M 38.
    Enthält auch Skizzen zu Studienkomposition für Klavier M 34, M 35/42, M 36–37, M 39 und M* 404.", + "location": "CH-Bps, Sammlung Anton Webern.", + "description": { + "desc": ["1 Bogen (Bl. 1/2)."], + "writingMaterialString": "Notenpapier, 18 Systeme, Format: hoch 349 × 265 mm, Firmenzeichen: ##[JE]## | Protokoll. Schutzmarke | No. 5 | 18 linig. unten links auf Bl. 1r und 2r.", + "writingMaterials": [ + { + "paperType": "Notenpapier", + "systems": { + "number": 18, + "info": "", + "addendum": "" + }, + "format": { + "orientation": "hoch", + "height": { + "uncertainty": "", + "value": "349" + }, + "width": { + "uncertainty": "", + "value": "265" + } + }, + "firmSign": { + "variant": "FIRM_JE_NO_5_LIN_18_C", + "alt": "", + "location": [ + { + "info": "", + "folios": ["1r", "2r"], + "position": "unten links" + } + ] + }, + "folioAddendum": "1/2" + } + ], + "writingInstruments": { + "main": "Bleistift", + "secondary": [] + }, + "title": "", + "date": "", + "pagination": "", + "measureNumbers": "", + "instrumentation": "", + "annotations": "", + "contents": [ + { + "item": "M 34 Sk1", + "itemLinkTo": { + "complexId": "m34", + "sheetId": "M_34_Sk1a" + }, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 34)", + "folios": [ + { + "folio": "1r", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "1–2", + "measure": "1–7", + "linkTo": "M_34_Sk1a" + } + ], + [ + { + "system": "4–5", + "measure": "8–14", + "linkTo": "M_34_Sk1b" + } + ], + [ + { + "system": "7a–8a", + "measure": "15–16", + "linkTo": "M_34_Sk1c" + } + ] + ] + } + ] + }, + { + "item": "M 34 Sk1.1", + "itemLinkTo": { + "complexId": "m34", + "sheetId": "M_34_Sk1_1" + }, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 34)", + "folios": [ + { + "folio": "1r", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "6–8b", + "measure": "5–8", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M 35/42 Sk1", + "itemLinkTo": { + "complexId": "m35_42", + "sheetId": "M_35_42_Sk1" + }, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 35/42)", + "folios": [ + { + "folio": "1r", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "10–11", + "measure": "1–7", + "linkTo": "M_35_42_Sk1a" + } + ], + [ + { + "system": "13a–14a", + "measure": "8(1–2/4), {8(3/4)A–9A, 10}, 8(3/4)B–9B", + "linkTo": "M_35_42_Sk1b" + } + ] + ] + } + ] + }, + { + "item": "M 36 Sk1", + "itemLinkTo": { + "complexId": "m36", + "sheetId": "M_36_Sk1a" + }, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 36)", + "folios": [ + { + "folio": "1r", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "16–17", + "measure": "1–6", + "linkTo": "M_36_Sk1a" + } + ], + [ + { + "system": "14c–15b", + "measure": "7", + "linkTo": "M_36_Sk1b" + } + ], + [ + { + "system": "13b–14b", + "measure": "8–11", + "linkTo": "M_36_Sk1c" + } + ], + [ + { + "system": "12", + "measure": "12", + "linkTo": "M_36_Sk1d" + } + ], + [ + { + "system": "15a", + "measure": "16", + "linkTo": "M_36_Sk1e" + } + ] + ] + } + ] + }, + { + "item": "M* 404 Sk1", + "itemLinkTo": {}, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M* 404)", + "folios": [ + { + "folio": "1v", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "1–2", + "measure": "1–4, {5A}", + "linkTo": "" + } + ], + [ + { + "system": "4–5", + "measure": "5B, {6A–7A}, 6B–7B", + "linkTo": "" + } + ], + [ + { + "system": "10–11", + "measure": "8A–9A, 8B(3/4)–9B, 10–11", + "linkTo": "" + } + ], + [ + { + "system": "13a–14a", + "measure": "12–15", + "linkTo": "" + } + ], + [ + { + "system": "16a–17a", + "measure": "16", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M* 404 Sk1.1", + "itemLinkTo": {}, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M* 404)", + "folios": [ + { + "folio": "1v", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "7a–8a", + "measure": "1–2", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M* 404 Sk1.2", + "itemLinkTo": {}, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M* 404)", + "folios": [ + { + "folio": "1v", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "7b–8b", + "measure": "1–2", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M* 404 Sk1.3", + "itemLinkTo": {}, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M* 404)", + "folios": [ + { + "folio": "1v", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "7c–8c", + "measure": "x+1", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M* 404 Sk1.4", + "itemLinkTo": {}, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M* 404)", + "folios": [ + { + "folio": "1v", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "16b–17b", + "measure": "16–17", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M 38 Sk3", + "itemLinkTo": { + "complexId": "m38", + "sheetId": "M_38_Sk3a" + }, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 38)", + "folios": [ + { + "folio": "1v", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "15–16c", + "measure": "1–4", + "linkTo": "M_38_Sk3a" + } + ], + [ + { + "system": "13b–14b", + "measure": "5", + "linkTo": "M_38_Sk3b" + } + ], + [ + { + "system": "17c–18", + "measure": "6–8", + "linkTo": "M_38_Sk3c" + } + ] + ] + }, + { + "folio": "2v", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "1–2", + "measure": "9–10, {11A–12A}, 11B–12B", + "linkTo": "M_38_Sk3d" + } + ], + [ + { + "system": "4–5", + "measure": "13–17", + "linkTo": "M_38_Sk3e" + } + ] + ] + } + ] + }, + { + "item": "M 39 Sk1", + "itemLinkTo": {}, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 39)", + "folios": [ + { + "folio": "2r", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "2a–3a", + "measure": "1, {2A}", + "linkTo": "" + } + ], + [ + { + "system": "5–6", + "measure": "{2B}, 3–4, 5A", + "linkTo": "" + } + ], + [ + { + "system": "8a–9a", + "measure": "5B", + "linkTo": "" + } + ], + [ + { + "system": "11a–12a", + "measure": "6A, {7A–8A}", + "linkTo": "" + } + ], + [ + { + "system": "13a–14a", + "measure": "6B–8B", + "linkTo": "" + } + ], + [ + { + "system": "16–17", + "measure": "{9A–13A}", + "linkTo": "" + } + ], + [ + { + "system": "9c–10", + "measure": "{9B}", + "linkTo": "" + } + ], + [ + { + "system": "11b–12b", + "measure": "9C, 10B", + "linkTo": "" + } + ], + [ + { + "system": "13b–14b", + "measure": "11C, 12B", + "linkTo": "" + } + ], + [ + { + "system": "7–8c", + "measure": "13B, 14", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M 39 Sk1.1", + "itemLinkTo": {}, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 39)", + "folios": [ + { + "folio": "2r", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "8b–9b", + "measure": "2", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M 37 Sk1", + "itemLinkTo": { + "complexId": "m37", + "sheetId": "M_37_Sk1" + }, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 37)", + "folios": [ + { + "folio": "2r", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "18a", + "measure": "1–4", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M 37 Sk2", + "itemLinkTo": { + "complexId": "m37", + "sheetId": "M_37_Sk2" + }, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 37)", + "folios": [ + { + "folio": "2r", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "18b", + "measure": "1, {2A}, 2B, 3–5", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M 38 Sk2", + "itemLinkTo": { + "complexId": "m38", + "sheetId": "M_38_Sk2" + }, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 38)", + "folios": [ + { + "folio": "2r", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "18c", + "measure": "9–11", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M 38 Sk1", + "itemLinkTo": { + "complexId": "m38", + "sheetId": "M_38_Sk1" + }, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 38)", + "folios": [ + { + "folio": "2r", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "nach 18", + "measure": "1–12", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M 37 Sk3", + "itemLinkTo": { + "complexId": "m37", + "sheetId": "M_37_Sk3" + }, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 37)", + "folios": [ + { + "folio": "2v", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "7–8", + "measure": "1–6", + "linkTo": "M_37_Sk3a" + } + ], + [ + { + "system": "10–11", + "measure": "7–14", + "linkTo": "M_37_Sk3b" + } + ], + [ + { + "system": "13–14", + "measure": "15–21", + "linkTo": "M_37_Sk3c" + } + ] + ] + } + ] + } + ] + } + }, + { + "id": "source_B", + "siglum": "B", + "siglumAddendum": "", + "type": "Tintenniederschrift von
    Studienkomposition für Klavier M 38.
    Enthält auch Tintenniederschrift von Studienkomposition für Klavier M 34, M 35/42, M 36–37, M 39 Textfassung 1→2 und M 41 sowie Skizzen zu Studienkomposition für Klavier M 35/42 und M 39 Textfassung 2.", + "location": "CH-Bps, Sammlung Anton Webern.", + "description": { + "desc": ["1 Bogen (Bl. 1/2). Stockfleck und rötliche Verfärbung mittig am oberen Rand des Bogens."], + "writingMaterialString": "Notenpapier, 18 Systeme, Format: hoch 349 × 267 mm, Firmenzeichen: ##[JE]## | Protokoll. Schutzmarke | No. 5 | 18 linig. unten links auf Bl. 1r und 2r.", + "writingMaterials": [ + { + "paperType": "Notenpapier", + "systems": { + "number": 18, + "info": "", + "addendum": "" + }, + "format": { + "orientation": "hoch", + "height": { + "uncertainty": "", + "value": "349" + }, + "width": { + "uncertainty": "", + "value": "267" + } + }, + "firmSign": { + "variant": "FIRM_JE_NO_5_LIN_18_D", + "alt": "", + "location": [ + { + "info": "", + "folios": ["1r", "2r"], + "position": "unten links" + } + ] + }, + "folioAddendum": "1/2" + } + ], + "writingInstruments": { + "main": "schwarze Tinte, Bleistift", + "secondary": [] + }, + "title": "", + "date": "", + "pagination": "", + "measureNumbers": "", + "instrumentation": "", + "annotations": "", + "contents": [ + { + "item": "M 34", + "itemLinkTo": { + "complexId": "m34", + "sheetId": "M_34_TF1" + }, + "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M 34)", + "folios": [ + { + "folio": "1r", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "1–2", + "measure": "1–5", + "linkTo": "" + } + ], + [ + { + "system": "4–5", + "measure": "6–8", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M 35/42", + "itemLinkTo": { + "complexId": "m35_42", + "sheetId": "M_35_42_TF1" + }, + "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M 35/42)", + "folios": [ + { + "folio": "1r", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "7–8", + "measure": "1–7", + "linkTo": "" + } + ], + [ + { + "system": "10a–11a", + "measure": "8–9", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M 35/42 Sk2", + "itemLinkTo": { + "complexId": "m35_42", + "sheetId": "M_35_42_Sk2" + }, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 35/42)", + "folios": [ + { + "folio": "1r", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "10b–11b (Bleistift)", + "measure": "7(2–3/4)–9", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M 36", + "itemLinkTo": { + "complexId": "m36", + "sheetId": "M_36_TF1" + }, + "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M 36)", + "folios": [ + { + "folio": "1r", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "13–14", + "measure": "1–6", + "linkTo": "" + } + ], + [ + { + "system": "16–17", + "measure": "7–13", + "linkTo": "" + } + ] + ] + }, + { + "folio": "1v", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "1–2", + "measure": "14–16", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M 37", + "itemLinkTo": { + "complexId": "m37", + "sheetId": "M_37_TF1" + }, + "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M 37)", + "folios": [ + { + "folio": "1v", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "4–5", + "measure": "1–7", + "linkTo": "" + } + ], + [ + { + "system": "7–8", + "measure": "8–15", + "linkTo": "" + } + ], + [ + { + "system": "10–11", + "measure": "16–21", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M 38", + "itemLinkTo": { + "complexId": "m38", + "sheetId": "M_38_TF1" + }, + "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M 38)", + "folios": [ + { + "folio": "1v", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "13–14", + "measure": "1–6", + "linkTo": "" + } + ], + [ + { + "system": "15–16", + "measure": "7–12", + "linkTo": "" + } + ], + [ + { + "system": "17–18", + "measure": "13–20", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M 39", + "itemLinkTo": {}, + "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M 39: Textfassung 1→2)", + "folios": [ + { + "folio": "2r", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "1–2", + "measure": "1–3", + "linkTo": "" + } + ], + [ + { + "system": "4–5", + "measure": "4–7", + "linkTo": "" + } + ], + [ + { + "system": "7–8", + "measure": "8–12 → T. 8, {9–12}", + "linkTo": "" + } + ], + [ + { + "system": "10–11", + "measure": "13–16 → T. {13–14}, 13–14", + "linkTo": "" + } + ], + [ + { + "system": "13–14", + "measure": "17–19 → T. 15–17", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M 39 Sk2", + "itemLinkTo": {}, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 39: Textfassung 2)", + "folios": [ + { + "folio": "2r", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "16a–17a (Bleistift)", + "measure": "9–10", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M 39 Sk3", + "itemLinkTo": {}, + "itemDescription": "(Skizze zu Studienkomposition für Klavier M 39: Textfassung 2)", + "folios": [ + { + "folio": "2r", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "13b–14b (Bleistift)", + "measure": "16–17(1–2/4)", + "linkTo": "" + } + ], + [ + { + "system": "16b–17b (Bleistift)", + "measure": "17(3–4/4)–19", + "linkTo": "" + } + ] + ] + } + ] + }, + { + "item": "M 41", + "itemLinkTo": {}, + "itemDescription": "(Tintenniederschrift von Studienkomposition für Klavier M 41)", + "folios": [ + { + "folio": "2v", + "folioLinkTo": "", + "folioDescription": "", + "systemGroups": [ + [ + { + "system": "1–2", + "measure": "1–6", + "linkTo": "" + } + ], + [ + { + "system": "4–5", + "measure": "7–12", + "linkTo": "" + } + ], + [ + { + "system": "7–8", + "measure": "13–18", + "linkTo": "" + } + ], + [ + { + "system": "10–11", + "measure": "19–25", + "linkTo": "" + } + ], + [ + { + "system": "13–14", + "measure": "26–30", + "linkTo": "" + } + ], + [ + { + "system": "16–17", + "measure": "31", + "linkTo": "" + } + ] + ] + } + ] + } + ] + } + } + ] +} diff --git a/src/assets/data/edition/series/2/section/2a/m38/source-evaluation.json b/src/assets/data/edition/series/2/section/2a/m38/source-evaluation.json new file mode 100644 index 000000000..9b0086498 --- /dev/null +++ b/src/assets/data/edition/series/2/section/2a/m38/source-evaluation.json @@ -0,0 +1,8 @@ +{ + "sources": [ + { + "id": "m38", + "content": [] + } + ] +} diff --git a/src/assets/data/edition/series/2/section/2a/m38/source-list.json b/src/assets/data/edition/series/2/section/2a/m38/source-list.json index 422ff9665..42c357f2f 100644 --- a/src/assets/data/edition/series/2/section/2a/m38/source-list.json +++ b/src/assets/data/edition/series/2/section/2a/m38/source-list.json @@ -3,7 +3,7 @@ { "siglum": "A", "siglumAddendum": "", - "type": "Skizzen zu
    Studienkomposition für Klavier M 38.
    Enthält auch Skizzen zu Studienkomposition für Klavier M 34–37, M 39 Textfassung 1→2 und M* 404.", + "type": "Skizzen zu
    Studienkomposition für Klavier M 38.
    Enthält auch Skizzen zu Studienkomposition für Klavier M 34, M 35/42, M 36–37, M 39 und M* 404.", "location": "CH-Bps, Sammlung Anton Webern.", "hasDescription": true, "linkTo": "source_A" @@ -11,7 +11,7 @@ { "siglum": "B", "siglumAddendum": "", - "type": "Tintenniederschrift von
    Studienkomposition für Klavier M 38.
    Enthält auch Tintenniederschrift von Studienkomposition für Klavier M 34–37, M 39 Textfassung 1→2 und M 41 sowie Skizzen zu Studienkomposition für Klavier M 35 und M 39 Textfassung 2.", + "type": "Tintenniederschrift von
    Studienkomposition für Klavier M 38.
    Enthält auch Tintenniederschrift von Studienkomposition für Klavier M 34, M 35/42, M 36–37, M 39 Textfassung 1→2 und M 41 sowie Skizzen zu Studienkomposition für Klavier M 35/42 und M 39 Textfassung 2.", "location": "CH-Bps, Sammlung Anton Webern.", "hasDescription": true, "linkTo": "source_B" diff --git a/src/assets/data/edition/series/2/section/2a/m38/svg-sheets.json b/src/assets/data/edition/series/2/section/2a/m38/svg-sheets.json new file mode 100644 index 000000000..95b4201b7 --- /dev/null +++ b/src/assets/data/edition/series/2/section/2a/m38/svg-sheets.json @@ -0,0 +1,81 @@ +{ + "sheets": { + "workEditions": [], + "textEditions": [ + { + "id": "M_38_TF1", + "label": "M 38 einzige Textfassung", + "content": [ + { + "svg": "assets/img/edition/series/2/section/2a/m38/M38_Textfassung1-1von1-final.svg", + "image": "", + "partial": "", + "convolute": "B" + } + ] + } + ], + "sketchEditions": [ + { + "id": "M_38_Sk1", + "label": "M 38 Sk1", + "content": [ + { + "svg": "assets/img/edition/series/2/section/2a/m38/M38_Sk1-1von1-final.svg", + "image": "", + "partial": "", + "convolute": "A" + } + ] + }, + { + "id": "M_38_Sk2", + "label": "M 38 Sk2", + "content": [ + { + "svg": "assets/img/edition/series/2/section/2a/m38/M38_Sk2-1von1-final.svg", + "image": "", + "partial": "", + "convolute": "A" + } + ] + }, + { + "id": "M_38_Sk3", + "label": "M 38 Sk3", + "content": [ + { + "svg": "assets/img/edition/series/2/section/2a/m38/M38_Sk3-1von5-final.svg", + "image": "", + "partial": "a", + "convolute": "A" + }, + { + "svg": "assets/img/edition/series/2/section/2a/m38/M38_Sk3-2von5-final.svg", + "image": "", + "partial": "b", + "convolute": "A" + }, + { + "svg": "assets/img/edition/series/2/section/2a/m38/M38_Sk3-3von5-final.svg", + "image": "", + "partial": "c", + "convolute": "A" + }, + { + "svg": "assets/img/edition/series/2/section/2a/m38/M38_Sk3-4von5-final.svg", + "image": "", + "partial": "d", + "convolute": "A" + }, + { + "svg": "assets/img/edition/series/2/section/2a/m38/M38_Sk3-5von5-final.svg", + "image": "", + "partial": "e", + "convolute": "A" + } + ] + } + ] + } +} diff --git a/src/assets/data/edition/series/2/section/2a/m38/textcritics.json b/src/assets/data/edition/series/2/section/2a/m38/textcritics.json new file mode 100644 index 000000000..c109aadf5 --- /dev/null +++ b/src/assets/data/edition/series/2/section/2a/m38/textcritics.json @@ -0,0 +1,286 @@ +{ + "textcritics": [ + { + "id": "M_38_TF1", + "label": "M 38 einzige Textfassung", + "description": [ + "Für die Textedition der Studienkomposition für Klavier M 38 ist B relevante Quelle. A enthält Skizzen.
    B weist zwei unterscheidbare Korrekturschichten auf: Korrekturen 1 mit Tinte sowie die später entstandenen Korrekturen 2 mit Bleistift. Der Zustand vor Korrekturen 1 ist nicht immer zu entziffern.
    Hauptquelle für die Textedition der Studienkomposition für Klavier M 38 ist B nach Korrekturen 1." + ], + "comments": [ + { + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g4083", + "measure": "12", + "system": "Klav. u.", + "position": "2/4", + "comment": "Unterstimmenschicht: B2/E korrigiert zu E1/E mit Blick auf harmonischen Kontext." + }, + { + "svgGroupId": "g4087", + "measure": "17", + "system": "Klav. o.", + "position": "6/8", + "comment": "a1/cis2 ergänzt mit Blick auf Ligaturbögen von 5/8 zu 6/8." + }, + { + "svgGroupId": "g4091", + "measure": "19", + "system": "Klav. u.", + "position": "1. Note", + "comment": "Viertelnote C korrigiert zu Halbe Note mit Blick auf metrischen Kontext (vgl. Korrekturen mit Tinte)." + }, + { + "svgGroupId": "g4095", + "measure": "19", + "system": "Klav. o.", + "position": "5/8", + "comment": "f korrigiert zu a mit Blick auf Stimmführung und analog T. 7." + } + ] + } + ] + }, + { + "id": "M_38_Sk1", + "label": "M 38 Sk1", + "description": [ + "Sk1 enthält einen rhythmischen Entwurf des Melodieverlaufs der Studienkomposition für Klavier M 38." + ], + "comments": [ + { + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g989", + "measure": "2", + "system": "nach 18", + "position": "1. Note", + "comment": "Punktierte Halbe Note überschreibt Viertelnote." + }, + { + "svgGroupId": "g1030", + "measure": "6", + "system": "nach 18", + "position": "1. Note", + "comment": "Halbe Note überschreibt Viertelnote." + }, + { + "svgGroupId": "g1037", + "measure": "10", + "system": "nach 18", + "position": "1. Note", + "comment": "Achtelnote überschreibt punktierte Halbe Note." + }, + { + "svgGroupId": "g1045", + "measure": "10", + "system": "nach 18", + "position": "2/8–6/8", + "comment": "Überschreibungen nicht eindeutig zu entziffern. Taktstrich am Ende zudem möglicherweise gestrichen." + }, + { + "svgGroupId": "g1063", + "measure": "11", + "system": "nach 18", + "position": "", + "comment": "sic. Rhythmisch-metrische Aufteilung am Ende von Sk1 nicht ganz klar." + } + ] + } + ] + }, + { + "id": "M_38_Sk2", + "label": "M 38 Sk2", + "description": [ + "Sk2 enthält eine flüchtige, teils nur rhythmisch formulierte Darstellung des Zwischenthemas der Studienkomposition für Klavier M 38." + ], + "comments": [ + { + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g950", + "measure": "11", + "system": "18", + "position": "1.–2. Note", + "comment": "Achtelnote–Viertelnote überschreibt zusammengebalkte Achtelnoten." + } + ] + } + ], + "linkBoxes": [ + { + "svgGroupId": "g1", + "linkTo": { + "complexId": "m37", + "sheetId": "M_37_Sk1" + } + }, + { + "svgGroupId": "g2", + "linkTo": { + "complexId": "m37", + "sheetId": "M_37_Sk2" + } + } + ] + }, + { + "id": "M_38_Sk3", + "label": "M 38 Sk3", + "description": [ + "Sk3 ist die Verlaufsskizze zu der Studienkomposition für Klavier M 38." + ], + "comments": [ + { + "blockHeader": "", + "blockComments": [ + { + "svgGroupId": "g985", + "measure": "2", + "system": "15", + "position": "1. Note", + "comment": "Halbe Note überschreibt Viertelnote a1." + }, + { + "svgGroupId": "g1056", + "measure": "3", + "system": "15", + "position": "3/4", + "comment": "f2 überschreibt g2." + }, + { + "svgGroupId": "g1062", + "measure": "4", + "system": "15", + "position": "3/4", + "comment": "g2 überschreibt a2." + }, + { + "svgGroupId": "g985", + "measure": "2", + "system": "15", + "position": "1. Note", + "comment": "Halbe Note überschreibt Viertelnote a1." + }, + { + "svgGroupId": "g955", + "measure": "5", + "system": "14", + "position": "1. Note", + "comment": "G überschreibt F." + }, + { + "svgGroupId": "g1110", + "measure": "7", + "system": "17", + "position": "1. Note", + "comment": "Notenkopf c2 gestrichen." + }, + { + "svgGroupId": "g1104", + "measure": "7", + "system": "17", + "position": "2–6/8", + "comment": "c2–b1–g1–f1–e1 überschreibt d2–c2–a1–g1–f1." + }, + { + "svgGroupId": "g1268", + "measure": "9", + "system": "2", + "position": "2/4", + "comment": "Viertelnote C1/C gestrichen und ersetzt durch Es/Es." + }, + { + "svgGroupId": "g1276", + "measure": "9", + "system": "2", + "position": "3/4", + "comment": "D überschreibt H1." + }, + { + "svgGroupId": "g1306", + "measure": "10", + "system": "2", + "position": "1/4", + "comment": "{{ref.getGlyph('[a]')}}E überschreibt F." + }, + { + "svgGroupId": "g1310", + "measure": "10", + "system": "1", + "position": "2/8", + "comment": "{{ref.getGlyph('[a]')}} zu g2 überschreibt {{ref.getGlyph('[#]')}}." + }, + { + "svgGroupId": "g1323", + "measure": "10", + "system": "2", + "position": "2/4", + "comment": "G1/E überschreibt E/e." + }, + { + "svgGroupId": "g1412", + "measure": "10", + "system": "2", + "position": "3/4", + "comment": "Gis/Gis1 überschreibt E/e." + }, + { + "svgGroupId": "g1420", + "measure": "{11A}", + "system": "1", + "position": "5/8", + "comment": "c1 überschreibt b." + }, + { + "svgGroupId": "g1426", + "measure": "{11A} bis
    {12A}", + "system": "1–2", + "position": "1/8
    2/8", + "comment": "Noten gestrichen." + }, + { + "svgGroupId": "g1443", + "measure": "12B", + "system": "1", + "position": "2/4", + "comment": "Notenkopf {{ref.getGlyph('[b]')}}as gestrichen." + }, + { + "svgGroupId": "g998", + "measure": "14", + "system": "4", + "position": "1/4", + "comment": "Unterstimmenschicht: Viertelnote überschreibt Halbe Note." + }, + { + "svgGroupId": "g1033", + "measure": "15", + "system": "4", + "position": "1. Note", + "comment": "Halbe Note f1/d2/f2 überschreibt Viertelnote f1/b1/f2." + }, + { + "svgGroupId": "g1039", + "measure": "15", + "system": "5", + "position": "2/4", + "comment": "d überschreibt c." + }, + { + "svgGroupId": "g1045", + "measure": "16", + "system": "5", + "position": "1/4", + "comment": "Viertelnote überschreibt Halbe Note." + } + ] + } + ] + } + ] +} diff --git a/src/assets/img/edition/series/2/section/2a/m35_42/M35_42_Sk1-2von6-final.svg b/src/assets/img/edition/series/2/section/2a/m35_42/M35_42_Sk1-2von6-final.svg index c666e1156..7e1d6b738 100644 --- a/src/assets/img/edition/series/2/section/2a/m35_42/M35_42_Sk1-2von6-final.svg +++ b/src/assets/img/edition/series/2/section/2a/m35_42/M35_42_Sk1-2von6-final.svg @@ -414,12 +414,8 @@ - - - - - - + + @@ -434,6 +430,6 @@ - + diff --git a/src/assets/img/edition/series/2/section/2a/m36/M36_Sk1-1von5-final.svg b/src/assets/img/edition/series/2/section/2a/m36/M36_Sk1-1von5-final.svg new file mode 100644 index 000000000..6220a2182 --- /dev/null +++ b/src/assets/img/edition/series/2/section/2a/m36/M36_Sk1-1von5-final.svg @@ -0,0 +1,445 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/img/edition/series/2/section/2a/m36/M36_Sk1-2von5-final.svg b/src/assets/img/edition/series/2/section/2a/m36/M36_Sk1-2von5-final.svg new file mode 100644 index 000000000..fe846815a --- /dev/null +++ b/src/assets/img/edition/series/2/section/2a/m36/M36_Sk1-2von5-final.svg @@ -0,0 +1,277 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/img/edition/series/2/section/2a/m36/M36_Sk1-3von5-final.svg b/src/assets/img/edition/series/2/section/2a/m36/M36_Sk1-3von5-final.svg new file mode 100644 index 000000000..d85e93295 --- /dev/null +++ b/src/assets/img/edition/series/2/section/2a/m36/M36_Sk1-3von5-final.svg @@ -0,0 +1,410 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/img/edition/series/2/section/2a/m36/M36_Sk1-4von5-final.svg b/src/assets/img/edition/series/2/section/2a/m36/M36_Sk1-4von5-final.svg new file mode 100644 index 000000000..ac7716c3c --- /dev/null +++ b/src/assets/img/edition/series/2/section/2a/m36/M36_Sk1-4von5-final.svg @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/img/edition/series/2/section/2a/m36/M36_Sk1-5von5-final.svg b/src/assets/img/edition/series/2/section/2a/m36/M36_Sk1-5von5-final.svg new file mode 100644 index 000000000..75883920f --- /dev/null +++ b/src/assets/img/edition/series/2/section/2a/m36/M36_Sk1-5von5-final.svg @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/img/edition/series/2/section/2a/m36/M36_Textfassung1-1von1-final.svg b/src/assets/img/edition/series/2/section/2a/m36/M36_Textfassung1-1von1-final.svg new file mode 100644 index 000000000..06f015ca0 --- /dev/null +++ b/src/assets/img/edition/series/2/section/2a/m36/M36_Textfassung1-1von1-final.svg @@ -0,0 +1,1093 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/img/edition/series/2/section/2a/m37/M37_Sk1-1von1-final.svg b/src/assets/img/edition/series/2/section/2a/m37/M37_Sk1-1von1-final.svg index 06433281b..f2a46a0fb 100644 --- a/src/assets/img/edition/series/2/section/2a/m37/M37_Sk1-1von1-final.svg +++ b/src/assets/img/edition/series/2/section/2a/m37/M37_Sk1-1von1-final.svg @@ -101,7 +101,7 @@ - + diff --git a/src/assets/img/edition/series/2/section/2a/m37/M37_Sk2-1von1-final.svg b/src/assets/img/edition/series/2/section/2a/m37/M37_Sk2-1von1-final.svg index 70401f395..c80dc51ae 100644 --- a/src/assets/img/edition/series/2/section/2a/m37/M37_Sk2-1von1-final.svg +++ b/src/assets/img/edition/series/2/section/2a/m37/M37_Sk2-1von1-final.svg @@ -131,7 +131,7 @@ - + diff --git a/src/assets/img/edition/series/2/section/2a/m38/M38_Sk1-1von1-final.svg b/src/assets/img/edition/series/2/section/2a/m38/M38_Sk1-1von1-final.svg new file mode 100644 index 000000000..44de021ac --- /dev/null +++ b/src/assets/img/edition/series/2/section/2a/m38/M38_Sk1-1von1-final.svg @@ -0,0 +1,347 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/img/edition/series/2/section/2a/m38/M38_Sk2-1von1-final.svg b/src/assets/img/edition/series/2/section/2a/m38/M38_Sk2-1von1-final.svg new file mode 100644 index 000000000..8091bfb68 --- /dev/null +++ b/src/assets/img/edition/series/2/section/2a/m38/M38_Sk2-1von1-final.svg @@ -0,0 +1,230 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/img/edition/series/2/section/2a/m38/M38_Sk3-1von5-final.svg b/src/assets/img/edition/series/2/section/2a/m38/M38_Sk3-1von5-final.svg new file mode 100644 index 000000000..4e9b99c36 --- /dev/null +++ b/src/assets/img/edition/series/2/section/2a/m38/M38_Sk3-1von5-final.svg @@ -0,0 +1,360 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/img/edition/series/2/section/2a/m38/M38_Sk3-2von5-final.svg b/src/assets/img/edition/series/2/section/2a/m38/M38_Sk3-2von5-final.svg new file mode 100644 index 000000000..e958b0c03 --- /dev/null +++ b/src/assets/img/edition/series/2/section/2a/m38/M38_Sk3-2von5-final.svg @@ -0,0 +1,273 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/img/edition/series/2/section/2a/m38/M38_Sk3-3von5-final.svg b/src/assets/img/edition/series/2/section/2a/m38/M38_Sk3-3von5-final.svg new file mode 100644 index 000000000..99da001fb --- /dev/null +++ b/src/assets/img/edition/series/2/section/2a/m38/M38_Sk3-3von5-final.svg @@ -0,0 +1,403 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/img/edition/series/2/section/2a/m38/M38_Sk3-4von5-final.svg b/src/assets/img/edition/series/2/section/2a/m38/M38_Sk3-4von5-final.svg new file mode 100644 index 000000000..b3c9d9187 --- /dev/null +++ b/src/assets/img/edition/series/2/section/2a/m38/M38_Sk3-4von5-final.svg @@ -0,0 +1,601 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/img/edition/series/2/section/2a/m38/M38_Sk3-5von5-final.svg b/src/assets/img/edition/series/2/section/2a/m38/M38_Sk3-5von5-final.svg new file mode 100644 index 000000000..89c629c0c --- /dev/null +++ b/src/assets/img/edition/series/2/section/2a/m38/M38_Sk3-5von5-final.svg @@ -0,0 +1,312 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/img/edition/series/2/section/2a/m38/M38_Textfassung1-1von1-final.svg b/src/assets/img/edition/series/2/section/2a/m38/M38_Textfassung1-1von1-final.svg new file mode 100644 index 000000000..663757eee --- /dev/null +++ b/src/assets/img/edition/series/2/section/2a/m38/M38_Textfassung1-1von1-final.svg @@ -0,0 +1,1796 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/themes/scss/main.scss b/src/assets/themes/scss/main.scss index f102004bf..af92230bd 100644 --- a/src/assets/themes/scss/main.scss +++ b/src/assets/themes/scss/main.scss @@ -407,6 +407,14 @@ span.facet-badge { text-overflow: ellipsis; } +.unicode { + font-size: 3em; + line-height: 12px; + position: relative; + vertical-align: bottom; + top: 7.5px; +} + /****** COLOURS ******/ .olivedrab { color: olivedrab; diff --git a/src/testing/mock-data/mockEditionData.ts b/src/testing/mock-data/mockEditionData.ts index 6691766bf..890d2d22b 100644 --- a/src/testing/mock-data/mockEditionData.ts +++ b/src/testing/mock-data/mockEditionData.ts @@ -1,5 +1,10 @@ /* eslint-disable @typescript-eslint/naming-convention */ +import { + EDITION_CATALOGUE_TYPE_CONSTANTS, + EDITION_ROUTE_CONSTANTS, +} from '@awg-views/edition-view/edition-route-constants'; + /** * Test helper data file: mockEditionData. * @@ -8,6 +13,92 @@ * Exposed to be called from tests. */ export const mockEditionData = { + /** + * Test helper data constant: mockEditionComplexesList. + * + * It provides a mocked editionComplexesList object. + */ + mockEditionComplexesList: { + OP3: { + titleStatement: { + title: 'Vier Lieder', + catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.OPUS, + catalogueNumber: '12', + }, + publicationStatement: { + series: EDITION_ROUTE_CONSTANTS.SERIES_1, + section: EDITION_ROUTE_CONSTANTS.SECTION_5, + }, + respStatement: { + editors: [ + { + name: 'Thomas Ahrend', + homepage: 'https://www.anton-webern.ch/index.php?id', + }, + ], + lastModified: '7. August 2024', + }, + complexId: { + route: '/op12', + short: 'op. 12', + full: 'Vier Lieder op. 12', + }, + baseRoute: '/edition/complex/op12/', + }, + OP25: { + titleStatement: { + title: 'Drei Lieder nach Gedichten von Hildegard Jone', + catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.OPUS, + catalogueNumber: '25', + }, + publicationStatement: { + series: EDITION_ROUTE_CONSTANTS.SERIES_1, + section: EDITION_ROUTE_CONSTANTS.SECTION_5, + }, + respStatement: { + editors: [ + { + name: 'Thomas Ahrend', + homepage: 'https://www.anton-webern.ch/index.php?id', + }, + ], + lastModified: '7. August 2024', + }, + complexId: { + route: '/op25', + short: 'op. 25', + full: 'Drei Lieder nach Gedichten von Hildegard Jone op. 25', + }, + baseRoute: '/edition/complex/op25/', + }, + M22: { + titleStatement: { + title: 'Studienkomposition für Klavier/Streichquartett', + catalogueType: EDITION_CATALOGUE_TYPE_CONSTANTS.MNR, + catalogueNumber: '22', + }, + publicationStatement: { + series: EDITION_ROUTE_CONSTANTS.SERIES_1, + section: EDITION_ROUTE_CONSTANTS.SECTION_5, + }, + respStatement: { + editors: [ + { + name: 'Michael Matter', + homepage: 'https://www.anton-webern.ch/index.php?id', + }, + ], + lastModified: '7. August 2024', + }, + complexId: { + route: '/m22', + short: 'M 22', + full: 'Studienkomposition für Klavier/Streichquartett M 22', + }, + baseRoute: '/edition/complex/m22/', + }, + }, + /** * Test helper data constant: mockFolioConvoluteData. * @@ -43,6 +134,36 @@ export const mockEditionData = { }, ], }, + { + complexId: 'op12', + sheetId: 'M_212_Sk3', + sigle: 'M 212 Sk3', + sigleAddendum: 'T. 3', + sectionPartition: 1, + sections: [ + { + position: 1, + startSystem: 5, + endSystem: 7, + relativeToSystem: 'above', + }, + ], + }, + { + complexId: 'op12', + sheetId: 'M_212_Sk2', + sigle: 'M 212 Sk2', + sigleAddendum: 'T. 2', + sectionPartition: 1, + sections: [ + { + position: 1, + startSystem: 5, + endSystem: 7, + relativeToSystem: 'below', + }, + ], + }, ], }, ], @@ -149,6 +270,32 @@ export const mockEditionData = { */ mockModalSnippet: 'OP12_SHEET_COMING_SOON', + /** + * Test helper data constant: mockPreface Data. + * + * It provides a mocked preface data object. + */ + mockPrefaceData: { + preface: [ + { + id: 'de', + content: [ + "Die AWG gliedert sich in drei Serien:", + "Sie werden nicht zu dem für den Druck typischen {{ref.getGlyph('[ped]')}}.-Zeichen vereinheitlicht.", + "Zugang zur AWG-Online-Edition: edition.anton-webern.ch", + ], + }, + { + id: 'en', + content: [ + "The AWG is divided into three series:", + "They are not unified to the {{ref.getGlyph('[ped]')}}. character typical for printing.", + "Access to the AWG online edition: edition.anton-webern.ch", + ], + }, + ], + }, + /** * Test helper data constant: mockRowTablesData. * @@ -1044,33 +1191,57 @@ export const mockEditionData = { rowtable: true, comments: [ { - svgGroupId: 'svg-group-1', - measure: '10', - system: '12', - position: '1. Note', - comment: 'Viertelnote überschreibt Halbe Note.', - }, - { - svgGroupId: 'svg-group-2', - measure: '10', - system: '12', - position: '2. Note', - comment: - "Die Skizzen in A enthalten datierte Verlaufsskizzen zu allen vier Liedern. Siehe Test SkXYZ T. [11] und Test Sk1.", - }, - { - svgGroupId: 'svg-group-3', - measure: '{13}', - system: '12', - position: '3. Note', - comment: '{{ref.getGlyph("[a]")}} überschreibt {{ref.getGlyph("[b]")}}.', + blockHeader: 'blockheader 1', + blockComments: [ + { + svgGroupId: 'svg-group-1', + measure: '10', + system: '12', + position: '1. Note', + comment: 'Viertelnote überschreibt Halbe Note.', + }, + { + svgGroupId: 'svg-group-2', + measure: '10', + system: '12', + position: '2. Note', + comment: + "Die Skizzen in A enthalten datierte Verlaufsskizzen zu allen vier Liedern. Siehe Test SkXYZ T. [11] und Test Sk1.", + }, + { + svgGroupId: 'svg-group-3', + measure: '{13}', + system: '12', + position: '3. Note', + comment: '{{ref.getGlyph("[a]")}} überschreibt {{ref.getGlyph("[b]")}}.', + }, + { + svgGroupId: 'svg-group-4', + measure: '[12]', + system: '13', + position: '', + comment: 'radierte, nicht entzifferbare Schicht.', + }, + ], }, { - svgGroupId: 'svg-group-4', - measure: '[12]', - system: '13', - position: '', - comment: 'radierte, nicht entzifferbare Schicht.', + blockHeader: 'blockheader 2', + blockComments: [ + { + svgGroupId: 'svg-group-5', + measure: '11', + system: '13', + position: '1. Note', + comment: 'Viertelnote überschreibt Halbe Note.', + }, + { + svgGroupId: 'svg-group-6', + measure: '11', + system: '13', + position: '2. Note', + comment: 'Halbe Note überschreibt Viertelnote.', + }, + ], }, ], linkBoxes: [], diff --git a/src/testing/mock-data/mockEditionOutline.ts b/src/testing/mock-data/mockEditionOutline.ts index 8b71303c6..2d22ba2ff 100644 --- a/src/testing/mock-data/mockEditionOutline.ts +++ b/src/testing/mock-data/mockEditionOutline.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/naming-convention */ -import { EDITION_COMPLEXES } from '@awg-app/views/edition-view/data'; -import { EDITION_ROUTE_CONSTANTS } from '@awg-app/views/edition-view/edition-route-constants'; +import { EDITION_ROUTE_CONSTANTS } from '@awg-views/edition-view/edition-route-constants'; +import { EditionComplexesService } from '@awg-views/edition-view/services'; /** * Test helper data file: mockEditionOutline. @@ -17,37 +17,37 @@ export const mockEditionOutline = [ sections: [ { section: EDITION_ROUTE_CONSTANTS.SECTION_1, - complexes: { opus: [], mnr: [] }, + complexTypes: { opus: [], mnr: [] }, disabled: true, }, { section: EDITION_ROUTE_CONSTANTS.SECTION_2, - complexes: { opus: [], mnr: [] }, + complexTypes: { opus: [], mnr: [] }, disabled: true, }, { section: EDITION_ROUTE_CONSTANTS.SECTION_3, - complexes: { opus: [], mnr: [] }, + complexTypes: { opus: [], mnr: [] }, disabled: true, }, { section: EDITION_ROUTE_CONSTANTS.SECTION_4, - complexes: { opus: [], mnr: [] }, + complexTypes: { opus: [], mnr: [] }, disabled: true, }, { section: EDITION_ROUTE_CONSTANTS.SECTION_5, - complexes: { + complexTypes: { opus: [ - { complex: EDITION_COMPLEXES.OP12, disabled: false }, - { complex: EDITION_COMPLEXES.OP23, disabled: false }, - { complex: EDITION_COMPLEXES.OP25, disabled: false }, + { complex: EditionComplexesService.getEditionComplexById('OP12'), disabled: false }, + { complex: EditionComplexesService.getEditionComplexById('OP23'), disabled: false }, + { complex: EditionComplexesService.getEditionComplexById('OP25'), disabled: false }, ], mnr: [ - { complex: EDITION_COMPLEXES.M212, disabled: false }, - { complex: EDITION_COMPLEXES.M213, disabled: false }, - { complex: EDITION_COMPLEXES.M216, disabled: false }, - { complex: EDITION_COMPLEXES.M217, disabled: false }, + { complex: EditionComplexesService.getEditionComplexById('M212'), disabled: false }, + { complex: EditionComplexesService.getEditionComplexById('M213'), disabled: false }, + { complex: EditionComplexesService.getEditionComplexById('M216'), disabled: false }, + { complex: EditionComplexesService.getEditionComplexById('M217'), disabled: false }, ], }, disabled: true, diff --git a/src/testing/svg-drawing-helper.ts b/src/testing/svg-drawing-helper.ts index 276f75404..8c0d20464 100644 --- a/src/testing/svg-drawing-helper.ts +++ b/src/testing/svg-drawing-helper.ts @@ -1,4 +1,4 @@ -import { D3Selection, EditionSvgLinkBox, EditionSvgOverlay } from '@awg-app/views/edition-view/models'; +import { D3Selection, EditionSvgLinkBox, EditionSvgOverlay } from '@awg-views/edition-view/models'; import * as D3_SELECTION from 'd3-selection'; diff --git a/yarn.lock b/yarn.lock index 21b53cd13..8205b533f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -22,13 +22,18 @@ __metadata: languageName: node linkType: hard -"@angular-devkit/architect@npm:0.1800.6": - version: 0.1800.6 - resolution: "@angular-devkit/architect@npm:0.1800.6" +"@angular-devkit/architect@npm:0.1802.0": + version: 0.1802.0 + resolution: "@angular-devkit/architect@npm:0.1802.0" dependencies: - "@angular-devkit/core": "npm:18.0.6" + "@angular-devkit/core": "npm:18.2.0" rxjs: "npm:7.8.1" - checksum: 10c0/d44716a1996ca76897cbb0642092445e7a19258d9ea3b6a44942377c0e11b048304f5655ffa51383de291c9e825f31cdf8cdd80bbf86831216cb041a6092d18d + dependenciesMeta: + esbuild: + built: true + puppeteer: + built: true + checksum: 10c0/f7705bd028874437b8009ac7189ef781f70a8d010efd709a287dd19c7d1ede9b792e225a031b6cdac6d55005b78d7b41540573561e65900df710b2bf45656c34 languageName: node linkType: hard @@ -42,74 +47,72 @@ __metadata: languageName: node linkType: hard -"@angular-devkit/build-angular@npm:^18.0.6": - version: 18.0.6 - resolution: "@angular-devkit/build-angular@npm:18.0.6" +"@angular-devkit/build-angular@npm:^18.2.0": + version: 18.2.0 + resolution: "@angular-devkit/build-angular@npm:18.2.0" dependencies: "@ampproject/remapping": "npm:2.3.0" - "@angular-devkit/architect": "npm:0.1800.6" - "@angular-devkit/build-webpack": "npm:0.1800.6" - "@angular-devkit/core": "npm:18.0.6" - "@angular/build": "npm:18.0.6" - "@babel/core": "npm:7.24.5" - "@babel/generator": "npm:7.24.5" - "@babel/helper-annotate-as-pure": "npm:7.22.5" - "@babel/helper-split-export-declaration": "npm:7.24.5" - "@babel/plugin-transform-async-generator-functions": "npm:7.24.3" - "@babel/plugin-transform-async-to-generator": "npm:7.24.1" - "@babel/plugin-transform-runtime": "npm:7.24.3" - "@babel/preset-env": "npm:7.24.5" - "@babel/runtime": "npm:7.24.5" - "@discoveryjs/json-ext": "npm:0.5.7" - "@ngtools/webpack": "npm:18.0.6" + "@angular-devkit/architect": "npm:0.1802.0" + "@angular-devkit/build-webpack": "npm:0.1802.0" + "@angular-devkit/core": "npm:18.2.0" + "@angular/build": "npm:18.2.0" + "@babel/core": "npm:7.25.2" + "@babel/generator": "npm:7.25.0" + "@babel/helper-annotate-as-pure": "npm:7.24.7" + "@babel/helper-split-export-declaration": "npm:7.24.7" + "@babel/plugin-transform-async-generator-functions": "npm:7.25.0" + "@babel/plugin-transform-async-to-generator": "npm:7.24.7" + "@babel/plugin-transform-runtime": "npm:7.24.7" + "@babel/preset-env": "npm:7.25.3" + "@babel/runtime": "npm:7.25.0" + "@discoveryjs/json-ext": "npm:0.6.1" + "@ngtools/webpack": "npm:18.2.0" "@vitejs/plugin-basic-ssl": "npm:1.1.0" ansi-colors: "npm:4.1.3" - autoprefixer: "npm:10.4.19" + autoprefixer: "npm:10.4.20" babel-loader: "npm:9.1.3" browserslist: "npm:^4.21.5" - copy-webpack-plugin: "npm:11.0.0" - critters: "npm:0.0.22" - css-loader: "npm:7.1.1" - esbuild: "npm:0.21.3" - esbuild-wasm: "npm:0.21.3" + copy-webpack-plugin: "npm:12.0.2" + critters: "npm:0.0.24" + css-loader: "npm:7.1.2" + esbuild: "npm:0.23.0" + esbuild-wasm: "npm:0.23.0" fast-glob: "npm:3.3.2" http-proxy-middleware: "npm:3.0.0" - https-proxy-agent: "npm:7.0.4" - inquirer: "npm:9.2.22" - istanbul-lib-instrument: "npm:6.0.2" - jsonc-parser: "npm:3.2.1" + https-proxy-agent: "npm:7.0.5" + istanbul-lib-instrument: "npm:6.0.3" + jsonc-parser: "npm:3.3.1" karma-source-map-support: "npm:1.4.0" less: "npm:4.2.0" less-loader: "npm:12.2.0" license-webpack-plugin: "npm:4.0.2" - loader-utils: "npm:3.2.1" - magic-string: "npm:0.30.10" + loader-utils: "npm:3.3.1" + magic-string: "npm:0.30.11" mini-css-extract-plugin: "npm:2.9.0" mrmime: "npm:2.0.0" - open: "npm:8.4.2" + open: "npm:10.1.0" ora: "npm:5.4.1" parse5-html-rewriting-stream: "npm:7.0.0" picomatch: "npm:4.0.2" - piscina: "npm:4.5.0" - postcss: "npm:8.4.38" + piscina: "npm:4.6.1" + postcss: "npm:8.4.41" postcss-loader: "npm:8.1.1" resolve-url-loader: "npm:5.0.0" rxjs: "npm:7.8.1" - sass: "npm:1.77.2" - sass-loader: "npm:14.2.1" - semver: "npm:7.6.2" + sass: "npm:1.77.8" + sass-loader: "npm:16.0.0" + semver: "npm:7.6.3" source-map-loader: "npm:5.0.0" source-map-support: "npm:0.5.21" - terser: "npm:5.31.0" + terser: "npm:5.31.6" tree-kill: "npm:1.2.2" - tslib: "npm:2.6.2" - undici: "npm:6.18.0" - vite: "npm:5.2.11" + tslib: "npm:2.6.3" + vite: "npm:5.4.0" watchpack: "npm:2.4.1" - webpack: "npm:5.91.0" - webpack-dev-middleware: "npm:7.2.1" + webpack: "npm:5.93.0" + webpack-dev-middleware: "npm:7.3.0" webpack-dev-server: "npm:5.0.4" - webpack-merge: "npm:5.10.0" + webpack-merge: "npm:6.0.1" webpack-subresource-integrity: "npm:5.1.0" peerDependencies: "@angular/compiler-cli": ^18.0.0 @@ -124,10 +127,13 @@ __metadata: ng-packagr: ^18.0.0 protractor: ^7.0.0 tailwindcss: ^2.0.0 || ^3.0.0 - typescript: ">=5.4 <5.5" + typescript: ">=5.4 <5.6" dependenciesMeta: esbuild: + built: true optional: true + puppeteer: + built: true peerDependenciesMeta: "@angular/localize": optional: true @@ -151,20 +157,25 @@ __metadata: optional: true tailwindcss: optional: true - checksum: 10c0/2fc11c01807c9bf63957cd6ffac408283097b7a8a13787f4ede55378138ee4f507b4513ddf77b4ed76b6b09381331feb0a26708786526478109b533feae049ec + checksum: 10c0/9cd89b392417ae8ba284035f9bb2c27f47c3ff76edaac3c9f2586cf25902f6fa4f64484dbeae37f21f31dd1beeca3d43901901acdf0f98586a3fc36163b6ff52 languageName: node linkType: hard -"@angular-devkit/build-webpack@npm:0.1800.6": - version: 0.1800.6 - resolution: "@angular-devkit/build-webpack@npm:0.1800.6" +"@angular-devkit/build-webpack@npm:0.1802.0": + version: 0.1802.0 + resolution: "@angular-devkit/build-webpack@npm:0.1802.0" dependencies: - "@angular-devkit/architect": "npm:0.1800.6" + "@angular-devkit/architect": "npm:0.1802.0" rxjs: "npm:7.8.1" peerDependencies: webpack: ^5.30.0 webpack-dev-server: ^5.0.2 - checksum: 10c0/648fb42f74feb2c88cd16e65c9c4eb3f6142c6ad833dca66af0571beefa7cf5465e8f5454d2b29eeac6ad98c8bd9d3cdeab1c6d48eabb73633fac872b41198b7 + dependenciesMeta: + esbuild: + built: true + puppeteer: + built: true + checksum: 10c0/7d0873483b83e24c4ad99dd0f1904dd99e37fee286328d4a391bcef384d454c0532f9d50f71bdb128fcb35be35fab826060184bb623dbbaab2d319c1e3d5576c languageName: node linkType: hard @@ -206,22 +217,27 @@ __metadata: languageName: node linkType: hard -"@angular-devkit/core@npm:18.0.6": - version: 18.0.6 - resolution: "@angular-devkit/core@npm:18.0.6" +"@angular-devkit/core@npm:18.2.0": + version: 18.2.0 + resolution: "@angular-devkit/core@npm:18.2.0" dependencies: - ajv: "npm:8.13.0" + ajv: "npm:8.17.1" ajv-formats: "npm:3.0.1" - jsonc-parser: "npm:3.2.1" + jsonc-parser: "npm:3.3.1" picomatch: "npm:4.0.2" rxjs: "npm:7.8.1" source-map: "npm:0.7.4" peerDependencies: chokidar: ^3.5.2 + dependenciesMeta: + esbuild: + built: true + puppeteer: + built: true peerDependenciesMeta: chokidar: optional: true - checksum: 10c0/e8697b8af56cf4a0b344edf82d21d1824aad9cf705fa536f7c3d1e4c11c98a7390af8e15add248fc31bb708b186dba52a0246612a5b059f8bf06d7982ff8eed9 + checksum: 10c0/b18bdf7cb4ec3dd37d402558d50f07577d83983591912905efadcb050816bd53253cda4c0392ecacbbcd23dff39cecdb6f0b145c02e9c53e11f2896ef0ff6400 languageName: node linkType: hard @@ -238,16 +254,21 @@ __metadata: languageName: node linkType: hard -"@angular-devkit/schematics@npm:18.0.6": - version: 18.0.6 - resolution: "@angular-devkit/schematics@npm:18.0.6" +"@angular-devkit/schematics@npm:18.2.0": + version: 18.2.0 + resolution: "@angular-devkit/schematics@npm:18.2.0" dependencies: - "@angular-devkit/core": "npm:18.0.6" - jsonc-parser: "npm:3.2.1" - magic-string: "npm:0.30.10" + "@angular-devkit/core": "npm:18.2.0" + jsonc-parser: "npm:3.3.1" + magic-string: "npm:0.30.11" ora: "npm:5.4.1" rxjs: "npm:7.8.1" - checksum: 10c0/bc28e8d1e6bc6f576d6573f37bdb720b983c10fa55e85f03b0a3eced5554f72c0d653992ac487db9fcef75b186dc1df1cfc9e5fdd0ba47a9e940d539602d3ae8 + dependenciesMeta: + esbuild: + built: true + puppeteer: + built: true + checksum: 10c0/b091907564f586d8dcea979b3aebb02bdbea45139b68249c2176d1c4945360ddb7e2cb7ea150a40186c57657b1527f797ac09afcc450f212322208c48d31cfc1 languageName: node linkType: hard @@ -264,139 +285,134 @@ __metadata: languageName: node linkType: hard -"@angular-eslint/builder@npm:^18.1.0": - version: 18.1.0 - resolution: "@angular-eslint/builder@npm:18.1.0" - dependencies: - "@nx/devkit": "npm:^19.0.6" - nx: "npm:^19.0.6" +"@angular-eslint/builder@npm:^18.3.0": + version: 18.3.0 + resolution: "@angular-eslint/builder@npm:18.3.0" peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: "*" - checksum: 10c0/e23ccbf29bf4d57ca2afa933cdddde7031c82e1383c37e7fba739725816696c5e9ef996284d6b75cc2a053d09ea0d6bb4a398580adf8a10820f9cf9e1a87ef33 + checksum: 10c0/03aeea6eeccca6dbaccf5ba2b2014bf53d8b2b2af6a5df44306654d408fc97b621ba61fa0b862411187107aae1f63bae04a7dae13a35af46a653ccb043463f29 languageName: node linkType: hard -"@angular-eslint/bundled-angular-compiler@npm:18.1.0": - version: 18.1.0 - resolution: "@angular-eslint/bundled-angular-compiler@npm:18.1.0" - checksum: 10c0/0ceffce34a1940a55ffced811c3937c799f12f787c092a9d69b9656a7ea8ce7f533416ea73b9dad840547eb8d11d0d4e742d3504e61d8e459fbe426af99bd9b8 +"@angular-eslint/bundled-angular-compiler@npm:18.3.0": + version: 18.3.0 + resolution: "@angular-eslint/bundled-angular-compiler@npm:18.3.0" + checksum: 10c0/06bb1acad2e8ac7cbed781c7b5c026bc746a2d6a471c9367ad929d29174eefdaab2914ace5f597b11da6ae971a42dc5f50efd2a30d026cc4b14a3f3d86ac94bb languageName: node linkType: hard -"@angular-eslint/eslint-plugin-template@npm:18.1.0, @angular-eslint/eslint-plugin-template@npm:^18.1.0": - version: 18.1.0 - resolution: "@angular-eslint/eslint-plugin-template@npm:18.1.0" +"@angular-eslint/eslint-plugin-template@npm:18.3.0, @angular-eslint/eslint-plugin-template@npm:^18.3.0": + version: 18.3.0 + resolution: "@angular-eslint/eslint-plugin-template@npm:18.3.0" dependencies: - "@angular-eslint/bundled-angular-compiler": "npm:18.1.0" - "@angular-eslint/utils": "npm:18.1.0" + "@angular-eslint/bundled-angular-compiler": "npm:18.3.0" + "@angular-eslint/utils": "npm:18.3.0" aria-query: "npm:5.3.0" - axobject-query: "npm:4.0.0" + axobject-query: "npm:4.1.0" peerDependencies: - "@typescript-eslint/utils": ^7.11.0 || ^8.0.0-alpha.37 + "@typescript-eslint/utils": ^7.11.0 || ^8.0.0 eslint: ^8.57.0 || ^9.0.0 typescript: "*" - checksum: 10c0/a46457024ed254b7b7ee543fb5c3be5596be29a85a6e997175ea18f4efb7ecd7c9175b217197f2f7518a0e879be78f0b775f50c384840d878ce4647a9e80b5f5 + checksum: 10c0/cc43370c3b35bbe5f22eac01f0a81a9ac5877a2b25bcc248f93009f67b030e4eb9c3d6562658200475f00354aa8e672c1c172e23e198d32d288b31e48d24b0a4 languageName: node linkType: hard -"@angular-eslint/eslint-plugin@npm:18.1.0, @angular-eslint/eslint-plugin@npm:^18.1.0": - version: 18.1.0 - resolution: "@angular-eslint/eslint-plugin@npm:18.1.0" +"@angular-eslint/eslint-plugin@npm:18.3.0, @angular-eslint/eslint-plugin@npm:^18.3.0": + version: 18.3.0 + resolution: "@angular-eslint/eslint-plugin@npm:18.3.0" dependencies: - "@angular-eslint/bundled-angular-compiler": "npm:18.1.0" - "@angular-eslint/utils": "npm:18.1.0" + "@angular-eslint/bundled-angular-compiler": "npm:18.3.0" + "@angular-eslint/utils": "npm:18.3.0" peerDependencies: - "@typescript-eslint/utils": ^7.11.0 || ^8.0.0-alpha.37 + "@typescript-eslint/utils": ^7.11.0 || ^8.0.0 eslint: ^8.57.0 || ^9.0.0 typescript: "*" - checksum: 10c0/e943c84399a70e85706ae40f8cce77ad0720e7e70c6e7c752b94afd2ed85a5b36262b64c165672920e72a11a1ef45e09156120941aa5abce9cd8dc315933b75e + checksum: 10c0/8f671554076c312aae8e229adc53dce728a35c346a62e2891193ae5a5c15d0cb52b1c3025b5765e91c319dc936f31a060cc2f9b53c98c1ca94834b9b9e3b38fd languageName: node linkType: hard -"@angular-eslint/schematics@npm:^18.1.0": - version: 18.1.0 - resolution: "@angular-eslint/schematics@npm:18.1.0" +"@angular-eslint/schematics@npm:^18.3.0": + version: 18.3.0 + resolution: "@angular-eslint/schematics@npm:18.3.0" dependencies: - "@angular-eslint/eslint-plugin": "npm:18.1.0" - "@angular-eslint/eslint-plugin-template": "npm:18.1.0" - "@nx/devkit": "npm:^19.0.6" - ignore: "npm:5.3.1" - nx: "npm:^19.0.6" - semver: "npm:7.6.2" + "@angular-eslint/eslint-plugin": "npm:18.3.0" + "@angular-eslint/eslint-plugin-template": "npm:18.3.0" + ignore: "npm:5.3.2" + semver: "npm:7.6.3" strip-json-comments: "npm:3.1.1" peerDependencies: "@angular-devkit/core": ">= 18.0.0 < 19.0.0" "@angular-devkit/schematics": ">= 18.0.0 < 19.0.0" - checksum: 10c0/ccc2aa8a1849ec337143293495b0897c7cb399258060b4a4127838fa1835763b9a2b0a19dc6a430a189bf963087324eb416769b2289cd6263da27879141aa990 + checksum: 10c0/cc69110e6e4e2f6212449679fae3ef38a81fbd2792c050ba6a9ae06aadeb2c60e7f8568ffcf9a7b68236172c5f845681dcfaf8f04d9029b319167bde115051f8 languageName: node linkType: hard -"@angular-eslint/template-parser@npm:^18.1.0": - version: 18.1.0 - resolution: "@angular-eslint/template-parser@npm:18.1.0" +"@angular-eslint/template-parser@npm:^18.3.0": + version: 18.3.0 + resolution: "@angular-eslint/template-parser@npm:18.3.0" dependencies: - "@angular-eslint/bundled-angular-compiler": "npm:18.1.0" - eslint-scope: "npm:^8.0.0" + "@angular-eslint/bundled-angular-compiler": "npm:18.3.0" + eslint-scope: "npm:^8.0.2" peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: "*" - checksum: 10c0/52ecb0b7c9546623aa399aa0a65364f775c818c77f4e35a2a2e507ddba1428a61cea2b0b4dcbac76b00e2b671ba524752c38ebcddf15e097caf6963dfbb82e24 + checksum: 10c0/df124a1ee4f160847ee105f7c674976b2017071bb92d100b3c90de91565296f8c95c138e2382213cb666a9bbb90aaae4aafc10e58684dc59ec11f19d6b2d4d4c languageName: node linkType: hard -"@angular-eslint/utils@npm:18.1.0": - version: 18.1.0 - resolution: "@angular-eslint/utils@npm:18.1.0" +"@angular-eslint/utils@npm:18.3.0": + version: 18.3.0 + resolution: "@angular-eslint/utils@npm:18.3.0" dependencies: - "@angular-eslint/bundled-angular-compiler": "npm:18.1.0" + "@angular-eslint/bundled-angular-compiler": "npm:18.3.0" peerDependencies: - "@typescript-eslint/utils": ^7.11.0 || ^8.0.0-alpha.37 + "@typescript-eslint/utils": ^7.11.0 || ^8.0.0 eslint: ^8.57.0 || ^9.0.0 typescript: "*" - checksum: 10c0/81c7f29bcda7e93bf97f1514aad7ed6583c0a5c093d67e17df491d9cfd2387b21269400d57505ac1b4dc617b6007f655333d1ae98ef2aab6d20fe156db977b2a + checksum: 10c0/c3e0e1d580af6462f306703f1016c15ff57399315bba8425355d531cb42a215b547a02699e2c2d68d01011d9a7a64c0d4d20bec9c36ff195fbc87fdf5af346be languageName: node linkType: hard -"@angular/animations@npm:^18.0.5": - version: 18.0.5 - resolution: "@angular/animations@npm:18.0.5" +"@angular/animations@npm:^18.2.0": + version: 18.2.0 + resolution: "@angular/animations@npm:18.2.0" dependencies: tslib: "npm:^2.3.0" peerDependencies: - "@angular/core": 18.0.5 - checksum: 10c0/a65642c24bbc43e01d6942e338f9f325e9c5e44c948bfc140a4c91cc88a22205fc01da0e8a5d3f9fec2ecaa1e428f76e8281a4a268533e0b4dbcdf2627f992ad + "@angular/core": 18.2.0 + checksum: 10c0/8ad61102c4862a8e78a6d373f4f8c944a75268767f09050a086cd0e05f06a5e8adb99388b7fbc44923f4cc28bd13445ebb3098f60c3a3addfc53d4a70102c99a languageName: node linkType: hard -"@angular/build@npm:18.0.6": - version: 18.0.6 - resolution: "@angular/build@npm:18.0.6" +"@angular/build@npm:18.2.0": + version: 18.2.0 + resolution: "@angular/build@npm:18.2.0" dependencies: "@ampproject/remapping": "npm:2.3.0" - "@angular-devkit/architect": "npm:0.1800.6" - "@babel/core": "npm:7.24.5" - "@babel/helper-annotate-as-pure": "npm:7.22.5" - "@babel/helper-split-export-declaration": "npm:7.24.5" + "@angular-devkit/architect": "npm:0.1802.0" + "@babel/core": "npm:7.25.2" + "@babel/helper-annotate-as-pure": "npm:7.24.7" + "@babel/helper-split-export-declaration": "npm:7.24.7" + "@babel/plugin-syntax-import-attributes": "npm:7.24.7" + "@inquirer/confirm": "npm:3.1.22" "@vitejs/plugin-basic-ssl": "npm:1.1.0" - ansi-colors: "npm:4.1.3" browserslist: "npm:^4.23.0" - critters: "npm:0.0.22" - esbuild: "npm:0.21.3" + critters: "npm:0.0.24" + esbuild: "npm:0.23.0" fast-glob: "npm:3.3.2" - https-proxy-agent: "npm:7.0.4" - inquirer: "npm:9.2.22" - lmdb: "npm:3.0.8" - magic-string: "npm:0.30.10" + https-proxy-agent: "npm:7.0.5" + listr2: "npm:8.2.4" + lmdb: "npm:3.0.13" + magic-string: "npm:0.30.11" mrmime: "npm:2.0.0" - ora: "npm:5.4.1" parse5-html-rewriting-stream: "npm:7.0.0" picomatch: "npm:4.0.2" - piscina: "npm:4.5.0" - sass: "npm:1.77.2" - semver: "npm:7.6.2" - undici: "npm:6.18.0" - vite: "npm:5.2.11" + piscina: "npm:4.6.1" + rollup: "npm:4.20.0" + sass: "npm:1.77.8" + semver: "npm:7.6.3" + vite: "npm:5.4.0" watchpack: "npm:2.4.1" peerDependencies: "@angular/compiler-cli": ^18.0.0 @@ -406,7 +422,12 @@ __metadata: less: ^4.2.0 postcss: ^8.4.0 tailwindcss: ^2.0.0 || ^3.0.0 - typescript: ">=5.4 <5.5" + typescript: ">=5.4 <5.6" + dependenciesMeta: + esbuild: + built: true + puppeteer: + built: true peerDependenciesMeta: "@angular/localize": optional: true @@ -420,54 +441,59 @@ __metadata: optional: true tailwindcss: optional: true - checksum: 10c0/5b8592bb79a0d270e0cbe2072139b6548f9427ccaee016bfd0155f68a439ed1116e9e7c15297e31fd4f094c5b737f1821a045f1a595d0bb52329d6429748c2f8 + checksum: 10c0/50c3c3ef2289771a33ce94486dbf5875281fb4e9091e2777663159b5e3a5a8fb78ddc914f7b6a652f1dcc21fc2f3dffaa011778e8906781da0bd107dbd4ea3d3 languageName: node linkType: hard -"@angular/cli@npm:^18.0.6": - version: 18.0.6 - resolution: "@angular/cli@npm:18.0.6" +"@angular/cli@npm:^18.2.0": + version: 18.2.0 + resolution: "@angular/cli@npm:18.2.0" dependencies: - "@angular-devkit/architect": "npm:0.1800.6" - "@angular-devkit/core": "npm:18.0.6" - "@angular-devkit/schematics": "npm:18.0.6" - "@schematics/angular": "npm:18.0.6" + "@angular-devkit/architect": "npm:0.1802.0" + "@angular-devkit/core": "npm:18.2.0" + "@angular-devkit/schematics": "npm:18.2.0" + "@inquirer/prompts": "npm:5.3.8" + "@listr2/prompt-adapter-inquirer": "npm:2.0.15" + "@schematics/angular": "npm:18.2.0" "@yarnpkg/lockfile": "npm:1.1.0" - ansi-colors: "npm:4.1.3" - ini: "npm:4.1.2" - inquirer: "npm:9.2.22" - jsonc-parser: "npm:3.2.1" - npm-package-arg: "npm:11.0.2" - npm-pick-manifest: "npm:9.0.1" - ora: "npm:5.4.1" + ini: "npm:4.1.3" + jsonc-parser: "npm:3.3.1" + listr2: "npm:8.2.4" + npm-package-arg: "npm:11.0.3" + npm-pick-manifest: "npm:9.1.0" pacote: "npm:18.0.6" resolve: "npm:1.22.8" - semver: "npm:7.6.2" + semver: "npm:7.6.3" symbol-observable: "npm:4.0.0" yargs: "npm:17.7.2" + dependenciesMeta: + esbuild: + built: true + puppeteer: + built: true bin: ng: bin/ng.js - checksum: 10c0/be3ee0a47dd8c9950a0df9ec27eee70760c5fc8fd53c7320e6259b31375b2c267a6eebfb1a07f44e0567f96698d04dc3e62706d338e101c244efc82700c93a3c + checksum: 10c0/986cd7a49e321ee494c8723769df5a01de9bda69fe1b34df05afd11cebe2f174d1a6bd60844d409dee2a2ae7805e76a5982523aaa2d59c40080bd09b10518afc languageName: node linkType: hard -"@angular/common@npm:^18.0.5": - version: 18.0.5 - resolution: "@angular/common@npm:18.0.5" +"@angular/common@npm:^18.2.0": + version: 18.2.0 + resolution: "@angular/common@npm:18.2.0" dependencies: tslib: "npm:^2.3.0" peerDependencies: - "@angular/core": 18.0.5 + "@angular/core": 18.2.0 rxjs: ^6.5.3 || ^7.4.0 - checksum: 10c0/0a08e08adf23b52d3a7e1473dd051868a9e15341fe69513154c2544d2dbf82e1e9adf1550bea660d0af58f161d8b77a6e6569f4c23785f65f5b8be9c410e860b + checksum: 10c0/c6ded4739979d5e62d45eaa504031c163bee1f2ef4f1c7d4382494e69379da0855c43ddbdd74450247239468d26f9306b61a585a9401b04ce97fd5e4933af4ea languageName: node linkType: hard -"@angular/compiler-cli@npm:^18.0.5": - version: 18.0.5 - resolution: "@angular/compiler-cli@npm:18.0.5" +"@angular/compiler-cli@npm:^18.2.0": + version: 18.2.0 + resolution: "@angular/compiler-cli@npm:18.2.0" dependencies: - "@babel/core": "npm:7.24.7" + "@babel/core": "npm:7.25.2" "@jridgewell/sourcemap-codec": "npm:^1.4.14" chokidar: "npm:^3.0.0" convert-source-map: "npm:^1.5.1" @@ -476,132 +502,132 @@ __metadata: tslib: "npm:^2.3.0" yargs: "npm:^17.2.1" peerDependencies: - "@angular/compiler": 18.0.5 - typescript: ">=5.4 <5.5" + "@angular/compiler": 18.2.0 + typescript: ">=5.4 <5.6" bin: ng-xi18n: bundles/src/bin/ng_xi18n.js ngc: bundles/src/bin/ngc.js ngcc: bundles/ngcc/index.js - checksum: 10c0/947bcaa1d4c760ccc5b16b411d09e7c1c4d1cf9d1503ec151e1a456adebed15ad451649f6266c6bfd1e0993e2ecc7d8695d571ccb59952a50e4d8d211a2b7954 + checksum: 10c0/d9922a5a4b5ac5b8d82bac0bb766d6d1645f0a7f3ac2c4bb863efc4fcc0d36bf9442ba842a0f594cf3d32103c221db3340195646f8341df8dcbed7a08eaebaac languageName: node linkType: hard -"@angular/compiler@npm:^18.0.5": - version: 18.0.5 - resolution: "@angular/compiler@npm:18.0.5" +"@angular/compiler@npm:^18.2.0": + version: 18.2.0 + resolution: "@angular/compiler@npm:18.2.0" dependencies: tslib: "npm:^2.3.0" peerDependencies: - "@angular/core": 18.0.5 + "@angular/core": 18.2.0 peerDependenciesMeta: "@angular/core": optional: true - checksum: 10c0/88a8a7cea12e407543b61403ea39974ca590c0633c2f714113861f1e68b06a66dacfbd2d0442168652b1052d37bc1054f0c6d5216e2afc0e0782f8a3b8e25a4d + checksum: 10c0/db1510d33a6caaef27aa7eb94423be9c6e652707cea37166a774f90d2ff1e36ef9d60b38076abaf829666c1256aa0c3c8daa8e662fd0dd112c7c8135b003ad0c languageName: node linkType: hard -"@angular/core@npm:^18.0.5": - version: 18.0.5 - resolution: "@angular/core@npm:18.0.5" +"@angular/core@npm:^18.2.0": + version: 18.2.0 + resolution: "@angular/core@npm:18.2.0" dependencies: tslib: "npm:^2.3.0" peerDependencies: rxjs: ^6.5.3 || ^7.4.0 - zone.js: ~0.14.0 - checksum: 10c0/3a27257938cc8fd9f784308ec959d2e105b8a110486ea70af6c8afa54e9f2aa45d8964976e6299d7d62bb6c36c4dedc5b85dbd303ad14ca09d345e1ddc81ef1a + zone.js: ~0.14.10 + checksum: 10c0/a66b9c474bf3b32dc3e678353bd79c2c9c0a8e9531500828d51e3c4a1998bcfaa9834ad5910646dfbd5d7fc9d8f37b55f024f6d5f08407a405c94f0c44f50683 languageName: node linkType: hard -"@angular/forms@npm:^18.0.5": - version: 18.0.5 - resolution: "@angular/forms@npm:18.0.5" +"@angular/forms@npm:^18.2.0": + version: 18.2.0 + resolution: "@angular/forms@npm:18.2.0" dependencies: tslib: "npm:^2.3.0" peerDependencies: - "@angular/common": 18.0.5 - "@angular/core": 18.0.5 - "@angular/platform-browser": 18.0.5 + "@angular/common": 18.2.0 + "@angular/core": 18.2.0 + "@angular/platform-browser": 18.2.0 rxjs: ^6.5.3 || ^7.4.0 - checksum: 10c0/ed0be2621843bb0000c4c2c75b735f0944f6f043ca871d525facd238f719b82ad34b8aa759cb01b34476220e8decad1a45d6286b614781a01ac33cb77d0f0ed4 + checksum: 10c0/5a71b10a7d54b102cf69a79c60e2eb1dc515d11fa8c827c56e3738ee3fbe256f5ca63b46314bb0a3adba7675465919546142785a64dc9f931d7600f295e97e96 languageName: node linkType: hard -"@angular/localize@npm:^18.0.5": - version: 18.0.5 - resolution: "@angular/localize@npm:18.0.5" +"@angular/localize@npm:^18.2.0": + version: 18.2.0 + resolution: "@angular/localize@npm:18.2.0" dependencies: - "@babel/core": "npm:7.24.7" + "@babel/core": "npm:7.25.2" "@types/babel__core": "npm:7.20.5" fast-glob: "npm:3.3.2" yargs: "npm:^17.2.1" peerDependencies: - "@angular/compiler": 18.0.5 - "@angular/compiler-cli": 18.0.5 + "@angular/compiler": 18.2.0 + "@angular/compiler-cli": 18.2.0 bin: localize-extract: tools/bundles/src/extract/cli.js localize-migrate: tools/bundles/src/migrate/cli.js localize-translate: tools/bundles/src/translate/cli.js - checksum: 10c0/7c124a031a812e7d7be6edf49dc62eeb0e21bdba4db2c94a2b3cc45044ef73baf230c4f8e2bd9dd77e98d3e224d286af8deaa9400e8b5ff95a9ecf5d641e351c + checksum: 10c0/c278f43533656fd1de9fa78e4ad563048ee8814e4562f356f1ae39f6eb0f3186aa854592d44c570e02803a264e5ceca08cbaf1e49446c2448f1263f840e07775 languageName: node linkType: hard -"@angular/platform-browser-dynamic@npm:^18.0.5": - version: 18.0.5 - resolution: "@angular/platform-browser-dynamic@npm:18.0.5" +"@angular/platform-browser-dynamic@npm:^18.2.0": + version: 18.2.0 + resolution: "@angular/platform-browser-dynamic@npm:18.2.0" dependencies: tslib: "npm:^2.3.0" peerDependencies: - "@angular/common": 18.0.5 - "@angular/compiler": 18.0.5 - "@angular/core": 18.0.5 - "@angular/platform-browser": 18.0.5 - checksum: 10c0/2fb841ecea38a7515be0bdc350d4458a5ccc8f2dd055883328b9ac3515098ca3737cdd73708fee336e4c537a84c553dfd6703002b35998c2c03a1180ebf0e272 + "@angular/common": 18.2.0 + "@angular/compiler": 18.2.0 + "@angular/core": 18.2.0 + "@angular/platform-browser": 18.2.0 + checksum: 10c0/874f2c97e948f05b14c20b2da22e4633f277ca3b41c6cfb8b388b4428e6302d8c79bbbdb7262d539c177453824cff1a046f39d0fb754a0ae502d36595b39c44c languageName: node linkType: hard -"@angular/platform-browser@npm:^18.0.5": - version: 18.0.5 - resolution: "@angular/platform-browser@npm:18.0.5" +"@angular/platform-browser@npm:^18.2.0": + version: 18.2.0 + resolution: "@angular/platform-browser@npm:18.2.0" dependencies: tslib: "npm:^2.3.0" peerDependencies: - "@angular/animations": 18.0.5 - "@angular/common": 18.0.5 - "@angular/core": 18.0.5 + "@angular/animations": 18.2.0 + "@angular/common": 18.2.0 + "@angular/core": 18.2.0 peerDependenciesMeta: "@angular/animations": optional: true - checksum: 10c0/c449aea482e3b9018ec1b6036a32da8c462fa7cd0bd30cdf4fe2121a3a54af148d638fd8e2340755614cc5356b24b6fa98ce2c39ac9008de48283b321514f3cc + checksum: 10c0/270bed2ec0fa1df62a4172762debee8f25e6de4eddb0610db82bfdb44a6c61b6cd33c479f740a43550a7eccbacebe961cd5ecdbed91afe119f3b5cfbfc455acf languageName: node linkType: hard -"@angular/platform-server@npm:^18.0.5": - version: 18.0.5 - resolution: "@angular/platform-server@npm:18.0.5" +"@angular/platform-server@npm:^18.2.0": + version: 18.2.0 + resolution: "@angular/platform-server@npm:18.2.0" dependencies: tslib: "npm:^2.3.0" xhr2: "npm:^0.2.0" peerDependencies: - "@angular/animations": 18.0.5 - "@angular/common": 18.0.5 - "@angular/compiler": 18.0.5 - "@angular/core": 18.0.5 - "@angular/platform-browser": 18.0.5 - checksum: 10c0/99aee9a306449ed8d5c6ae1f973984920f38fcc675ec9baf0144c003e86fa9122a535e700718d6ef638877188ef6e49d62b130d41b4f5d220a729db902407836 + "@angular/animations": 18.2.0 + "@angular/common": 18.2.0 + "@angular/compiler": 18.2.0 + "@angular/core": 18.2.0 + "@angular/platform-browser": 18.2.0 + checksum: 10c0/e03481b765bb429e75ed0e3305183647204519f5a01117460af25bc489880b90a60e438f76990a1de5cf1035f8de4f09331023168d6bb4c3eb38d254bd157398 languageName: node linkType: hard -"@angular/router@npm:^18.0.5": - version: 18.0.5 - resolution: "@angular/router@npm:18.0.5" +"@angular/router@npm:^18.2.0": + version: 18.2.0 + resolution: "@angular/router@npm:18.2.0" dependencies: tslib: "npm:^2.3.0" peerDependencies: - "@angular/common": 18.0.5 - "@angular/core": 18.0.5 - "@angular/platform-browser": 18.0.5 + "@angular/common": 18.2.0 + "@angular/core": 18.2.0 + "@angular/platform-browser": 18.2.0 rxjs: ^6.5.3 || ^7.4.0 - checksum: 10c0/449a25624fd216364f2b3a4ffd58cadadd5103274156a4623176c063be94afdf7e81c9a1c8e8a90c349bb4a994587bb4e08ddd5120cccb3f484ee68d33a1e9ff + checksum: 10c0/c15189eb083c1ee358b9715d269d33d6b160157d02c54c3eec3e8afade389e12f700af8a3103b6cb91d9a53f11fae73ed9a9620fc95239b2399a10b90b4494ba languageName: node linkType: hard @@ -616,7 +642,7 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.24.2, @babel/code-frame@npm:^7.24.7": +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.24.7": version: 7.24.7 resolution: "@babel/code-frame@npm:7.24.7" dependencies: @@ -626,37 +652,51 @@ __metadata: languageName: node linkType: hard -"@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.24.4, @babel/compat-data@npm:^7.24.7": +"@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.24.7": version: 7.24.7 resolution: "@babel/compat-data@npm:7.24.7" checksum: 10c0/dcd93a5632b04536498fbe2be5af1057f635fd7f7090483d8e797878559037e5130b26862ceb359acbae93ed27e076d395ddb4663db6b28a665756ffd02d324f languageName: node linkType: hard -"@babel/core@npm:7.24.5": - version: 7.24.5 - resolution: "@babel/core@npm:7.24.5" +"@babel/compat-data@npm:^7.24.8": + version: 7.24.9 + resolution: "@babel/compat-data@npm:7.24.9" + checksum: 10c0/95a69c9ed00ae78b4921f33403e9b35518e6139a0c46af763c65dea160720cb57c6cc23f7d30249091a0248335b0e39de5c8dfa8e7877c830e44561e0bdc1254 + languageName: node + linkType: hard + +"@babel/compat-data@npm:^7.25.2": + version: 7.25.2 + resolution: "@babel/compat-data@npm:7.25.2" + checksum: 10c0/5bf1f14d6e5f0d37c19543e99209ff4a94bb97915e1ce01e5334a144aa08cd56b6e62ece8135dac77e126723d63d4d4b96fc603a12c43b88c28f4b5e070270c5 + languageName: node + linkType: hard + +"@babel/core@npm:7.25.2": + version: 7.25.2 + resolution: "@babel/core@npm:7.25.2" dependencies: "@ampproject/remapping": "npm:^2.2.0" - "@babel/code-frame": "npm:^7.24.2" - "@babel/generator": "npm:^7.24.5" - "@babel/helper-compilation-targets": "npm:^7.23.6" - "@babel/helper-module-transforms": "npm:^7.24.5" - "@babel/helpers": "npm:^7.24.5" - "@babel/parser": "npm:^7.24.5" - "@babel/template": "npm:^7.24.0" - "@babel/traverse": "npm:^7.24.5" - "@babel/types": "npm:^7.24.5" + "@babel/code-frame": "npm:^7.24.7" + "@babel/generator": "npm:^7.25.0" + "@babel/helper-compilation-targets": "npm:^7.25.2" + "@babel/helper-module-transforms": "npm:^7.25.2" + "@babel/helpers": "npm:^7.25.0" + "@babel/parser": "npm:^7.25.0" + "@babel/template": "npm:^7.25.0" + "@babel/traverse": "npm:^7.25.2" + "@babel/types": "npm:^7.25.2" convert-source-map: "npm:^2.0.0" debug: "npm:^4.1.0" gensync: "npm:^1.0.0-beta.2" json5: "npm:^2.2.3" semver: "npm:^6.3.1" - checksum: 10c0/e26ba810a77bc8e21579a12fc36c79a0a60554404dc9447f2d64eb1f26d181c48d3b97d39d9f158e9911ec7162a8280acfaf2b4b210e975f0dd4bd4dbb1ee159 + checksum: 10c0/a425fa40e73cb72b6464063a57c478bc2de9dbcc19c280f1b55a3d88b35d572e87e8594e7d7b4880331addb6faef641bbeb701b91b41b8806cd4deae5d74f401 languageName: node linkType: hard -"@babel/core@npm:7.24.7, @babel/core@npm:^7.12.3, @babel/core@npm:^7.23.9, @babel/core@npm:^7.24.6": +"@babel/core@npm:^7.12.3, @babel/core@npm:^7.23.9, @babel/core@npm:^7.24.6": version: 7.24.7 resolution: "@babel/core@npm:7.24.7" dependencies: @@ -679,19 +719,19 @@ __metadata: languageName: node linkType: hard -"@babel/generator@npm:7.24.5": - version: 7.24.5 - resolution: "@babel/generator@npm:7.24.5" +"@babel/generator@npm:7.25.0, @babel/generator@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/generator@npm:7.25.0" dependencies: - "@babel/types": "npm:^7.24.5" + "@babel/types": "npm:^7.25.0" "@jridgewell/gen-mapping": "npm:^0.3.5" "@jridgewell/trace-mapping": "npm:^0.3.25" jsesc: "npm:^2.5.1" - checksum: 10c0/0d64f880150e7dfb92ceff2b4ac865f36aa1e295120920246492ffd0146562dabf79ba8699af1c8833f8a7954818d4d146b7b02f808df4d6024fb99f98b2f78d + checksum: 10c0/d0e2dfcdc8bdbb5dded34b705ceebf2e0bc1b06795a1530e64fb6a3ccf313c189db7f60c1616effae48114e1a25adc75855bc4496f3779a396b3377bae718ce7 languageName: node linkType: hard -"@babel/generator@npm:^7.24.5, @babel/generator@npm:^7.24.7": +"@babel/generator@npm:^7.24.7": version: 7.24.7 resolution: "@babel/generator@npm:7.24.7" dependencies: @@ -703,16 +743,19 @@ __metadata: languageName: node linkType: hard -"@babel/helper-annotate-as-pure@npm:7.22.5": - version: 7.22.5 - resolution: "@babel/helper-annotate-as-pure@npm:7.22.5" +"@babel/generator@npm:^7.24.8": + version: 7.24.10 + resolution: "@babel/generator@npm:7.24.10" dependencies: - "@babel/types": "npm:^7.22.5" - checksum: 10c0/5a80dc364ddda26b334bbbc0f6426cab647381555ef7d0cd32eb284e35b867c012ce6ce7d52a64672ed71383099c99d32765b3d260626527bb0e3470b0f58e45 + "@babel/types": "npm:^7.24.9" + "@jridgewell/gen-mapping": "npm:^0.3.5" + "@jridgewell/trace-mapping": "npm:^0.3.25" + jsesc: "npm:^2.5.1" + checksum: 10c0/abcfd75f625aecc87ce6036ef788b12723fd3c46530df1130d1f00d18e48b462849ddaeef8b1a02bfdcb6e28956389a98c5729dad1c3c5448307dacb6c959f29 languageName: node linkType: hard -"@babel/helper-annotate-as-pure@npm:^7.24.7": +"@babel/helper-annotate-as-pure@npm:7.24.7, @babel/helper-annotate-as-pure@npm:^7.24.7": version: 7.24.7 resolution: "@babel/helper-annotate-as-pure@npm:7.24.7" dependencies: @@ -731,7 +774,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-compilation-targets@npm:^7.22.6, @babel/helper-compilation-targets@npm:^7.23.6, @babel/helper-compilation-targets@npm:^7.24.7": +"@babel/helper-compilation-targets@npm:^7.22.6, @babel/helper-compilation-targets@npm:^7.24.7": version: 7.24.7 resolution: "@babel/helper-compilation-targets@npm:7.24.7" dependencies: @@ -744,6 +787,32 @@ __metadata: languageName: node linkType: hard +"@babel/helper-compilation-targets@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/helper-compilation-targets@npm:7.24.8" + dependencies: + "@babel/compat-data": "npm:^7.24.8" + "@babel/helper-validator-option": "npm:^7.24.8" + browserslist: "npm:^4.23.1" + lru-cache: "npm:^5.1.1" + semver: "npm:^6.3.1" + checksum: 10c0/2885c44ef6aaf82b7e4352b30089bb09fbe08ed5ec24eb452c2bdc3c021e2a65ab412f74b3d67ec1398da0356c730b33a2ceca1d67d34c85080d31ca6efa9aec + languageName: node + linkType: hard + +"@babel/helper-compilation-targets@npm:^7.25.2": + version: 7.25.2 + resolution: "@babel/helper-compilation-targets@npm:7.25.2" + dependencies: + "@babel/compat-data": "npm:^7.25.2" + "@babel/helper-validator-option": "npm:^7.24.8" + browserslist: "npm:^4.23.1" + lru-cache: "npm:^5.1.1" + semver: "npm:^6.3.1" + checksum: 10c0/de10e986b5322c9f807350467dc845ec59df9e596a5926a3b5edbb4710d8e3b8009d4396690e70b88c3844fe8ec4042d61436dd4b92d1f5f75655cf43ab07e99 + languageName: node + linkType: hard + "@babel/helper-create-class-features-plugin@npm:^7.24.7": version: 7.24.7 resolution: "@babel/helper-create-class-features-plugin@npm:7.24.7" @@ -776,6 +845,19 @@ __metadata: languageName: node linkType: hard +"@babel/helper-create-regexp-features-plugin@npm:^7.25.0": + version: 7.25.2 + resolution: "@babel/helper-create-regexp-features-plugin@npm:7.25.2" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.24.7" + regexpu-core: "npm:^5.3.1" + semver: "npm:^6.3.1" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10c0/85a7e3639c118856fb1113f54fb7e3bf7698171ddfd0cd6fccccd5426b3727bc1434fe7f69090441dcde327feef9de917e00d35e47ab820047057518dd675317 + languageName: node + linkType: hard + "@babel/helper-define-polyfill-provider@npm:^0.6.1, @babel/helper-define-polyfill-provider@npm:^0.6.2": version: 0.6.2 resolution: "@babel/helper-define-polyfill-provider@npm:0.6.2" @@ -791,7 +873,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-environment-visitor@npm:^7.22.20, @babel/helper-environment-visitor@npm:^7.24.7": +"@babel/helper-environment-visitor@npm:^7.24.7": version: 7.24.7 resolution: "@babel/helper-environment-visitor@npm:7.24.7" dependencies: @@ -829,7 +911,17 @@ __metadata: languageName: node linkType: hard -"@babel/helper-module-imports@npm:^7.24.1, @babel/helper-module-imports@npm:^7.24.3, @babel/helper-module-imports@npm:^7.24.7": +"@babel/helper-member-expression-to-functions@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/helper-member-expression-to-functions@npm:7.24.8" + dependencies: + "@babel/traverse": "npm:^7.24.8" + "@babel/types": "npm:^7.24.8" + checksum: 10c0/7e14a5acc91f6cd26305a4441b82eb6f616bd70b096a4d2099a968f16b26d50207eec0b9ebfc466fefd62bd91587ac3be878117cdfec819b7151911183cb0e5a + languageName: node + linkType: hard + +"@babel/helper-module-imports@npm:^7.24.7": version: 7.24.7 resolution: "@babel/helper-module-imports@npm:7.24.7" dependencies: @@ -839,7 +931,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-module-transforms@npm:^7.24.5, @babel/helper-module-transforms@npm:^7.24.7": +"@babel/helper-module-transforms@npm:^7.24.7": version: 7.24.7 resolution: "@babel/helper-module-transforms@npm:7.24.7" dependencies: @@ -854,6 +946,20 @@ __metadata: languageName: node linkType: hard +"@babel/helper-module-transforms@npm:^7.24.8, @babel/helper-module-transforms@npm:^7.25.0, @babel/helper-module-transforms@npm:^7.25.2": + version: 7.25.2 + resolution: "@babel/helper-module-transforms@npm:7.25.2" + dependencies: + "@babel/helper-module-imports": "npm:^7.24.7" + "@babel/helper-simple-access": "npm:^7.24.7" + "@babel/helper-validator-identifier": "npm:^7.24.7" + "@babel/traverse": "npm:^7.25.2" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10c0/adaa15970ace0aee5934b5a633789b5795b6229c6a9cf3e09a7e80aa33e478675eee807006a862aa9aa517935d81f88a6db8a9f5936e3a2a40ec75f8062bc329 + languageName: node + linkType: hard + "@babel/helper-optimise-call-expression@npm:^7.24.7": version: 7.24.7 resolution: "@babel/helper-optimise-call-expression@npm:7.24.7" @@ -863,14 +969,21 @@ __metadata: languageName: node linkType: hard -"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.24.0, @babel/helper-plugin-utils@npm:^7.24.5, @babel/helper-plugin-utils@npm:^7.24.7, @babel/helper-plugin-utils@npm:^7.8.0, @babel/helper-plugin-utils@npm:^7.8.3": +"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.24.7, @babel/helper-plugin-utils@npm:^7.8.0, @babel/helper-plugin-utils@npm:^7.8.3": version: 7.24.7 resolution: "@babel/helper-plugin-utils@npm:7.24.7" checksum: 10c0/c3d38cd9b3520757bb4a279255cc3f956fc0ac1c193964bd0816ebd5c86e30710be8e35252227e0c9d9e0f4f56d9b5f916537f2bc588084b0988b4787a967d31 languageName: node linkType: hard -"@babel/helper-remap-async-to-generator@npm:^7.22.20, @babel/helper-remap-async-to-generator@npm:^7.24.7": +"@babel/helper-plugin-utils@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/helper-plugin-utils@npm:7.24.8" + checksum: 10c0/0376037f94a3bfe6b820a39f81220ac04f243eaee7193774b983e956c1750883ff236b30785795abbcda43fac3ece74750566830c2daa4d6e3870bb0dff34c2d + languageName: node + linkType: hard + +"@babel/helper-remap-async-to-generator@npm:^7.24.7": version: 7.24.7 resolution: "@babel/helper-remap-async-to-generator@npm:7.24.7" dependencies: @@ -883,6 +996,19 @@ __metadata: languageName: node linkType: hard +"@babel/helper-remap-async-to-generator@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/helper-remap-async-to-generator@npm:7.25.0" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.24.7" + "@babel/helper-wrap-function": "npm:^7.25.0" + "@babel/traverse": "npm:^7.25.0" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10c0/0d17b5f7bb6a607edc9cc62fff8056dd9f341bf2f919884f97b99170d143022a5e7ae57922c4891e4fc360ad291e708d2f8cd8989f1d3cd7a17600159984f5a6 + languageName: node + linkType: hard + "@babel/helper-replace-supers@npm:^7.24.7": version: 7.24.7 resolution: "@babel/helper-replace-supers@npm:7.24.7" @@ -896,6 +1022,19 @@ __metadata: languageName: node linkType: hard +"@babel/helper-replace-supers@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/helper-replace-supers@npm:7.25.0" + dependencies: + "@babel/helper-member-expression-to-functions": "npm:^7.24.8" + "@babel/helper-optimise-call-expression": "npm:^7.24.7" + "@babel/traverse": "npm:^7.25.0" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10c0/b4b6650ab3d56c39a259367cd97f8df2f21c9cebb3716fea7bca40a150f8847bfb82f481e98927c7c6579b48a977b5a8f77318a1c6aeb497f41ecd6dbc3fdfef + languageName: node + linkType: hard + "@babel/helper-simple-access@npm:^7.24.7": version: 7.24.7 resolution: "@babel/helper-simple-access@npm:7.24.7" @@ -916,16 +1055,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-split-export-declaration@npm:7.24.5": - version: 7.24.5 - resolution: "@babel/helper-split-export-declaration@npm:7.24.5" - dependencies: - "@babel/types": "npm:^7.24.5" - checksum: 10c0/d7a812d67d031a348f3fb0e6263ce2dbe6038f81536ba7fb16db385383bcd6542b71833194303bf6d3d0e4f7b6b584c9c8fae8772122e2ce68fc9bdf07f4135d - languageName: node - linkType: hard - -"@babel/helper-split-export-declaration@npm:^7.24.7": +"@babel/helper-split-export-declaration@npm:7.24.7, @babel/helper-split-export-declaration@npm:^7.24.7": version: 7.24.7 resolution: "@babel/helper-split-export-declaration@npm:7.24.7" dependencies: @@ -941,6 +1071,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-string-parser@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/helper-string-parser@npm:7.24.8" + checksum: 10c0/6361f72076c17fabf305e252bf6d580106429014b3ab3c1f5c4eb3e6d465536ea6b670cc0e9a637a77a9ad40454d3e41361a2909e70e305116a23d68ce094c08 + languageName: node + linkType: hard + "@babel/helper-validator-identifier@npm:^7.24.7": version: 7.24.7 resolution: "@babel/helper-validator-identifier@npm:7.24.7" @@ -948,13 +1085,20 @@ __metadata: languageName: node linkType: hard -"@babel/helper-validator-option@npm:^7.23.5, @babel/helper-validator-option@npm:^7.24.7": +"@babel/helper-validator-option@npm:^7.24.7": version: 7.24.7 resolution: "@babel/helper-validator-option@npm:7.24.7" checksum: 10c0/21aea2b7bc5cc8ddfb828741d5c8116a84cbc35b4a3184ec53124f08e09746f1f67a6f9217850188995ca86059a7942e36d8965a6730784901def777b7e8a436 languageName: node linkType: hard +"@babel/helper-validator-option@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/helper-validator-option@npm:7.24.8" + checksum: 10c0/73db93a34ae89201351288bee7623eed81a54000779462a986105b54ffe82069e764afd15171a428b82e7c7a9b5fec10b5d5603b216317a414062edf5c67a21f + languageName: node + linkType: hard + "@babel/helper-wrap-function@npm:^7.24.7": version: 7.24.7 resolution: "@babel/helper-wrap-function@npm:7.24.7" @@ -967,7 +1111,18 @@ __metadata: languageName: node linkType: hard -"@babel/helpers@npm:^7.24.5, @babel/helpers@npm:^7.24.7": +"@babel/helper-wrap-function@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/helper-wrap-function@npm:7.25.0" + dependencies: + "@babel/template": "npm:^7.25.0" + "@babel/traverse": "npm:^7.25.0" + "@babel/types": "npm:^7.25.0" + checksum: 10c0/d54601a98384c191cbc1ff07b03a19e288ef8d5c6bfafe270b2a303d96e7304eb296002921ed464cc1b105a547d1db146eb86b0be617924dee1ba1b379cdc216 + languageName: node + linkType: hard + +"@babel/helpers@npm:^7.24.7": version: 7.24.7 resolution: "@babel/helpers@npm:7.24.7" dependencies: @@ -977,6 +1132,16 @@ __metadata: languageName: node linkType: hard +"@babel/helpers@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/helpers@npm:7.25.0" + dependencies: + "@babel/template": "npm:^7.25.0" + "@babel/types": "npm:^7.25.0" + checksum: 10c0/b7fe007fc4194268abf70aa3810365085e290e6528dcb9fbbf7a765d43c74b6369ce0f99c5ccd2d44c413853099daa449c9a0123f0b212ac8d18643f2e8174b8 + languageName: node + linkType: hard + "@babel/highlight@npm:^7.24.7": version: 7.24.7 resolution: "@babel/highlight@npm:7.24.7" @@ -989,7 +1154,7 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.23.9, @babel/parser@npm:^7.24.5, @babel/parser@npm:^7.24.7": +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.23.9, @babel/parser@npm:^7.24.7": version: 7.24.7 resolution: "@babel/parser@npm:7.24.7" bin: @@ -998,7 +1163,27 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.24.5, @babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.24.7": +"@babel/parser@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/parser@npm:7.24.8" + bin: + parser: ./bin/babel-parser.js + checksum: 10c0/ce69671de8fa6f649abf849be262707ac700b573b8b1ce1893c66cc6cd76aeb1294a19e8c290b0eadeb2f47d3f413a2e57a281804ffbe76bfb9fa50194cf3c52 + languageName: node + linkType: hard + +"@babel/parser@npm:^7.25.0, @babel/parser@npm:^7.25.3": + version: 7.25.3 + resolution: "@babel/parser@npm:7.25.3" + dependencies: + "@babel/types": "npm:^7.25.2" + bin: + parser: ./bin/babel-parser.js + checksum: 10c0/874b01349aedb805d6694f867a752fdc7469778fad76aca4548d2cc6ce96087c3ba5fb917a6f8d05d2d1a74aae309b5f50f1a4dba035f5a2c9fcfe6e106d2c4e + languageName: node + linkType: hard + +"@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:7.24.7" dependencies: @@ -1010,7 +1195,30 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.24.1, @babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.24.7": +"@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.25.3": + version: 7.25.3 + resolution: "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:7.25.3" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.24.8" + "@babel/traverse": "npm:^7.25.3" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10c0/814b4d3f102e7556a5053d1acf57ef601cfcff39a2c81b8cdc6a5c842e3cb9838f5925d1466a5f1e6416e74c9c83586a3c07fbd7fb8610a396c2becdf9ae5790 + languageName: node + linkType: hard + +"@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:7.25.0" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.24.8" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10c0/9645a1f47b3750acadb1353c02e71cc712d072aafe5ce115ed3a886bc14c5d9200cfb0b5b5e60e813baa549b800cf798f8714019fd246c699053cf68c428e426 + languageName: node + linkType: hard + +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.24.7" dependencies: @@ -1021,7 +1229,18 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:^7.24.1, @babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:^7.24.7": +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.25.0" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.24.8" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10c0/ed1ce1c90cac46c01825339fd0f2a96fa071b016fb819d8dfaf8e96300eae30e74870cb47e4dc80d4ce2fb287869f102878b4f3b35bc927fec8b1d0d76bcf612 + languageName: node + linkType: hard + +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:7.24.7" dependencies: @@ -1034,7 +1253,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.24.1, @babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.24.7": +"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:7.24.7" dependencies: @@ -1046,6 +1265,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:7.25.0" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.24.8" + "@babel/traverse": "npm:^7.25.0" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10c0/45988025537a9d4a27b610fd696a18fd9ba9336621a69b4fb40560eeb10c79657f85c92a37f30c7c8fb29c22970eea0b373315795a891f1a05549a6cfe5a6bfe + languageName: node + linkType: hard + "@babel/plugin-proposal-private-property-in-object@npm:7.21.0-placeholder-for-preset-env.2": version: 7.21.0-placeholder-for-preset-env.2 resolution: "@babel/plugin-proposal-private-property-in-object@npm:7.21.0-placeholder-for-preset-env.2" @@ -1110,7 +1341,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-import-assertions@npm:^7.24.1, @babel/plugin-syntax-import-assertions@npm:^7.24.7": +"@babel/plugin-syntax-import-assertions@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-syntax-import-assertions@npm:7.24.7" dependencies: @@ -1121,7 +1352,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-import-attributes@npm:^7.24.1, @babel/plugin-syntax-import-attributes@npm:^7.24.7": +"@babel/plugin-syntax-import-attributes@npm:7.24.7, @babel/plugin-syntax-import-attributes@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-syntax-import-attributes@npm:7.24.7" dependencies: @@ -1254,7 +1485,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-arrow-functions@npm:^7.24.1, @babel/plugin-transform-arrow-functions@npm:^7.24.7": +"@babel/plugin-transform-arrow-functions@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-arrow-functions@npm:7.24.7" dependencies: @@ -1265,21 +1496,21 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-async-generator-functions@npm:7.24.3": - version: 7.24.3 - resolution: "@babel/plugin-transform-async-generator-functions@npm:7.24.3" +"@babel/plugin-transform-async-generator-functions@npm:7.25.0, @babel/plugin-transform-async-generator-functions@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/plugin-transform-async-generator-functions@npm:7.25.0" dependencies: - "@babel/helper-environment-visitor": "npm:^7.22.20" - "@babel/helper-plugin-utils": "npm:^7.24.0" - "@babel/helper-remap-async-to-generator": "npm:^7.22.20" + "@babel/helper-plugin-utils": "npm:^7.24.8" + "@babel/helper-remap-async-to-generator": "npm:^7.25.0" "@babel/plugin-syntax-async-generators": "npm:^7.8.4" + "@babel/traverse": "npm:^7.25.0" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/55ceed059f819dcccbfe69600bfa1c055ada466bd54eda117cfdd2cf773dd85799e2f6556e4a559b076e93b9704abcca2aef9d72aad7dc8a5d3d17886052f1d3 + checksum: 10c0/5348c3a33d16e0d62f13482c6fa432185ba096d58880b08d42450f7db662d6b03e6149d495c8620897dcd3da35061068cbd6c09da7d0ec95743e55a788809e4e languageName: node linkType: hard -"@babel/plugin-transform-async-generator-functions@npm:^7.24.3, @babel/plugin-transform-async-generator-functions@npm:^7.24.7": +"@babel/plugin-transform-async-generator-functions@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-async-generator-functions@npm:7.24.7" dependencies: @@ -1293,20 +1524,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-async-to-generator@npm:7.24.1": - version: 7.24.1 - resolution: "@babel/plugin-transform-async-to-generator@npm:7.24.1" - dependencies: - "@babel/helper-module-imports": "npm:^7.24.1" - "@babel/helper-plugin-utils": "npm:^7.24.0" - "@babel/helper-remap-async-to-generator": "npm:^7.22.20" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/3731ba8e83cbea1ab22905031f25b3aeb0b97c6467360a2cc685352f16e7c786417d8883bc747f5a0beff32266bdb12a05b6292e7b8b75967087200a7bc012c4 - languageName: node - linkType: hard - -"@babel/plugin-transform-async-to-generator@npm:^7.24.1, @babel/plugin-transform-async-to-generator@npm:^7.24.7": +"@babel/plugin-transform-async-to-generator@npm:7.24.7, @babel/plugin-transform-async-to-generator@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-async-to-generator@npm:7.24.7" dependencies: @@ -1319,7 +1537,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-block-scoped-functions@npm:^7.24.1, @babel/plugin-transform-block-scoped-functions@npm:^7.24.7": +"@babel/plugin-transform-block-scoped-functions@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-block-scoped-functions@npm:7.24.7" dependencies: @@ -1330,7 +1548,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-block-scoping@npm:^7.24.5, @babel/plugin-transform-block-scoping@npm:^7.24.7": +"@babel/plugin-transform-block-scoping@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-block-scoping@npm:7.24.7" dependencies: @@ -1341,7 +1559,18 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-class-properties@npm:^7.24.1, @babel/plugin-transform-class-properties@npm:^7.24.7": +"@babel/plugin-transform-block-scoping@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/plugin-transform-block-scoping@npm:7.25.0" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.24.8" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/382931c75a5d0ea560387e76cb57b03461300527e4784efcb2fb62f36c1eb0ab331327b6034def256baa0cad9050925a61f9c0d56261b6afd6a29c3065fb0bd4 + languageName: node + linkType: hard + +"@babel/plugin-transform-class-properties@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-class-properties@npm:7.24.7" dependencies: @@ -1353,7 +1582,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-class-static-block@npm:^7.24.4, @babel/plugin-transform-class-static-block@npm:^7.24.7": +"@babel/plugin-transform-class-static-block@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-class-static-block@npm:7.24.7" dependencies: @@ -1366,7 +1595,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-classes@npm:^7.24.5, @babel/plugin-transform-classes@npm:^7.24.7": +"@babel/plugin-transform-classes@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-classes@npm:7.24.7" dependencies: @@ -1384,7 +1613,23 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-computed-properties@npm:^7.24.1, @babel/plugin-transform-computed-properties@npm:^7.24.7": +"@babel/plugin-transform-classes@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/plugin-transform-classes@npm:7.25.0" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.24.7" + "@babel/helper-compilation-targets": "npm:^7.24.8" + "@babel/helper-plugin-utils": "npm:^7.24.8" + "@babel/helper-replace-supers": "npm:^7.25.0" + "@babel/traverse": "npm:^7.25.0" + globals: "npm:^11.1.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/4451dccf8a7979427ae042afe381233f30764a8072faf0de1337a4fc297c6d7cb40df9e28931ac096e5b56392d0cd97d3ce10aee68288150a8701624d362a791 + languageName: node + linkType: hard + +"@babel/plugin-transform-computed-properties@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-computed-properties@npm:7.24.7" dependencies: @@ -1396,7 +1641,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-destructuring@npm:^7.24.5, @babel/plugin-transform-destructuring@npm:^7.24.7": +"@babel/plugin-transform-destructuring@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-destructuring@npm:7.24.7" dependencies: @@ -1407,7 +1652,18 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-dotall-regex@npm:^7.24.1, @babel/plugin-transform-dotall-regex@npm:^7.24.7": +"@babel/plugin-transform-destructuring@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/plugin-transform-destructuring@npm:7.24.8" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.24.8" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/804968c1d5f5072c717505296c1e5d5ec33e90550423de66de82bbcb78157156e8470bbe77a04ab8c710a88a06360a30103cf223ac7eff4829adedd6150de5ce + languageName: node + linkType: hard + +"@babel/plugin-transform-dotall-regex@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-dotall-regex@npm:7.24.7" dependencies: @@ -1419,7 +1675,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-duplicate-keys@npm:^7.24.1, @babel/plugin-transform-duplicate-keys@npm:^7.24.7": +"@babel/plugin-transform-duplicate-keys@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-duplicate-keys@npm:7.24.7" dependencies: @@ -1430,7 +1686,19 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-dynamic-import@npm:^7.24.1, @babel/plugin-transform-dynamic-import@npm:^7.24.7": +"@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:7.25.0" + dependencies: + "@babel/helper-create-regexp-features-plugin": "npm:^7.25.0" + "@babel/helper-plugin-utils": "npm:^7.24.8" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10c0/1c9b57ddd9b33696e88911d0e7975e1573ebc46219c4b30eb1dc746cbb71aedfac6f6dab7fdfdec54dd58f31468bf6ab56b157661ea4ffe58f906d71f89544c8 + languageName: node + linkType: hard + +"@babel/plugin-transform-dynamic-import@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-dynamic-import@npm:7.24.7" dependencies: @@ -1442,7 +1710,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-exponentiation-operator@npm:^7.24.1, @babel/plugin-transform-exponentiation-operator@npm:^7.24.7": +"@babel/plugin-transform-exponentiation-operator@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-exponentiation-operator@npm:7.24.7" dependencies: @@ -1454,7 +1722,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-export-namespace-from@npm:^7.24.1, @babel/plugin-transform-export-namespace-from@npm:^7.24.7": +"@babel/plugin-transform-export-namespace-from@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-export-namespace-from@npm:7.24.7" dependencies: @@ -1466,7 +1734,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-for-of@npm:^7.24.1, @babel/plugin-transform-for-of@npm:^7.24.7": +"@babel/plugin-transform-for-of@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-for-of@npm:7.24.7" dependencies: @@ -1478,7 +1746,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-function-name@npm:^7.24.1, @babel/plugin-transform-function-name@npm:^7.24.7": +"@babel/plugin-transform-function-name@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-function-name@npm:7.24.7" dependencies: @@ -1491,7 +1759,20 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-json-strings@npm:^7.24.1, @babel/plugin-transform-json-strings@npm:^7.24.7": +"@babel/plugin-transform-function-name@npm:^7.25.1": + version: 7.25.1 + resolution: "@babel/plugin-transform-function-name@npm:7.25.1" + dependencies: + "@babel/helper-compilation-targets": "npm:^7.24.8" + "@babel/helper-plugin-utils": "npm:^7.24.8" + "@babel/traverse": "npm:^7.25.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/e74912174d5e33d1418b840443c2e226a7b76cc017c1ed20ee30a566e4f1794d4a123be03180da046241576e8b692731807ba1f52608922acf1cb2cb6957593f + languageName: node + linkType: hard + +"@babel/plugin-transform-json-strings@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-json-strings@npm:7.24.7" dependencies: @@ -1503,7 +1784,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-literals@npm:^7.24.1, @babel/plugin-transform-literals@npm:^7.24.7": +"@babel/plugin-transform-literals@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-literals@npm:7.24.7" dependencies: @@ -1514,7 +1795,18 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-logical-assignment-operators@npm:^7.24.1, @babel/plugin-transform-logical-assignment-operators@npm:^7.24.7": +"@babel/plugin-transform-literals@npm:^7.25.2": + version: 7.25.2 + resolution: "@babel/plugin-transform-literals@npm:7.25.2" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.24.8" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/0796883217b0885d37e7f6d350773be349e469a812b6bf11ccf862a6edf65103d3e7c849529d65381b441685c12e756751d8c2489a0fd3f8139bb5ef93185f58 + languageName: node + linkType: hard + +"@babel/plugin-transform-logical-assignment-operators@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-logical-assignment-operators@npm:7.24.7" dependencies: @@ -1526,7 +1818,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-member-expression-literals@npm:^7.24.1, @babel/plugin-transform-member-expression-literals@npm:^7.24.7": +"@babel/plugin-transform-member-expression-literals@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-member-expression-literals@npm:7.24.7" dependencies: @@ -1537,7 +1829,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-modules-amd@npm:^7.24.1, @babel/plugin-transform-modules-amd@npm:^7.24.7": +"@babel/plugin-transform-modules-amd@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-modules-amd@npm:7.24.7" dependencies: @@ -1549,7 +1841,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-modules-commonjs@npm:^7.24.1, @babel/plugin-transform-modules-commonjs@npm:^7.24.7": +"@babel/plugin-transform-modules-commonjs@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-modules-commonjs@npm:7.24.7" dependencies: @@ -1562,7 +1854,20 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-modules-systemjs@npm:^7.24.1, @babel/plugin-transform-modules-systemjs@npm:^7.24.7": +"@babel/plugin-transform-modules-commonjs@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/plugin-transform-modules-commonjs@npm:7.24.8" + dependencies: + "@babel/helper-module-transforms": "npm:^7.24.8" + "@babel/helper-plugin-utils": "npm:^7.24.8" + "@babel/helper-simple-access": "npm:^7.24.7" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/f1cf552307ebfced20d3907c1dd8be941b277f0364aa655e2b5fee828c84c54065745183104dae86f1f93ea0406db970a463ef7ceaaed897623748e99640e5a7 + languageName: node + linkType: hard + +"@babel/plugin-transform-modules-systemjs@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-modules-systemjs@npm:7.24.7" dependencies: @@ -1576,7 +1881,21 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-modules-umd@npm:^7.24.1, @babel/plugin-transform-modules-umd@npm:^7.24.7": +"@babel/plugin-transform-modules-systemjs@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/plugin-transform-modules-systemjs@npm:7.25.0" + dependencies: + "@babel/helper-module-transforms": "npm:^7.25.0" + "@babel/helper-plugin-utils": "npm:^7.24.8" + "@babel/helper-validator-identifier": "npm:^7.24.7" + "@babel/traverse": "npm:^7.25.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/fca6198da71237e4bb1274b3b67a0c81d56013c9535361242b6bfa87d70a9597854aadb45d4d8203369be4a655e158be2a5d20af0040b1f8d1bfc47db3ad7b68 + languageName: node + linkType: hard + +"@babel/plugin-transform-modules-umd@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-modules-umd@npm:7.24.7" dependencies: @@ -1588,7 +1907,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-named-capturing-groups-regex@npm:^7.22.5, @babel/plugin-transform-named-capturing-groups-regex@npm:^7.24.7": +"@babel/plugin-transform-named-capturing-groups-regex@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-named-capturing-groups-regex@npm:7.24.7" dependencies: @@ -1600,7 +1919,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-new-target@npm:^7.24.1, @babel/plugin-transform-new-target@npm:^7.24.7": +"@babel/plugin-transform-new-target@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-new-target@npm:7.24.7" dependencies: @@ -1611,7 +1930,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.24.1, @babel/plugin-transform-nullish-coalescing-operator@npm:^7.24.7": +"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-nullish-coalescing-operator@npm:7.24.7" dependencies: @@ -1623,7 +1942,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-numeric-separator@npm:^7.24.1, @babel/plugin-transform-numeric-separator@npm:^7.24.7": +"@babel/plugin-transform-numeric-separator@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-numeric-separator@npm:7.24.7" dependencies: @@ -1635,7 +1954,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-object-rest-spread@npm:^7.24.5, @babel/plugin-transform-object-rest-spread@npm:^7.24.7": +"@babel/plugin-transform-object-rest-spread@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-object-rest-spread@npm:7.24.7" dependencies: @@ -1649,7 +1968,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-object-super@npm:^7.24.1, @babel/plugin-transform-object-super@npm:^7.24.7": +"@babel/plugin-transform-object-super@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-object-super@npm:7.24.7" dependencies: @@ -1661,7 +1980,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-optional-catch-binding@npm:^7.24.1, @babel/plugin-transform-optional-catch-binding@npm:^7.24.7": +"@babel/plugin-transform-optional-catch-binding@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-optional-catch-binding@npm:7.24.7" dependencies: @@ -1673,7 +1992,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-optional-chaining@npm:^7.24.5, @babel/plugin-transform-optional-chaining@npm:^7.24.7": +"@babel/plugin-transform-optional-chaining@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-optional-chaining@npm:7.24.7" dependencies: @@ -1686,7 +2005,20 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-parameters@npm:^7.24.5, @babel/plugin-transform-parameters@npm:^7.24.7": +"@babel/plugin-transform-optional-chaining@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/plugin-transform-optional-chaining@npm:7.24.8" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.24.8" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.24.7" + "@babel/plugin-syntax-optional-chaining": "npm:^7.8.3" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/4ffbe1aad7dec7c9aa2bf6ceb4b2f91f96815b2784f2879bde80e46934f59d64a12cb2c6262e40897c4754d77d2c35d8a5cfed63044fdebf94978b1ed3d14b17 + languageName: node + linkType: hard + +"@babel/plugin-transform-parameters@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-parameters@npm:7.24.7" dependencies: @@ -1697,7 +2029,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-private-methods@npm:^7.24.1, @babel/plugin-transform-private-methods@npm:^7.24.6, @babel/plugin-transform-private-methods@npm:^7.24.7": +"@babel/plugin-transform-private-methods@npm:^7.24.6, @babel/plugin-transform-private-methods@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-private-methods@npm:7.24.7" dependencies: @@ -1709,7 +2041,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-private-property-in-object@npm:^7.24.5, @babel/plugin-transform-private-property-in-object@npm:^7.24.7": +"@babel/plugin-transform-private-property-in-object@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-private-property-in-object@npm:7.24.7" dependencies: @@ -1723,7 +2055,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-property-literals@npm:^7.24.1, @babel/plugin-transform-property-literals@npm:^7.24.7": +"@babel/plugin-transform-property-literals@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-property-literals@npm:7.24.7" dependencies: @@ -1734,7 +2066,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-regenerator@npm:^7.24.1, @babel/plugin-transform-regenerator@npm:^7.24.7": +"@babel/plugin-transform-regenerator@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-regenerator@npm:7.24.7" dependencies: @@ -1746,7 +2078,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-reserved-words@npm:^7.24.1, @babel/plugin-transform-reserved-words@npm:^7.24.7": +"@babel/plugin-transform-reserved-words@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-reserved-words@npm:7.24.7" dependencies: @@ -1757,23 +2089,23 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-runtime@npm:7.24.3": - version: 7.24.3 - resolution: "@babel/plugin-transform-runtime@npm:7.24.3" +"@babel/plugin-transform-runtime@npm:7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-runtime@npm:7.24.7" dependencies: - "@babel/helper-module-imports": "npm:^7.24.3" - "@babel/helper-plugin-utils": "npm:^7.24.0" + "@babel/helper-module-imports": "npm:^7.24.7" + "@babel/helper-plugin-utils": "npm:^7.24.7" babel-plugin-polyfill-corejs2: "npm:^0.4.10" babel-plugin-polyfill-corejs3: "npm:^0.10.1" babel-plugin-polyfill-regenerator: "npm:^0.6.1" semver: "npm:^6.3.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/ee01967bf405d84bd95ca4089166a18fb23fe9851a6da53dcf712a7f8ba003319996f21f320d568ec76126e18adfaee978206ccda86eef7652d47cc9a052e75e + checksum: 10c0/a33f5095872bbba00b8ee553dfe6941477e69a017a2e65e9dd86e80dab5c627635093b796eb1eb22aaaf2f874704f63ad1d99b952b83b59ef6b368ae04e5bb41 languageName: node linkType: hard -"@babel/plugin-transform-shorthand-properties@npm:^7.24.1, @babel/plugin-transform-shorthand-properties@npm:^7.24.7": +"@babel/plugin-transform-shorthand-properties@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-shorthand-properties@npm:7.24.7" dependencies: @@ -1784,7 +2116,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-spread@npm:^7.24.1, @babel/plugin-transform-spread@npm:^7.24.7": +"@babel/plugin-transform-spread@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-spread@npm:7.24.7" dependencies: @@ -1796,7 +2128,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-sticky-regex@npm:^7.24.1, @babel/plugin-transform-sticky-regex@npm:^7.24.7": +"@babel/plugin-transform-sticky-regex@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-sticky-regex@npm:7.24.7" dependencies: @@ -1807,7 +2139,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-template-literals@npm:^7.24.1, @babel/plugin-transform-template-literals@npm:^7.24.7": +"@babel/plugin-transform-template-literals@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-template-literals@npm:7.24.7" dependencies: @@ -1818,7 +2150,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-typeof-symbol@npm:^7.24.5, @babel/plugin-transform-typeof-symbol@npm:^7.24.7": +"@babel/plugin-transform-typeof-symbol@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-typeof-symbol@npm:7.24.7" dependencies: @@ -1829,7 +2161,18 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-unicode-escapes@npm:^7.24.1, @babel/plugin-transform-unicode-escapes@npm:^7.24.7": +"@babel/plugin-transform-typeof-symbol@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/plugin-transform-typeof-symbol@npm:7.24.8" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.24.8" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/2f570a4fbbdc5fd85f48165a97452826560051e3b8efb48c3bb0a0a33ee8485633439e7b71bfe3ef705583a1df43f854f49125bd759abdedc195b2cf7e60012a + languageName: node + linkType: hard + +"@babel/plugin-transform-unicode-escapes@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-unicode-escapes@npm:7.24.7" dependencies: @@ -1840,7 +2183,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-unicode-property-regex@npm:^7.24.1, @babel/plugin-transform-unicode-property-regex@npm:^7.24.7": +"@babel/plugin-transform-unicode-property-regex@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-unicode-property-regex@npm:7.24.7" dependencies: @@ -1852,7 +2195,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-unicode-regex@npm:^7.24.1, @babel/plugin-transform-unicode-regex@npm:^7.24.7": +"@babel/plugin-transform-unicode-regex@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-unicode-regex@npm:7.24.7" dependencies: @@ -1864,7 +2207,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-unicode-sets-regex@npm:^7.24.1, @babel/plugin-transform-unicode-sets-regex@npm:^7.24.7": +"@babel/plugin-transform-unicode-sets-regex@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-unicode-sets-regex@npm:7.24.7" dependencies: @@ -1876,26 +2219,27 @@ __metadata: languageName: node linkType: hard -"@babel/preset-env@npm:7.24.5": - version: 7.24.5 - resolution: "@babel/preset-env@npm:7.24.5" +"@babel/preset-env@npm:7.25.3": + version: 7.25.3 + resolution: "@babel/preset-env@npm:7.25.3" dependencies: - "@babel/compat-data": "npm:^7.24.4" - "@babel/helper-compilation-targets": "npm:^7.23.6" - "@babel/helper-plugin-utils": "npm:^7.24.5" - "@babel/helper-validator-option": "npm:^7.23.5" - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "npm:^7.24.5" - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "npm:^7.24.1" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "npm:^7.24.1" - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "npm:^7.24.1" + "@babel/compat-data": "npm:^7.25.2" + "@babel/helper-compilation-targets": "npm:^7.25.2" + "@babel/helper-plugin-utils": "npm:^7.24.8" + "@babel/helper-validator-option": "npm:^7.24.8" + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "npm:^7.25.3" + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "npm:^7.25.0" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "npm:^7.25.0" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "npm:^7.24.7" + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "npm:^7.25.0" "@babel/plugin-proposal-private-property-in-object": "npm:7.21.0-placeholder-for-preset-env.2" "@babel/plugin-syntax-async-generators": "npm:^7.8.4" "@babel/plugin-syntax-class-properties": "npm:^7.12.13" "@babel/plugin-syntax-class-static-block": "npm:^7.14.5" "@babel/plugin-syntax-dynamic-import": "npm:^7.8.3" "@babel/plugin-syntax-export-namespace-from": "npm:^7.8.3" - "@babel/plugin-syntax-import-assertions": "npm:^7.24.1" - "@babel/plugin-syntax-import-attributes": "npm:^7.24.1" + "@babel/plugin-syntax-import-assertions": "npm:^7.24.7" + "@babel/plugin-syntax-import-attributes": "npm:^7.24.7" "@babel/plugin-syntax-import-meta": "npm:^7.10.4" "@babel/plugin-syntax-json-strings": "npm:^7.8.3" "@babel/plugin-syntax-logical-assignment-operators": "npm:^7.10.4" @@ -1907,63 +2251,64 @@ __metadata: "@babel/plugin-syntax-private-property-in-object": "npm:^7.14.5" "@babel/plugin-syntax-top-level-await": "npm:^7.14.5" "@babel/plugin-syntax-unicode-sets-regex": "npm:^7.18.6" - "@babel/plugin-transform-arrow-functions": "npm:^7.24.1" - "@babel/plugin-transform-async-generator-functions": "npm:^7.24.3" - "@babel/plugin-transform-async-to-generator": "npm:^7.24.1" - "@babel/plugin-transform-block-scoped-functions": "npm:^7.24.1" - "@babel/plugin-transform-block-scoping": "npm:^7.24.5" - "@babel/plugin-transform-class-properties": "npm:^7.24.1" - "@babel/plugin-transform-class-static-block": "npm:^7.24.4" - "@babel/plugin-transform-classes": "npm:^7.24.5" - "@babel/plugin-transform-computed-properties": "npm:^7.24.1" - "@babel/plugin-transform-destructuring": "npm:^7.24.5" - "@babel/plugin-transform-dotall-regex": "npm:^7.24.1" - "@babel/plugin-transform-duplicate-keys": "npm:^7.24.1" - "@babel/plugin-transform-dynamic-import": "npm:^7.24.1" - "@babel/plugin-transform-exponentiation-operator": "npm:^7.24.1" - "@babel/plugin-transform-export-namespace-from": "npm:^7.24.1" - "@babel/plugin-transform-for-of": "npm:^7.24.1" - "@babel/plugin-transform-function-name": "npm:^7.24.1" - "@babel/plugin-transform-json-strings": "npm:^7.24.1" - "@babel/plugin-transform-literals": "npm:^7.24.1" - "@babel/plugin-transform-logical-assignment-operators": "npm:^7.24.1" - "@babel/plugin-transform-member-expression-literals": "npm:^7.24.1" - "@babel/plugin-transform-modules-amd": "npm:^7.24.1" - "@babel/plugin-transform-modules-commonjs": "npm:^7.24.1" - "@babel/plugin-transform-modules-systemjs": "npm:^7.24.1" - "@babel/plugin-transform-modules-umd": "npm:^7.24.1" - "@babel/plugin-transform-named-capturing-groups-regex": "npm:^7.22.5" - "@babel/plugin-transform-new-target": "npm:^7.24.1" - "@babel/plugin-transform-nullish-coalescing-operator": "npm:^7.24.1" - "@babel/plugin-transform-numeric-separator": "npm:^7.24.1" - "@babel/plugin-transform-object-rest-spread": "npm:^7.24.5" - "@babel/plugin-transform-object-super": "npm:^7.24.1" - "@babel/plugin-transform-optional-catch-binding": "npm:^7.24.1" - "@babel/plugin-transform-optional-chaining": "npm:^7.24.5" - "@babel/plugin-transform-parameters": "npm:^7.24.5" - "@babel/plugin-transform-private-methods": "npm:^7.24.1" - "@babel/plugin-transform-private-property-in-object": "npm:^7.24.5" - "@babel/plugin-transform-property-literals": "npm:^7.24.1" - "@babel/plugin-transform-regenerator": "npm:^7.24.1" - "@babel/plugin-transform-reserved-words": "npm:^7.24.1" - "@babel/plugin-transform-shorthand-properties": "npm:^7.24.1" - "@babel/plugin-transform-spread": "npm:^7.24.1" - "@babel/plugin-transform-sticky-regex": "npm:^7.24.1" - "@babel/plugin-transform-template-literals": "npm:^7.24.1" - "@babel/plugin-transform-typeof-symbol": "npm:^7.24.5" - "@babel/plugin-transform-unicode-escapes": "npm:^7.24.1" - "@babel/plugin-transform-unicode-property-regex": "npm:^7.24.1" - "@babel/plugin-transform-unicode-regex": "npm:^7.24.1" - "@babel/plugin-transform-unicode-sets-regex": "npm:^7.24.1" + "@babel/plugin-transform-arrow-functions": "npm:^7.24.7" + "@babel/plugin-transform-async-generator-functions": "npm:^7.25.0" + "@babel/plugin-transform-async-to-generator": "npm:^7.24.7" + "@babel/plugin-transform-block-scoped-functions": "npm:^7.24.7" + "@babel/plugin-transform-block-scoping": "npm:^7.25.0" + "@babel/plugin-transform-class-properties": "npm:^7.24.7" + "@babel/plugin-transform-class-static-block": "npm:^7.24.7" + "@babel/plugin-transform-classes": "npm:^7.25.0" + "@babel/plugin-transform-computed-properties": "npm:^7.24.7" + "@babel/plugin-transform-destructuring": "npm:^7.24.8" + "@babel/plugin-transform-dotall-regex": "npm:^7.24.7" + "@babel/plugin-transform-duplicate-keys": "npm:^7.24.7" + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "npm:^7.25.0" + "@babel/plugin-transform-dynamic-import": "npm:^7.24.7" + "@babel/plugin-transform-exponentiation-operator": "npm:^7.24.7" + "@babel/plugin-transform-export-namespace-from": "npm:^7.24.7" + "@babel/plugin-transform-for-of": "npm:^7.24.7" + "@babel/plugin-transform-function-name": "npm:^7.25.1" + "@babel/plugin-transform-json-strings": "npm:^7.24.7" + "@babel/plugin-transform-literals": "npm:^7.25.2" + "@babel/plugin-transform-logical-assignment-operators": "npm:^7.24.7" + "@babel/plugin-transform-member-expression-literals": "npm:^7.24.7" + "@babel/plugin-transform-modules-amd": "npm:^7.24.7" + "@babel/plugin-transform-modules-commonjs": "npm:^7.24.8" + "@babel/plugin-transform-modules-systemjs": "npm:^7.25.0" + "@babel/plugin-transform-modules-umd": "npm:^7.24.7" + "@babel/plugin-transform-named-capturing-groups-regex": "npm:^7.24.7" + "@babel/plugin-transform-new-target": "npm:^7.24.7" + "@babel/plugin-transform-nullish-coalescing-operator": "npm:^7.24.7" + "@babel/plugin-transform-numeric-separator": "npm:^7.24.7" + "@babel/plugin-transform-object-rest-spread": "npm:^7.24.7" + "@babel/plugin-transform-object-super": "npm:^7.24.7" + "@babel/plugin-transform-optional-catch-binding": "npm:^7.24.7" + "@babel/plugin-transform-optional-chaining": "npm:^7.24.8" + "@babel/plugin-transform-parameters": "npm:^7.24.7" + "@babel/plugin-transform-private-methods": "npm:^7.24.7" + "@babel/plugin-transform-private-property-in-object": "npm:^7.24.7" + "@babel/plugin-transform-property-literals": "npm:^7.24.7" + "@babel/plugin-transform-regenerator": "npm:^7.24.7" + "@babel/plugin-transform-reserved-words": "npm:^7.24.7" + "@babel/plugin-transform-shorthand-properties": "npm:^7.24.7" + "@babel/plugin-transform-spread": "npm:^7.24.7" + "@babel/plugin-transform-sticky-regex": "npm:^7.24.7" + "@babel/plugin-transform-template-literals": "npm:^7.24.7" + "@babel/plugin-transform-typeof-symbol": "npm:^7.24.8" + "@babel/plugin-transform-unicode-escapes": "npm:^7.24.7" + "@babel/plugin-transform-unicode-property-regex": "npm:^7.24.7" + "@babel/plugin-transform-unicode-regex": "npm:^7.24.7" + "@babel/plugin-transform-unicode-sets-regex": "npm:^7.24.7" "@babel/preset-modules": "npm:0.1.6-no-external-plugins" babel-plugin-polyfill-corejs2: "npm:^0.4.10" babel-plugin-polyfill-corejs3: "npm:^0.10.4" babel-plugin-polyfill-regenerator: "npm:^0.6.1" - core-js-compat: "npm:^3.31.0" + core-js-compat: "npm:^3.37.1" semver: "npm:^6.3.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/2cc0edae09205d6409a75d02e53aaa1c590e89adbb7b389019c7b75e4c47b6b63eeb1a816df5c42b672ce410747e7ddc23b6747e8e41a6c95d6fa00c665509e2 + checksum: 10c0/9287dc2e296fe2aa3367d84c2a799db17c9d1e48bba86525f47c6f51f5ba2e2cce454f45f4ae2ef928f9077c0640b04556b55b94835675ceeca94a0c5133205e languageName: node linkType: hard @@ -2078,12 +2423,12 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:7.24.5": - version: 7.24.5 - resolution: "@babel/runtime@npm:7.24.5" +"@babel/runtime@npm:7.25.0": + version: 7.25.0 + resolution: "@babel/runtime@npm:7.25.0" dependencies: regenerator-runtime: "npm:^0.14.0" - checksum: 10c0/05730e43e8ba6550eae9fd4fb5e7d9d3cb91140379425abcb2a1ff9cebad518a280d82c4c4b0f57ada26a863106ac54a748d90c775790c0e2cd0ddd85ccdf346 + checksum: 10c0/bd3faf246170826cef2071a94d7b47b49d532351360ecd17722d03f6713fd93a3eb3dbd9518faa778d5e8ccad7392a7a604e56bd37aaad3f3aa68d619ccd983d languageName: node linkType: hard @@ -2096,7 +2441,7 @@ __metadata: languageName: node linkType: hard -"@babel/template@npm:^7.24.0, @babel/template@npm:^7.24.7": +"@babel/template@npm:^7.24.7": version: 7.24.7 resolution: "@babel/template@npm:7.24.7" dependencies: @@ -2107,7 +2452,18 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.24.5, @babel/traverse@npm:^7.24.7": +"@babel/template@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/template@npm:7.25.0" + dependencies: + "@babel/code-frame": "npm:^7.24.7" + "@babel/parser": "npm:^7.25.0" + "@babel/types": "npm:^7.25.0" + checksum: 10c0/4e31afd873215744c016e02b04f43b9fa23205d6d0766fb2e93eb4091c60c1b88897936adb895fb04e3c23de98dfdcbe31bc98daaa1a4e0133f78bb948e1209b + languageName: node + linkType: hard + +"@babel/traverse@npm:^7.24.7": version: 7.24.7 resolution: "@babel/traverse@npm:7.24.7" dependencies: @@ -2125,7 +2481,40 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.22.5, @babel/types@npm:^7.24.5, @babel/types@npm:^7.24.7, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3": +"@babel/traverse@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/traverse@npm:7.24.8" + dependencies: + "@babel/code-frame": "npm:^7.24.7" + "@babel/generator": "npm:^7.24.8" + "@babel/helper-environment-visitor": "npm:^7.24.7" + "@babel/helper-function-name": "npm:^7.24.7" + "@babel/helper-hoist-variables": "npm:^7.24.7" + "@babel/helper-split-export-declaration": "npm:^7.24.7" + "@babel/parser": "npm:^7.24.8" + "@babel/types": "npm:^7.24.8" + debug: "npm:^4.3.1" + globals: "npm:^11.1.0" + checksum: 10c0/67a5cc35824455cdb54fb9e196a44b3186283e29018a9c2331f51763921e18e891b3c60c283615a27540ec8eb4c8b89f41c237b91f732a7aa518b2eb7a0d434d + languageName: node + linkType: hard + +"@babel/traverse@npm:^7.25.0, @babel/traverse@npm:^7.25.1, @babel/traverse@npm:^7.25.2, @babel/traverse@npm:^7.25.3": + version: 7.25.3 + resolution: "@babel/traverse@npm:7.25.3" + dependencies: + "@babel/code-frame": "npm:^7.24.7" + "@babel/generator": "npm:^7.25.0" + "@babel/parser": "npm:^7.25.3" + "@babel/template": "npm:^7.25.0" + "@babel/types": "npm:^7.25.2" + debug: "npm:^4.3.1" + globals: "npm:^11.1.0" + checksum: 10c0/4c8a1966fa90b53a783a4afd2fcdaa6ab1a912e6621dca9fcc6633e80ccb9491620e88caf73b537da4e16cefd537b548c87d7087868d5b0066414dea375c0e9b + languageName: node + linkType: hard + +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.24.7, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3": version: 7.24.7 resolution: "@babel/types@npm:7.24.7" dependencies: @@ -2136,6 +2525,28 @@ __metadata: languageName: node linkType: hard +"@babel/types@npm:^7.24.8, @babel/types@npm:^7.24.9": + version: 7.24.9 + resolution: "@babel/types@npm:7.24.9" + dependencies: + "@babel/helper-string-parser": "npm:^7.24.8" + "@babel/helper-validator-identifier": "npm:^7.24.7" + to-fast-properties: "npm:^2.0.0" + checksum: 10c0/4970b3481cab39c5c3fdb7c28c834df5c7049f3c7f43baeafe121bb05270ebf0da7c65b097abf314877f213baa591109c82204f30d66cdd46c22ece4a2f32415 + languageName: node + linkType: hard + +"@babel/types@npm:^7.25.0, @babel/types@npm:^7.25.2": + version: 7.25.2 + resolution: "@babel/types@npm:7.25.2" + dependencies: + "@babel/helper-string-parser": "npm:^7.24.8" + "@babel/helper-validator-identifier": "npm:^7.24.7" + to-fast-properties: "npm:^2.0.0" + checksum: 10c0/e489435856be239f8cc1120c90a197e4c2865385121908e5edb7223cfdff3768cba18f489adfe0c26955d9e7bbb1fb10625bc2517505908ceb0af848989bd864 + languageName: node + linkType: hard + "@codemirror/autocomplete@npm:^6.0.0": version: 6.16.2 resolution: "@codemirror/autocomplete@npm:6.16.2" @@ -2179,12 +2590,12 @@ __metadata: languageName: node linkType: hard -"@codemirror/legacy-modes@npm:^6.4.0": - version: 6.4.0 - resolution: "@codemirror/legacy-modes@npm:6.4.0" +"@codemirror/legacy-modes@npm:^6.4.1": + version: 6.4.1 + resolution: "@codemirror/legacy-modes@npm:6.4.1" dependencies: "@codemirror/language": "npm:^6.0.0" - checksum: 10c0/0d4a4c120fcc2e476393a3e1fc6d5d396c9b64e3b4c35ea473fdb71f5117fbedca8be4e360321272880665dd8bd6aca2ce8736209056e9c7cec714f003ce28aa + checksum: 10c0/4a75eb664bde93f3979084c386a85074eb2522503220ca1999bb6b33cf188bca44c024aefa378f784db7f3d55ba9707abd4194fe1dc7a2cec330a5f986501644 languageName: node linkType: hard @@ -2235,20 +2646,20 @@ __metadata: languageName: node linkType: hard -"@commitlint/cli@npm:^19.3.0": - version: 19.3.0 - resolution: "@commitlint/cli@npm:19.3.0" +"@commitlint/cli@npm:^19.4.0": + version: 19.4.0 + resolution: "@commitlint/cli@npm:19.4.0" dependencies: "@commitlint/format": "npm:^19.3.0" "@commitlint/lint": "npm:^19.2.2" - "@commitlint/load": "npm:^19.2.0" - "@commitlint/read": "npm:^19.2.1" + "@commitlint/load": "npm:^19.4.0" + "@commitlint/read": "npm:^19.4.0" "@commitlint/types": "npm:^19.0.3" execa: "npm:^8.0.1" yargs: "npm:^17.0.0" bin: commitlint: cli.js - checksum: 10c0/12049b6ccb1fd3939c5713fdc9b2aa9054985f3ced465e9494ce7c23b3c69a9e9ea25c84fffa5ba147b6bb5cd086a29000dfac2218a7592494b007bab592e057 + checksum: 10c0/b3f4a0b07ae18c59bcc7c4a10fa5e265271d1f76b94d1c64371104b0f9cdabf8480c941382c3de5db53513b3c4785acc02f9445a1f357361ff4f5ff4ecdf5f4b languageName: node linkType: hard @@ -2331,9 +2742,9 @@ __metadata: languageName: node linkType: hard -"@commitlint/load@npm:^19.2.0": - version: 19.2.0 - resolution: "@commitlint/load@npm:19.2.0" +"@commitlint/load@npm:^19.4.0": + version: 19.4.0 + resolution: "@commitlint/load@npm:19.4.0" dependencies: "@commitlint/config-validator": "npm:^19.0.3" "@commitlint/execute-rule": "npm:^19.0.0" @@ -2345,7 +2756,7 @@ __metadata: lodash.isplainobject: "npm:^4.0.6" lodash.merge: "npm:^4.6.2" lodash.uniq: "npm:^4.5.0" - checksum: 10c0/100ad63e99f59cdad7f48748b77a9a55710a2487971dd2ee503ba003aaf407ab49acf844a45c87a8b5e0a4de3a037cadaed9460ecd6d2e886bbdf943eb344bb2 + checksum: 10c0/805fd80b1f0e127a03b89405c60535dd89fd6676c749ef86e4a41af787f3c9cae0c18c5d5ce906bd6620f566b37d19a4edff63d21539da4212414fd741e19c72 languageName: node linkType: hard @@ -2367,16 +2778,16 @@ __metadata: languageName: node linkType: hard -"@commitlint/read@npm:^19.2.1": - version: 19.2.1 - resolution: "@commitlint/read@npm:19.2.1" +"@commitlint/read@npm:^19.4.0": + version: 19.4.0 + resolution: "@commitlint/read@npm:19.4.0" dependencies: "@commitlint/top-level": "npm:^19.0.0" "@commitlint/types": "npm:^19.0.3" execa: "npm:^8.0.1" git-raw-commits: "npm:^4.0.0" minimist: "npm:^1.2.8" - checksum: 10c0/9aef7e24164fe502c59b8acb867a9193bff2aab9bcdd74b9c18e2fada27d631360a1e3ce74898104bc8eae45129216d4227d22fa20ca65b59d6ad45b26d71b66 + checksum: 10c0/b0243feeb903fe4bb15bc352b10116451ac280fffbf2220a684e0f01ce4583e558b944ff8a6901f8a70faa0ec6020fa720da70328fb110747dbd4a7162695125 languageName: node linkType: hard @@ -2567,338 +2978,349 @@ __metadata: languageName: node linkType: hard -"@es-joy/jsdoccomment@npm:~0.43.1": - version: 0.43.1 - resolution: "@es-joy/jsdoccomment@npm:0.43.1" +"@discoveryjs/json-ext@npm:0.6.1": + version: 0.6.1 + resolution: "@discoveryjs/json-ext@npm:0.6.1" + checksum: 10c0/116838b9685f26ce88335703f0f0cb84a242f9db93a6b408676c314a3bfd916ef405d84c3ff427e882dc4775b586e3a8a9d88fecc07cc93cbd33f6d560db29bf + languageName: node + linkType: hard + +"@es-joy/jsdoccomment@npm:~0.48.0": + version: 0.48.0 + resolution: "@es-joy/jsdoccomment@npm:0.48.0" dependencies: - "@types/eslint": "npm:^8.56.5" - "@types/estree": "npm:^1.0.5" - "@typescript-eslint/types": "npm:^7.2.0" comment-parser: "npm:1.4.1" - esquery: "npm:^1.5.0" - jsdoc-type-pratt-parser: "npm:~4.0.0" - checksum: 10c0/2a4842b0e37eb937d55e3028ab2cd7ece7097e1f8c878bb9e28c3309371844688c2869d25bb949e2664c9ba63e388ea09b769c9f42f77515d328ec40e6fcfed1 + esquery: "npm:^1.6.0" + jsdoc-type-pratt-parser: "npm:~4.1.0" + checksum: 10c0/8d87c7c0426fade009c30ab429d4ede53fd253d40b55079c02bdacdaa4c0fe904aaea5e3084cd98052f2bed6b3030c381d84f4a3251b343a71fee6f681a08bee languageName: node linkType: hard -"@esbuild/aix-ppc64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/aix-ppc64@npm:0.20.2" +"@esbuild/aix-ppc64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/aix-ppc64@npm:0.21.5" conditions: os=aix & cpu=ppc64 languageName: node linkType: hard -"@esbuild/aix-ppc64@npm:0.21.3": - version: 0.21.3 - resolution: "@esbuild/aix-ppc64@npm:0.21.3" +"@esbuild/aix-ppc64@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/aix-ppc64@npm:0.23.0" conditions: os=aix & cpu=ppc64 languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/android-arm64@npm:0.20.2" +"@esbuild/android-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/android-arm64@npm:0.21.5" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.21.3": - version: 0.21.3 - resolution: "@esbuild/android-arm64@npm:0.21.3" +"@esbuild/android-arm64@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/android-arm64@npm:0.23.0" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@esbuild/android-arm@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/android-arm@npm:0.20.2" +"@esbuild/android-arm@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/android-arm@npm:0.21.5" conditions: os=android & cpu=arm languageName: node linkType: hard -"@esbuild/android-arm@npm:0.21.3": - version: 0.21.3 - resolution: "@esbuild/android-arm@npm:0.21.3" +"@esbuild/android-arm@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/android-arm@npm:0.23.0" conditions: os=android & cpu=arm languageName: node linkType: hard -"@esbuild/android-x64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/android-x64@npm:0.20.2" +"@esbuild/android-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/android-x64@npm:0.21.5" conditions: os=android & cpu=x64 languageName: node linkType: hard -"@esbuild/android-x64@npm:0.21.3": - version: 0.21.3 - resolution: "@esbuild/android-x64@npm:0.21.3" +"@esbuild/android-x64@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/android-x64@npm:0.23.0" conditions: os=android & cpu=x64 languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/darwin-arm64@npm:0.20.2" +"@esbuild/darwin-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/darwin-arm64@npm:0.21.5" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.21.3": - version: 0.21.3 - resolution: "@esbuild/darwin-arm64@npm:0.21.3" +"@esbuild/darwin-arm64@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/darwin-arm64@npm:0.23.0" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/darwin-x64@npm:0.20.2" +"@esbuild/darwin-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/darwin-x64@npm:0.21.5" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.21.3": - version: 0.21.3 - resolution: "@esbuild/darwin-x64@npm:0.21.3" +"@esbuild/darwin-x64@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/darwin-x64@npm:0.23.0" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/freebsd-arm64@npm:0.20.2" +"@esbuild/freebsd-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/freebsd-arm64@npm:0.21.5" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.21.3": - version: 0.21.3 - resolution: "@esbuild/freebsd-arm64@npm:0.21.3" +"@esbuild/freebsd-arm64@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/freebsd-arm64@npm:0.23.0" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/freebsd-x64@npm:0.20.2" +"@esbuild/freebsd-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/freebsd-x64@npm:0.21.5" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.21.3": - version: 0.21.3 - resolution: "@esbuild/freebsd-x64@npm:0.21.3" +"@esbuild/freebsd-x64@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/freebsd-x64@npm:0.23.0" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/linux-arm64@npm:0.20.2" +"@esbuild/linux-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-arm64@npm:0.21.5" conditions: os=linux & cpu=arm64 languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.21.3": - version: 0.21.3 - resolution: "@esbuild/linux-arm64@npm:0.21.3" +"@esbuild/linux-arm64@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/linux-arm64@npm:0.23.0" conditions: os=linux & cpu=arm64 languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/linux-arm@npm:0.20.2" +"@esbuild/linux-arm@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-arm@npm:0.21.5" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.21.3": - version: 0.21.3 - resolution: "@esbuild/linux-arm@npm:0.21.3" +"@esbuild/linux-arm@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/linux-arm@npm:0.23.0" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/linux-ia32@npm:0.20.2" +"@esbuild/linux-ia32@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-ia32@npm:0.21.5" conditions: os=linux & cpu=ia32 languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.21.3": - version: 0.21.3 - resolution: "@esbuild/linux-ia32@npm:0.21.3" +"@esbuild/linux-ia32@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/linux-ia32@npm:0.23.0" conditions: os=linux & cpu=ia32 languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/linux-loong64@npm:0.20.2" +"@esbuild/linux-loong64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-loong64@npm:0.21.5" conditions: os=linux & cpu=loong64 languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.21.3": - version: 0.21.3 - resolution: "@esbuild/linux-loong64@npm:0.21.3" +"@esbuild/linux-loong64@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/linux-loong64@npm:0.23.0" conditions: os=linux & cpu=loong64 languageName: node linkType: hard -"@esbuild/linux-mips64el@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/linux-mips64el@npm:0.20.2" +"@esbuild/linux-mips64el@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-mips64el@npm:0.21.5" conditions: os=linux & cpu=mips64el languageName: node linkType: hard -"@esbuild/linux-mips64el@npm:0.21.3": - version: 0.21.3 - resolution: "@esbuild/linux-mips64el@npm:0.21.3" +"@esbuild/linux-mips64el@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/linux-mips64el@npm:0.23.0" conditions: os=linux & cpu=mips64el languageName: node linkType: hard -"@esbuild/linux-ppc64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/linux-ppc64@npm:0.20.2" +"@esbuild/linux-ppc64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-ppc64@npm:0.21.5" conditions: os=linux & cpu=ppc64 languageName: node linkType: hard -"@esbuild/linux-ppc64@npm:0.21.3": - version: 0.21.3 - resolution: "@esbuild/linux-ppc64@npm:0.21.3" +"@esbuild/linux-ppc64@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/linux-ppc64@npm:0.23.0" conditions: os=linux & cpu=ppc64 languageName: node linkType: hard -"@esbuild/linux-riscv64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/linux-riscv64@npm:0.20.2" +"@esbuild/linux-riscv64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-riscv64@npm:0.21.5" conditions: os=linux & cpu=riscv64 languageName: node linkType: hard -"@esbuild/linux-riscv64@npm:0.21.3": - version: 0.21.3 - resolution: "@esbuild/linux-riscv64@npm:0.21.3" +"@esbuild/linux-riscv64@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/linux-riscv64@npm:0.23.0" conditions: os=linux & cpu=riscv64 languageName: node linkType: hard -"@esbuild/linux-s390x@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/linux-s390x@npm:0.20.2" +"@esbuild/linux-s390x@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-s390x@npm:0.21.5" conditions: os=linux & cpu=s390x languageName: node linkType: hard -"@esbuild/linux-s390x@npm:0.21.3": - version: 0.21.3 - resolution: "@esbuild/linux-s390x@npm:0.21.3" +"@esbuild/linux-s390x@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/linux-s390x@npm:0.23.0" conditions: os=linux & cpu=s390x languageName: node linkType: hard -"@esbuild/linux-x64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/linux-x64@npm:0.20.2" +"@esbuild/linux-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-x64@npm:0.21.5" conditions: os=linux & cpu=x64 languageName: node linkType: hard -"@esbuild/linux-x64@npm:0.21.3": - version: 0.21.3 - resolution: "@esbuild/linux-x64@npm:0.21.3" +"@esbuild/linux-x64@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/linux-x64@npm:0.23.0" conditions: os=linux & cpu=x64 languageName: node linkType: hard -"@esbuild/netbsd-x64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/netbsd-x64@npm:0.20.2" +"@esbuild/netbsd-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/netbsd-x64@npm:0.21.5" conditions: os=netbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/netbsd-x64@npm:0.21.3": - version: 0.21.3 - resolution: "@esbuild/netbsd-x64@npm:0.21.3" +"@esbuild/netbsd-x64@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/netbsd-x64@npm:0.23.0" conditions: os=netbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/openbsd-x64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/openbsd-x64@npm:0.20.2" +"@esbuild/openbsd-arm64@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/openbsd-arm64@npm:0.23.0" + conditions: os=openbsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/openbsd-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/openbsd-x64@npm:0.21.5" conditions: os=openbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/openbsd-x64@npm:0.21.3": - version: 0.21.3 - resolution: "@esbuild/openbsd-x64@npm:0.21.3" +"@esbuild/openbsd-x64@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/openbsd-x64@npm:0.23.0" conditions: os=openbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/sunos-x64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/sunos-x64@npm:0.20.2" +"@esbuild/sunos-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/sunos-x64@npm:0.21.5" conditions: os=sunos & cpu=x64 languageName: node linkType: hard -"@esbuild/sunos-x64@npm:0.21.3": - version: 0.21.3 - resolution: "@esbuild/sunos-x64@npm:0.21.3" +"@esbuild/sunos-x64@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/sunos-x64@npm:0.23.0" conditions: os=sunos & cpu=x64 languageName: node linkType: hard -"@esbuild/win32-arm64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/win32-arm64@npm:0.20.2" +"@esbuild/win32-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/win32-arm64@npm:0.21.5" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@esbuild/win32-arm64@npm:0.21.3": - version: 0.21.3 - resolution: "@esbuild/win32-arm64@npm:0.21.3" +"@esbuild/win32-arm64@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/win32-arm64@npm:0.23.0" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@esbuild/win32-ia32@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/win32-ia32@npm:0.20.2" +"@esbuild/win32-ia32@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/win32-ia32@npm:0.21.5" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@esbuild/win32-ia32@npm:0.21.3": - version: 0.21.3 - resolution: "@esbuild/win32-ia32@npm:0.21.3" +"@esbuild/win32-ia32@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/win32-ia32@npm:0.23.0" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@esbuild/win32-x64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/win32-x64@npm:0.20.2" +"@esbuild/win32-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/win32-x64@npm:0.21.5" conditions: os=win32 & cpu=x64 languageName: node linkType: hard -"@esbuild/win32-x64@npm:0.21.3": - version: 0.21.3 - resolution: "@esbuild/win32-x64@npm:0.21.3" +"@esbuild/win32-x64@npm:0.23.0": + version: 0.23.0 + resolution: "@esbuild/win32-x64@npm:0.23.0" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -2997,95 +3419,262 @@ __metadata: languageName: node linkType: hard -"@fortawesome/angular-fontawesome@npm:^0.15.0": - version: 0.15.0 - resolution: "@fortawesome/angular-fontawesome@npm:0.15.0" +"@fortawesome/angular-fontawesome@npm:^0.15.0": + version: 0.15.0 + resolution: "@fortawesome/angular-fontawesome@npm:0.15.0" + dependencies: + "@fortawesome/fontawesome-svg-core": "npm:^6.5.2" + tslib: "npm:^2.6.2" + peerDependencies: + "@angular/core": ^18.0.0 + checksum: 10c0/9ddc4d167850e3b507bb16edecefb84872cbb464f4dab3e113b1910a57c2ccd28e329b897e7394cbed7f10bb1ed659e9acdb905c5ec19f03f8e7aa4ddce3c247 + languageName: node + linkType: hard + +"@fortawesome/fontawesome-common-types@npm:6.5.2": + version: 6.5.2 + resolution: "@fortawesome/fontawesome-common-types@npm:6.5.2" + checksum: 10c0/12104e93a0056ad1077f7350826f52aa26465bb1d6b4ce75dab0307072a3871301ec750c3a34d89d05e7338c9b446fa2793150cf58a5167217021943ef877d77 + languageName: node + linkType: hard + +"@fortawesome/fontawesome-common-types@npm:6.6.0": + version: 6.6.0 + resolution: "@fortawesome/fontawesome-common-types@npm:6.6.0" + checksum: 10c0/f76e5959f6ce01355f599126a3a68facba578dc8ebb7ad40fbd22417b7056364a577c1887720ec9653d4efa5b704a01150f5064fc7de237d697fd80e3d9c83aa + languageName: node + linkType: hard + +"@fortawesome/fontawesome-svg-core@npm:^6.5.2": + version: 6.5.2 + resolution: "@fortawesome/fontawesome-svg-core@npm:6.5.2" + dependencies: + "@fortawesome/fontawesome-common-types": "npm:6.5.2" + checksum: 10c0/91695dd375623988d16e6f0dc69d20350ef3fa3296fe40aa08877aae7beaf64378134656a2227419fe648dcd27a81c03fe1fd9a6c87956d863164b0380ba77d0 + languageName: node + linkType: hard + +"@fortawesome/free-solid-svg-icons@npm:^6.6.0": + version: 6.6.0 + resolution: "@fortawesome/free-solid-svg-icons@npm:6.6.0" + dependencies: + "@fortawesome/fontawesome-common-types": "npm:6.6.0" + checksum: 10c0/34828d5e682c6f9d19e3a892ff8a390128fa7dc68768b11c727c11b6a05e5efc929206bfbec83e9d3ae0590a6f6ea22fd5e447fea647e560650f7f3ef1cff543 + languageName: node + linkType: hard + +"@gar/promisify@npm:^1.0.1": + version: 1.1.3 + resolution: "@gar/promisify@npm:1.1.3" + checksum: 10c0/0b3c9958d3cd17f4add3574975e3115ae05dc7f1298a60810414b16f6f558c137b5fb3cd3905df380bacfd955ec13f67c1e6710cbb5c246a7e8d65a8289b2bff + languageName: node + linkType: hard + +"@gfx/zopfli@npm:^1.0.15": + version: 1.0.15 + resolution: "@gfx/zopfli@npm:1.0.15" + dependencies: + base64-js: "npm:^1.3.0" + checksum: 10c0/b1ae57c68d144887e8c3752f7cc88dc6af3d75d523c665b5ab6e5fbc84d9de3459c84cb2dee677579a6d7f29b9e445faac1aabecf0ee4eafd1fb0c3f61f8988a + languageName: node + linkType: hard + +"@humanwhocodes/config-array@npm:^0.11.14": + version: 0.11.14 + resolution: "@humanwhocodes/config-array@npm:0.11.14" + dependencies: + "@humanwhocodes/object-schema": "npm:^2.0.2" + debug: "npm:^4.3.1" + minimatch: "npm:^3.0.5" + checksum: 10c0/66f725b4ee5fdd8322c737cb5013e19fac72d4d69c8bf4b7feb192fcb83442b035b92186f8e9497c220e58b2d51a080f28a73f7899bc1ab288c3be172c467541 + languageName: node + linkType: hard + +"@humanwhocodes/module-importer@npm:^1.0.1": + version: 1.0.1 + resolution: "@humanwhocodes/module-importer@npm:1.0.1" + checksum: 10c0/909b69c3b86d482c26b3359db16e46a32e0fb30bd306a3c176b8313b9e7313dba0f37f519de6aa8b0a1921349e505f259d19475e123182416a506d7f87e7f529 + languageName: node + linkType: hard + +"@humanwhocodes/object-schema@npm:^2.0.2": + version: 2.0.3 + resolution: "@humanwhocodes/object-schema@npm:2.0.3" + checksum: 10c0/80520eabbfc2d32fe195a93557cef50dfe8c8905de447f022675aaf66abc33ae54098f5ea78548d925aa671cd4ab7c7daa5ad704fe42358c9b5e7db60f80696c + languageName: node + linkType: hard + +"@hutson/parse-repository-url@npm:^3.0.0": + version: 3.0.2 + resolution: "@hutson/parse-repository-url@npm:3.0.2" + checksum: 10c0/d9197757ecad2df18d29d3e1d1fe0716d458fd88b849c71cbec9e78239f911074c97e8d764dfd8ed890431c1137e52dd7a337207fd65be20ce0784f7860ae4d1 + languageName: node + linkType: hard + +"@inquirer/checkbox@npm:^2.4.7": + version: 2.4.7 + resolution: "@inquirer/checkbox@npm:2.4.7" + dependencies: + "@inquirer/core": "npm:^9.0.10" + "@inquirer/figures": "npm:^1.0.5" + "@inquirer/type": "npm:^1.5.2" + ansi-escapes: "npm:^4.3.2" + yoctocolors-cjs: "npm:^2.1.2" + checksum: 10c0/92bd2727f316e2304b150ef32eb3023200512de154b49b6e121f468c2ad6fa58cb3b37d9dc91d1a2dc039e932dd934df5ce481acb2555cacac2b0308acb05576 + languageName: node + linkType: hard + +"@inquirer/confirm@npm:3.1.22, @inquirer/confirm@npm:^3.1.22": + version: 3.1.22 + resolution: "@inquirer/confirm@npm:3.1.22" + dependencies: + "@inquirer/core": "npm:^9.0.10" + "@inquirer/type": "npm:^1.5.2" + checksum: 10c0/99e1a17e62a674d8e440a11bf4e9d5a62666247823b091314e52ee40929a6a6e8ce60086ec653bbeb59117bfc940d807c6f4b604cf5cf51f24009b9d09d5bf98 + languageName: node + linkType: hard + +"@inquirer/core@npm:^9.0.10": + version: 9.0.10 + resolution: "@inquirer/core@npm:9.0.10" + dependencies: + "@inquirer/figures": "npm:^1.0.5" + "@inquirer/type": "npm:^1.5.2" + "@types/mute-stream": "npm:^0.0.4" + "@types/node": "npm:^22.1.0" + "@types/wrap-ansi": "npm:^3.0.0" + ansi-escapes: "npm:^4.3.2" + cli-spinners: "npm:^2.9.2" + cli-width: "npm:^4.1.0" + mute-stream: "npm:^1.0.0" + signal-exit: "npm:^4.1.0" + strip-ansi: "npm:^6.0.1" + wrap-ansi: "npm:^6.2.0" + yoctocolors-cjs: "npm:^2.1.2" + checksum: 10c0/117f50a55b5ebee8bfc62ea6adec87035f28ee7ace1efea67895c3d32ab50bf569ecd3ca33c457d0c7ae4240b9fe4d7b698ab70946ac561ab579d0920ddc98bb + languageName: node + linkType: hard + +"@inquirer/editor@npm:^2.1.22": + version: 2.1.22 + resolution: "@inquirer/editor@npm:2.1.22" dependencies: - "@fortawesome/fontawesome-svg-core": "npm:^6.5.2" - tslib: "npm:^2.6.2" - peerDependencies: - "@angular/core": ^18.0.0 - checksum: 10c0/9ddc4d167850e3b507bb16edecefb84872cbb464f4dab3e113b1910a57c2ccd28e329b897e7394cbed7f10bb1ed659e9acdb905c5ec19f03f8e7aa4ddce3c247 + "@inquirer/core": "npm:^9.0.10" + "@inquirer/type": "npm:^1.5.2" + external-editor: "npm:^3.1.0" + checksum: 10c0/a2e65362ed187695450b092c8f5698661002e4e24e1e800dfbbfeaa8e71f60b5d5e1dfa98b9402457c02cab1762ac2b20d3364c11db0b5572aa61caf55f5beba languageName: node linkType: hard -"@fortawesome/fontawesome-common-types@npm:6.5.2": - version: 6.5.2 - resolution: "@fortawesome/fontawesome-common-types@npm:6.5.2" - checksum: 10c0/12104e93a0056ad1077f7350826f52aa26465bb1d6b4ce75dab0307072a3871301ec750c3a34d89d05e7338c9b446fa2793150cf58a5167217021943ef877d77 +"@inquirer/expand@npm:^2.1.22": + version: 2.1.22 + resolution: "@inquirer/expand@npm:2.1.22" + dependencies: + "@inquirer/core": "npm:^9.0.10" + "@inquirer/type": "npm:^1.5.2" + yoctocolors-cjs: "npm:^2.1.2" + checksum: 10c0/0f9d3447ca6b9e24e0179b4ec53f463647a8323d8a041bc3321f19a2914176117a264bcc6deb723e3f9ec718d3faf672f3f840f0898bbff4371fa899b239b411 languageName: node linkType: hard -"@fortawesome/fontawesome-svg-core@npm:^6.5.2": - version: 6.5.2 - resolution: "@fortawesome/fontawesome-svg-core@npm:6.5.2" - dependencies: - "@fortawesome/fontawesome-common-types": "npm:6.5.2" - checksum: 10c0/91695dd375623988d16e6f0dc69d20350ef3fa3296fe40aa08877aae7beaf64378134656a2227419fe648dcd27a81c03fe1fd9a6c87956d863164b0380ba77d0 +"@inquirer/figures@npm:^1.0.5": + version: 1.0.5 + resolution: "@inquirer/figures@npm:1.0.5" + checksum: 10c0/ec9ba23db42cb33fa18eb919abf2a18e750e739e64c1883ce4a98345cd5711c60cac12d1faf56a859f52d387deb221c8d3dfe60344ee07955a9a262f8b821fe3 languageName: node linkType: hard -"@fortawesome/free-solid-svg-icons@npm:^6.5.2": - version: 6.5.2 - resolution: "@fortawesome/free-solid-svg-icons@npm:6.5.2" +"@inquirer/input@npm:^2.2.9": + version: 2.2.9 + resolution: "@inquirer/input@npm:2.2.9" dependencies: - "@fortawesome/fontawesome-common-types": "npm:6.5.2" - checksum: 10c0/af2778b91ba4bf7b61ae0cdf0d39d75b6906a82bfdf8e977881d987b86a32ce157297853b7892aa3b609076b5542ea1e1e78b520d57b6f50677a2a748cf3434c + "@inquirer/core": "npm:^9.0.10" + "@inquirer/type": "npm:^1.5.2" + checksum: 10c0/0fcdc5d9c17712f9a2c79f39d1e03ed4a58cfe1dd1095209b4c83621dba2cb94db03b7df0df34e22584bce9e53403a284c76721def66a452e4751666d945d99f languageName: node linkType: hard -"@gar/promisify@npm:^1.0.1": - version: 1.1.3 - resolution: "@gar/promisify@npm:1.1.3" - checksum: 10c0/0b3c9958d3cd17f4add3574975e3115ae05dc7f1298a60810414b16f6f558c137b5fb3cd3905df380bacfd955ec13f67c1e6710cbb5c246a7e8d65a8289b2bff +"@inquirer/number@npm:^1.0.10": + version: 1.0.10 + resolution: "@inquirer/number@npm:1.0.10" + dependencies: + "@inquirer/core": "npm:^9.0.10" + "@inquirer/type": "npm:^1.5.2" + checksum: 10c0/efa7c49322d8f36eeb8afb704bba673c10fcf7992babc8ad5f25d4c8db0fbafc0007439abdef05a462171b37a68b981981859587ff5b71e79002ffac65be859a languageName: node linkType: hard -"@gfx/zopfli@npm:^1.0.15": - version: 1.0.15 - resolution: "@gfx/zopfli@npm:1.0.15" +"@inquirer/password@npm:^2.1.22": + version: 2.1.22 + resolution: "@inquirer/password@npm:2.1.22" dependencies: - base64-js: "npm:^1.3.0" - checksum: 10c0/b1ae57c68d144887e8c3752f7cc88dc6af3d75d523c665b5ab6e5fbc84d9de3459c84cb2dee677579a6d7f29b9e445faac1aabecf0ee4eafd1fb0c3f61f8988a + "@inquirer/core": "npm:^9.0.10" + "@inquirer/type": "npm:^1.5.2" + ansi-escapes: "npm:^4.3.2" + checksum: 10c0/5cd5bab0026d673539710f424e6f7dda8abea4863a0cddf982278b15a250f5a2be0a0f17fdf970a900d33187a64ad987d24d038cfbed2599b5a2a97c169bbddc languageName: node linkType: hard -"@humanwhocodes/config-array@npm:^0.11.14": - version: 0.11.14 - resolution: "@humanwhocodes/config-array@npm:0.11.14" +"@inquirer/prompts@npm:5.3.8": + version: 5.3.8 + resolution: "@inquirer/prompts@npm:5.3.8" dependencies: - "@humanwhocodes/object-schema": "npm:^2.0.2" - debug: "npm:^4.3.1" - minimatch: "npm:^3.0.5" - checksum: 10c0/66f725b4ee5fdd8322c737cb5013e19fac72d4d69c8bf4b7feb192fcb83442b035b92186f8e9497c220e58b2d51a080f28a73f7899bc1ab288c3be172c467541 + "@inquirer/checkbox": "npm:^2.4.7" + "@inquirer/confirm": "npm:^3.1.22" + "@inquirer/editor": "npm:^2.1.22" + "@inquirer/expand": "npm:^2.1.22" + "@inquirer/input": "npm:^2.2.9" + "@inquirer/number": "npm:^1.0.10" + "@inquirer/password": "npm:^2.1.22" + "@inquirer/rawlist": "npm:^2.2.4" + "@inquirer/search": "npm:^1.0.7" + "@inquirer/select": "npm:^2.4.7" + checksum: 10c0/2c49afb5e9f7d825c1489d8c587f985418e890508802e1483d1cb8da46644e9803b2f0a8b71f53f0ff5d9273ca39e28faeadf7d6691467eb5c0dbbde900e5233 languageName: node linkType: hard -"@humanwhocodes/module-importer@npm:^1.0.1": - version: 1.0.1 - resolution: "@humanwhocodes/module-importer@npm:1.0.1" - checksum: 10c0/909b69c3b86d482c26b3359db16e46a32e0fb30bd306a3c176b8313b9e7313dba0f37f519de6aa8b0a1921349e505f259d19475e123182416a506d7f87e7f529 +"@inquirer/rawlist@npm:^2.2.4": + version: 2.2.4 + resolution: "@inquirer/rawlist@npm:2.2.4" + dependencies: + "@inquirer/core": "npm:^9.0.10" + "@inquirer/type": "npm:^1.5.2" + yoctocolors-cjs: "npm:^2.1.2" + checksum: 10c0/d7c5e0784bb357f6465b7ca08a22310f124fb61db6cce7a1860305d8d25dcdfa66db216d4cc52873d68ae379376984cf8d9cd14880fbca41b7b03802be49caf8 languageName: node linkType: hard -"@humanwhocodes/object-schema@npm:^2.0.2": - version: 2.0.3 - resolution: "@humanwhocodes/object-schema@npm:2.0.3" - checksum: 10c0/80520eabbfc2d32fe195a93557cef50dfe8c8905de447f022675aaf66abc33ae54098f5ea78548d925aa671cd4ab7c7daa5ad704fe42358c9b5e7db60f80696c +"@inquirer/search@npm:^1.0.7": + version: 1.0.7 + resolution: "@inquirer/search@npm:1.0.7" + dependencies: + "@inquirer/core": "npm:^9.0.10" + "@inquirer/figures": "npm:^1.0.5" + "@inquirer/type": "npm:^1.5.2" + yoctocolors-cjs: "npm:^2.1.2" + checksum: 10c0/29179cc32236689b956cccdc092b537c67e841c5cd0a6473b92f9e71f56c0fb737baa4856bf76572f07c0c3999b6b5ea1ce3b74ef56504e179098f700a85a5cf languageName: node linkType: hard -"@hutson/parse-repository-url@npm:^3.0.0": - version: 3.0.2 - resolution: "@hutson/parse-repository-url@npm:3.0.2" - checksum: 10c0/d9197757ecad2df18d29d3e1d1fe0716d458fd88b849c71cbec9e78239f911074c97e8d764dfd8ed890431c1137e52dd7a337207fd65be20ce0784f7860ae4d1 +"@inquirer/select@npm:^2.4.7": + version: 2.4.7 + resolution: "@inquirer/select@npm:2.4.7" + dependencies: + "@inquirer/core": "npm:^9.0.10" + "@inquirer/figures": "npm:^1.0.5" + "@inquirer/type": "npm:^1.5.2" + ansi-escapes: "npm:^4.3.2" + yoctocolors-cjs: "npm:^2.1.2" + checksum: 10c0/34e120a263ca2e7edeab08ef6ca24d0966135e8d1a9d6f167fbc03fa8f057391228d58292281609a25d51eb9d59d0b1d00146bd2a5811c5d3880800321cfe8e6 languageName: node linkType: hard -"@inquirer/figures@npm:^1.0.2": - version: 1.0.3 - resolution: "@inquirer/figures@npm:1.0.3" - checksum: 10c0/099e062f000baafb4010014ece443d0cd211f562194854dc52a128bfe514611f8cc3da4cdb5092d75440956aff201dcd8e893b8a71feb104f97b0b00c6a696cf +"@inquirer/type@npm:^1.5.1, @inquirer/type@npm:^1.5.2": + version: 1.5.2 + resolution: "@inquirer/type@npm:1.5.2" + dependencies: + mute-stream: "npm:^1.0.0" + checksum: 10c0/e2c91562c07440620bd805a60438b78c188d2727d86f396a68c480e4357469a72cd80bd2c158faa6b987671911566bd4fc12976f4bdda1a3441594e318c40058 languageName: node linkType: hard @@ -3110,15 +3699,6 @@ __metadata: languageName: node linkType: hard -"@jest/schemas@npm:^29.6.3": - version: 29.6.3 - resolution: "@jest/schemas@npm:29.6.3" - dependencies: - "@sinclair/typebox": "npm:^0.27.8" - checksum: 10c0/b329e89cd5f20b9278ae1233df74016ebf7b385e0d14b9f4c1ad18d096c4c19d1e687aa113a9c976b16ec07f021ae53dea811fb8c1248a50ac34fbe009fdf6be - languageName: node - linkType: hard - "@jridgewell/gen-mapping@npm:^0.3.5": version: 0.3.5 resolution: "@jridgewell/gen-mapping@npm:0.3.5" @@ -3161,6 +3741,13 @@ __metadata: languageName: node linkType: hard +"@jridgewell/sourcemap-codec@npm:^1.5.0": + version: 1.5.0 + resolution: "@jridgewell/sourcemap-codec@npm:1.5.0" + checksum: 10c0/2eb864f276eb1096c3c11da3e9bb518f6d9fc0023c78344cdc037abadc725172c70314bdb360f2d4b7bffec7f5d657ce006816bc5d4ecb35e61b66132db00c18 + languageName: node + linkType: hard + "@jridgewell/trace-mapping@npm:^0.3.20, @jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25": version: 0.3.25 resolution: "@jridgewell/trace-mapping@npm:0.3.25" @@ -3248,53 +3835,55 @@ __metadata: languageName: node linkType: hard -"@ljharb/through@npm:^2.3.13": - version: 2.3.13 - resolution: "@ljharb/through@npm:2.3.13" +"@listr2/prompt-adapter-inquirer@npm:2.0.15": + version: 2.0.15 + resolution: "@listr2/prompt-adapter-inquirer@npm:2.0.15" dependencies: - call-bind: "npm:^1.0.7" - checksum: 10c0/fb60b2fb2c674a674d8ebdb8972ccf52f8a62a9c1f5a2ac42557bc0273231c65d642aa2d7627cbb300766a25ae4642acd0f95fba2f8a1ff891086f0cb15807c3 + "@inquirer/type": "npm:^1.5.1" + peerDependencies: + "@inquirer/prompts": ">= 3 < 6" + checksum: 10c0/c7eb85315be9ea11973b095331a7cd55b2ec4b2655da071e119e3233f0a2412df1e7319641da30f07cfadee21862d721177618147c3a50830dd6ae0778d4c5f4 languageName: node linkType: hard -"@lmdb/lmdb-darwin-arm64@npm:3.0.8": - version: 3.0.8 - resolution: "@lmdb/lmdb-darwin-arm64@npm:3.0.8" +"@lmdb/lmdb-darwin-arm64@npm:3.0.13": + version: 3.0.13 + resolution: "@lmdb/lmdb-darwin-arm64@npm:3.0.13" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@lmdb/lmdb-darwin-x64@npm:3.0.8": - version: 3.0.8 - resolution: "@lmdb/lmdb-darwin-x64@npm:3.0.8" +"@lmdb/lmdb-darwin-x64@npm:3.0.13": + version: 3.0.13 + resolution: "@lmdb/lmdb-darwin-x64@npm:3.0.13" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@lmdb/lmdb-linux-arm64@npm:3.0.8": - version: 3.0.8 - resolution: "@lmdb/lmdb-linux-arm64@npm:3.0.8" +"@lmdb/lmdb-linux-arm64@npm:3.0.13": + version: 3.0.13 + resolution: "@lmdb/lmdb-linux-arm64@npm:3.0.13" conditions: os=linux & cpu=arm64 languageName: node linkType: hard -"@lmdb/lmdb-linux-arm@npm:3.0.8": - version: 3.0.8 - resolution: "@lmdb/lmdb-linux-arm@npm:3.0.8" +"@lmdb/lmdb-linux-arm@npm:3.0.13": + version: 3.0.13 + resolution: "@lmdb/lmdb-linux-arm@npm:3.0.13" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@lmdb/lmdb-linux-x64@npm:3.0.8": - version: 3.0.8 - resolution: "@lmdb/lmdb-linux-x64@npm:3.0.8" +"@lmdb/lmdb-linux-x64@npm:3.0.13": + version: 3.0.13 + resolution: "@lmdb/lmdb-linux-x64@npm:3.0.13" conditions: os=linux & cpu=x64 languageName: node linkType: hard -"@lmdb/lmdb-win32-x64@npm:3.0.8": - version: 3.0.8 - resolution: "@lmdb/lmdb-win32-x64@npm:3.0.8" +"@lmdb/lmdb-win32-x64@npm:3.0.13": + version: 3.0.13 + resolution: "@lmdb/lmdb-win32-x64@npm:3.0.13" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -3357,14 +3946,19 @@ __metadata: languageName: node linkType: hard -"@ngtools/webpack@npm:18.0.6": - version: 18.0.6 - resolution: "@ngtools/webpack@npm:18.0.6" +"@ngtools/webpack@npm:18.2.0": + version: 18.2.0 + resolution: "@ngtools/webpack@npm:18.2.0" peerDependencies: "@angular/compiler-cli": ^18.0.0 - typescript: ">=5.4 <5.5" + typescript: ">=5.4 <5.6" webpack: ^5.54.0 - checksum: 10c0/98c081476c56da5fb820be711b0922cefc07254ccd0fb0f0f04f628819e90524134ca8f97b7c1ce5b1f02ea18be63b1718e0362d9eef9443eaa741db09070773 + dependenciesMeta: + esbuild: + built: true + puppeteer: + built: true + checksum: 10c0/621c28b5acaa7c8c83a81f3267bcde2e2dc55e49ae711999e644af9000d3ab8e8a070e6db02e8bb52c0bb357a0a69a93dc7082841ebbd7d55b060683c95f48d1 languageName: node linkType: hard @@ -3517,116 +4111,6 @@ __metadata: languageName: node linkType: hard -"@nrwl/devkit@npm:19.1.2": - version: 19.1.2 - resolution: "@nrwl/devkit@npm:19.1.2" - dependencies: - "@nx/devkit": "npm:19.1.2" - checksum: 10c0/97f7af65cd67430ea5a9818531d68b7fb72b9feba344d5d17794bc9cc4bdcfd23352d0034deb21405745d2b78ff4671e853d9cad59a9b95ce8c00f6178e8f506 - languageName: node - linkType: hard - -"@nrwl/tao@npm:19.1.2": - version: 19.1.2 - resolution: "@nrwl/tao@npm:19.1.2" - dependencies: - nx: "npm:19.1.2" - tslib: "npm:^2.3.0" - bin: - tao: index.js - checksum: 10c0/dde2cf007717bf595d28e5a9e8d0392e5d0d0f92ad201581e35b124e1d6d4f5a55ecee1c7c21e98c3284fb1f3af05fea796fd01e201dc01597a17066ae6c4a72 - languageName: node - linkType: hard - -"@nx/devkit@npm:19.1.2, @nx/devkit@npm:^19.0.6": - version: 19.1.2 - resolution: "@nx/devkit@npm:19.1.2" - dependencies: - "@nrwl/devkit": "npm:19.1.2" - ejs: "npm:^3.1.7" - enquirer: "npm:~2.3.6" - ignore: "npm:^5.0.4" - minimatch: "npm:9.0.3" - semver: "npm:^7.5.3" - tmp: "npm:~0.2.1" - tslib: "npm:^2.3.0" - yargs-parser: "npm:21.1.1" - peerDependencies: - nx: ">= 17 <= 20" - checksum: 10c0/b8484c6243be0afab41a148c369724e659ac06f1324f66f9707db9182707e5ca61b9ccede1aca7933cd9d69dbab87bdc300a04b5c644b0ead2c4440d97160792 - languageName: node - linkType: hard - -"@nx/nx-darwin-arm64@npm:19.1.2": - version: 19.1.2 - resolution: "@nx/nx-darwin-arm64@npm:19.1.2" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - -"@nx/nx-darwin-x64@npm:19.1.2": - version: 19.1.2 - resolution: "@nx/nx-darwin-x64@npm:19.1.2" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - -"@nx/nx-freebsd-x64@npm:19.1.2": - version: 19.1.2 - resolution: "@nx/nx-freebsd-x64@npm:19.1.2" - conditions: os=freebsd & cpu=x64 - languageName: node - linkType: hard - -"@nx/nx-linux-arm-gnueabihf@npm:19.1.2": - version: 19.1.2 - resolution: "@nx/nx-linux-arm-gnueabihf@npm:19.1.2" - conditions: os=linux & cpu=arm - languageName: node - linkType: hard - -"@nx/nx-linux-arm64-gnu@npm:19.1.2": - version: 19.1.2 - resolution: "@nx/nx-linux-arm64-gnu@npm:19.1.2" - conditions: os=linux & cpu=arm64 & libc=glibc - languageName: node - linkType: hard - -"@nx/nx-linux-arm64-musl@npm:19.1.2": - version: 19.1.2 - resolution: "@nx/nx-linux-arm64-musl@npm:19.1.2" - conditions: os=linux & cpu=arm64 & libc=musl - languageName: node - linkType: hard - -"@nx/nx-linux-x64-gnu@npm:19.1.2": - version: 19.1.2 - resolution: "@nx/nx-linux-x64-gnu@npm:19.1.2" - conditions: os=linux & cpu=x64 & libc=glibc - languageName: node - linkType: hard - -"@nx/nx-linux-x64-musl@npm:19.1.2": - version: 19.1.2 - resolution: "@nx/nx-linux-x64-musl@npm:19.1.2" - conditions: os=linux & cpu=x64 & libc=musl - languageName: node - linkType: hard - -"@nx/nx-win32-arm64-msvc@npm:19.1.2": - version: 19.1.2 - resolution: "@nx/nx-win32-arm64-msvc@npm:19.1.2" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - -"@nx/nx-win32-x64-msvc@npm:19.1.2": - version: 19.1.2 - resolution: "@nx/nx-win32-x64-msvc@npm:19.1.2" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - "@pkgjs/parseargs@npm:^0.11.0": version: 0.11.0 resolution: "@pkgjs/parseargs@npm:0.11.0" @@ -3662,6 +4146,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-android-arm-eabi@npm:4.20.0": + version: 4.20.0 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.20.0" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + "@rollup/rollup-android-arm64@npm:4.18.0": version: 4.18.0 resolution: "@rollup/rollup-android-arm64@npm:4.18.0" @@ -3669,6 +4160,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-android-arm64@npm:4.20.0": + version: 4.20.0 + resolution: "@rollup/rollup-android-arm64@npm:4.20.0" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + "@rollup/rollup-darwin-arm64@npm:4.18.0": version: 4.18.0 resolution: "@rollup/rollup-darwin-arm64@npm:4.18.0" @@ -3676,6 +4174,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-darwin-arm64@npm:4.20.0": + version: 4.20.0 + resolution: "@rollup/rollup-darwin-arm64@npm:4.20.0" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + "@rollup/rollup-darwin-x64@npm:4.18.0": version: 4.18.0 resolution: "@rollup/rollup-darwin-x64@npm:4.18.0" @@ -3683,6 +4188,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-darwin-x64@npm:4.20.0": + version: 4.20.0 + resolution: "@rollup/rollup-darwin-x64@npm:4.20.0" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + "@rollup/rollup-linux-arm-gnueabihf@npm:4.18.0": version: 4.18.0 resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.18.0" @@ -3690,6 +4202,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-arm-gnueabihf@npm:4.20.0": + version: 4.20.0 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.20.0" + conditions: os=linux & cpu=arm & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-arm-musleabihf@npm:4.18.0": version: 4.18.0 resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.18.0" @@ -3697,6 +4216,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-arm-musleabihf@npm:4.20.0": + version: 4.20.0 + resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.20.0" + conditions: os=linux & cpu=arm & libc=musl + languageName: node + linkType: hard + "@rollup/rollup-linux-arm64-gnu@npm:4.18.0": version: 4.18.0 resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.18.0" @@ -3704,6 +4230,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-arm64-gnu@npm:4.20.0": + version: 4.20.0 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.20.0" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-arm64-musl@npm:4.18.0": version: 4.18.0 resolution: "@rollup/rollup-linux-arm64-musl@npm:4.18.0" @@ -3711,6 +4244,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-arm64-musl@npm:4.20.0": + version: 4.20.0 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.20.0" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + "@rollup/rollup-linux-powerpc64le-gnu@npm:4.18.0": version: 4.18.0 resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.18.0" @@ -3718,6 +4258,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-powerpc64le-gnu@npm:4.20.0": + version: 4.20.0 + resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.20.0" + conditions: os=linux & cpu=ppc64 & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-riscv64-gnu@npm:4.18.0": version: 4.18.0 resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.18.0" @@ -3725,6 +4272,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-riscv64-gnu@npm:4.20.0": + version: 4.20.0 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.20.0" + conditions: os=linux & cpu=riscv64 & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-s390x-gnu@npm:4.18.0": version: 4.18.0 resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.18.0" @@ -3732,6 +4286,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-s390x-gnu@npm:4.20.0": + version: 4.20.0 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.20.0" + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-x64-gnu@npm:4.18.0": version: 4.18.0 resolution: "@rollup/rollup-linux-x64-gnu@npm:4.18.0" @@ -3739,6 +4300,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-x64-gnu@npm:4.20.0": + version: 4.20.0 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.20.0" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-x64-musl@npm:4.18.0": version: 4.18.0 resolution: "@rollup/rollup-linux-x64-musl@npm:4.18.0" @@ -3746,6 +4314,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-x64-musl@npm:4.20.0": + version: 4.20.0 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.20.0" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + "@rollup/rollup-win32-arm64-msvc@npm:4.18.0": version: 4.18.0 resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.18.0" @@ -3753,6 +4328,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-win32-arm64-msvc@npm:4.20.0": + version: 4.20.0 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.20.0" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + "@rollup/rollup-win32-ia32-msvc@npm:4.18.0": version: 4.18.0 resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.18.0" @@ -3760,6 +4342,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-win32-ia32-msvc@npm:4.20.0": + version: 4.20.0 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.20.0" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + "@rollup/rollup-win32-x64-msvc@npm:4.18.0": version: 4.18.0 resolution: "@rollup/rollup-win32-x64-msvc@npm:4.18.0" @@ -3767,14 +4356,26 @@ __metadata: languageName: node linkType: hard -"@schematics/angular@npm:18.0.6": - version: 18.0.6 - resolution: "@schematics/angular@npm:18.0.6" +"@rollup/rollup-win32-x64-msvc@npm:4.20.0": + version: 4.20.0 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.20.0" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@schematics/angular@npm:18.2.0": + version: 18.2.0 + resolution: "@schematics/angular@npm:18.2.0" dependencies: - "@angular-devkit/core": "npm:18.0.6" - "@angular-devkit/schematics": "npm:18.0.6" - jsonc-parser: "npm:3.2.1" - checksum: 10c0/8c562958e80d2da584de7bec617d802a280dd4c0576c76b66ab06c217e1b978c04c7b2e0409e6fc834a045a4b7c97aa2d60356d60c26deecd1930dad63e04dc2 + "@angular-devkit/core": "npm:18.2.0" + "@angular-devkit/schematics": "npm:18.2.0" + jsonc-parser: "npm:3.3.1" + dependenciesMeta: + esbuild: + built: true + puppeteer: + built: true + checksum: 10c0/6547c795cd60d46fb6b694858dd5ca3dba90ead1706c3a612c56951b897c2b456164a8ab2ec840266b50bdd2f040bde086d2d5169e7770f91d88076fcbabdf1e languageName: node linkType: hard @@ -3836,10 +4437,10 @@ __metadata: languageName: node linkType: hard -"@sinclair/typebox@npm:^0.27.8": - version: 0.27.8 - resolution: "@sinclair/typebox@npm:0.27.8" - checksum: 10c0/ef6351ae073c45c2ac89494dbb3e1f87cc60a93ce4cde797b782812b6f97da0d620ae81973f104b43c9b7eaa789ad20ba4f6a1359f1cc62f63729a55a7d22d4e +"@sindresorhus/merge-streams@npm:^2.1.0": + version: 2.3.0 + resolution: "@sindresorhus/merge-streams@npm:2.3.0" + checksum: 10c0/69ee906f3125fb2c6bb6ec5cdd84e8827d93b49b3892bce8b62267116cc7e197b5cccf20c160a1d32c26014ecd14470a72a5e3ee37a58f1d6dadc0db1ccf3894 languageName: node linkType: hard @@ -4286,7 +4887,7 @@ __metadata: languageName: node linkType: hard -"@types/eslint@npm:*, @types/eslint@npm:^8.56.5": +"@types/eslint@npm:*": version: 8.56.10 resolution: "@types/eslint@npm:8.56.10" dependencies: @@ -4385,6 +4986,15 @@ __metadata: languageName: node linkType: hard +"@types/mute-stream@npm:^0.0.4": + version: 0.0.4 + resolution: "@types/mute-stream@npm:0.0.4" + dependencies: + "@types/node": "npm:*" + checksum: 10c0/944730fd7b398c5078de3c3d4d0afeec8584283bc694da1803fdfca14149ea385e18b1b774326f1601baf53898ce6d121a952c51eb62d188ef6fcc41f725c0dc + languageName: node + linkType: hard + "@types/node-forge@npm:^1.3.0": version: 1.3.11 resolution: "@types/node-forge@npm:1.3.11" @@ -4403,12 +5013,21 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^18.19.39": - version: 18.19.39 - resolution: "@types/node@npm:18.19.39" +"@types/node@npm:^20.14.14": + version: 20.14.14 + resolution: "@types/node@npm:20.14.14" dependencies: undici-types: "npm:~5.26.4" - checksum: 10c0/a9eb33bc093beba6bd5d4e839de7d1d1f496cd7e741c2f6c7161318dba0f37227bb25d8306907194992488d6c59a7363a419d72298549483d33402227a2d435b + checksum: 10c0/4fc8d368df2b6f5497698327b30db68d7d20e32221ce7d057fb15cbd5834685b2fde0440609e4cb2204e5d305b928f008faf41b950a425f3fd55b60cb1b997cf + languageName: node + linkType: hard + +"@types/node@npm:^22.1.0": + version: 22.3.0 + resolution: "@types/node@npm:22.3.0" + dependencies: + undici-types: "npm:~6.18.2" + checksum: 10c0/855be3b97f4262a84818f889ff898e147dcef4f72b866e3551a8367380cdb63a45cf3929f09d9a0647f62706f8d4772e91a1ecd1bd7c6a80d6744c2b0cbca608 languageName: node linkType: hard @@ -4486,6 +5105,13 @@ __metadata: languageName: node linkType: hard +"@types/wrap-ansi@npm:^3.0.0": + version: 3.0.0 + resolution: "@types/wrap-ansi@npm:3.0.0" + checksum: 10c0/8d8f53363f360f38135301a06b596c295433ad01debd082078c33c6ed98b05a5c8fe8853a88265432126096084f4a135ec1564e3daad631b83296905509f90b3 + languageName: node + linkType: hard + "@types/ws@npm:^8.5.10": version: 8.5.10 resolution: "@types/ws@npm:8.5.10" @@ -4495,44 +5121,44 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:^7.14.1": - version: 7.14.1 - resolution: "@typescript-eslint/eslint-plugin@npm:7.14.1" +"@typescript-eslint/eslint-plugin@npm:^8.1.0": + version: 8.1.0 + resolution: "@typescript-eslint/eslint-plugin@npm:8.1.0" dependencies: "@eslint-community/regexpp": "npm:^4.10.0" - "@typescript-eslint/scope-manager": "npm:7.14.1" - "@typescript-eslint/type-utils": "npm:7.14.1" - "@typescript-eslint/utils": "npm:7.14.1" - "@typescript-eslint/visitor-keys": "npm:7.14.1" + "@typescript-eslint/scope-manager": "npm:8.1.0" + "@typescript-eslint/type-utils": "npm:8.1.0" + "@typescript-eslint/utils": "npm:8.1.0" + "@typescript-eslint/visitor-keys": "npm:8.1.0" graphemer: "npm:^1.4.0" ignore: "npm:^5.3.1" natural-compare: "npm:^1.4.0" ts-api-utils: "npm:^1.3.0" peerDependencies: - "@typescript-eslint/parser": ^7.0.0 - eslint: ^8.56.0 + "@typescript-eslint/parser": ^8.0.0 || ^8.0.0-alpha.0 + eslint: ^8.57.0 || ^9.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 10c0/7c2b9b98a38d78326b0ff7348fe001203eda10817ca7834a7a01f492ae7c2508469bbafaa933208d6459f8ff6685277685983cf6f6843e556a6ab2aa5c05080c + checksum: 10c0/7bbeae588f859b59c34d6a76cac06ef0fa605921b40c5d3b65b94829984280ea84c4dd3f5cb9ce2eb326f5563e9abb4c90ebff05c47f83f4def296c2ea1fa86c languageName: node linkType: hard -"@typescript-eslint/parser@npm:^7.14.1": - version: 7.14.1 - resolution: "@typescript-eslint/parser@npm:7.14.1" +"@typescript-eslint/parser@npm:^8.1.0": + version: 8.1.0 + resolution: "@typescript-eslint/parser@npm:8.1.0" dependencies: - "@typescript-eslint/scope-manager": "npm:7.14.1" - "@typescript-eslint/types": "npm:7.14.1" - "@typescript-eslint/typescript-estree": "npm:7.14.1" - "@typescript-eslint/visitor-keys": "npm:7.14.1" + "@typescript-eslint/scope-manager": "npm:8.1.0" + "@typescript-eslint/types": "npm:8.1.0" + "@typescript-eslint/typescript-estree": "npm:8.1.0" + "@typescript-eslint/visitor-keys": "npm:8.1.0" debug: "npm:^4.3.4" peerDependencies: - eslint: ^8.56.0 + eslint: ^8.57.0 || ^9.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 10c0/db3169d4852685cfb27db741c557f58a3e52104bfacc7621beb7c94ec36ac2a08d4e410ac86745db52f482fbfc87e99fa0a26c1d7a10d37a215cce85e1661f0e + checksum: 10c0/b94b2d3ab5ca505484d100701fad6a04a5dc8d595029bac1b9f5b8a4a91d80fd605b0f65d230b36a97ab7e5d55eeb0c28af2ab63929a3e4ab8fdefd2a548c36b languageName: node linkType: hard @@ -4546,44 +5172,42 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:7.14.1": - version: 7.14.1 - resolution: "@typescript-eslint/scope-manager@npm:7.14.1" +"@typescript-eslint/scope-manager@npm:8.1.0": + version: 8.1.0 + resolution: "@typescript-eslint/scope-manager@npm:8.1.0" dependencies: - "@typescript-eslint/types": "npm:7.14.1" - "@typescript-eslint/visitor-keys": "npm:7.14.1" - checksum: 10c0/f8c05a0d6f8de4cc19b90a4da308817c66e53f36f7ec48f6cc23e93c7399bc418643d8135933aaf5fc013199cbef0e1ea4223f5147db5ca401b239eaf087011e + "@typescript-eslint/types": "npm:8.1.0" + "@typescript-eslint/visitor-keys": "npm:8.1.0" + checksum: 10c0/2bcf8cd176a1819bddcae16c572e7da8fba821b995a91cd53d64d8d6b85a17f5a895522f281ba57e34929574bddd4d6684ee3e545ec4e8096be4c3198e253a9a languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:7.14.1": - version: 7.14.1 - resolution: "@typescript-eslint/type-utils@npm:7.14.1" +"@typescript-eslint/type-utils@npm:8.1.0": + version: 8.1.0 + resolution: "@typescript-eslint/type-utils@npm:8.1.0" dependencies: - "@typescript-eslint/typescript-estree": "npm:7.14.1" - "@typescript-eslint/utils": "npm:7.14.1" + "@typescript-eslint/typescript-estree": "npm:8.1.0" + "@typescript-eslint/utils": "npm:8.1.0" debug: "npm:^4.3.4" ts-api-utils: "npm:^1.3.0" - peerDependencies: - eslint: ^8.56.0 peerDependenciesMeta: typescript: optional: true - checksum: 10c0/bd1c4a8db6273e24156fb10da2cbeb52b4eb03f819da193d4b6bd5a95db3b5524c6fe00d088308d8855b9ae60a3b82afa3a06e89982a09a8573561da960758fd + checksum: 10c0/62753941c4136e8d2daa72fe0410dea48e5317a6f12ece6382ca85e29912bd1b3f739b61d1060fc0a1f8c488dfc905beab4c8b8497951a21c3138a659c7271ec languageName: node linkType: hard -"@typescript-eslint/types@npm:7.12.0, @typescript-eslint/types@npm:^7.2.0": +"@typescript-eslint/types@npm:7.12.0": version: 7.12.0 resolution: "@typescript-eslint/types@npm:7.12.0" checksum: 10c0/76786d02a0838750d74ad6e49b026875c0753b81c5a46a56525a1e82d89c0939a13434b03494e3b31b7ffbba7824f426c5b502a12337806a1f6ca560b5dad46c languageName: node linkType: hard -"@typescript-eslint/types@npm:7.14.1": - version: 7.14.1 - resolution: "@typescript-eslint/types@npm:7.14.1" - checksum: 10c0/5b7bda83c47a9b386482e63447c6b0ed7bd4e82eb43f11a180c6e2f3d2e7a2828f57bcbed82196ad761c49e363cccf4c81a89f1fc976e9f5f0a79dcc928fa2d2 +"@typescript-eslint/types@npm:8.1.0": + version: 8.1.0 + resolution: "@typescript-eslint/types@npm:8.1.0" + checksum: 10c0/ceade44455f45974e68956016c4d1c6626580732f7f9675e14ffa63db80b551752b0df596b20473dae9f0dc6ed966e17417dc2cf36e1a82b6ab0edc97c5eaa50 languageName: node linkType: hard @@ -4606,12 +5230,12 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:7.14.1": - version: 7.14.1 - resolution: "@typescript-eslint/typescript-estree@npm:7.14.1" +"@typescript-eslint/typescript-estree@npm:8.1.0": + version: 8.1.0 + resolution: "@typescript-eslint/typescript-estree@npm:8.1.0" dependencies: - "@typescript-eslint/types": "npm:7.14.1" - "@typescript-eslint/visitor-keys": "npm:7.14.1" + "@typescript-eslint/types": "npm:8.1.0" + "@typescript-eslint/visitor-keys": "npm:8.1.0" debug: "npm:^4.3.4" globby: "npm:^11.1.0" is-glob: "npm:^4.0.3" @@ -4621,21 +5245,21 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10c0/a8da9bcc4de3334a225424946abd99374de05c42098455419224bc0f46bb1b66115f8bd6ae268461294b90943ed4a407bcd255c0fa60eb76ba4cdc5fc7c20855 + checksum: 10c0/a7bc8275df1c79c4cb14ef086c56674316dd4907efec53eddca35d0b5220428b69c82178ce2d95138da2e398269c8bd0764cae8020a36417e411e35c3c47bc4b languageName: node linkType: hard -"@typescript-eslint/utils@npm:7.14.1": - version: 7.14.1 - resolution: "@typescript-eslint/utils@npm:7.14.1" +"@typescript-eslint/utils@npm:8.1.0": + version: 8.1.0 + resolution: "@typescript-eslint/utils@npm:8.1.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.4.0" - "@typescript-eslint/scope-manager": "npm:7.14.1" - "@typescript-eslint/types": "npm:7.14.1" - "@typescript-eslint/typescript-estree": "npm:7.14.1" + "@typescript-eslint/scope-manager": "npm:8.1.0" + "@typescript-eslint/types": "npm:8.1.0" + "@typescript-eslint/typescript-estree": "npm:8.1.0" peerDependencies: - eslint: ^8.56.0 - checksum: 10c0/c7f635a3c2c6c085e1d51a52088e55cad9d7e1257b1f60378e5eeb6eb0871db027d42747e9ef60a2f557cf9dd68b2ce014d488d795db8f771506290b164b0e5a + eslint: ^8.57.0 || ^9.0.0 + checksum: 10c0/c95503a6bdcd98b1ff04d1adbf46377b2036b1c510d90a4a056401f996f775f06c3108c95fb81cd6babc9c97b73b91b8e848f0337bc508de8a49c993582f0e75 languageName: node linkType: hard @@ -4663,13 +5287,13 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:7.14.1": - version: 7.14.1 - resolution: "@typescript-eslint/visitor-keys@npm:7.14.1" +"@typescript-eslint/visitor-keys@npm:8.1.0": + version: 8.1.0 + resolution: "@typescript-eslint/visitor-keys@npm:8.1.0" dependencies: - "@typescript-eslint/types": "npm:7.14.1" + "@typescript-eslint/types": "npm:8.1.0" eslint-visitor-keys: "npm:^3.4.3" - checksum: 10c0/39ac489990fcfdcee442f27658431a0eb44ccf694f701a45df2a108c47cea9582e0955bff0d449047549149385f72895a5d7e6c1622ece1fe32594b7cecb85f3 + checksum: 10c0/b7544dbb0eec1ddbfcd95c04b51b9a739c2e768c16d1c88508f976a2b0d1bc02fefb7491930e06e48073a5c07c6f488cd8403bba3a8b918888b93a88d5ac3869 languageName: node linkType: hard @@ -4852,33 +5476,12 @@ __metadata: resolution: "@xtuc/long@npm:4.2.2" checksum: 10c0/8582cbc69c79ad2d31568c412129bf23d2b1210a1dfb60c82d5a1df93334da4ee51f3057051658569e2c196d8dc33bc05ae6b974a711d0d16e801e1d0647ccd1 languageName: node - linkType: hard - -"@yarnpkg/lockfile@npm:1.1.0, @yarnpkg/lockfile@npm:^1.1.0": - version: 1.1.0 - resolution: "@yarnpkg/lockfile@npm:1.1.0" - checksum: 10c0/0bfa50a3d756623d1f3409bc23f225a1d069424dbc77c6fd2f14fb377390cd57ec703dc70286e081c564be9051ead9ba85d81d66a3e68eeb6eb506d4e0c0fbda - languageName: node - linkType: hard - -"@yarnpkg/parsers@npm:3.0.0-rc.46": - version: 3.0.0-rc.46 - resolution: "@yarnpkg/parsers@npm:3.0.0-rc.46" - dependencies: - js-yaml: "npm:^3.10.0" - tslib: "npm:^2.4.0" - checksum: 10c0/c7f421c6885142f351459031c093fb2e79abcce6f4a89765a10e600bb7ab122949c54bcea2b23de9572a2b34ba29f822b17831c1c43ba50373ceb8cb5b336667 - languageName: node - linkType: hard - -"@zkochan/js-yaml@npm:0.0.7": - version: 0.0.7 - resolution: "@zkochan/js-yaml@npm:0.0.7" - dependencies: - argparse: "npm:^2.0.1" - bin: - js-yaml: bin/js-yaml.js - checksum: 10c0/c8b3525717912811f9422ed50e94c5751ed6f771eb1b7e5cde097f14835654931e2bdaecb1e5fc37b51cf8d822410a307f16dd1581d46149398c30215f3f9bac + linkType: hard + +"@yarnpkg/lockfile@npm:1.1.0": + version: 1.1.0 + resolution: "@yarnpkg/lockfile@npm:1.1.0" + checksum: 10c0/0bfa50a3d756623d1f3409bc23f225a1d069424dbc77c6fd2f14fb377390cd57ec703dc70286e081c564be9051ead9ba85d81d66a3e68eeb6eb506d4e0c0fbda languageName: node linkType: hard @@ -4927,12 +5530,12 @@ __metadata: languageName: node linkType: hard -"acorn-import-assertions@npm:^1.9.0": - version: 1.9.0 - resolution: "acorn-import-assertions@npm:1.9.0" +"acorn-import-attributes@npm:^1.9.5": + version: 1.9.5 + resolution: "acorn-import-attributes@npm:1.9.5" peerDependencies: acorn: ^8 - checksum: 10c0/3b4a194e128efdc9b86c2b1544f623aba4c1aa70d638f8ab7dc3971a5b4aa4c57bd62f99af6e5325bb5973c55863b4112e708a6f408bad7a138647ca72283afe + checksum: 10c0/5926eaaead2326d5a86f322ff1b617b0f698aa61dc719a5baa0e9d955c9885cc71febac3fb5bacff71bbf2c4f9c12db2056883c68c53eb962c048b952e1e013d languageName: node linkType: hard @@ -4961,6 +5564,15 @@ __metadata: languageName: node linkType: hard +"acorn@npm:^8.12.0": + version: 8.12.1 + resolution: "acorn@npm:8.12.1" + bin: + acorn: bin/acorn + checksum: 10c0/51fb26cd678f914e13287e886da2d7021f8c2bc0ccc95e03d3e0447ee278dd3b40b9c57dc222acd5881adcf26f3edc40901a4953403232129e3876793cd17386 + languageName: node + linkType: hard + "add-stream@npm:^1.0.0": version: 1.0.0 resolution: "add-stream@npm:1.0.0" @@ -5075,6 +5687,18 @@ __metadata: languageName: node linkType: hard +"ajv@npm:8.17.1": + version: 8.17.1 + resolution: "ajv@npm:8.17.1" + dependencies: + fast-deep-equal: "npm:^3.1.3" + fast-uri: "npm:^3.0.1" + json-schema-traverse: "npm:^1.0.0" + require-from-string: "npm:^2.0.2" + checksum: 10c0/ec3ba10a573c6b60f94639ffc53526275917a2df6810e4ab5a6b959d87459f9ef3f00d5e7865b82677cb7d21590355b34da14d1d0b9c32d75f95a187e76fff35 + languageName: node + linkType: hard + "ajv@npm:^6.12.4, ajv@npm:^6.12.5": version: 6.12.6 resolution: "ajv@npm:6.12.6" @@ -5123,7 +5747,7 @@ __metadata: languageName: node linkType: hard -"ansi-colors@npm:4.1.3, ansi-colors@npm:^4.1.1, ansi-colors@npm:^4.1.3": +"ansi-colors@npm:4.1.3, ansi-colors@npm:^4.1.3": version: 4.1.3 resolution: "ansi-colors@npm:4.1.3" checksum: 10c0/ec87a2f59902f74e61eada7f6e6fe20094a628dab765cfdbd03c3477599368768cffccdb5d3bb19a1b6c99126783a143b1fee31aab729b31ffe5836c7e5e28b9 @@ -5139,10 +5763,12 @@ __metadata: languageName: node linkType: hard -"ansi-escapes@npm:^6.2.0": - version: 6.2.1 - resolution: "ansi-escapes@npm:6.2.1" - checksum: 10c0/a2c6f58b044be5f69662ee17073229b492daa2425a7fd99a665db6c22eab6e4ab42752807def7281c1c7acfed48f87f2362dda892f08c2c437f1b39c6b033103 +"ansi-escapes@npm:^7.0.0": + version: 7.0.0 + resolution: "ansi-escapes@npm:7.0.0" + dependencies: + environment: "npm:^1.0.0" + checksum: 10c0/86e51e36fabef18c9c004af0a280573e828900641cea35134a124d2715e0c5a473494ab4ce396614505da77638ae290ff72dd8002d9747d2ee53f5d6bbe336be languageName: node linkType: hard @@ -5187,13 +5813,6 @@ __metadata: languageName: node linkType: hard -"ansi-styles@npm:^5.0.0": - version: 5.2.0 - resolution: "ansi-styles@npm:5.2.0" - checksum: 10c0/9c4ca80eb3c2fb7b33841c210d2f20807f40865d27008d7c3f707b7f95cab7d67462a565e2388ac3285b71cb3d9bb2173de8da37c57692a362885ec34d6e27df - languageName: node - linkType: hard - "ansi-styles@npm:^6.0.0, ansi-styles@npm:^6.1.0, ansi-styles@npm:^6.2.1": version: 6.2.1 resolution: "ansi-styles@npm:6.2.1" @@ -5251,15 +5870,6 @@ __metadata: languageName: node linkType: hard -"argparse@npm:^1.0.7": - version: 1.0.10 - resolution: "argparse@npm:1.0.10" - dependencies: - sprintf-js: "npm:~1.0.2" - checksum: 10c0/b2972c5c23c63df66bca144dbc65d180efa74f25f8fd9b7d9a0a6c88ae839db32df3d54770dcb6460cf840d232b60695d1a6b1053f599d84e73f7437087712de - languageName: node - linkType: hard - "argparse@npm:^2.0.1": version: 2.0.1 resolution: "argparse@npm:2.0.1" @@ -5421,21 +6031,21 @@ __metadata: languageName: node linkType: hard -"autoprefixer@npm:10.4.19": - version: 10.4.19 - resolution: "autoprefixer@npm:10.4.19" +"autoprefixer@npm:10.4.20": + version: 10.4.20 + resolution: "autoprefixer@npm:10.4.20" dependencies: - browserslist: "npm:^4.23.0" - caniuse-lite: "npm:^1.0.30001599" + browserslist: "npm:^4.23.3" + caniuse-lite: "npm:^1.0.30001646" fraction.js: "npm:^4.3.7" normalize-range: "npm:^0.1.2" - picocolors: "npm:^1.0.0" + picocolors: "npm:^1.0.1" postcss-value-parser: "npm:^4.2.0" peerDependencies: postcss: ^8.1.0 bin: autoprefixer: bin/autoprefixer - checksum: 10c0/fe0178eb8b1da4f15c6535cd329926609b22d1811e047371dccce50563623f8075dd06fb167daff059e4228da651b0bdff6d9b44281541eaf0ce0b79125bfd19 + checksum: 10c0/e1f00978a26e7c5b54ab12036d8c13833fad7222828fc90914771b1263f51b28c7ddb5803049de4e77696cbd02bb25cfc3634e80533025bb26c26aacdf938940 languageName: node linkType: hard @@ -5452,38 +6062,38 @@ __metadata: version: 0.0.0-use.local resolution: "awg-app@workspace:." dependencies: - "@angular-devkit/build-angular": "npm:^18.0.6" - "@angular-eslint/builder": "npm:^18.1.0" - "@angular-eslint/eslint-plugin": "npm:^18.1.0" - "@angular-eslint/eslint-plugin-template": "npm:^18.1.0" - "@angular-eslint/schematics": "npm:^18.1.0" - "@angular-eslint/template-parser": "npm:^18.1.0" - "@angular/animations": "npm:^18.0.5" - "@angular/cli": "npm:^18.0.6" - "@angular/common": "npm:^18.0.5" - "@angular/compiler": "npm:^18.0.5" - "@angular/compiler-cli": "npm:^18.0.5" - "@angular/core": "npm:^18.0.5" - "@angular/forms": "npm:^18.0.5" - "@angular/localize": "npm:^18.0.5" - "@angular/platform-browser": "npm:^18.0.5" - "@angular/platform-browser-dynamic": "npm:^18.0.5" - "@angular/platform-server": "npm:^18.0.5" - "@angular/router": "npm:^18.0.5" - "@codemirror/legacy-modes": "npm:^6.4.0" - "@commitlint/cli": "npm:^19.3.0" + "@angular-devkit/build-angular": "npm:^18.2.0" + "@angular-eslint/builder": "npm:^18.3.0" + "@angular-eslint/eslint-plugin": "npm:^18.3.0" + "@angular-eslint/eslint-plugin-template": "npm:^18.3.0" + "@angular-eslint/schematics": "npm:^18.3.0" + "@angular-eslint/template-parser": "npm:^18.3.0" + "@angular/animations": "npm:^18.2.0" + "@angular/cli": "npm:^18.2.0" + "@angular/common": "npm:^18.2.0" + "@angular/compiler": "npm:^18.2.0" + "@angular/compiler-cli": "npm:^18.2.0" + "@angular/core": "npm:^18.2.0" + "@angular/forms": "npm:^18.2.0" + "@angular/localize": "npm:^18.2.0" + "@angular/platform-browser": "npm:^18.2.0" + "@angular/platform-browser-dynamic": "npm:^18.2.0" + "@angular/platform-server": "npm:^18.2.0" + "@angular/router": "npm:^18.2.0" + "@codemirror/legacy-modes": "npm:^6.4.1" + "@commitlint/cli": "npm:^19.4.0" "@commitlint/config-angular": "npm:^19.3.0" "@compodoc/compodoc": "npm:^1.1.25" "@fortawesome/angular-fontawesome": "npm:^0.15.0" - "@fortawesome/free-solid-svg-icons": "npm:^6.5.2" + "@fortawesome/free-solid-svg-icons": "npm:^6.6.0" "@kolkov/ngx-gallery": "npm:2.0.1" "@ng-bootstrap/ng-bootstrap": "npm:^17.0.0" "@popperjs/core": "npm:^2.11.8" "@types/d3": "npm:^7.4.3" "@types/jasmine": "npm:~5.1.4" - "@types/node": "npm:^18.19.39" - "@typescript-eslint/eslint-plugin": "npm:^7.14.1" - "@typescript-eslint/parser": "npm:^7.14.1" + "@types/node": "npm:^20.14.14" + "@typescript-eslint/eslint-plugin": "npm:^8.1.0" + "@typescript-eslint/parser": "npm:^8.1.0" angular-cli-ghpages: "npm:^2.0.1" bootstrap: "npm:^5.3.3" codemirror: "npm:^6.0.1" @@ -5499,50 +6109,37 @@ __metadata: eslint-plugin-angular: "npm:^4.1.0" eslint-plugin-deprecation: "npm:^3.0.0" eslint-plugin-import: "npm:^2.29.1" - eslint-plugin-jsdoc: "npm:^48.5.0" - eslint-plugin-prettier: "npm:^5.1.3" + eslint-plugin-jsdoc: "npm:^50.2.2" + eslint-plugin-prettier: "npm:^5.2.1" font-awesome: "npm:^4.7.0" gzipper: "npm:^7.2.0" - husky: "npm:^9.0.11" - jasmine-core: "npm:~5.1.2" + husky: "npm:^9.1.4" + jasmine-core: "npm:~5.2.0" json2typescript: "npm:^1.5.1" - karma: "npm:~6.4.3" + karma: "npm:~6.4.4" karma-chrome-launcher: "npm:~3.2.0" karma-coverage: "npm:^2.2.1" karma-jasmine: "npm:~5.1.0" karma-jasmine-html-reporter: "npm:^2.1.0" - lint-staged: "npm:^15.2.7" - n3: "npm:^1.17.4" + lint-staged: "npm:^15.2.9" + n3: "npm:^1.20.4" ngx-json-viewer: "npm:^3.2.1" - prettier: "npm:^3.3.2" + prettier: "npm:^3.3.3" rdfstore: "musicenfanthen/rdfstore-js#v0.9.18-alpha.16" rxjs: "npm:~7.8.1" source-map-explorer: "npm:^2.5.3" stream: "npm:^0.0.3" tslib: "npm:^2.6.2" - typescript: "npm:~5.5.2" + typescript: "npm:~5.5.4" webpack-bundle-analyzer: "npm:^4.10.2" - zone.js: "npm:~0.14.7" + zone.js: "npm:~0.14.10" languageName: unknown linkType: soft -"axios@npm:^1.6.0": - version: 1.7.2 - resolution: "axios@npm:1.7.2" - dependencies: - follow-redirects: "npm:^1.15.6" - form-data: "npm:^4.0.0" - proxy-from-env: "npm:^1.1.0" - checksum: 10c0/cbd47ce380fe045313364e740bb03b936420b8b5558c7ea36a4563db1258c658f05e40feb5ddd41f6633fdd96d37ac2a76f884dad599c5b0224b4c451b3fa7ae - languageName: node - linkType: hard - -"axobject-query@npm:4.0.0": - version: 4.0.0 - resolution: "axobject-query@npm:4.0.0" - dependencies: - dequal: "npm:^2.0.3" - checksum: 10c0/4d756b5c2ff099f1c7f99e55a5de9b2066cb2a13a3170185ff34bfec2d7bcab81eb820a4e7340d35c251341b61ebee6e705b7ce64db78224df1df5a4d68448fe +"axobject-query@npm:4.1.0": + version: 4.1.0 + resolution: "axobject-query@npm:4.1.0" + checksum: 10c0/c470e4f95008f232eadd755b018cb55f16c03ccf39c027b941cd8820ac6b68707ce5d7368a46756db4256fbc91bb4ead368f84f7fb034b2b7932f082f6dc0775 languageName: node linkType: hard @@ -5796,6 +6393,34 @@ __metadata: languageName: node linkType: hard +"browserslist@npm:^4.23.1": + version: 4.23.2 + resolution: "browserslist@npm:4.23.2" + dependencies: + caniuse-lite: "npm:^1.0.30001640" + electron-to-chromium: "npm:^1.4.820" + node-releases: "npm:^2.0.14" + update-browserslist-db: "npm:^1.1.0" + bin: + browserslist: cli.js + checksum: 10c0/0217d23c69ed61cdd2530c7019bf7c822cd74c51f8baab18dd62457fed3129f52499f8d3a6f809ae1fb7bb3050aa70caa9a529cc36c7478427966dbf429723a5 + languageName: node + linkType: hard + +"browserslist@npm:^4.23.3": + version: 4.23.3 + resolution: "browserslist@npm:4.23.3" + dependencies: + caniuse-lite: "npm:^1.0.30001646" + electron-to-chromium: "npm:^1.5.4" + node-releases: "npm:^2.0.18" + update-browserslist-db: "npm:^1.1.0" + bin: + browserslist: cli.js + checksum: 10c0/3063bfdf812815346447f4796c8f04601bf5d62003374305fd323c2a463e42776475bcc5309264e39bcf9a8605851e53560695991a623be988138b3ff8c66642 + languageName: node + linkType: hard + "btoa@npm:^1.2.1": version: 1.2.1 resolution: "btoa@npm:1.2.1" @@ -5946,13 +6571,27 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.30001587, caniuse-lite@npm:^1.0.30001599": +"caniuse-lite@npm:^1.0.30001587": version: 1.0.30001628 resolution: "caniuse-lite@npm:1.0.30001628" checksum: 10c0/7f3e198d30220e02d54ea9de1562725d65e89e4318e16b5addd550a8cd6d240de4d42eecb97506c5eafdf5193ad39624729e12b6385fc63b2a2b8e8c430cbcb1 languageName: node linkType: hard +"caniuse-lite@npm:^1.0.30001640": + version: 1.0.30001643 + resolution: "caniuse-lite@npm:1.0.30001643" + checksum: 10c0/7fcd0fd180bbe6764311ad57b0d39c23afdcc3bb1d8f804e7a76752c62a85b1bb7cf74b672d9da2f0afe7ad75336ff811a6fe279eb2a54bc04c272b6b62e57f1 + languageName: node + linkType: hard + +"caniuse-lite@npm:^1.0.30001646": + version: 1.0.30001651 + resolution: "caniuse-lite@npm:1.0.30001651" + checksum: 10c0/7821278952a6dbd17358e5d08083d258f092e2a530f5bc1840657cb140fbbc5ec44293bc888258c44a18a9570cde149ed05819ac8320b9710cf22f699891e6ad + languageName: node + linkType: hard + "canonicalize@npm:^1.0.1": version: 1.0.8 resolution: "canonicalize@npm:1.0.8" @@ -6071,7 +6710,7 @@ __metadata: languageName: node linkType: hard -"cli-cursor@npm:3.1.0, cli-cursor@npm:^3.1.0": +"cli-cursor@npm:^3.1.0": version: 3.1.0 resolution: "cli-cursor@npm:3.1.0" dependencies: @@ -6080,23 +6719,16 @@ __metadata: languageName: node linkType: hard -"cli-cursor@npm:^4.0.0": - version: 4.0.0 - resolution: "cli-cursor@npm:4.0.0" +"cli-cursor@npm:^5.0.0": + version: 5.0.0 + resolution: "cli-cursor@npm:5.0.0" dependencies: - restore-cursor: "npm:^4.0.0" - checksum: 10c0/e776e8c3c6727300d0539b0d25160b2bb56aed1a63942753ba1826b012f337a6f4b7ace3548402e4f2f13b5e16bfd751be672c44b203205e7eca8be94afec42c - languageName: node - linkType: hard - -"cli-spinners@npm:2.6.1": - version: 2.6.1 - resolution: "cli-spinners@npm:2.6.1" - checksum: 10c0/6abcdfef59aa68e6b51376d87d257f9120a0a7120a39dd21633702d24797decb6dc747dff2217c88732710db892b5053c5c672d221b6c4d13bbcb5372e203596 + restore-cursor: "npm:^5.0.0" + checksum: 10c0/7ec62f69b79f6734ab209a3e4dbdc8af7422d44d360a7cb1efa8a0887bbe466a6e625650c466fe4359aee44dbe2dc0b6994b583d40a05d0808a5cb193641d220 languageName: node linkType: hard -"cli-spinners@npm:^2.5.0": +"cli-spinners@npm:^2.5.0, cli-spinners@npm:^2.9.2": version: 2.9.2 resolution: "cli-spinners@npm:2.9.2" checksum: 10c0/907a1c227ddf0d7a101e7ab8b300affc742ead4b4ebe920a5bf1bc6d45dce2958fcd195eb28fa25275062fe6fa9b109b93b63bc8033396ed3bcb50297008b3a3 @@ -6772,19 +7404,19 @@ __metadata: languageName: node linkType: hard -"copy-webpack-plugin@npm:11.0.0": - version: 11.0.0 - resolution: "copy-webpack-plugin@npm:11.0.0" +"copy-webpack-plugin@npm:12.0.2": + version: 12.0.2 + resolution: "copy-webpack-plugin@npm:12.0.2" dependencies: - fast-glob: "npm:^3.2.11" + fast-glob: "npm:^3.3.2" glob-parent: "npm:^6.0.1" - globby: "npm:^13.1.1" + globby: "npm:^14.0.0" normalize-path: "npm:^3.0.0" - schema-utils: "npm:^4.0.0" - serialize-javascript: "npm:^6.0.0" + schema-utils: "npm:^4.2.0" + serialize-javascript: "npm:^6.0.2" peerDependencies: webpack: ^5.1.0 - checksum: 10c0/a667dd226b26f148584a35fb705f5af926d872584912cf9fd203c14f2b3a68f473a1f5cf768ec1dd5da23820823b850e5d50458b685c468e4a224b25c12a15b4 + checksum: 10c0/1a2715a1280a37b81b7040b89ed962db4aa75475b164f84f266fa4e81f209269b13f8bff10b104dff7558854bafedcdd4f30c40fd23ecd8fa28af45516b459cd languageName: node linkType: hard @@ -6797,6 +7429,15 @@ __metadata: languageName: node linkType: hard +"core-js-compat@npm:^3.37.1": + version: 3.38.0 + resolution: "core-js-compat@npm:3.38.0" + dependencies: + browserslist: "npm:^4.23.3" + checksum: 10c0/9d653a448b8a491034358d2f052e63dda86f75fb65646e2d313a938212470ba1c2f5a83bf31cc583d6c87a9e8d7b0d49458447cab2ff36c4caa097ae381de336 + languageName: node + linkType: hard + "core-util-is@npm:~1.0.0": version: 1.0.3 resolution: "core-util-is@npm:1.0.3" @@ -6851,9 +7492,9 @@ __metadata: languageName: node linkType: hard -"critters@npm:0.0.22": - version: 0.0.22 - resolution: "critters@npm:0.0.22" +"critters@npm:0.0.24": + version: 0.0.24 + resolution: "critters@npm:0.0.24" dependencies: chalk: "npm:^4.1.0" css-select: "npm:^5.1.0" @@ -6862,7 +7503,7 @@ __metadata: htmlparser2: "npm:^8.0.2" postcss: "npm:^8.4.23" postcss-media-query-parser: "npm:^0.2.3" - checksum: 10c0/951c1c2f46b848f188b0e4a169e6fe56cc2a6d2934f5270372cfd48aadb6d475b9ad8d55b6d6182843c3ae117cfc05952f353bd4455122b122d2ecf7ff28687b + checksum: 10c0/a8f2fc45200e1e48ec82a1832565ec0c869b338cbb35506e0155c4affee5ed9a7478b956e699bd837926051d4249c93f371add7fb14bb9c383944077d696814e languageName: node linkType: hard @@ -6884,9 +7525,9 @@ __metadata: languageName: node linkType: hard -"css-loader@npm:7.1.1": - version: 7.1.1 - resolution: "css-loader@npm:7.1.1" +"css-loader@npm:7.1.2": + version: 7.1.2 + resolution: "css-loader@npm:7.1.2" dependencies: icss-utils: "npm:^5.1.0" postcss: "npm:^8.4.33" @@ -6904,7 +7545,7 @@ __metadata: optional: true webpack: optional: true - checksum: 10c0/ebb4ffe68e9df0036fcce66ae182648d4d16b2fdfdc04a5bf7d7783776d389a23be161bb7139a3f842dc75466882544f46d2183bc9399d0bacf83b66a1802b41 + checksum: 10c0/edec9ed71e3c416c9c6ad41c138834c94baf7629de3b97a3337ae8cec4a45e05c57bdb7c4b4d267229fc04b8970d0d1c0734ded8dcd0ac8c7c286b36facdbbf0 languageName: node linkType: hard @@ -7208,6 +7849,18 @@ __metadata: languageName: node linkType: hard +"debug@npm:^4.3.6, debug@npm:~4.3.6": + version: 4.3.6 + resolution: "debug@npm:4.3.6" + dependencies: + ms: "npm:2.1.2" + peerDependenciesMeta: + supports-color: + optional: true + checksum: 10c0/3293416bff072389c101697d4611c402a6bacd1900ac20c0492f61a9cdd6b3b29750fc7f5e299f8058469ef60ff8fb79b86395a30374fbd2490113c1c7112285 + languageName: node + linkType: hard + "decache@npm:^4.6.2": version: 4.6.2 resolution: "decache@npm:4.6.2" @@ -7459,13 +8112,6 @@ __metadata: languageName: node linkType: hard -"diff-sequences@npm:^29.6.3": - version: 29.6.3 - resolution: "diff-sequences@npm:29.6.3" - checksum: 10c0/32e27ac7dbffdf2fb0eb5a84efd98a9ad084fbabd5ac9abb8757c6770d5320d2acd172830b28c4add29bb873d59420601dfc805ac4064330ce59b1adfd0593b2 - languageName: node - linkType: hard - "dir-glob@npm:^3.0.1": version: 3.0.1 resolution: "dir-glob@npm:3.0.1" @@ -7568,20 +8214,6 @@ __metadata: languageName: node linkType: hard -"dotenv-expand@npm:~10.0.0": - version: 10.0.0 - resolution: "dotenv-expand@npm:10.0.0" - checksum: 10c0/298f5018e29cfdcb0b5f463ba8e8627749103fbcf6cf81c561119115754ed582deee37b49dfc7253028aaba875ab7aea5fa90e5dac88e511d009ab0e6677924e - languageName: node - linkType: hard - -"dotenv@npm:~16.3.1": - version: 16.3.2 - resolution: "dotenv@npm:16.3.2" - checksum: 10c0/a87d62cef0810b670cb477db1a24a42a093b6b428c9e65c185ce1d6368ad7175234b13547718ba08da18df43faae4f814180cc0366e11be1ded2277abc4dd22e - languageName: node - linkType: hard - "dotgitignore@npm:^2.1.0": version: 2.1.0 resolution: "dotgitignore@npm:2.1.0" @@ -7632,7 +8264,7 @@ __metadata: languageName: node linkType: hard -"ejs@npm:^3.1.5, ejs@npm:^3.1.7": +"ejs@npm:^3.1.5": version: 3.1.10 resolution: "ejs@npm:3.1.10" dependencies: @@ -7650,6 +8282,20 @@ __metadata: languageName: node linkType: hard +"electron-to-chromium@npm:^1.4.820": + version: 1.5.1 + resolution: "electron-to-chromium@npm:1.5.1" + checksum: 10c0/011ca31948e8355981920619b8946dda31408f468652686909775df7c5773b01fa10d0172b758e2c1fd07601606285442ca98053df2b1dc0fd525f0e7a48178e + languageName: node + linkType: hard + +"electron-to-chromium@npm:^1.5.4": + version: 1.5.8 + resolution: "electron-to-chromium@npm:1.5.8" + checksum: 10c0/801de2afa0479ffa0cd0e36b7865241dcd3a66a92fca28457431d2dc2bd9c2d066ab07578b419426c504df196f078c63283ee47140c28039d224ec2631acbcee + languageName: node + linkType: hard + "email-addresses@npm:^3.0.1": version: 3.1.0 resolution: "email-addresses@npm:3.1.0" @@ -7742,7 +8388,7 @@ __metadata: languageName: node linkType: hard -"enhanced-resolve@npm:^5.16.0": +"enhanced-resolve@npm:^5.17.0": version: 5.17.0 resolution: "enhanced-resolve@npm:5.17.0" dependencies: @@ -7752,15 +8398,6 @@ __metadata: languageName: node linkType: hard -"enquirer@npm:~2.3.6": - version: 2.3.6 - resolution: "enquirer@npm:2.3.6" - dependencies: - ansi-colors: "npm:^4.1.1" - checksum: 10c0/8e070e052c2c64326a2803db9084d21c8aaa8c688327f133bf65c4a712586beb126fd98c8a01cfb0433e82a4bd3b6262705c55a63e0f7fb91d06b9cedbde9a11 - languageName: node - linkType: hard - "ent@npm:~2.2.0": version: 2.2.0 resolution: "ent@npm:2.2.0" @@ -7782,6 +8419,13 @@ __metadata: languageName: node linkType: hard +"environment@npm:^1.0.0": + version: 1.1.0 + resolution: "environment@npm:1.1.0" + checksum: 10c0/fb26434b0b581ab397039e51ff3c92b34924a98b2039dcb47e41b7bca577b9dbf134a8eadb364415c74464b682e2d3afe1a4c0eb9873dc44ea814c5d3103331d + languageName: node + linkType: hard + "err-code@npm:^2.0.2": version: 2.0.3 resolution: "err-code@npm:2.0.3" @@ -7957,42 +8601,43 @@ __metadata: languageName: node linkType: hard -"esbuild-wasm@npm:0.21.3": - version: 0.21.3 - resolution: "esbuild-wasm@npm:0.21.3" +"esbuild-wasm@npm:0.23.0": + version: 0.23.0 + resolution: "esbuild-wasm@npm:0.23.0" bin: esbuild: bin/esbuild - checksum: 10c0/2afbd5a868cfa73c17aa57cd7756dee021e9013db122ac0d434770376fcbd8daba193d764b9fe38e00e408f5867435df81806e8db947bf55efcad12eaa16b882 + checksum: 10c0/027a5d8db3b9a39523d68885de9e02f82ec0a0174668fa184b1bc7af4c1e17ed07180d9ceccc714ec8d5d8b7d43faf3f81e8c675b4921fa5262b1e1aa876f457 languageName: node linkType: hard -"esbuild@npm:0.21.3": - version: 0.21.3 - resolution: "esbuild@npm:0.21.3" - dependencies: - "@esbuild/aix-ppc64": "npm:0.21.3" - "@esbuild/android-arm": "npm:0.21.3" - "@esbuild/android-arm64": "npm:0.21.3" - "@esbuild/android-x64": "npm:0.21.3" - "@esbuild/darwin-arm64": "npm:0.21.3" - "@esbuild/darwin-x64": "npm:0.21.3" - "@esbuild/freebsd-arm64": "npm:0.21.3" - "@esbuild/freebsd-x64": "npm:0.21.3" - "@esbuild/linux-arm": "npm:0.21.3" - "@esbuild/linux-arm64": "npm:0.21.3" - "@esbuild/linux-ia32": "npm:0.21.3" - "@esbuild/linux-loong64": "npm:0.21.3" - "@esbuild/linux-mips64el": "npm:0.21.3" - "@esbuild/linux-ppc64": "npm:0.21.3" - "@esbuild/linux-riscv64": "npm:0.21.3" - "@esbuild/linux-s390x": "npm:0.21.3" - "@esbuild/linux-x64": "npm:0.21.3" - "@esbuild/netbsd-x64": "npm:0.21.3" - "@esbuild/openbsd-x64": "npm:0.21.3" - "@esbuild/sunos-x64": "npm:0.21.3" - "@esbuild/win32-arm64": "npm:0.21.3" - "@esbuild/win32-ia32": "npm:0.21.3" - "@esbuild/win32-x64": "npm:0.21.3" +"esbuild@npm:0.23.0": + version: 0.23.0 + resolution: "esbuild@npm:0.23.0" + dependencies: + "@esbuild/aix-ppc64": "npm:0.23.0" + "@esbuild/android-arm": "npm:0.23.0" + "@esbuild/android-arm64": "npm:0.23.0" + "@esbuild/android-x64": "npm:0.23.0" + "@esbuild/darwin-arm64": "npm:0.23.0" + "@esbuild/darwin-x64": "npm:0.23.0" + "@esbuild/freebsd-arm64": "npm:0.23.0" + "@esbuild/freebsd-x64": "npm:0.23.0" + "@esbuild/linux-arm": "npm:0.23.0" + "@esbuild/linux-arm64": "npm:0.23.0" + "@esbuild/linux-ia32": "npm:0.23.0" + "@esbuild/linux-loong64": "npm:0.23.0" + "@esbuild/linux-mips64el": "npm:0.23.0" + "@esbuild/linux-ppc64": "npm:0.23.0" + "@esbuild/linux-riscv64": "npm:0.23.0" + "@esbuild/linux-s390x": "npm:0.23.0" + "@esbuild/linux-x64": "npm:0.23.0" + "@esbuild/netbsd-x64": "npm:0.23.0" + "@esbuild/openbsd-arm64": "npm:0.23.0" + "@esbuild/openbsd-x64": "npm:0.23.0" + "@esbuild/sunos-x64": "npm:0.23.0" + "@esbuild/win32-arm64": "npm:0.23.0" + "@esbuild/win32-ia32": "npm:0.23.0" + "@esbuild/win32-x64": "npm:0.23.0" dependenciesMeta: "@esbuild/aix-ppc64": optional: true @@ -8030,6 +8675,8 @@ __metadata: optional: true "@esbuild/netbsd-x64": optional: true + "@esbuild/openbsd-arm64": + optional: true "@esbuild/openbsd-x64": optional: true "@esbuild/sunos-x64": @@ -8042,37 +8689,37 @@ __metadata: optional: true bin: esbuild: bin/esbuild - checksum: 10c0/5bf85ccd11cc7e7fbbb7ca3458a0fa019ec9b38e1ed9e61f0866b29419e7348231da0aa336e4645c3bda8e757fa20bd3fd8a5f73256308488086a6c7ec9b6ac5 - languageName: node - linkType: hard - -"esbuild@npm:^0.20.1": - version: 0.20.2 - resolution: "esbuild@npm:0.20.2" - dependencies: - "@esbuild/aix-ppc64": "npm:0.20.2" - "@esbuild/android-arm": "npm:0.20.2" - "@esbuild/android-arm64": "npm:0.20.2" - "@esbuild/android-x64": "npm:0.20.2" - "@esbuild/darwin-arm64": "npm:0.20.2" - "@esbuild/darwin-x64": "npm:0.20.2" - "@esbuild/freebsd-arm64": "npm:0.20.2" - "@esbuild/freebsd-x64": "npm:0.20.2" - "@esbuild/linux-arm": "npm:0.20.2" - "@esbuild/linux-arm64": "npm:0.20.2" - "@esbuild/linux-ia32": "npm:0.20.2" - "@esbuild/linux-loong64": "npm:0.20.2" - "@esbuild/linux-mips64el": "npm:0.20.2" - "@esbuild/linux-ppc64": "npm:0.20.2" - "@esbuild/linux-riscv64": "npm:0.20.2" - "@esbuild/linux-s390x": "npm:0.20.2" - "@esbuild/linux-x64": "npm:0.20.2" - "@esbuild/netbsd-x64": "npm:0.20.2" - "@esbuild/openbsd-x64": "npm:0.20.2" - "@esbuild/sunos-x64": "npm:0.20.2" - "@esbuild/win32-arm64": "npm:0.20.2" - "@esbuild/win32-ia32": "npm:0.20.2" - "@esbuild/win32-x64": "npm:0.20.2" + checksum: 10c0/08c148c067795165798c0467ce02d2d1ecedc096989bded5f0d795c61a1fcbec6c14d0a3c9f4ad6185cc29ec52087acaa335ed6d98be6ad57f7fa4264626bde0 + languageName: node + linkType: hard + +"esbuild@npm:^0.21.3": + version: 0.21.5 + resolution: "esbuild@npm:0.21.5" + dependencies: + "@esbuild/aix-ppc64": "npm:0.21.5" + "@esbuild/android-arm": "npm:0.21.5" + "@esbuild/android-arm64": "npm:0.21.5" + "@esbuild/android-x64": "npm:0.21.5" + "@esbuild/darwin-arm64": "npm:0.21.5" + "@esbuild/darwin-x64": "npm:0.21.5" + "@esbuild/freebsd-arm64": "npm:0.21.5" + "@esbuild/freebsd-x64": "npm:0.21.5" + "@esbuild/linux-arm": "npm:0.21.5" + "@esbuild/linux-arm64": "npm:0.21.5" + "@esbuild/linux-ia32": "npm:0.21.5" + "@esbuild/linux-loong64": "npm:0.21.5" + "@esbuild/linux-mips64el": "npm:0.21.5" + "@esbuild/linux-ppc64": "npm:0.21.5" + "@esbuild/linux-riscv64": "npm:0.21.5" + "@esbuild/linux-s390x": "npm:0.21.5" + "@esbuild/linux-x64": "npm:0.21.5" + "@esbuild/netbsd-x64": "npm:0.21.5" + "@esbuild/openbsd-x64": "npm:0.21.5" + "@esbuild/sunos-x64": "npm:0.21.5" + "@esbuild/win32-arm64": "npm:0.21.5" + "@esbuild/win32-ia32": "npm:0.21.5" + "@esbuild/win32-x64": "npm:0.21.5" dependenciesMeta: "@esbuild/aix-ppc64": optional: true @@ -8122,7 +8769,7 @@ __metadata: optional: true bin: esbuild: bin/esbuild - checksum: 10c0/66398f9fb2c65e456a3e649747b39af8a001e47963b25e86d9c09d2a48d61aa641b27da0ce5cad63df95ad246105e1d83e7fee0e1e22a0663def73b1c5101112 + checksum: 10c0/fa08508adf683c3f399e8a014a6382a6b65542213431e26206c0720e536b31c09b50798747c2a105a4bbba1d9767b8d3615a74c2f7bf1ddf6d836cd11eb672de languageName: node linkType: hard @@ -8236,32 +8883,33 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-jsdoc@npm:^48.5.0": - version: 48.5.0 - resolution: "eslint-plugin-jsdoc@npm:48.5.0" +"eslint-plugin-jsdoc@npm:^50.2.2": + version: 50.2.2 + resolution: "eslint-plugin-jsdoc@npm:50.2.2" dependencies: - "@es-joy/jsdoccomment": "npm:~0.43.1" + "@es-joy/jsdoccomment": "npm:~0.48.0" are-docs-informative: "npm:^0.0.2" comment-parser: "npm:1.4.1" - debug: "npm:^4.3.4" + debug: "npm:^4.3.6" escape-string-regexp: "npm:^4.0.0" - esquery: "npm:^1.5.0" - parse-imports: "npm:^2.1.0" - semver: "npm:^7.6.2" + espree: "npm:^10.1.0" + esquery: "npm:^1.6.0" + parse-imports: "npm:^2.1.1" + semver: "npm:^7.6.3" spdx-expression-parse: "npm:^4.0.0" - synckit: "npm:^0.9.0" + synckit: "npm:^0.9.1" peerDependencies: eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 - checksum: 10c0/1c5eb83df06cb228e44ad2c9da5b31987347a45b99d9e7a68957d178487a81603ad3c4c7db1ecba7e8a62d7ae20d9de1aec18a8cf2aa0e9169731cec54f78ab7 + checksum: 10c0/f41d30246f6a4b6acb55e8cd75cf4fc256315e141ab25f7740fa6fa58cdd24e08cb672b4a350da93aeb126d210bd25981310a50f97cfb108f6a7ce8668b6b90a languageName: node linkType: hard -"eslint-plugin-prettier@npm:^5.1.3": - version: 5.1.3 - resolution: "eslint-plugin-prettier@npm:5.1.3" +"eslint-plugin-prettier@npm:^5.2.1": + version: 5.2.1 + resolution: "eslint-plugin-prettier@npm:5.2.1" dependencies: prettier-linter-helpers: "npm:^1.0.0" - synckit: "npm:^0.8.6" + synckit: "npm:^0.9.1" peerDependencies: "@types/eslint": ">=8.0.0" eslint: ">=8.0.0" @@ -8272,7 +8920,7 @@ __metadata: optional: true eslint-config-prettier: optional: true - checksum: 10c0/f45d5fc1fcfec6b0cf038a7a65ddd10a25df4fe3f9e1f6b7f0d5100e66f046a26a2492e69ee765dddf461b93c114cf2e1eb18d4970aafa6f385448985c136e09 + checksum: 10c0/4bc8bbaf5bb556c9c501dcdff369137763c49ccaf544f9fa91400360ed5e3a3f1234ab59690e06beca5b1b7e6f6356978cdd3b02af6aba3edea2ffe69ca6e8b2 languageName: node linkType: hard @@ -8296,13 +8944,13 @@ __metadata: languageName: node linkType: hard -"eslint-scope@npm:^8.0.0": - version: 8.0.1 - resolution: "eslint-scope@npm:8.0.1" +"eslint-scope@npm:^8.0.2": + version: 8.0.2 + resolution: "eslint-scope@npm:8.0.2" dependencies: esrecurse: "npm:^4.3.0" estraverse: "npm:^5.2.0" - checksum: 10c0/0ec40ab284e58ac7ef064ecd23c127e03d339fa57173c96852336c73afc70ce5631da21dc1c772415a37a421291845538dd69db83c68d611044c0fde1d1fa269 + checksum: 10c0/477f820647c8755229da913025b4567347fd1f0bf7cbdf3a256efff26a7e2e130433df052bd9e3d014025423dc00489bea47eb341002b15553673379c1a7dc36 languageName: node linkType: hard @@ -8313,6 +8961,13 @@ __metadata: languageName: node linkType: hard +"eslint-visitor-keys@npm:^4.0.0": + version: 4.0.0 + resolution: "eslint-visitor-keys@npm:4.0.0" + checksum: 10c0/76619f42cf162705a1515a6868e6fc7567e185c7063a05621a8ac4c3b850d022661262c21d9f1fc1d144ecf0d5d64d70a3f43c15c3fc969a61ace0fb25698cf5 + languageName: node + linkType: hard + "eslint@npm:^8.57.0": version: 8.57.0 resolution: "eslint@npm:8.57.0" @@ -8361,6 +9016,17 @@ __metadata: languageName: node linkType: hard +"espree@npm:^10.1.0": + version: 10.1.0 + resolution: "espree@npm:10.1.0" + dependencies: + acorn: "npm:^8.12.0" + acorn-jsx: "npm:^5.3.2" + eslint-visitor-keys: "npm:^4.0.0" + checksum: 10c0/52e6feaa77a31a6038f0c0e3fce93010a4625701925b0715cd54a2ae190b3275053a0717db698697b32653788ac04845e489d6773b508d6c2e8752f3c57470a0 + languageName: node + linkType: hard + "espree@npm:^9.6.0, espree@npm:^9.6.1": version: 9.6.1 resolution: "espree@npm:9.6.1" @@ -8372,17 +9038,7 @@ __metadata: languageName: node linkType: hard -"esprima@npm:^4.0.0": - version: 4.0.1 - resolution: "esprima@npm:4.0.1" - bin: - esparse: ./bin/esparse.js - esvalidate: ./bin/esvalidate.js - checksum: 10c0/ad4bab9ead0808cf56501750fd9d3fb276f6b105f987707d059005d57e182d18a7c9ec7f3a01794ebddcca676773e42ca48a32d67a250c9d35e009ca613caba3 - languageName: node - linkType: hard - -"esquery@npm:^1.4.2, esquery@npm:^1.5.0": +"esquery@npm:^1.4.2": version: 1.5.0 resolution: "esquery@npm:1.5.0" dependencies: @@ -8391,6 +9047,15 @@ __metadata: languageName: node linkType: hard +"esquery@npm:^1.6.0": + version: 1.6.0 + resolution: "esquery@npm:1.6.0" + dependencies: + estraverse: "npm:^5.1.0" + checksum: 10c0/cb9065ec605f9da7a76ca6dadb0619dfb611e37a81e318732977d90fab50a256b95fee2d925fba7c2f3f0523aa16f91587246693bc09bc34d5a59575fe6e93d2 + languageName: node + linkType: hard + "esrecurse@npm:^4.3.0": version: 4.3.0 resolution: "esrecurse@npm:4.3.0" @@ -8616,7 +9281,7 @@ __metadata: languageName: node linkType: hard -"fast-glob@npm:3.3.2, fast-glob@npm:^3.2.11, fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.0, fast-glob@npm:^3.3.2": +"fast-glob@npm:3.3.2, fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.2": version: 3.3.2 resolution: "fast-glob@npm:3.3.2" dependencies: @@ -8643,6 +9308,13 @@ __metadata: languageName: node linkType: hard +"fast-uri@npm:^3.0.1": + version: 3.0.1 + resolution: "fast-uri@npm:3.0.1" + checksum: 10c0/3cd46d6006083b14ca61ffe9a05b8eef75ef87e9574b6f68f2e17ecf4daa7aaadeff44e3f0f7a0ef4e0f7e7c20fc07beec49ff14dc72d0b500f00386592f2d10 + languageName: node + linkType: hard + "fastq@npm:^1.6.0": version: 1.17.1 resolution: "fastq@npm:1.17.1" @@ -8671,7 +9343,7 @@ __metadata: languageName: node linkType: hard -"figures@npm:3.2.0, figures@npm:^3.1.0": +"figures@npm:^3.1.0": version: 3.2.0 resolution: "figures@npm:3.2.0" dependencies: @@ -8869,7 +9541,7 @@ __metadata: languageName: node linkType: hard -"follow-redirects@npm:^1.0.0, follow-redirects@npm:^1.15.6": +"follow-redirects@npm:^1.0.0": version: 1.15.6 resolution: "follow-redirects@npm:1.15.6" peerDependenciesMeta: @@ -8960,7 +9632,7 @@ __metadata: languageName: node linkType: hard -"fs-extra@npm:^11.1.0, fs-extra@npm:^11.1.1, fs-extra@npm:^11.2.0": +"fs-extra@npm:^11.1.1, fs-extra@npm:^11.2.0": version: 11.2.0 resolution: "fs-extra@npm:11.2.0" dependencies: @@ -9362,16 +10034,17 @@ __metadata: languageName: node linkType: hard -"globby@npm:^13.1.1": - version: 13.2.2 - resolution: "globby@npm:13.2.2" +"globby@npm:^14.0.0": + version: 14.0.2 + resolution: "globby@npm:14.0.2" dependencies: - dir-glob: "npm:^3.0.1" - fast-glob: "npm:^3.3.0" + "@sindresorhus/merge-streams": "npm:^2.1.0" + fast-glob: "npm:^3.3.2" ignore: "npm:^5.2.4" - merge2: "npm:^1.4.1" - slash: "npm:^4.0.0" - checksum: 10c0/a8d7cc7cbe5e1b2d0f81d467bbc5bc2eac35f74eaded3a6c85fc26d7acc8e6de22d396159db8a2fc340b8a342e74cac58de8f4aee74146d3d146921a76062664 + path-type: "npm:^5.0.0" + slash: "npm:^5.1.0" + unicorn-magic: "npm:^0.1.0" + checksum: 10c0/3f771cd683b8794db1e7ebc8b6b888d43496d93a82aad4e9d974620f578581210b6c5a6e75ea29573ed16a1345222fab6e9b877a8d1ed56eeb147e09f69c6f78 languageName: node linkType: hard @@ -9744,13 +10417,13 @@ __metadata: languageName: node linkType: hard -"https-proxy-agent@npm:7.0.4, https-proxy-agent@npm:^7.0.1, https-proxy-agent@npm:^7.0.2": - version: 7.0.4 - resolution: "https-proxy-agent@npm:7.0.4" +"https-proxy-agent@npm:7.0.5": + version: 7.0.5 + resolution: "https-proxy-agent@npm:7.0.5" dependencies: agent-base: "npm:^7.0.2" debug: "npm:4" - checksum: 10c0/bc4f7c38da32a5fc622450b6cb49a24ff596f9bd48dcedb52d2da3fa1c1a80e100fb506bd59b326c012f21c863c69b275c23de1a01d0b84db396822fdf25e52b + checksum: 10c0/2490e3acec397abeb88807db52cac59102d5ed758feee6df6112ab3ccd8325e8a1ce8bce6f4b66e5470eca102d31e425ace904242e4fa28dbe0c59c4bafa7b2c languageName: node linkType: hard @@ -9764,6 +10437,16 @@ __metadata: languageName: node linkType: hard +"https-proxy-agent@npm:^7.0.1, https-proxy-agent@npm:^7.0.2": + version: 7.0.4 + resolution: "https-proxy-agent@npm:7.0.4" + dependencies: + agent-base: "npm:^7.0.2" + debug: "npm:4" + checksum: 10c0/bc4f7c38da32a5fc622450b6cb49a24ff596f9bd48dcedb52d2da3fa1c1a80e100fb506bd59b326c012f21c863c69b275c23de1a01d0b84db396822fdf25e52b + languageName: node + linkType: hard + "human-signals@npm:^1.1.1": version: 1.1.1 resolution: "human-signals@npm:1.1.1" @@ -9794,12 +10477,12 @@ __metadata: languageName: node linkType: hard -"husky@npm:^9.0.11": - version: 9.0.11 - resolution: "husky@npm:9.0.11" +"husky@npm:^9.1.4": + version: 9.1.4 + resolution: "husky@npm:9.1.4" bin: - husky: bin.mjs - checksum: 10c0/2c787dcf74a837fc9a4fea7da907509d4bd9a289f4ea10ecc9d86279e4d4542b0f5f6443a619bccae19e265f2677172cc2b86aae5c932a35a330cc227d914605 + husky: bin.js + checksum: 10c0/f5185003bef9ad9ec3f40e821963e4c12409b993fdcab89e3d660bed7d8c9d8bfd399f05222e27e0ead6589601fb1bb08d1a589c51751a4ab0547ead3429b8de languageName: node linkType: hard @@ -9862,7 +10545,14 @@ __metadata: languageName: node linkType: hard -"ignore@npm:5.3.1, ignore@npm:^5.0.4, ignore@npm:^5.2.0, ignore@npm:^5.2.4, ignore@npm:^5.3.1": +"ignore@npm:5.3.2": + version: 5.3.2 + resolution: "ignore@npm:5.3.2" + checksum: 10c0/f9f652c957983634ded1e7f02da3b559a0d4cc210fca3792cb67f1b153623c9c42efdc1c4121af171e295444459fc4a9201101fb041b1104a3c000bccb188337 + languageName: node + linkType: hard + +"ignore@npm:^5.2.0, ignore@npm:^5.2.4, ignore@npm:^5.3.1": version: 5.3.1 resolution: "ignore@npm:5.3.1" checksum: 10c0/703f7f45ffb2a27fb2c5a8db0c32e7dee66b33a225d28e8db4e1be6474795f606686a6e3bcc50e1aa12f2042db4c9d4a7d60af3250511de74620fbed052ea4cd @@ -9965,10 +10655,10 @@ __metadata: languageName: node linkType: hard -"ini@npm:4.1.2": - version: 4.1.2 - resolution: "ini@npm:4.1.2" - checksum: 10c0/e0ffe587038e26ca1debfece6f5e52fd17f4e65be59bb481bb24b89cd2be31a71f619465918da215916b4deba7d1134c228c58fe5e0db66a71a472dee9b8f99c +"ini@npm:4.1.3": + version: 4.1.3 + resolution: "ini@npm:4.1.3" + checksum: 10c0/0d27eff094d5f3899dd7c00d0c04ea733ca03a8eb6f9406ce15daac1a81de022cb417d6eaff7e4342451ffa663389c565ffc68d6825eaf686bf003280b945764 languageName: node linkType: hard @@ -9979,29 +10669,6 @@ __metadata: languageName: node linkType: hard -"inquirer@npm:9.2.22": - version: 9.2.22 - resolution: "inquirer@npm:9.2.22" - dependencies: - "@inquirer/figures": "npm:^1.0.2" - "@ljharb/through": "npm:^2.3.13" - ansi-escapes: "npm:^4.3.2" - chalk: "npm:^5.3.0" - cli-cursor: "npm:^3.1.0" - cli-width: "npm:^4.1.0" - external-editor: "npm:^3.1.0" - lodash: "npm:^4.17.21" - mute-stream: "npm:1.0.0" - ora: "npm:^5.4.1" - run-async: "npm:^3.0.0" - rxjs: "npm:^7.8.1" - string-width: "npm:^4.2.3" - strip-ansi: "npm:^6.0.1" - wrap-ansi: "npm:^6.2.0" - checksum: 10c0/a7dc69a42b634a7222e75783d733a24d776bff43dcc77c6f0a47637dbc02a362de182b30165ede7978cd9fe7d22bae14fdd84e0cbfaec8c2b0a89d9131867bca - languageName: node - linkType: hard - "internal-slot@npm:^1.0.4, internal-slot@npm:^1.0.7": version: 1.0.7 resolution: "internal-slot@npm:1.0.7" @@ -10488,16 +11155,16 @@ __metadata: languageName: node linkType: hard -"istanbul-lib-instrument@npm:6.0.2": - version: 6.0.2 - resolution: "istanbul-lib-instrument@npm:6.0.2" +"istanbul-lib-instrument@npm:6.0.3": + version: 6.0.3 + resolution: "istanbul-lib-instrument@npm:6.0.3" dependencies: "@babel/core": "npm:^7.23.9" "@babel/parser": "npm:^7.23.9" "@istanbuljs/schema": "npm:^0.1.3" istanbul-lib-coverage: "npm:^3.2.0" semver: "npm:^7.5.4" - checksum: 10c0/405c6ac037bf8c7ee7495980b0cd5544b2c53078c10534d0c9ceeb92a9ea7dcf8510f58ccfce31336458a8fa6ccef27b570bbb602abaa8c1650f5496a807477c + checksum: 10c0/a1894e060dd2a3b9f046ffdc87b44c00a35516f5e6b7baf4910369acca79e506fc5323a816f811ae23d82334b38e3ddeb8b3b331bd2c860540793b59a8689128 languageName: node linkType: hard @@ -10580,29 +11247,10 @@ __metadata: languageName: node linkType: hard -"jasmine-core@npm:~5.1.2": - version: 5.1.2 - resolution: "jasmine-core@npm:5.1.2" - checksum: 10c0/bca92fd9c69eb3ed6e11d9de2e06939ba2c4157acaf15f9a19efc87a10af6a6937acbc424726e34ea8b2cc06b3d6fe733fbd2cfd3c9a258b3528567f89d8a578 - languageName: node - linkType: hard - -"jest-diff@npm:^29.4.1": - version: 29.7.0 - resolution: "jest-diff@npm:29.7.0" - dependencies: - chalk: "npm:^4.0.0" - diff-sequences: "npm:^29.6.3" - jest-get-type: "npm:^29.6.3" - pretty-format: "npm:^29.7.0" - checksum: 10c0/89a4a7f182590f56f526443dde69acefb1f2f0c9e59253c61d319569856c4931eae66b8a3790c443f529267a0ddba5ba80431c585deed81827032b2b2a1fc999 - languageName: node - linkType: hard - -"jest-get-type@npm:^29.6.3": - version: 29.6.3 - resolution: "jest-get-type@npm:29.6.3" - checksum: 10c0/552e7a97a983d3c2d4e412a44eb7de0430ff773dd99f7500962c268d6dfbfa431d7d08f919c9d960530e5f7f78eb47f267ad9b318265e5092b3ff9ede0db7c2b +"jasmine-core@npm:~5.2.0": + version: 5.2.0 + resolution: "jasmine-core@npm:5.2.0" + checksum: 10c0/eac5298932fef389071529d55b8b4554646cb0094c765dac48d041e7e0c70822b0a3d831acaeec5b47ce0f0c90cad8e6926202ec67804638b4e5bf89a43def3e languageName: node linkType: hard @@ -10633,18 +11281,6 @@ __metadata: languageName: node linkType: hard -"js-yaml@npm:^3.10.0": - version: 3.14.1 - resolution: "js-yaml@npm:3.14.1" - dependencies: - argparse: "npm:^1.0.7" - esprima: "npm:^4.0.0" - bin: - js-yaml: bin/js-yaml.js - checksum: 10c0/6746baaaeac312c4db8e75fa22331d9a04cccb7792d126ed8ce6a0bbcfef0cedaddd0c5098fade53db067c09fe00aa1c957674b4765610a8b06a5a189e46433b - languageName: node - linkType: hard - "js-yaml@npm:^4.1.0": version: 4.1.0 resolution: "js-yaml@npm:4.1.0" @@ -10663,10 +11299,10 @@ __metadata: languageName: node linkType: hard -"jsdoc-type-pratt-parser@npm:~4.0.0": - version: 4.0.0 - resolution: "jsdoc-type-pratt-parser@npm:4.0.0" - checksum: 10c0/b23ef7bbbe2f56d72630d1c5a233dc9fecaff399063d373c57bef136908c1b05e723dac107177303c03ccf8d75aa51507510b282aa567600477479c5ea0c36d1 +"jsdoc-type-pratt-parser@npm:~4.1.0": + version: 4.1.0 + resolution: "jsdoc-type-pratt-parser@npm:4.1.0" + checksum: 10c0/7700372d2e733a32f7ea0a1df9cec6752321a5345c11a91b2ab478a031a426e934f16d5c1f15c8566c7b2c10af9f27892a29c2c789039f595470e929a4aa60ea languageName: node linkType: hard @@ -10796,7 +11432,7 @@ __metadata: languageName: node linkType: hard -"json5@npm:^2.1.2, json5@npm:^2.2.2, json5@npm:^2.2.3": +"json5@npm:^2.1.2, json5@npm:^2.2.3": version: 2.2.3 resolution: "json5@npm:2.2.3" bin: @@ -10805,13 +11441,6 @@ __metadata: languageName: node linkType: hard -"jsonc-parser@npm:3.2.0": - version: 3.2.0 - resolution: "jsonc-parser@npm:3.2.0" - checksum: 10c0/5a12d4d04dad381852476872a29dcee03a57439574e4181d91dca71904fcdcc5e8e4706c0a68a2c61ad9810e1e1c5806b5100d52d3e727b78f5cdc595401045b - languageName: node - linkType: hard - "jsonc-parser@npm:3.2.1": version: 3.2.1 resolution: "jsonc-parser@npm:3.2.1" @@ -10819,6 +11448,13 @@ __metadata: languageName: node linkType: hard +"jsonc-parser@npm:3.3.1": + version: 3.3.1 + resolution: "jsonc-parser@npm:3.3.1" + checksum: 10c0/269c3ae0a0e4f907a914bf334306c384aabb9929bd8c99f909275ebd5c2d3bc70b9bcd119ad794f339dec9f24b6a4ee9cd5a8ab2e6435e730ad4075388fc2ab6 + languageName: node + linkType: hard + "jsonfile@npm:^4.0.0": version: 4.0.0 resolution: "jsonfile@npm:4.0.0" @@ -10917,9 +11553,9 @@ __metadata: languageName: node linkType: hard -"karma@npm:~6.4.3": - version: 6.4.3 - resolution: "karma@npm:6.4.3" +"karma@npm:~6.4.4": + version: 6.4.4 + resolution: "karma@npm:6.4.4" dependencies: "@colors/colors": "npm:1.5.0" body-parser: "npm:^1.19.0" @@ -10947,7 +11583,7 @@ __metadata: yargs: "npm:^16.1.1" bin: karma: bin/karma - checksum: 10c0/dc9710600c69265fce24a91312a136396acef969b72aac05e342724a4223a799cd3676a20f73a4beda797908b7f534fa95c8228bd79fd5c54682020c626e4fdd + checksum: 10c0/1658c4b7396c0edf6f048289182e075b561902e02992e1a3eb72f56f67090ff0c7ad7c91ab099e88a790c60f9500c5a6f974d75f1769e3ea2dfccda52876ec0b languageName: node linkType: hard @@ -11082,10 +11718,10 @@ __metadata: languageName: node linkType: hard -"lilconfig@npm:~3.1.1": - version: 3.1.1 - resolution: "lilconfig@npm:3.1.1" - checksum: 10c0/311b559794546894e3fe176663427326026c1c644145be9e8041c58e268aa9328799b8dfe7e4dd8c6a4ae305feae95a1c9e007db3569f35b42b6e1bc8274754c +"lilconfig@npm:~3.1.2": + version: 3.1.2 + resolution: "lilconfig@npm:3.1.2" + checksum: 10c0/f059630b1a9bddaeba83059db00c672b64dc14074e9f232adce32b38ca1b5686ab737eb665c5ba3c32f147f0002b4bee7311ad0386a9b98547b5623e87071fbe languageName: node linkType: hard @@ -11096,61 +11732,54 @@ __metadata: languageName: node linkType: hard -"lines-and-columns@npm:~2.0.3": - version: 2.0.4 - resolution: "lines-and-columns@npm:2.0.4" - checksum: 10c0/4db28bf065cd7ad897c0700f22d3d0d7c5ed6777e138861c601c496d545340df3fc19e18bd04ff8d95a246a245eb55685b82ca2f8c2ca53a008e9c5316250379 - languageName: node - linkType: hard - -"lint-staged@npm:^15.2.7": - version: 15.2.7 - resolution: "lint-staged@npm:15.2.7" +"lint-staged@npm:^15.2.9": + version: 15.2.9 + resolution: "lint-staged@npm:15.2.9" dependencies: chalk: "npm:~5.3.0" commander: "npm:~12.1.0" - debug: "npm:~4.3.4" + debug: "npm:~4.3.6" execa: "npm:~8.0.1" - lilconfig: "npm:~3.1.1" - listr2: "npm:~8.2.1" + lilconfig: "npm:~3.1.2" + listr2: "npm:~8.2.4" micromatch: "npm:~4.0.7" pidtree: "npm:~0.6.0" string-argv: "npm:~0.3.2" - yaml: "npm:~2.4.2" + yaml: "npm:~2.5.0" bin: lint-staged: bin/lint-staged.js - checksum: 10c0/c14399f9782ae222a1748144254f24b5b9afc816dc8840bd02d50f523c6582796ff18410767eb1a73cf1a83bc6e492dea7b1c4f0912bf3e434c068221f13c878 + checksum: 10c0/820c622378b62b826974af17f1747e2a4b0556e4fb99d101af89ad298d392ff079f580fdc576f16a27e975d726b95d73495fd524139402ff654c4649ef2f1a6a languageName: node linkType: hard -"listr2@npm:~8.2.1": - version: 8.2.1 - resolution: "listr2@npm:8.2.1" +"listr2@npm:8.2.4, listr2@npm:~8.2.4": + version: 8.2.4 + resolution: "listr2@npm:8.2.4" dependencies: cli-truncate: "npm:^4.0.0" colorette: "npm:^2.0.20" eventemitter3: "npm:^5.0.1" - log-update: "npm:^6.0.0" - rfdc: "npm:^1.3.1" + log-update: "npm:^6.1.0" + rfdc: "npm:^1.4.1" wrap-ansi: "npm:^9.0.0" - checksum: 10c0/ac32cba8e5c79bcf0dbbb43c2fcc73e47902320c1fa1891074fefb3aa3dfaeef9c76348da22909f65334ba9bee1140bfc903e2f0c64427dd08ef4ba8f6b1dbd0 + checksum: 10c0/df5b129e9767de1997973cec6103cd4bd6fc3b3367685b7c23048d12b61d5b7e44fecd8a3d3534c0e1c963bd5ac43ca501d14712f46fa101050037be323a5c16 languageName: node linkType: hard -"lmdb@npm:3.0.8": - version: 3.0.8 - resolution: "lmdb@npm:3.0.8" - dependencies: - "@lmdb/lmdb-darwin-arm64": "npm:3.0.8" - "@lmdb/lmdb-darwin-x64": "npm:3.0.8" - "@lmdb/lmdb-linux-arm": "npm:3.0.8" - "@lmdb/lmdb-linux-arm64": "npm:3.0.8" - "@lmdb/lmdb-linux-x64": "npm:3.0.8" - "@lmdb/lmdb-win32-x64": "npm:3.0.8" - msgpackr: "npm:^1.9.9" +"lmdb@npm:3.0.13": + version: 3.0.13 + resolution: "lmdb@npm:3.0.13" + dependencies: + "@lmdb/lmdb-darwin-arm64": "npm:3.0.13" + "@lmdb/lmdb-darwin-x64": "npm:3.0.13" + "@lmdb/lmdb-linux-arm": "npm:3.0.13" + "@lmdb/lmdb-linux-arm64": "npm:3.0.13" + "@lmdb/lmdb-linux-x64": "npm:3.0.13" + "@lmdb/lmdb-win32-x64": "npm:3.0.13" + msgpackr: "npm:^1.10.2" node-addon-api: "npm:^6.1.0" node-gyp: "npm:latest" - node-gyp-build-optional-packages: "npm:5.1.1" + node-gyp-build-optional-packages: "npm:5.2.2" ordered-binary: "npm:^1.4.1" weak-lru-cache: "npm:^1.2.2" dependenciesMeta: @@ -11168,7 +11797,7 @@ __metadata: optional: true bin: download-lmdb-prebuilds: bin/download-prebuilds.js - checksum: 10c0/167a90984e0e843fd4280db357069a4814a2fe19770bfab9693387a44abc6690926c3a620e3c8fc70d2acd307507a72308be9121c28a569d7c258f5c5fb02fa0 + checksum: 10c0/feac522854112af3c8204c837356c70c06a6ce3a39c57c061008ac63aa52a71505e2e217b730e96ab5120ce4c22efc84b78a9fc0b8001a7e5af2e135938a7fd1 languageName: node linkType: hard @@ -11191,10 +11820,10 @@ __metadata: languageName: node linkType: hard -"loader-utils@npm:3.2.1": - version: 3.2.1 - resolution: "loader-utils@npm:3.2.1" - checksum: 10c0/d3e1f217d160e8e894a0385a33500d4ce14065e8ffb250f5a81ae65bc2c3baa50625ec34182ba4417b46b4ac6725aed64429e1104d6401e074af2aa1dd018394 +"loader-utils@npm:3.3.1": + version: 3.3.1 + resolution: "loader-utils@npm:3.3.1" + checksum: 10c0/f2af4eb185ac5bf7e56e1337b666f90744e9f443861ac521b48f093fb9e8347f191c8960b4388a3365147d218913bc23421234e7788db69f385bacfefa0b4758 languageName: node linkType: hard @@ -11340,7 +11969,7 @@ __metadata: languageName: node linkType: hard -"log-symbols@npm:^4.0.0, log-symbols@npm:^4.1.0": +"log-symbols@npm:^4.1.0": version: 4.1.0 resolution: "log-symbols@npm:4.1.0" dependencies: @@ -11350,16 +11979,16 @@ __metadata: languageName: node linkType: hard -"log-update@npm:^6.0.0": - version: 6.0.0 - resolution: "log-update@npm:6.0.0" +"log-update@npm:^6.1.0": + version: 6.1.0 + resolution: "log-update@npm:6.1.0" dependencies: - ansi-escapes: "npm:^6.2.0" - cli-cursor: "npm:^4.0.0" - slice-ansi: "npm:^7.0.0" + ansi-escapes: "npm:^7.0.0" + cli-cursor: "npm:^5.0.0" + slice-ansi: "npm:^7.1.0" strip-ansi: "npm:^7.1.0" wrap-ansi: "npm:^9.0.0" - checksum: 10c0/e0b3c3401ef49ce3eb17e2f83d644765e4f7988498fc1344eaa4f31ab30e510dcc469a7fb64dc01bd1c8d9237d917598fa677a9818705fb3774c10f6e9d4b27c + checksum: 10c0/4b350c0a83d7753fea34dcac6cd797d1dc9603291565de009baa4aa91c0447eab0d3815a05c8ec9ac04fdfffb43c82adcdb03ec1fceafd8518e1a8c1cff4ff89 languageName: node linkType: hard @@ -11438,6 +12067,15 @@ __metadata: languageName: node linkType: hard +"magic-string@npm:0.30.11": + version: 0.30.11 + resolution: "magic-string@npm:0.30.11" + dependencies: + "@jridgewell/sourcemap-codec": "npm:^1.5.0" + checksum: 10c0/b9eb370773d0bd90ca11a848753409d8e5309b1ad56d2a1aa49d6649da710a6d2fe7237ad1a643c5a5d3800de2b9946ed9690acdfc00e6cc1aeafff3ab1752c4 + languageName: node + linkType: hard + "make-dir@npm:^2.1.0": version: 2.1.0 resolution: "make-dir@npm:2.1.0" @@ -11685,6 +12323,13 @@ __metadata: languageName: node linkType: hard +"mimic-function@npm:^5.0.0": + version: 5.0.1 + resolution: "mimic-function@npm:5.0.1" + checksum: 10c0/f3d9464dd1816ecf6bdf2aec6ba32c0728022039d992f178237d8e289b48764fee4131319e72eedd4f7f094e22ded0af836c3187a7edc4595d28dd74368fd81d + languageName: node + linkType: hard + "mimic-response@npm:^3.1.0": version: 3.1.0 resolution: "mimic-response@npm:3.1.0" @@ -11718,15 +12363,6 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:9.0.3": - version: 9.0.3 - resolution: "minimatch@npm:9.0.3" - dependencies: - brace-expansion: "npm:^2.0.1" - checksum: 10c0/85f407dcd38ac3e180f425e86553911d101455ca3ad5544d6a7cec16286657e4f8a9aa6695803025c55e31e35a91a2252b5dc8e7d527211278b8b65b4dbd5eac - languageName: node - linkType: hard - "minimatch@npm:^3.0.4, minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": version: 3.1.2 resolution: "minimatch@npm:3.1.2" @@ -12012,7 +12648,7 @@ __metadata: languageName: node linkType: hard -"msgpackr@npm:^1.9.9": +"msgpackr@npm:^1.10.2": version: 1.10.2 resolution: "msgpackr@npm:1.10.2" dependencies: @@ -12036,7 +12672,7 @@ __metadata: languageName: node linkType: hard -"mute-stream@npm:1.0.0": +"mute-stream@npm:^1.0.0": version: 1.0.0 resolution: "mute-stream@npm:1.0.0" checksum: 10c0/dce2a9ccda171ec979a3b4f869a102b1343dee35e920146776780de182f16eae459644d187e38d59a3d37adf85685e1c17c38cf7bfda7e39a9880f7a1d10a74c @@ -12050,14 +12686,14 @@ __metadata: languageName: node linkType: hard -"n3@npm:^1.17.4": - version: 1.17.4 - resolution: "n3@npm:1.17.4" +"n3@npm:^1.20.4": + version: 1.20.4 + resolution: "n3@npm:1.20.4" dependencies: buffer: "npm:^6.0.3" queue-microtask: "npm:^1.1.2" readable-stream: "npm:^4.0.0" - checksum: 10c0/596e7da3e7b4edab7f8db1ea2972c4197457e7355ec5ae85f9bedf1fbc032630bbcb3db41d04c0dd65f4f55874c1ea893a247a12020846981dcef86d7f7049b8 + checksum: 10c0/6af387e29df5a68f4f2f117ed3e87acf7241ade2e852b09b40dab66447fa95b0fe8e020164018aa9e3ed97d904cc991b43b31770556bedeeea748a9b143f2d86 languageName: node linkType: hard @@ -12202,16 +12838,16 @@ __metadata: languageName: node linkType: hard -"node-gyp-build-optional-packages@npm:5.1.1": - version: 5.1.1 - resolution: "node-gyp-build-optional-packages@npm:5.1.1" +"node-gyp-build-optional-packages@npm:5.2.2": + version: 5.2.2 + resolution: "node-gyp-build-optional-packages@npm:5.2.2" dependencies: detect-libc: "npm:^2.0.1" bin: node-gyp-build-optional-packages: bin.js node-gyp-build-optional-packages-optional: optional.js node-gyp-build-optional-packages-test: build-test.js - checksum: 10c0/f9fad2061c48fb0fc90831cd11d6a7670d731d22a5b00c7d3441b43b4003543299ff64ff2729afe2cefd7d14928e560d469336e5bb00f613932ec2cd56b3665b + checksum: 10c0/c81128c6f91873381be178c5eddcbdf66a148a6a89a427ce2bcd457593ce69baf2a8662b6d22cac092d24aa9c43c230dec4e69b3a0da604503f4777cd77e282b languageName: node linkType: hard @@ -12266,13 +12902,6 @@ __metadata: languageName: node linkType: hard -"node-machine-id@npm:1.1.12": - version: 1.1.12 - resolution: "node-machine-id@npm:1.1.12" - checksum: 10c0/ab2fea5f75a6f1ce3c76c5e0ae3903b631230e0a99b003d176568fff8ddbdf7b2943be96cd8d220c497ca0f6149411831f8a450601929f326781cb1b59bab7f8 - languageName: node - linkType: hard - "node-releases@npm:^2.0.14": version: 2.0.14 resolution: "node-releases@npm:2.0.14" @@ -12280,6 +12909,13 @@ __metadata: languageName: node linkType: hard +"node-releases@npm:^2.0.18": + version: 2.0.18 + resolution: "node-releases@npm:2.0.18" + checksum: 10c0/786ac9db9d7226339e1dc84bbb42007cb054a346bd9257e6aa154d294f01bc6a6cddb1348fa099f079be6580acbb470e3c048effd5f719325abd0179e566fd27 + languageName: node + linkType: hard + "nopt@npm:^5.0.0": version: 5.0.0 resolution: "nopt@npm:5.0.0" @@ -12377,7 +13013,19 @@ __metadata: languageName: node linkType: hard -"npm-package-arg@npm:11.0.2, npm-package-arg@npm:^11.0.0": +"npm-package-arg@npm:11.0.3": + version: 11.0.3 + resolution: "npm-package-arg@npm:11.0.3" + dependencies: + hosted-git-info: "npm:^7.0.0" + proc-log: "npm:^4.0.0" + semver: "npm:^7.3.5" + validate-npm-package-name: "npm:^5.0.0" + checksum: 10c0/e18333485e05c3a8774f4b5701ef74f4799533e650b70a68ca8dd697666c9a8d46932cb765fc593edce299521033bd4025a40323d5240cea8a393c784c0c285a + languageName: node + linkType: hard + +"npm-package-arg@npm:^11.0.0": version: 11.0.2 resolution: "npm-package-arg@npm:11.0.2" dependencies: @@ -12398,7 +13046,19 @@ __metadata: languageName: node linkType: hard -"npm-pick-manifest@npm:9.0.1, npm-pick-manifest@npm:^9.0.0": +"npm-pick-manifest@npm:9.1.0": + version: 9.1.0 + resolution: "npm-pick-manifest@npm:9.1.0" + dependencies: + npm-install-checks: "npm:^6.0.0" + npm-normalize-package-bin: "npm:^3.0.0" + npm-package-arg: "npm:^11.0.0" + semver: "npm:^7.3.5" + checksum: 10c0/8765f4199755b381323da2bff2202b4b15b59f59dba0d1be3f2f793b591321cd19e1b5a686ef48d9753a6bd4868550da632541a45dfb61809d55664222d73e44 + languageName: node + linkType: hard + +"npm-pick-manifest@npm:^9.0.0": version: 9.0.1 resolution: "npm-pick-manifest@npm:9.0.1" dependencies: @@ -12465,89 +13125,6 @@ __metadata: languageName: node linkType: hard -"nx@npm:19.1.2, nx@npm:^19.0.6": - version: 19.1.2 - resolution: "nx@npm:19.1.2" - dependencies: - "@nrwl/tao": "npm:19.1.2" - "@nx/nx-darwin-arm64": "npm:19.1.2" - "@nx/nx-darwin-x64": "npm:19.1.2" - "@nx/nx-freebsd-x64": "npm:19.1.2" - "@nx/nx-linux-arm-gnueabihf": "npm:19.1.2" - "@nx/nx-linux-arm64-gnu": "npm:19.1.2" - "@nx/nx-linux-arm64-musl": "npm:19.1.2" - "@nx/nx-linux-x64-gnu": "npm:19.1.2" - "@nx/nx-linux-x64-musl": "npm:19.1.2" - "@nx/nx-win32-arm64-msvc": "npm:19.1.2" - "@nx/nx-win32-x64-msvc": "npm:19.1.2" - "@yarnpkg/lockfile": "npm:^1.1.0" - "@yarnpkg/parsers": "npm:3.0.0-rc.46" - "@zkochan/js-yaml": "npm:0.0.7" - axios: "npm:^1.6.0" - chalk: "npm:^4.1.0" - cli-cursor: "npm:3.1.0" - cli-spinners: "npm:2.6.1" - cliui: "npm:^8.0.1" - dotenv: "npm:~16.3.1" - dotenv-expand: "npm:~10.0.0" - enquirer: "npm:~2.3.6" - figures: "npm:3.2.0" - flat: "npm:^5.0.2" - fs-extra: "npm:^11.1.0" - ignore: "npm:^5.0.4" - jest-diff: "npm:^29.4.1" - jsonc-parser: "npm:3.2.0" - lines-and-columns: "npm:~2.0.3" - minimatch: "npm:9.0.3" - node-machine-id: "npm:1.1.12" - npm-run-path: "npm:^4.0.1" - open: "npm:^8.4.0" - ora: "npm:5.3.0" - semver: "npm:^7.5.3" - string-width: "npm:^4.2.3" - strong-log-transformer: "npm:^2.1.0" - tar-stream: "npm:~2.2.0" - tmp: "npm:~0.2.1" - tsconfig-paths: "npm:^4.1.2" - tslib: "npm:^2.3.0" - yargs: "npm:^17.6.2" - yargs-parser: "npm:21.1.1" - peerDependencies: - "@swc-node/register": ^1.8.0 - "@swc/core": ^1.3.85 - dependenciesMeta: - "@nx/nx-darwin-arm64": - optional: true - "@nx/nx-darwin-x64": - optional: true - "@nx/nx-freebsd-x64": - optional: true - "@nx/nx-linux-arm-gnueabihf": - optional: true - "@nx/nx-linux-arm64-gnu": - optional: true - "@nx/nx-linux-arm64-musl": - optional: true - "@nx/nx-linux-x64-gnu": - optional: true - "@nx/nx-linux-x64-musl": - optional: true - "@nx/nx-win32-arm64-msvc": - optional: true - "@nx/nx-win32-x64-msvc": - optional: true - peerDependenciesMeta: - "@swc-node/register": - optional: true - "@swc/core": - optional: true - bin: - nx: bin/nx.js - nx-cloud: bin/nx-cloud.js - checksum: 10c0/54afbf205811a076d23b717d8b23356046a98965d7e73f353e38bb5690bf37df68d84f7752de34477f0db80f2b4232dde6e9c6d52321e8bb72ef6f1d1589b056 - languageName: node - linkType: hard - "object-assign@npm:^4, object-assign@npm:^4.0.1, object-assign@npm:latest": version: 4.1.1 resolution: "object-assign@npm:4.1.1" @@ -12684,29 +13261,16 @@ __metadata: languageName: node linkType: hard -"open@npm:8.4.0": - version: 8.4.0 - resolution: "open@npm:8.4.0" - dependencies: - define-lazy-prop: "npm:^2.0.0" - is-docker: "npm:^2.1.1" - is-wsl: "npm:^2.2.0" - checksum: 10c0/585596580226cbeb7262f36b5acc7eed05211dc26980020a2527f829336b8b07fd79cdc4240f4d995b5615f635e0a59ebb0261c4419fef91edd5d4604c463f18 - languageName: node - linkType: hard - -"open@npm:8.4.2, open@npm:^8.4.0": - version: 8.4.2 - resolution: "open@npm:8.4.2" +"onetime@npm:^7.0.0": + version: 7.0.0 + resolution: "onetime@npm:7.0.0" dependencies: - define-lazy-prop: "npm:^2.0.0" - is-docker: "npm:^2.1.1" - is-wsl: "npm:^2.2.0" - checksum: 10c0/bb6b3a58401dacdb0aad14360626faf3fb7fba4b77816b373495988b724fb48941cad80c1b65d62bb31a17609b2cd91c41a181602caea597ca80dfbcc27e84c9 + mimic-function: "npm:^5.0.0" + checksum: 10c0/5cb9179d74b63f52a196a2e7037ba2b9a893245a5532d3f44360012005c9cadb60851d56716ebff18a6f47129dab7168022445df47c2aff3b276d92585ed1221 languageName: node linkType: hard -"open@npm:^10.0.3": +"open@npm:10.1.0, open@npm:^10.0.3": version: 10.1.0 resolution: "open@npm:10.1.0" dependencies: @@ -12718,6 +13282,17 @@ __metadata: languageName: node linkType: hard +"open@npm:8.4.0": + version: 8.4.0 + resolution: "open@npm:8.4.0" + dependencies: + define-lazy-prop: "npm:^2.0.0" + is-docker: "npm:^2.1.1" + is-wsl: "npm:^2.2.0" + checksum: 10c0/585596580226cbeb7262f36b5acc7eed05211dc26980020a2527f829336b8b07fd79cdc4240f4d995b5615f635e0a59ebb0261c4419fef91edd5d4604c463f18 + languageName: node + linkType: hard + "open@npm:^7.3.1": version: 7.4.2 resolution: "open@npm:7.4.2" @@ -12760,23 +13335,7 @@ __metadata: languageName: node linkType: hard -"ora@npm:5.3.0": - version: 5.3.0 - resolution: "ora@npm:5.3.0" - dependencies: - bl: "npm:^4.0.3" - chalk: "npm:^4.1.0" - cli-cursor: "npm:^3.1.0" - cli-spinners: "npm:^2.5.0" - is-interactive: "npm:^1.0.0" - log-symbols: "npm:^4.0.0" - strip-ansi: "npm:^6.0.0" - wcwidth: "npm:^1.0.1" - checksum: 10c0/30d5f3218eb75b0a2028c5fb9aa88e83e38a2f1745ab56839abb06c3ba31bae35f768f4e72c4f9e04e2a66be6a898e9312e8cf85c9333e1e3613eabb8c7cdf57 - languageName: node - linkType: hard - -"ora@npm:5.4.1, ora@npm:^5.4.1": +"ora@npm:5.4.1": version: 5.4.1 resolution: "ora@npm:5.4.1" dependencies: @@ -12975,13 +13534,13 @@ __metadata: languageName: node linkType: hard -"parse-imports@npm:^2.1.0": - version: 2.1.0 - resolution: "parse-imports@npm:2.1.0" +"parse-imports@npm:^2.1.1": + version: 2.1.1 + resolution: "parse-imports@npm:2.1.1" dependencies: es-module-lexer: "npm:^1.5.3" slashes: "npm:^3.0.12" - checksum: 10c0/18ef58008868d2d09e472bb540d63efc7cc27f2c33607e5d09c256ece7a30062cac292bda96d820438e94f3dbf558c85e4b084c10d238baa858796794e6cf628 + checksum: 10c0/c9bb0b4e1823f84f034d2d7bd2b37415b1715a5c963fda14968c706186b48b02c10e97d04bce042b9dcd679b42f29c391ea120799ddf581c7f54786edd99e3a9 languageName: node linkType: hard @@ -13149,6 +13708,13 @@ __metadata: languageName: node linkType: hard +"path-type@npm:^5.0.0": + version: 5.0.0 + resolution: "path-type@npm:5.0.0" + checksum: 10c0/e8f4b15111bf483900c75609e5e74e3fcb79f2ddb73e41470028fcd3e4b5162ec65da9907be077ee5012c18801ff7fffb35f9f37a077f3f81d85a0b7d6578efd + languageName: node + linkType: hard + "pause-stream@npm:^0.0.11": version: 0.0.11 resolution: "pause-stream@npm:0.0.11" @@ -13248,15 +13814,15 @@ __metadata: languageName: node linkType: hard -"piscina@npm:4.5.0": - version: 4.5.0 - resolution: "piscina@npm:4.5.0" +"piscina@npm:4.6.1": + version: 4.6.1 + resolution: "piscina@npm:4.6.1" dependencies: nice-napi: "npm:^1.0.2" dependenciesMeta: nice-napi: optional: true - checksum: 10c0/8eaf07dbd49fdbd9d6447585fa6ab005c0b226ace1a836a09d66021850fa6cca9cd479671fb0dd10784b4544363f08348642950caee9b80fd14f5d6ce6e45af0 + checksum: 10c0/2225fb42806f8d72bf09f2528bd65721b440dcc63ece957a9542a28b3b958be353dc48802fb11a8af66fdfd28a419300ed28e04573b8bf420e6dcfe63d6f58b5 languageName: node linkType: hard @@ -13380,7 +13946,18 @@ __metadata: languageName: node linkType: hard -"postcss@npm:8.4.38, postcss@npm:^8.2.14, postcss@npm:^8.4.23, postcss@npm:^8.4.33, postcss@npm:^8.4.38": +"postcss@npm:8.4.41, postcss@npm:^8.4.40": + version: 8.4.41 + resolution: "postcss@npm:8.4.41" + dependencies: + nanoid: "npm:^3.3.7" + picocolors: "npm:^1.0.1" + source-map-js: "npm:^1.2.0" + checksum: 10c0/c1828fc59e7ec1a3bf52b3a42f615dba53c67960ed82a81df6441b485fe43c20aba7f4e7c55425762fd99c594ecabbaaba8cf5b30fd79dfec5b52a9f63a2d690 + languageName: node + linkType: hard + +"postcss@npm:^8.2.14, postcss@npm:^8.4.23, postcss@npm:^8.4.33": version: 8.4.38 resolution: "postcss@npm:8.4.38" dependencies: @@ -13429,23 +14006,12 @@ __metadata: languageName: node linkType: hard -"prettier@npm:^3.3.2": - version: 3.3.2 - resolution: "prettier@npm:3.3.2" +"prettier@npm:^3.3.3": + version: 3.3.3 + resolution: "prettier@npm:3.3.3" bin: prettier: bin/prettier.cjs - checksum: 10c0/39ed27d17f0238da6dd6571d63026566bd790d3d0edac57c285fbab525982060c8f1e01955fe38134ab10f0951a6076da37f015db8173c02f14bc7f0803a384c - languageName: node - linkType: hard - -"pretty-format@npm:^29.7.0": - version: 29.7.0 - resolution: "pretty-format@npm:29.7.0" - dependencies: - "@jest/schemas": "npm:^29.6.3" - ansi-styles: "npm:^5.0.0" - react-is: "npm:^18.0.0" - checksum: 10c0/edc5ff89f51916f036c62ed433506b55446ff739358de77207e63e88a28ca2894caac6e73dcb68166a606e51c8087d32d400473e6a9fdd2dbe743f46c9c0276f + checksum: 10c0/b85828b08e7505716324e4245549b9205c0cacb25342a030ba8885aba2039a115dbcf75a0b7ca3b37bc9d101ee61fab8113fc69ca3359f2a226f1ecc07ad2e26 languageName: node linkType: hard @@ -13531,13 +14097,6 @@ __metadata: languageName: node linkType: hard -"proxy-from-env@npm:^1.1.0": - version: 1.1.0 - resolution: "proxy-from-env@npm:1.1.0" - checksum: 10c0/fe7dd8b1bdbbbea18d1459107729c3e4a2243ca870d26d34c2c1bcd3e4425b7bcc5112362df2d93cc7fb9746f6142b5e272fd1cc5c86ddf8580175186f6ad42b - languageName: node - linkType: hard - "proxy-middleware@npm:latest": version: 0.15.0 resolution: "proxy-middleware@npm:0.15.0" @@ -13695,13 +14254,6 @@ __metadata: languageName: node linkType: hard -"react-is@npm:^18.0.0": - version: 18.3.1 - resolution: "react-is@npm:18.3.1" - checksum: 10c0/f2f1e60010c683479e74c63f96b09fb41603527cd131a9959e2aee1e5a8b0caf270b365e5ca77d4a6b18aae659b60a86150bb3979073528877029b35aecd2072 - languageName: node - linkType: hard - "read-pkg-up@npm:^3.0.0": version: 3.0.0 resolution: "read-pkg-up@npm:3.0.0" @@ -13971,13 +14523,13 @@ __metadata: languageName: node linkType: hard -"restore-cursor@npm:^4.0.0": - version: 4.0.0 - resolution: "restore-cursor@npm:4.0.0" +"restore-cursor@npm:^5.0.0": + version: 5.1.0 + resolution: "restore-cursor@npm:5.1.0" dependencies: - onetime: "npm:^5.1.0" - signal-exit: "npm:^3.0.2" - checksum: 10c0/6f7da8c5e422ac26aa38354870b1afac09963572cf2879443540449068cb43476e9cbccf6f8de3e0171e0d6f7f533c2bc1a0a008003c9a525bbc098e89041318 + onetime: "npm:^7.0.0" + signal-exit: "npm:^4.1.0" + checksum: 10c0/c2ba89131eea791d1b25205bdfdc86699767e2b88dee2a590b1a6caa51737deac8bad0260a5ded2f7c074b7db2f3a626bcf1fcf3cdf35974cbeea5e2e6764f60 languageName: node linkType: hard @@ -14002,13 +14554,20 @@ __metadata: languageName: node linkType: hard -"rfdc@npm:^1.3.0, rfdc@npm:^1.3.1": +"rfdc@npm:^1.3.0": version: 1.3.1 resolution: "rfdc@npm:1.3.1" checksum: 10c0/69f65e3ed30970f8055fac9fbbef9ce578800ca19554eab1dcbffe73a4b8aef536bc4248313889cf25e3b4e38b212c721eabe30856575bf2b2bc3d90f8ba93ef languageName: node linkType: hard +"rfdc@npm:^1.4.1": + version: 1.4.1 + resolution: "rfdc@npm:1.4.1" + checksum: 10c0/4614e4292356cafade0b6031527eea9bc90f2372a22c012313be1dcc69a3b90c7338158b414539be863fa95bfcb2ddcd0587be696841af4e6679d85e62c060c7 + languageName: node + linkType: hard + "rimraf@npm:^3.0.2": version: 3.0.2 resolution: "rimraf@npm:3.0.2" @@ -14042,6 +14601,69 @@ __metadata: languageName: node linkType: hard +"rollup@npm:4.20.0": + version: 4.20.0 + resolution: "rollup@npm:4.20.0" + dependencies: + "@rollup/rollup-android-arm-eabi": "npm:4.20.0" + "@rollup/rollup-android-arm64": "npm:4.20.0" + "@rollup/rollup-darwin-arm64": "npm:4.20.0" + "@rollup/rollup-darwin-x64": "npm:4.20.0" + "@rollup/rollup-linux-arm-gnueabihf": "npm:4.20.0" + "@rollup/rollup-linux-arm-musleabihf": "npm:4.20.0" + "@rollup/rollup-linux-arm64-gnu": "npm:4.20.0" + "@rollup/rollup-linux-arm64-musl": "npm:4.20.0" + "@rollup/rollup-linux-powerpc64le-gnu": "npm:4.20.0" + "@rollup/rollup-linux-riscv64-gnu": "npm:4.20.0" + "@rollup/rollup-linux-s390x-gnu": "npm:4.20.0" + "@rollup/rollup-linux-x64-gnu": "npm:4.20.0" + "@rollup/rollup-linux-x64-musl": "npm:4.20.0" + "@rollup/rollup-win32-arm64-msvc": "npm:4.20.0" + "@rollup/rollup-win32-ia32-msvc": "npm:4.20.0" + "@rollup/rollup-win32-x64-msvc": "npm:4.20.0" + "@types/estree": "npm:1.0.5" + fsevents: "npm:~2.3.2" + dependenciesMeta: + "@rollup/rollup-android-arm-eabi": + optional: true + "@rollup/rollup-android-arm64": + optional: true + "@rollup/rollup-darwin-arm64": + optional: true + "@rollup/rollup-darwin-x64": + optional: true + "@rollup/rollup-linux-arm-gnueabihf": + optional: true + "@rollup/rollup-linux-arm-musleabihf": + optional: true + "@rollup/rollup-linux-arm64-gnu": + optional: true + "@rollup/rollup-linux-arm64-musl": + optional: true + "@rollup/rollup-linux-powerpc64le-gnu": + optional: true + "@rollup/rollup-linux-riscv64-gnu": + optional: true + "@rollup/rollup-linux-s390x-gnu": + optional: true + "@rollup/rollup-linux-x64-gnu": + optional: true + "@rollup/rollup-linux-x64-musl": + optional: true + "@rollup/rollup-win32-arm64-msvc": + optional: true + "@rollup/rollup-win32-ia32-msvc": + optional: true + "@rollup/rollup-win32-x64-msvc": + optional: true + fsevents: + optional: true + bin: + rollup: dist/bin/rollup + checksum: 10c0/9b23bf0e3380e64573a5f68a55274d5c7969036e55c19aab9fb4deea2e938d76769db70f3c95ee3783c24af152bea1772ad73f9e3625b6ffd4e600a788fe97ea + languageName: node + linkType: hard + "rollup@npm:^4.13.0": version: 4.18.0 resolution: "rollup@npm:4.18.0" @@ -14119,13 +14741,6 @@ __metadata: languageName: node linkType: hard -"run-async@npm:^3.0.0": - version: 3.0.0 - resolution: "run-async@npm:3.0.0" - checksum: 10c0/b18b562ae37c3020083dcaae29642e4cc360c824fbfb6b7d50d809a9d5227bb986152d09310255842c8dce40526e82ca768f02f00806c91ba92a8dfa6159cb85 - languageName: node - linkType: hard - "run-parallel@npm:^1.1.9": version: 1.2.0 resolution: "run-parallel@npm:1.2.0" @@ -14142,7 +14757,7 @@ __metadata: languageName: node linkType: hard -"rxjs@npm:7.8.1, rxjs@npm:^7.8.1, rxjs@npm:~7.8.1": +"rxjs@npm:7.8.1, rxjs@npm:~7.8.1": version: 7.8.1 resolution: "rxjs@npm:7.8.1" dependencies: @@ -14195,9 +14810,9 @@ __metadata: languageName: node linkType: hard -"sass-loader@npm:14.2.1": - version: 14.2.1 - resolution: "sass-loader@npm:14.2.1" +"sass-loader@npm:16.0.0": + version: 16.0.0 + resolution: "sass-loader@npm:16.0.0" dependencies: neo-async: "npm:^2.6.2" peerDependencies: @@ -14217,20 +14832,20 @@ __metadata: optional: true webpack: optional: true - checksum: 10c0/9a48d454584d96d6c562eb323bb9e3c6808e930eeaaa916975b97d45831e0b87936a8655cdb3a4512a25abc9587dea65a9616e42396be0d7e7c507a4795a8146 + checksum: 10c0/0d2c2ee89a380ae19f1d024008c241afb747c254cf8e2163b281533c803a1cb3933236f0cfbb59a296fce864e4274e32a80c30dadd5b98618a362f0be8bac20f languageName: node linkType: hard -"sass@npm:1.77.2": - version: 1.77.2 - resolution: "sass@npm:1.77.2" +"sass@npm:1.77.8": + version: 1.77.8 + resolution: "sass@npm:1.77.8" dependencies: chokidar: "npm:>=3.0.0 <4.0.0" immutable: "npm:^4.0.0" source-map-js: "npm:>=0.6.2 <2.0.0" bin: sass: sass.js - checksum: 10c0/0d292339064de3c902e209d41de9c4eb2038cff326476aeebbb5be3eee1d23400d975face2b8e124ae617b10af3e93bec01580f61912f34e4c517fe137a118b6 + checksum: 10c0/2bfd62794070352c804f949e69bd8bb5b4ec846deeb924251b2c3f7b503170fb1ae186f513f0166907749eb34e0277dee747edcb78c886fb471aac01be1e864c languageName: node linkType: hard @@ -14299,12 +14914,12 @@ __metadata: languageName: node linkType: hard -"semver@npm:7.6.2, semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.5.2, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.6.2": - version: 7.6.2 - resolution: "semver@npm:7.6.2" +"semver@npm:7.6.3, semver@npm:^7.6.3": + version: 7.6.3 + resolution: "semver@npm:7.6.3" bin: semver: bin/semver.js - checksum: 10c0/97d3441e97ace8be4b1976433d1c32658f6afaff09f143e52c593bae7eef33de19e3e369c88bd985ce1042c6f441c80c6803078d1de2a9988080b66684cbb30c + checksum: 10c0/88f33e148b210c153873cb08cfe1e281d518aaa9a666d4d148add6560db5cd3c582f3a08ccb91f38d5f379ead256da9931234ed122057f40bb5766e65e58adaf languageName: node linkType: hard @@ -14317,6 +14932,15 @@ __metadata: languageName: node linkType: hard +"semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.5.2, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.6.2": + version: 7.6.2 + resolution: "semver@npm:7.6.2" + bin: + semver: bin/semver.js + checksum: 10c0/97d3441e97ace8be4b1976433d1c32658f6afaff09f143e52c593bae7eef33de19e3e369c88bd985ce1042c6f441c80c6803078d1de2a9988080b66684cbb30c + languageName: node + linkType: hard + "send@npm:0.18.0, send@npm:latest": version: 0.18.0 resolution: "send@npm:0.18.0" @@ -14338,7 +14962,7 @@ __metadata: languageName: node linkType: hard -"serialize-javascript@npm:^6.0.0, serialize-javascript@npm:^6.0.1": +"serialize-javascript@npm:^6.0.1, serialize-javascript@npm:^6.0.2": version: 6.0.2 resolution: "serialize-javascript@npm:6.0.2" dependencies: @@ -14548,10 +15172,10 @@ __metadata: languageName: node linkType: hard -"slash@npm:^4.0.0": - version: 4.0.0 - resolution: "slash@npm:4.0.0" - checksum: 10c0/b522ca75d80d107fd30d29df0549a7b2537c83c4c4ecd12cd7d4ea6c8aaca2ab17ada002e7a1d78a9d736a0261509f26ea5b489082ee443a3a810586ef8eff18 +"slash@npm:^5.1.0": + version: 5.1.0 + resolution: "slash@npm:5.1.0" + checksum: 10c0/eb48b815caf0bdc390d0519d41b9e0556a14380f6799c72ba35caf03544d501d18befdeeef074bc9c052acf69654bc9e0d79d7f1de0866284137a40805299eb3 languageName: node linkType: hard @@ -14572,7 +15196,7 @@ __metadata: languageName: node linkType: hard -"slice-ansi@npm:^7.0.0": +"slice-ansi@npm:^7.1.0": version: 7.1.0 resolution: "slice-ansi@npm:7.1.0" dependencies: @@ -14847,13 +15471,6 @@ __metadata: languageName: node linkType: hard -"sprintf-js@npm:~1.0.2": - version: 1.0.3 - resolution: "sprintf-js@npm:1.0.3" - checksum: 10c0/ecadcfe4c771890140da5023d43e190b7566d9cf8b2d238600f31bec0fc653f328da4450eb04bd59a431771a8e9cc0e118f0aa3974b683a4981b4e07abc2a5bb - languageName: node - linkType: hard - "sqlite3@npm:>=2.1.1, sqlite3@npm:^5.1.6": version: 5.1.7 resolution: "sqlite3@npm:5.1.7" @@ -15116,19 +15733,6 @@ __metadata: languageName: node linkType: hard -"strong-log-transformer@npm:^2.1.0": - version: 2.1.0 - resolution: "strong-log-transformer@npm:2.1.0" - dependencies: - duplexer: "npm:^0.1.1" - minimist: "npm:^1.2.0" - through: "npm:^2.3.4" - bin: - sl-log-transformer: bin/sl-log-transformer.js - checksum: 10c0/3c3b8aa8f34d661910563ff996412e2f527fc814e699a376854b554d4a4294ab7e285b4e2c08a080a7b19c5600a9b93a98798d3ac600fe3de545ca6605c07829 - languageName: node - linkType: hard - "style-mod@npm:^4.0.0, style-mod@npm:^4.1.0": version: 4.1.2 resolution: "style-mod@npm:4.1.2" @@ -15191,23 +15795,13 @@ __metadata: languageName: node linkType: hard -"synckit@npm:^0.8.6": - version: 0.8.8 - resolution: "synckit@npm:0.8.8" - dependencies: - "@pkgr/core": "npm:^0.1.0" - tslib: "npm:^2.6.2" - checksum: 10c0/c3d3aa8e284f3f84f2f868b960c9f49239b364e35f6d20825a448449a3e9c8f49fe36cdd5196b30615682f007830d46f2ea354003954c7336723cb821e4b6519 - languageName: node - linkType: hard - -"synckit@npm:^0.9.0": - version: 0.9.0 - resolution: "synckit@npm:0.9.0" +"synckit@npm:^0.9.1": + version: 0.9.1 + resolution: "synckit@npm:0.9.1" dependencies: "@pkgr/core": "npm:^0.1.0" tslib: "npm:^2.6.2" - checksum: 10c0/b5c1e7c03fefe3d36a9ab4e71dd21859cb32be4138712c31a893382a568fd00efc59ede8f521dd7e53d43a2fea92bdf717e987ea9ed6ad94f97ef28d71d0ba2f + checksum: 10c0/d8b89e1bf30ba3ffb469d8418c836ad9c0c062bf47028406b4d06548bc66af97155ea2303b96c93bf5c7c0f0d66153a6fbd6924c76521b434e6a9898982abc2e languageName: node linkType: hard @@ -15237,7 +15831,7 @@ __metadata: languageName: node linkType: hard -"tar-stream@npm:^2.1.4, tar-stream@npm:~2.2.0": +"tar-stream@npm:^2.1.4": version: 2.2.0 resolution: "tar-stream@npm:2.2.0" dependencies: @@ -15306,7 +15900,21 @@ __metadata: languageName: node linkType: hard -"terser@npm:5.31.0, terser@npm:^5.26.0": +"terser@npm:5.31.6": + version: 5.31.6 + resolution: "terser@npm:5.31.6" + dependencies: + "@jridgewell/source-map": "npm:^0.3.3" + acorn: "npm:^8.8.2" + commander: "npm:^2.20.0" + source-map-support: "npm:~0.5.20" + bin: + terser: bin/terser + checksum: 10c0/b17d02b65a52a5041430572b3c514475820f5e7590fa93773c0f5b4be601ccf3f6d745bf5a79f3ee58187cf85edf61c24ddf4345783839fccb44c9c8fa9b427e + languageName: node + linkType: hard + +"terser@npm:^5.26.0": version: 5.31.0 resolution: "terser@npm:5.31.0" dependencies: @@ -15369,7 +15977,7 @@ __metadata: languageName: node linkType: hard -"through@npm:2, through@npm:>=2.2.7 <3, through@npm:^2.3.4, through@npm:^2.3.8, through@npm:~2.3, through@npm:~2.3.4": +"through@npm:2, through@npm:>=2.2.7 <3, through@npm:^2.3.8, through@npm:~2.3, through@npm:~2.3.4": version: 2.3.8 resolution: "through@npm:2.3.8" checksum: 10c0/4b09f3774099de0d4df26d95c5821a62faee32c7e96fb1f4ebd54a2d7c11c57fe88b0a0d49cf375de5fee5ae6bf4eb56dbbf29d07366864e2ee805349970d3cc @@ -15399,7 +16007,7 @@ __metadata: languageName: node linkType: hard -"tmp@npm:^0.2.1, tmp@npm:~0.2.1": +"tmp@npm:^0.2.1": version: 0.2.3 resolution: "tmp@npm:0.2.3" checksum: 10c0/3e809d9c2f46817475b452725c2aaa5d11985cf18d32a7a970ff25b568438e2c076c2e8609224feef3b7923fa9749b74428e3e634f6b8e520c534eef2fd24125 @@ -15533,25 +16141,7 @@ __metadata: languageName: node linkType: hard -"tsconfig-paths@npm:^4.1.2": - version: 4.2.0 - resolution: "tsconfig-paths@npm:4.2.0" - dependencies: - json5: "npm:^2.2.2" - minimist: "npm:^1.2.6" - strip-bom: "npm:^3.0.0" - checksum: 10c0/09a5877402d082bb1134930c10249edeebc0211f36150c35e1c542e5b91f1047b1ccf7da1e59babca1ef1f014c525510f4f870de7c9bda470c73bb4e2721b3ea - languageName: node - linkType: hard - -"tslib@npm:2.6.2": - version: 2.6.2 - resolution: "tslib@npm:2.6.2" - checksum: 10c0/e03a8a4271152c8b26604ed45535954c0a45296e32445b4b87f8a5abdb2421f40b59b4ca437c4346af0f28179780d604094eb64546bee2019d903d01c6c19bdb - languageName: node - linkType: hard - -"tslib@npm:^2.0.0, tslib@npm:^2.1.0, tslib@npm:^2.3.0, tslib@npm:^2.3.1, tslib@npm:^2.4.0, tslib@npm:^2.6.2": +"tslib@npm:2.6.3, tslib@npm:^2.0.0, tslib@npm:^2.1.0, tslib@npm:^2.3.0, tslib@npm:^2.3.1, tslib@npm:^2.6.2": version: 2.6.3 resolution: "tslib@npm:2.6.3" checksum: 10c0/2598aef53d9dbe711af75522464b2104724d6467b26a60f2bdac8297d2b5f1f6b86a71f61717384aa8fd897240467aaa7bcc36a0700a0faf751293d1331db39a @@ -15722,13 +16312,13 @@ __metadata: languageName: node linkType: hard -"typescript@npm:~5.5.2": - version: 5.5.2 - resolution: "typescript@npm:5.5.2" +"typescript@npm:~5.5.4": + version: 5.5.4 + resolution: "typescript@npm:5.5.4" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10c0/8ca39b27b5f9bd7f32db795045933ab5247897660627251e8254180b792a395bf061ea7231947d5d7ffa5cb4cc771970fd4ef543275f9b559f08c9325cccfce3 + checksum: 10c0/422be60f89e661eab29ac488c974b6cc0a660fb2228003b297c3d10c32c90f3bcffc1009b43876a082515a3c376b1eefcce823d6e78982e6878408b9a923199c languageName: node linkType: hard @@ -15742,13 +16332,13 @@ __metadata: languageName: node linkType: hard -"typescript@patch:typescript@npm%3A~5.5.2#optional!builtin": - version: 5.5.2 - resolution: "typescript@patch:typescript@npm%3A5.5.2#optional!builtin::version=5.5.2&hash=b45daf" +"typescript@patch:typescript@npm%3A~5.5.4#optional!builtin": + version: 5.5.4 + resolution: "typescript@patch:typescript@npm%3A5.5.4#optional!builtin::version=5.5.4&hash=b45daf" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10c0/6721ac8933a70c252d7b640b345792e103d881811ff660355617c1836526dbb71c2044e2e77a8823fb3570b469f33276875a4cab6d3c4de4ae7d7ee1c3074ae4 + checksum: 10c0/10dd9881baba22763de859e8050d6cb6e2db854197495c6f1929b08d1eb2b2b00d0b5d9b0bcee8472f1c3f4a7ef6a5d7ebe0cfd703f853aa5ae465b8404bc1ba languageName: node linkType: hard @@ -15794,10 +16384,10 @@ __metadata: languageName: node linkType: hard -"undici@npm:6.18.0": - version: 6.18.0 - resolution: "undici@npm:6.18.0" - checksum: 10c0/b888f13169357999abe94f7a9870800987696887952dd3780a5e4d9b43532088ef8d2e747969934ac57752900fb59e5725289f97cad458da3317501a47ccb85a +"undici-types@npm:~6.18.2": + version: 6.18.2 + resolution: "undici-types@npm:6.18.2" + checksum: 10c0/dea28163891a5af7624c120107dc07a74c369ee94c6dd1d0de29af061ee129fac4846f97130589f4436b85f6102c73d30328ca908be02626dd8ab9fec5642aba languageName: node linkType: hard @@ -15953,6 +16543,20 @@ __metadata: languageName: node linkType: hard +"update-browserslist-db@npm:^1.1.0": + version: 1.1.0 + resolution: "update-browserslist-db@npm:1.1.0" + dependencies: + escalade: "npm:^3.1.2" + picocolors: "npm:^1.0.1" + peerDependencies: + browserslist: ">= 4.21.0" + bin: + update-browserslist-db: cli.js + checksum: 10c0/a7452de47785842736fb71547651c5bbe5b4dc1e3722ccf48a704b7b34e4dcf633991eaa8e4a6a517ffb738b3252eede3773bef673ef9021baa26b056d63a5b9 + languageName: node + linkType: hard + "uri-js@npm:^4.2.2, uri-js@npm:^4.4.1": version: 4.4.1 resolution: "uri-js@npm:4.4.1" @@ -16048,19 +16652,20 @@ __metadata: languageName: node linkType: hard -"vite@npm:5.2.11": - version: 5.2.11 - resolution: "vite@npm:5.2.11" +"vite@npm:5.4.0": + version: 5.4.0 + resolution: "vite@npm:5.4.0" dependencies: - esbuild: "npm:^0.20.1" + esbuild: "npm:^0.21.3" fsevents: "npm:~2.3.3" - postcss: "npm:^8.4.38" + postcss: "npm:^8.4.40" rollup: "npm:^4.13.0" peerDependencies: "@types/node": ^18.0.0 || >=20.0.0 less: "*" lightningcss: ^1.21.0 sass: "*" + sass-embedded: "*" stylus: "*" sugarss: "*" terser: ^5.4.0 @@ -16076,6 +16681,8 @@ __metadata: optional: true sass: optional: true + sass-embedded: + optional: true stylus: optional: true sugarss: @@ -16084,7 +16691,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 10c0/664b8d68e4f5152ae16bd2041af1bbaf11c43630ac461835bc31ff7d019913b33e465386e09f66dc1037d7aeefbb06939e0173787c063319bc2bd30c3b9ad8e4 + checksum: 10c0/122de7795e1c3c08cd0acc7d77296f908398266b424492be7310400107f37a3cf4c9506f2b4b16619e57299ca2859b8ca187aac5e25f8e66d84f9204a1d72d18 languageName: node linkType: hard @@ -16182,7 +16789,26 @@ __metadata: languageName: node linkType: hard -"webpack-dev-middleware@npm:7.2.1, webpack-dev-middleware@npm:^7.1.0": +"webpack-dev-middleware@npm:7.3.0": + version: 7.3.0 + resolution: "webpack-dev-middleware@npm:7.3.0" + dependencies: + colorette: "npm:^2.0.10" + memfs: "npm:^4.6.0" + mime-types: "npm:^2.1.31" + on-finished: "npm:^2.4.1" + range-parser: "npm:^1.2.1" + schema-utils: "npm:^4.0.0" + peerDependencies: + webpack: ^5.0.0 + peerDependenciesMeta: + webpack: + optional: true + checksum: 10c0/03d34e1c7af3af8c98efe754ce6cfb9fe84a1f02d312bc37a77f55b8ae9525bc3ac913fc92c0143ab93a3a6377781661f07336031fcd5e6bbddccc11df9345db + languageName: node + linkType: hard + +"webpack-dev-middleware@npm:^7.1.0": version: 7.2.1 resolution: "webpack-dev-middleware@npm:7.2.1" dependencies: @@ -16248,14 +16874,14 @@ __metadata: languageName: node linkType: hard -"webpack-merge@npm:5.10.0": - version: 5.10.0 - resolution: "webpack-merge@npm:5.10.0" +"webpack-merge@npm:6.0.1": + version: 6.0.1 + resolution: "webpack-merge@npm:6.0.1" dependencies: clone-deep: "npm:^4.0.1" flat: "npm:^5.0.2" - wildcard: "npm:^2.0.0" - checksum: 10c0/b607c84cabaf74689f965420051a55a08722d897bdd6c29cb0b2263b451c090f962d41ecf8c9bf56b0ab3de56e65476ace0a8ecda4f4a4663684243d90e0512b + wildcard: "npm:^2.0.1" + checksum: 10c0/bf1429567858b353641801b8a2696ca0aac270fc8c55d4de8a7b586fe07d27fdcfc83099a98ab47e6162383db8dd63bb8cc25b1beb2ec82150422eec843b0dc0 languageName: node linkType: hard @@ -16281,9 +16907,9 @@ __metadata: languageName: node linkType: hard -"webpack@npm:5.91.0": - version: 5.91.0 - resolution: "webpack@npm:5.91.0" +"webpack@npm:5.93.0": + version: 5.93.0 + resolution: "webpack@npm:5.93.0" dependencies: "@types/eslint-scope": "npm:^3.7.3" "@types/estree": "npm:^1.0.5" @@ -16291,10 +16917,10 @@ __metadata: "@webassemblyjs/wasm-edit": "npm:^1.12.1" "@webassemblyjs/wasm-parser": "npm:^1.12.1" acorn: "npm:^8.7.1" - acorn-import-assertions: "npm:^1.9.0" + acorn-import-attributes: "npm:^1.9.5" browserslist: "npm:^4.21.10" chrome-trace-event: "npm:^1.0.2" - enhanced-resolve: "npm:^5.16.0" + enhanced-resolve: "npm:^5.17.0" es-module-lexer: "npm:^1.2.1" eslint-scope: "npm:5.1.1" events: "npm:^3.2.0" @@ -16314,7 +16940,7 @@ __metadata: optional: true bin: webpack: bin/webpack.js - checksum: 10c0/74a3e0ea1c9a492accf035317f31769ffeaaab415811524b9f17bc7bf7012c5b6e1a9860df5ca6903f3ae2618727b801eb47d9351a2595dfffb25941d368b88c + checksum: 10c0/f0c72f1325ff57a4cc461bb978e6e1296f2a7d45c9765965271aa686ccdd448512956f4d7fdcf8c164d073af046c5a0aba17ce85ea98e33e5e2bfbfe13aa5808 languageName: node linkType: hard @@ -16442,7 +17068,7 @@ __metadata: languageName: node linkType: hard -"wildcard@npm:^2.0.0": +"wildcard@npm:^2.0.1": version: 2.0.1 resolution: "wildcard@npm:2.0.1" checksum: 10c0/08f70cd97dd9a20aea280847a1fe8148e17cae7d231640e41eb26d2388697cbe65b67fd9e68715251c39b080c5ae4f76d71a9a69fa101d897273efdfb1b58bf7 @@ -16626,7 +17252,7 @@ __metadata: languageName: node linkType: hard -"yaml@npm:^2.4.1, yaml@npm:~2.4.2": +"yaml@npm:^2.4.1": version: 2.4.3 resolution: "yaml@npm:2.4.3" bin: @@ -16635,10 +17261,12 @@ __metadata: languageName: node linkType: hard -"yargs-parser@npm:21.1.1, yargs-parser@npm:^21.1.1": - version: 21.1.1 - resolution: "yargs-parser@npm:21.1.1" - checksum: 10c0/f84b5e48169479d2f402239c59f084cfd1c3acc197a05c59b98bab067452e6b3ea46d4dd8ba2985ba7b3d32a343d77df0debd6b343e5dae3da2aab2cdf5886b2 +"yaml@npm:~2.5.0": + version: 2.5.0 + resolution: "yaml@npm:2.5.0" + bin: + yaml: bin.mjs + checksum: 10c0/771a1df083c8217cf04ef49f87244ae2dd7d7457094425e793b8f056159f167602ce172aa32d6bca21f787d24ec724aee3cecde938f6643564117bd151452631 languageName: node linkType: hard @@ -16649,7 +17277,14 @@ __metadata: languageName: node linkType: hard -"yargs@npm:17.7.2, yargs@npm:^17.0.0, yargs@npm:^17.2.1, yargs@npm:^17.6.2, yargs@npm:^17.7.2": +"yargs-parser@npm:^21.1.1": + version: 21.1.1 + resolution: "yargs-parser@npm:21.1.1" + checksum: 10c0/f84b5e48169479d2f402239c59f084cfd1c3acc197a05c59b98bab067452e6b3ea46d4dd8ba2985ba7b3d32a343d77df0debd6b343e5dae3da2aab2cdf5886b2 + languageName: node + linkType: hard + +"yargs@npm:17.7.2, yargs@npm:^17.0.0, yargs@npm:^17.2.1, yargs@npm:^17.7.2": version: 17.7.2 resolution: "yargs@npm:17.7.2" dependencies: @@ -16693,6 +17328,13 @@ __metadata: languageName: node linkType: hard +"yoctocolors-cjs@npm:^2.1.2": + version: 2.1.2 + resolution: "yoctocolors-cjs@npm:2.1.2" + checksum: 10c0/a0e36eb88fea2c7981eab22d1ba45e15d8d268626e6c4143305e2c1628fa17ebfaa40cd306161a8ce04c0a60ee0262058eab12567493d5eb1409780853454c6f + languageName: node + linkType: hard + "zepto@npm:^1.2.0": version: 1.2.0 resolution: "zepto@npm:1.2.0" @@ -16700,9 +17342,9 @@ __metadata: languageName: node linkType: hard -"zone.js@npm:~0.14.7": - version: 0.14.7 - resolution: "zone.js@npm:0.14.7" - checksum: 10c0/5a5fccb78ea4653ccf3ad5c11448ffa4e005b50a0fd43da713fcc19584746000ea889ca45163d2e6e18e3a4ed7be42cdbc0dbb4dcb28449f02d23408696668cc +"zone.js@npm:~0.14.10": + version: 0.14.10 + resolution: "zone.js@npm:0.14.10" + checksum: 10c0/61283d152cb1eff899bae61621dccd572aa9f47e0c60c04b249bf86b43e3e4ba627bf6dba371b725023a4f302f39e554d7bf2d25bbf40c869c6c52f774b17e8b languageName: node linkType: hard
+ +