changeset 129:f47661b9ed34

merge
author drewp@bigasterisk.com
date Fri, 05 May 2023 21:27:24 -0700
parents 5a1a79f54779 (diff) 16db0e62dd9e (current diff)
children 73a70d00fb74
files
diffstat 26 files changed, 2701 insertions(+), 1029 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.dependency-cruiser.js	Fri May 05 21:27:24 2023 -0700
@@ -0,0 +1,449 @@
+/** @type {import('dependency-cruiser').IConfiguration} */
+module.exports = {
+  forbidden: [
+    /* rules from the 'recommended' preset: */
+    {
+      name: 'no-circular',
+      severity: 'warn',
+      comment:
+        'This dependency is part of a circular relationship. You might want to revise ' +
+        'your solution (i.e. use dependency inversion, make sure the modules have a single responsibility) ',
+      from: {},
+      to: {
+        circular: true
+      }
+    },
+    {
+      name: 'no-orphans',
+      comment:
+        "This is an orphan module - it's likely not used (anymore?). Either use it or " +
+        "remove it. If it's logical this module is an orphan (i.e. it's a config file), " +
+        "add an exception for it in your dependency-cruiser configuration. By default " +
+        "this rule does not scrutinize dot-files (e.g. .eslintrc.js), TypeScript declaration " +
+        "files (.d.ts), tsconfig.json and some of the babel and webpack configs.",
+      severity: 'warn',
+      from: {
+        orphan: true,
+        pathNot: [
+          '(^|/)\\.[^/]+\\.(js|cjs|mjs|ts|json)$', // dot files
+          '\\.d\\.ts$',                            // TypeScript declaration files
+          '(^|/)tsconfig\\.json$',                 // TypeScript config
+          '(^|/)(babel|webpack)\\.config\\.(js|cjs|mjs|ts|json)$' // other configs
+        ]
+      },
+      to: {},
+    },
+    {
+      name: 'no-deprecated-core',
+      comment:
+        'A module depends on a node core module that has been deprecated. Find an alternative - these are ' +
+        "bound to exist - node doesn't deprecate lightly.",
+      severity: 'warn',
+      from: {},
+      to: {
+        dependencyTypes: [
+          'core'
+        ],
+        path: [
+          '^(v8\/tools\/codemap)$',
+          '^(v8\/tools\/consarray)$',
+          '^(v8\/tools\/csvparser)$',
+          '^(v8\/tools\/logreader)$',
+          '^(v8\/tools\/profile_view)$',
+          '^(v8\/tools\/profile)$',
+          '^(v8\/tools\/SourceMap)$',
+          '^(v8\/tools\/splaytree)$',
+          '^(v8\/tools\/tickprocessor-driver)$',
+          '^(v8\/tools\/tickprocessor)$',
+          '^(node-inspect\/lib\/_inspect)$',
+          '^(node-inspect\/lib\/internal\/inspect_client)$',
+          '^(node-inspect\/lib\/internal\/inspect_repl)$',
+          '^(async_hooks)$',
+          '^(punycode)$',
+          '^(domain)$',
+          '^(constants)$',
+          '^(sys)$',
+          '^(_linklist)$',
+          '^(_stream_wrap)$'
+        ],
+      }
+    },
+    {
+      name: 'not-to-deprecated',
+      comment:
+        'This module uses a (version of an) npm module that has been deprecated. Either upgrade to a later ' +
+        'version of that module, or find an alternative. Deprecated modules are a security risk.',
+      severity: 'warn',
+      from: {},
+      to: {
+        dependencyTypes: [
+          'deprecated'
+        ]
+      }
+    },
+    {
+      name: 'no-non-package-json',
+      severity: 'error',
+      comment:
+        "This module depends on an npm package that isn't in the 'dependencies' section of your package.json. " +
+        "That's problematic as the package either (1) won't be available on live (2 - worse) will be " +
+        "available on live with an non-guaranteed version. Fix it by adding the package to the dependencies " +
+        "in your package.json.",
+      from: {},
+      to: {
+        dependencyTypes: [
+          'npm-no-pkg',
+          'npm-unknown'
+        ]
+      }
+    },
+    {
+      name: 'not-to-unresolvable',
+      comment:
+        "This module depends on a module that cannot be found ('resolved to disk'). If it's an npm " +
+        'module: add it to your package.json. In all other cases you likely already know what to do.',
+      severity: 'error',
+      from: {},
+      to: {
+        couldNotResolve: true
+      }
+    },
+    {
+      name: 'no-duplicate-dep-types',
+      comment:
+        "Likely this module depends on an external ('npm') package that occurs more than once " +
+        "in your package.json i.e. bot as a devDependencies and in dependencies. This will cause " +
+        "maintenance problems later on.",
+      severity: 'warn',
+      from: {},
+      to: {
+        moreThanOneDependencyType: true,
+        // as it's pretty common to have a type import be a type only import 
+        // _and_ (e.g.) a devDependency - don't consider type-only dependency
+        // types for this rule
+        dependencyTypesNot: ["type-only"]
+      }
+    },
+
+    /* rules you might want to tweak for your specific situation: */
+    {
+      name: 'not-to-spec',
+      comment:
+        'This module depends on a spec (test) file. The sole responsibility of a spec file is to test code. ' +
+        "If there's something in a spec that's of use to other modules, it doesn't have that single " +
+        'responsibility anymore. Factor it out into (e.g.) a separate utility/ helper or a mock.',
+      severity: 'error',
+      from: {},
+      to: {
+        path: '\\.(spec|test)\\.(js|mjs|cjs|ts|ls|coffee|litcoffee|coffee\\.md)$'
+      }
+    },
+    {
+      name: 'not-to-dev-dep',
+      severity: 'error',
+      comment:
+        "This module depends on an npm package from the 'devDependencies' section of your " +
+        'package.json. It looks like something that ships to production, though. To prevent problems ' +
+        "with npm packages that aren't there on production declare it (only!) in the 'dependencies'" +
+        'section of your package.json. If this module is development only - add it to the ' +
+        'from.pathNot re of the not-to-dev-dep rule in the dependency-cruiser configuration',
+      from: {
+        path: '^(src)',
+        pathNot: '\\.(spec|test)\\.(js|mjs|cjs|ts|ls|coffee|litcoffee|coffee\\.md)$'
+      },
+      to: {
+        dependencyTypes: [
+          'npm-dev'
+        ]
+      }
+    },
+    {
+      name: 'optional-deps-used',
+      severity: 'info',
+      comment:
+        "This module depends on an npm package that is declared as an optional dependency " +
+        "in your package.json. As this makes sense in limited situations only, it's flagged here. " +
+        "If you're using an optional dependency here by design - add an exception to your" +
+        "dependency-cruiser configuration.",
+      from: {},
+      to: {
+        dependencyTypes: [
+          'npm-optional'
+        ]
+      }
+    },
+    {
+      name: 'peer-deps-used',
+      comment:
+        "This module depends on an npm package that is declared as a peer dependency " +
+        "in your package.json. This makes sense if your package is e.g. a plugin, but in " +
+        "other cases - maybe not so much. If the use of a peer dependency is intentional " +
+        "add an exception to your dependency-cruiser configuration.",
+      severity: 'warn',
+      from: {},
+      to: {
+        dependencyTypes: [
+          'npm-peer'
+        ]
+      }
+    }
+  ],
+  options: {
+
+    /* conditions specifying which files not to follow further when encountered:
+       - path: a regular expression to match
+       - dependencyTypes: see https://github.com/sverweij/dependency-cruiser/blob/master/doc/rules-reference.md#dependencytypes-and-dependencytypesnot
+       for a complete list
+    */
+    doNotFollow: {
+      path: 'node_modules'
+    },
+
+    /* conditions specifying which dependencies to exclude
+       - path: a regular expression to match
+       - dynamic: a boolean indicating whether to ignore dynamic (true) or static (false) dependencies.
+          leave out if you want to exclude neither (recommended!)
+    */
+    exclude : {
+      path: '.*\.test\.ts',
+    //   dynamic: true
+    },
+
+    /* pattern specifying which files to include (regular expression)
+       dependency-cruiser will skip everything not matching this pattern
+    */
+    // includeOnly : '',
+
+    /* dependency-cruiser will include modules matching against the focus
+       regular expression in its output, as well as their neighbours (direct
+       dependencies and dependents)
+    */
+    // focus : '',
+
+    /* list of module systems to cruise */
+    // moduleSystems: ['amd', 'cjs', 'es6', 'tsd'],
+
+    /* prefix for links in html and svg output (e.g. 'https://github.com/you/yourrepo/blob/develop/'
+       to open it on your online repo or `vscode://file/${process.cwd()}/` to 
+       open it in visual studio code),
+     */
+    // prefix: '',
+
+    /* false (the default): ignore dependencies that only exist before typescript-to-javascript compilation
+       true: also detect dependencies that only exist before typescript-to-javascript compilation
+       "specify": for each dependency identify whether it only exists before compilation or also after
+     */
+    tsPreCompilationDeps: true,
+    
+    /* 
+       list of extensions to scan that aren't javascript or compile-to-javascript. 
+       Empty by default. Only put extensions in here that you want to take into
+       account that are _not_ parsable. 
+    */
+    // extraExtensionsToScan: [".json", ".jpg", ".png", ".svg", ".webp"],
+
+    /* if true combines the package.jsons found from the module up to the base
+       folder the cruise is initiated from. Useful for how (some) mono-repos
+       manage dependencies & dependency definitions.
+     */
+    // combinedDependencies: false,
+
+    /* if true leave symlinks untouched, otherwise use the realpath */
+    // preserveSymlinks: false,
+
+    /* TypeScript project file ('tsconfig.json') to use for
+       (1) compilation and
+       (2) resolution (e.g. with the paths property)
+
+       The (optional) fileName attribute specifies which file to take (relative to
+       dependency-cruiser's current working directory). When not provided
+       defaults to './tsconfig.json'.
+     */
+    tsConfig: {
+      fileName: 'tsconfig.json'
+    },
+
+    /* Webpack configuration to use to get resolve options from.
+
+       The (optional) fileName attribute specifies which file to take (relative
+       to dependency-cruiser's current working directory. When not provided defaults
+       to './webpack.conf.js'.
+
+       The (optional) `env` and `arguments` attributes contain the parameters to be passed if
+       your webpack config is a function and takes them (see webpack documentation
+       for details)
+     */
+    // webpackConfig: {
+    //  fileName: './webpack.config.js',
+    //  env: {},
+    //  arguments: {},
+    // },
+
+    /* Babel config ('.babelrc', '.babelrc.json', '.babelrc.json5', ...) to use
+      for compilation (and whatever other naughty things babel plugins do to
+      source code). This feature is well tested and usable, but might change
+      behavior a bit over time (e.g. more precise results for used module 
+      systems) without dependency-cruiser getting a major version bump.
+     */
+    // babelConfig: {
+    //   fileName: './.babelrc'
+    // },
+
+    /* List of strings you have in use in addition to cjs/ es6 requires
+       & imports to declare module dependencies. Use this e.g. if you've
+       re-declared require, use a require-wrapper or use window.require as
+       a hack.
+    */
+    // exoticRequireStrings: [],
+    /* options to pass on to enhanced-resolve, the package dependency-cruiser
+       uses to resolve module references to disk. You can set most of these
+       options in a webpack.conf.js - this section is here for those
+       projects that don't have a separate webpack config file.
+
+       Note: settings in webpack.conf.js override the ones specified here.
+     */
+    enhancedResolveOptions: {
+      /* List of strings to consider as 'exports' fields in package.json. Use
+         ['exports'] when you use packages that use such a field and your environment
+         supports it (e.g. node ^12.19 || >=14.7 or recent versions of webpack).
+
+         If you have an `exportsFields` attribute in your webpack config, that one
+         will have precedence over the one specified here.
+      */ 
+      exportsFields: ["exports"],
+      /* List of conditions to check for in the exports field. e.g. use ['imports']
+         if you're only interested in exposed es6 modules, ['require'] for commonjs,
+         or all conditions at once `(['import', 'require', 'node', 'default']`)
+         if anything goes for you. Only works when the 'exportsFields' array is
+         non-empty.
+
+        If you have a 'conditionNames' attribute in your webpack config, that one will
+        have precedence over the one specified here.
+      */
+      conditionNames: ["import", "require", "node", "default"],
+      /*
+         The extensions, by default are the same as the ones dependency-cruiser
+         can access (run `npx depcruise --info` to see which ones that are in
+         _your_ environment. If that list is larger than what you need (e.g. 
+         it contains .js, .jsx, .ts, .tsx, .cts, .mts - but you don't use 
+         TypeScript you can pass just the extensions you actually use (e.g. 
+         [".js", ".jsx"]). This can speed up the most expensive step in 
+         dependency cruising (module resolution) quite a bit.
+       */
+      // extensions: [".js", ".jsx", ".ts", ".tsx", ".d.ts"],
+      /* 
+         If your TypeScript project makes use of types specified in 'types'
+         fields in package.jsons of external dependencies, specify "types"
+         in addition to "main" in here, so enhanced-resolve (the resolver
+         dependency-cruiser uses) knows to also look there. You can also do
+         this if you're not sure, but still use TypeScript. In a future version
+         of dependency-cruiser this will likely become the default.
+       */
+      mainFields: ["main", "types"],
+    },
+    reporterOptions: {
+      dot: {
+        /* pattern of modules that can be consolidated in the detailed
+           graphical dependency graph. The default pattern in this configuration
+           collapses everything in node_modules to one folder deep so you see
+           the external modules, but not the innards your app depends upon.
+         */
+        collapsePattern: 'node_modules/(@[^/]+/[^/]+|[^/]+)',
+
+        /* Options to tweak the appearance of your graph.See
+           https://github.com/sverweij/dependency-cruiser/blob/master/doc/options-reference.md#reporteroptions
+           for details and some examples. If you don't specify a theme
+           don't worry - dependency-cruiser will fall back to the default one.
+        */
+        // theme: {
+        //   graph: {
+        //     /* use splines: "ortho" for straight lines. Be aware though
+        //       graphviz might take a long time calculating ortho(gonal)
+        //       routings.
+        //    */
+        //     splines: "true"
+        //   },
+        //   modules: [
+        //     {
+        //       criteria: { matchesFocus: true },
+        //       attributes: {
+        //         fillcolor: "lime",
+        //         penwidth: 2,
+        //       },
+        //     },
+        //     {
+        //       criteria: { matchesFocus: false },
+        //       attributes: {
+        //         fillcolor: "lightgrey",
+        //       },
+        //     },
+        //     {
+        //       criteria: { matchesReaches: true },
+        //       attributes: {
+        //         fillcolor: "lime",
+        //         penwidth: 2,
+        //       },
+        //     },
+        //     {
+        //       criteria: { matchesReaches: false },
+        //       attributes: {
+        //         fillcolor: "lightgrey",
+        //       },
+        //     },
+        //     {
+        //       criteria: { source: "^src/model" },
+        //       attributes: { fillcolor: "#ccccff" }
+        //     },
+        //     {
+        //       criteria: { source: "^src/view" },
+        //       attributes: { fillcolor: "#ccffcc" }
+        //     },
+        //   ],
+        //   dependencies: [
+        //     {
+        //       criteria: { "rules[0].severity": "error" },
+        //       attributes: { fontcolor: "red", color: "red" }
+        //     },
+        //     {
+        //       criteria: { "rules[0].severity": "warn" },
+        //       attributes: { fontcolor: "orange", color: "orange" }
+        //     },
+        //     {
+        //       criteria: { "rules[0].severity": "info" },
+        //       attributes: { fontcolor: "blue", color: "blue" }
+        //     },
+        //     {
+        //       criteria: { resolved: "^src/model" },
+        //       attributes: { color: "#0000ff77" }
+        //     },
+        //     {
+        //       criteria: { resolved: "^src/view" },
+        //       attributes: { color: "#00770077" }
+        //     }
+        //   ]
+        // }
+      },
+      archi: {
+        /* pattern of modules that can be consolidated in the high level
+          graphical dependency graph. If you use the high level graphical
+          dependency graph reporter (`archi`) you probably want to tweak
+          this collapsePattern to your situation.
+        */
+        collapsePattern: '^(packages|src|lib|app|bin|test(s?)|spec(s?))/[^/]+|node_modules/(@[^/]+/[^/]+|[^/]+)',
+
+        /* Options to tweak the appearance of your graph.See
+           https://github.com/sverweij/dependency-cruiser/blob/master/doc/options-reference.md#reporteroptions
+           for details and some examples. If you don't specify a theme
+           for 'archi' dependency-cruiser will use the one specified in the
+           dot section (see above), if any, and otherwise use the default one.
+         */
+        // theme: {
+        // },
+      },
+      "text": {
+        "highlightFocused": true
+      },
+    }
+  }
+};
+// generated: dependency-cruiser@12.12.0 on 2023-05-05T19:06:19.143Z
--- a/.hgignore	Fri May 05 21:14:49 2023 -0700
+++ b/.hgignore	Fri May 05 21:27:24 2023 -0700
@@ -7,3 +7,4 @@
 .vscode/settings.json
 types/
 dist/
+deps.svg
--- a/package.json	Fri May 05 21:14:49 2023 -0700
+++ b/package.json	Fri May 05 21:27:24 2023 -0700
@@ -1,6 +1,6 @@
 {
   "name": "@bigasterisk/streamed-graph",
-  "version": "0.0.8",
+  "version": "0.0.9",
   "license": "MIT",
   "author": {
     "name": "Drew Perttula",
@@ -17,16 +17,20 @@
   "module": "src/index.ts",
   "types": "types/index.d.ts",
   "dependencies": {
-    "@types/jsonld": "^1.5.6",
+    "@types/jsonld": "^1.5.8",
     "@types/n3": "^1.10.4",
-    "immutable": "^4.0.0",
-    "jsonld": "^2.0.2",
-    "lit": "^2.1.3",
-    "n3": "git+https://github.com/rdfjs/N3.js.git#088006449c9e8275351db604b3d184071fef31a7",
-    "rdf-js": "^4.0.2"
+    "immutable": "^4.3.0",
+    "jsonld": "^8.1.1",
+    "jsonld-streaming-parser": "^3.2.0",
+    "lit": "^2.7.2",
+    "n3": "^1.16.3",
+    "rdf-js": "^4.0.2",
+    "rdf-parse": "^2.3.2",
+    "sub-events": "^1.9.0"
   },
   "devDependencies": {
     "@types/jest": "^27.4.0",
+    "dependency-cruiser": "^12.12.0",
     "jest": "^27.5.1",
     "stylus": "^0.56.0",
     "ts-jest": "^27.1.3",
--- a/pnpm-lock.yaml	Fri May 05 21:14:49 2023 -0700
+++ b/pnpm-lock.yaml	Fri May 05 21:27:24 2023 -0700
@@ -1,35 +1,43 @@
-lockfileVersion: 5.3
+lockfileVersion: 5.4
 
 specifiers:
   '@types/jest': ^27.4.0
-  '@types/jsonld': ^1.5.6
+  '@types/jsonld': ^1.5.8
   '@types/n3': ^1.10.4
-  immutable: ^4.0.0
+  dependency-cruiser: ^12.12.0
+  immutable: ^4.3.0
   jest: ^27.5.1
-  jsonld: ^2.0.2
-  lit: ^2.1.3
-  n3: git+https://github.com/rdfjs/N3.js.git#088006449c9e8275351db604b3d184071fef31a7
+  jsonld: ^8.1.1
+  jsonld-streaming-parser: ^3.2.0
+  lit: ^2.7.2
+  n3: ^1.16.3
   rdf-js: ^4.0.2
+  rdf-parse: ^2.3.2
   stylus: ^0.56.0
+  sub-events: ^1.9.0
   ts-jest: ^27.1.3
   tslib: ^2.3.1
   typescript: ^4.5.5
   vite: ^2.8.1
 
 dependencies:
-  '@types/jsonld': 1.5.6
+  '@types/jsonld': 1.5.8
   '@types/n3': 1.10.4
-  immutable: 4.0.0
-  jsonld: 2.0.2
-  lit: 2.1.3
-  n3: github.com/rdfjs/N3.js/088006449c9e8275351db604b3d184071fef31a7
+  dependency-cruiser: 12.12.0
+  immutable: 4.3.0
+  jsonld: 8.1.1
+  jsonld-streaming-parser: 3.2.0
+  lit: 2.7.2
+  n3: 1.16.4
   rdf-js: 4.0.2
+  rdf-parse: 2.3.2
+  sub-events: 1.9.0
 
 devDependencies:
   '@types/jest': 27.4.0
   jest: 27.5.1
   stylus: 0.56.0
-  ts-jest: 27.1.3_1e2406a8ca2ae3dc934d01f9ee2aebbb
+  ts-jest: 27.1.3_dysankgkflr5ze2nah464kxlxm
   tslib: 2.3.1
   typescript: 4.5.5
   vite: 2.8.1_stylus@0.56.0
@@ -64,7 +72,7 @@
       convert-source-map: 1.8.0
       debug: 4.3.3
       gensync: 1.0.0-beta.2
-      json5: 2.2.0
+      json5: 2.2.3
       semver: 6.3.0
       source-map: 0.5.7
     transitivePeerDependencies:
@@ -218,6 +226,8 @@
     resolution: {integrity: sha512-6V0qdPUaiVHH3RtZeLIsc+6pDhbYzHR8ogA8w+f+Wc77DuXto19g2QUwveINoS34Uw+W8/hQDGJCx+i4n7xcng==}
     engines: {node: '>=6.0.0'}
     hasBin: true
+    dependencies:
+      '@babel/types': 7.16.0
     dev: true
 
   /@babel/plugin-syntax-async-generators/7.8.4_@babel+core@7.16.0:
@@ -377,6 +387,252 @@
     resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==}
     dev: true
 
+  /@bergos/jsonparse/1.4.1:
+    resolution: {integrity: sha512-vXIT0nzZGX/+yMD5bx2VhTzc92H55tPoehh1BW/FZHOndWGFddrH3MAfdx39FRc7irABirW6EQaGxIJYV6CGuA==}
+    engines: {'0': node >= 0.2.0}
+    dependencies:
+      buffer: 6.0.3
+    dev: false
+
+  /@comunica/actor-abstract-mediatyped/2.6.8:
+    resolution: {integrity: sha512-KpBcWz7MBsP+su6/Mok7Pj2H0S934BriEvBCjUhDr11TYDLTTQjl6TuyiNJFeOmJk+ppkJZy6Cj9Y8JxG3yoEA==}
+    dependencies:
+      '@comunica/core': 2.6.8
+      '@comunica/types': 2.6.8
+    dev: false
+
+  /@comunica/actor-abstract-parse/2.6.8:
+    resolution: {integrity: sha512-NetA7wLeBDdaoolv7QPX6JvEDeXJ4R4KzuV0C8ylX1/RyZTTobqW/pSAKcDxodMyw1Ah5q7pGjtvF35gf6Onuw==}
+    dependencies:
+      '@comunica/core': 2.6.8
+      readable-stream: 4.3.0
+    dev: false
+
+  /@comunica/actor-http-fetch/2.6.9:
+    resolution: {integrity: sha512-p3JPL8Ms9WjG/YMXeYnQNFFYU1rQ2BAlPcKc4FmdMuqg+fRtNu/VnGX1+Thxp/fF0CZlOy9Z9ljIt8LyIkvWKw==}
+    dependencies:
+      '@comunica/bus-http': 2.6.9
+      '@comunica/context-entries': 2.6.8
+      '@comunica/mediatortype-time': 2.6.8
+      abort-controller: 3.0.0
+      cross-fetch: 3.1.5
+    transitivePeerDependencies:
+      - encoding
+    dev: false
+
+  /@comunica/actor-http-proxy/2.6.9:
+    resolution: {integrity: sha512-lHug5vpBIlRWxWpHX9IAai+e8W/OhcmAK1NP7XH3MQ89C6Wjf9GuQrSfsi8CCfIrIj/Y/x4e3wCiC93/V33bQQ==}
+    dependencies:
+      '@comunica/bus-http': 2.6.9
+      '@comunica/context-entries': 2.6.8
+      '@comunica/mediatortype-time': 2.6.8
+      '@comunica/types': 2.6.8
+    transitivePeerDependencies:
+      - encoding
+    dev: false
+
+  /@comunica/actor-rdf-parse-html-microdata/2.6.8:
+    resolution: {integrity: sha512-lDR1kHX0bTOjlOQBxUXBy/Csch2exQg/uzn3J3VOrOEdi6PLQl2YD3Knv1j7/TLoWE6KyU5vMPVqANlERXKB/Q==}
+    dependencies:
+      '@comunica/bus-rdf-parse-html': 2.6.8
+      '@comunica/core': 2.6.8
+      microdata-rdf-streaming-parser: 2.0.1
+    dev: false
+
+  /@comunica/actor-rdf-parse-html-rdfa/2.6.8:
+    resolution: {integrity: sha512-uavBJ8NzHBMsE9xbUy8EeDEd384DyndHIh0jLgCsmLawSS75kdBp/m1iydMRoWqv12NZFkhtmPQCsC0gseXDAw==}
+    dependencies:
+      '@comunica/bus-rdf-parse-html': 2.6.8
+      '@comunica/core': 2.6.8
+      rdfa-streaming-parser: 2.0.1
+    dev: false
+
+  /@comunica/actor-rdf-parse-html-script/2.6.8:
+    resolution: {integrity: sha512-FC4fTbSya7HHLDWzMlR3gST4bhu6R0Utnv0YVeXc8OssOYpqWqSSGpSWP+kvEcJif6vedIblKuV49ixbL6yxEw==}
+    dependencies:
+      '@comunica/bus-rdf-parse': 2.6.8
+      '@comunica/bus-rdf-parse-html': 2.6.8
+      '@comunica/context-entries': 2.6.8
+      '@comunica/core': 2.6.8
+      '@comunica/types': 2.6.8
+      '@rdfjs/types': 1.1.0
+      readable-stream: 4.3.0
+      relative-to-absolute-iri: 1.0.7
+    transitivePeerDependencies:
+      - encoding
+    dev: false
+
+  /@comunica/actor-rdf-parse-html/2.6.8:
+    resolution: {integrity: sha512-LV/7Wth/Gw35fCoBul/jX9KchhGWn+K41Y+6SsEENJYStvJAANDxSuSckW9vqHoz54kx5OslbNqVCFh59PZMQQ==}
+    dependencies:
+      '@comunica/bus-rdf-parse': 2.6.8
+      '@comunica/bus-rdf-parse-html': 2.6.8
+      '@comunica/core': 2.6.8
+      '@comunica/types': 2.6.8
+      '@rdfjs/types': 1.1.0
+      htmlparser2: 8.0.2
+      readable-stream: 4.3.0
+    dev: false
+
+  /@comunica/actor-rdf-parse-jsonld/2.6.9:
+    resolution: {integrity: sha512-Xrn/btRySgMV7QmrAs/a6IMYo+ujh0Pn09TKfxLFa7xCQXozwRZI4dXnpaoCTBxc8xPZfVS3WrrmzRop2QjOoA==}
+    dependencies:
+      '@comunica/bus-http': 2.6.9
+      '@comunica/bus-rdf-parse': 2.6.8
+      '@comunica/context-entries': 2.6.8
+      '@comunica/core': 2.6.8
+      '@comunica/types': 2.6.8
+      jsonld-context-parser: 2.3.0
+      jsonld-streaming-parser: 3.2.0
+      stream-to-string: 1.2.1
+    transitivePeerDependencies:
+      - encoding
+    dev: false
+
+  /@comunica/actor-rdf-parse-n3/2.6.8:
+    resolution: {integrity: sha512-D7+bjo9qV6dJMf5IjQfWKCtoVFvUG37EPJAXIX9f950JJmcWrc6JFnYMpFGZWDQOBIAxTepBszD5QkTM54JNfw==}
+    dependencies:
+      '@comunica/bus-rdf-parse': 2.6.8
+      '@comunica/types': 2.6.8
+      n3: 1.16.4
+    dev: false
+
+  /@comunica/actor-rdf-parse-rdfxml/2.6.8:
+    resolution: {integrity: sha512-aBHIf+OGt3REgkCcf9+u8Ywo0FAj/k9VTNgrTm6K/TZEmSpzdlD+gdFnBOH9bw2yN4otYt7bkH4siaIUjTunMA==}
+    dependencies:
+      '@comunica/bus-rdf-parse': 2.6.8
+      '@comunica/types': 2.6.8
+      rdfxml-streaming-parser: 2.2.2
+    dev: false
+
+  /@comunica/actor-rdf-parse-shaclc/2.6.8:
+    resolution: {integrity: sha512-hGM3eoCqyZuwAg9SLDdJjbFo79YHgADKDP+LjJnlxtrwt3vWTy8NLcodeg7NrvlbMS5UDadtK51402VBAiumCw==}
+    dependencies:
+      '@comunica/bus-rdf-parse': 2.6.8
+      '@comunica/types': 2.6.8
+      '@rdfjs/types': 1.1.0
+      asynciterator: 3.8.0
+      readable-stream: 4.3.0
+      shaclc-parse: 1.3.0
+      stream-to-string: 1.2.1
+    dev: false
+
+  /@comunica/actor-rdf-parse-xml-rdfa/2.6.8:
+    resolution: {integrity: sha512-enBcz9aCcpdgGX97zgjo2SbTLBgHuJ/mReF2vr7ipT/+3+Sjw40Vi56+SY5SeeU5NOeNvnxAN5O31CPIc2+yUg==}
+    dependencies:
+      '@comunica/bus-rdf-parse': 2.6.8
+      '@comunica/types': 2.6.8
+      rdfa-streaming-parser: 2.0.1
+    dev: false
+
+  /@comunica/bus-http/2.6.9:
+    resolution: {integrity: sha512-ha5dpMjVuUKG4rkFg212yKq5uA8/E00fTnBMN9pZPib3NYdvDqDZve7IMicn1+3kJQLQnjQvwtJSSmDGmQl+Fg==}
+    dependencies:
+      '@comunica/core': 2.6.8
+      is-stream: 2.0.1
+      readable-stream-node-to-web: 1.0.1
+      readable-web-to-node-stream: 3.0.2
+      web-streams-ponyfill: 1.4.2
+    dev: false
+
+  /@comunica/bus-init/2.6.8:
+    resolution: {integrity: sha512-GunaovksCb5GSL3ErO0oHC30XhP0E/mZ0KxixGudFZcwhHAm9YBTujSvETztXY9n2ssCRRJbdgvncFlv2Q5hjw==}
+    dependencies:
+      '@comunica/core': 2.6.8
+      readable-stream: 4.3.0
+    dev: false
+
+  /@comunica/bus-rdf-parse-html/2.6.8:
+    resolution: {integrity: sha512-tYbPp1IS2pcxbLU4ihj2XXqP//LxccH/CvTDvvbaJ867Nr/BC2E6hhp/gIFAFOX+Qinfe7noSHqhdOrX090Z8w==}
+    dependencies:
+      '@comunica/core': 2.6.8
+      '@rdfjs/types': 1.1.0
+    dev: false
+
+  /@comunica/bus-rdf-parse/2.6.8:
+    resolution: {integrity: sha512-BONoy83F8LFoLBW3eLlcw6C3+sDYj4MG/1mU3vhK8CeNHfJ5ykd28CIjGd4IZl+/voQFXGt+JY6U6vrws9UqWg==}
+    dependencies:
+      '@comunica/actor-abstract-mediatyped': 2.6.8
+      '@comunica/actor-abstract-parse': 2.6.8
+      '@comunica/core': 2.6.8
+      '@rdfjs/types': 1.1.0
+    dev: false
+
+  /@comunica/config-query-sparql/2.6.0:
+    resolution: {integrity: sha512-Ih02KeThu1RWdiV7JfpD8u0lc3hu547EG5pDhe9igGPjU+ijNbahfJJzKrR7LcJrMTGtydEN+z2allIlBKSftA==}
+    dev: false
+
+  /@comunica/context-entries/2.6.8:
+    resolution: {integrity: sha512-FxccdYmTypcCzaC88P1WSkEMuSQHgAvrU4G7elbB4dnmdq5SzPw9VJEKFuW5FI3/XUE2trjzWxm30NVnjPjvwg==}
+    dependencies:
+      '@comunica/core': 2.6.8
+      '@comunica/types': 2.6.8
+      '@rdfjs/types': 1.1.0
+      jsonld-context-parser: 2.3.0
+      sparqlalgebrajs: 4.0.5
+    transitivePeerDependencies:
+      - encoding
+    dev: false
+
+  /@comunica/core/2.6.8:
+    resolution: {integrity: sha512-e1nlVt8xBgEvPU3YO51nz4qozDgM6nmjFkaZDLejpipVmz87mmdnDzkJhteR6EdR+8XBDXRSjuWguJAfx93pOQ==}
+    engines: {node: '>=14.0'}
+    dependencies:
+      '@comunica/types': 2.6.8
+      immutable: 4.3.0
+    dev: false
+
+  /@comunica/mediator-combine-pipeline/2.6.8:
+    resolution: {integrity: sha512-6vH2+gPrfY0esKeiURfMQncRaQNElp7WCMKXYWiJYhIJvpLdigNG90jDBbrNbPJNNE6PSmINBVEKxlO59mVA3A==}
+    dependencies:
+      '@comunica/core': 2.6.8
+      '@comunica/types': 2.6.8
+    dev: false
+
+  /@comunica/mediator-combine-union/2.6.8:
+    resolution: {integrity: sha512-XNR84eBB5CkHC+S4mcl2Htf8vgT3OGLW7BhcYgMn6eQOsFzTQcKluLJpVeQ5vC/gIcmiK5dpgN5Pqn5iGM+KZQ==}
+    dependencies:
+      '@comunica/core': 2.6.8
+    dev: false
+
+  /@comunica/mediator-number/2.6.8:
+    resolution: {integrity: sha512-0K1uagchvhSLR/yeGMCTid3M9s7YNkHh1UTWqCLAl294DoJeaVgvn6AuCo3cq0kUIdK/gnobpiqLqcuErTW6Ig==}
+    dependencies:
+      '@comunica/core': 2.6.8
+    dev: false
+
+  /@comunica/mediator-race/2.6.8:
+    resolution: {integrity: sha512-8Ck91/pNxkhRwd0DItB8Rhuw/26UTFYAmz5lV7jQt3rbG2izCMezOEl5b9uaYGN82Mb1Q85Zj/qEz+AQQAr20w==}
+    dependencies:
+      '@comunica/core': 2.6.8
+    dev: false
+
+  /@comunica/mediatortype-time/2.6.8:
+    resolution: {integrity: sha512-krBNKO2EHLBOo752Y4XhncE2SaJNQdYW6RQsjNJo5UQsWQiyAx+IsNXhVjkew3H6PI8B8vrpFO+l0L2Ik10HVA==}
+    dependencies:
+      '@comunica/core': 2.6.8
+    dev: false
+
+  /@comunica/types/2.6.8:
+    resolution: {integrity: sha512-iwMRsrvjGyWSp/R7+VYvlI9OunMvq8FmB4SOmaw48QqkmH31qgdECxR9HZ+zsFpGOVJsetoqSRYDyc6iQkEIbA==}
+    dependencies:
+      '@rdfjs/types': 1.1.0
+      '@types/yargs': 17.0.24
+      asynciterator: 3.8.0
+      sparqlalgebrajs: 4.0.5
+    dev: false
+
+  /@digitalbazaar/http-client/3.4.0:
+    resolution: {integrity: sha512-B/T3Xlo5UjPkoAqX/DQOAF2D5khgNZJZhoQ1d1b3ykYd2XnwOQ6srz1T+SsWVfjbXyLajN7j/nfKy7QiUofN+A==}
+    engines: {node: '>=14.0'}
+    dependencies:
+      ky: 0.33.3
+      ky-universal: 0.11.0_ky@0.33.3
+      undici: 5.22.0
+    transitivePeerDependencies:
+      - web-streams-polyfill
+    dev: false
+
   /@istanbuljs/load-nyc-config/1.1.0:
     resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==}
     engines: {node: '>=8'}
@@ -398,7 +654,7 @@
     engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
     dependencies:
       '@jest/types': 27.5.1
-      '@types/node': 16.11.11
+      '@types/node': 18.16.1
       chalk: 4.1.2
       jest-message-util: 27.5.1
       jest-util: 27.5.1
@@ -456,7 +712,7 @@
     dependencies:
       '@jest/fake-timers': 27.5.1
       '@jest/types': 27.5.1
-      '@types/node': 16.11.11
+      '@types/node': 18.16.1
       jest-mock: 27.5.1
     dev: true
 
@@ -466,7 +722,7 @@
     dependencies:
       '@jest/types': 27.5.1
       '@sinonjs/fake-timers': 8.1.0
-      '@types/node': 16.11.11
+      '@types/node': 18.16.1
       jest-message-util: 27.5.1
       jest-mock: 27.5.1
       jest-util: 27.5.1
@@ -495,7 +751,7 @@
       '@jest/test-result': 27.5.1
       '@jest/transform': 27.5.1
       '@jest/types': 27.5.1
-      '@types/node': 16.11.11
+      '@types/node': 18.16.1
       chalk: 4.1.2
       collect-v8-coverage: 1.0.1
       exit: 0.1.2
@@ -579,7 +835,7 @@
     dependencies:
       '@types/istanbul-lib-coverage': 2.0.3
       '@types/istanbul-reports': 3.0.1
-      '@types/node': 16.11.11
+      '@types/node': 18.16.1
       '@types/yargs': 16.0.4
       chalk: 4.1.2
     dev: true
@@ -590,13 +846,19 @@
     dependencies:
       '@types/istanbul-lib-coverage': 2.0.3
       '@types/istanbul-reports': 3.0.1
-      '@types/node': 16.11.11
+      '@types/node': 18.16.1
       '@types/yargs': 16.0.4
       chalk: 4.1.2
     dev: true
 
-  /@lit/reactive-element/1.1.1:
-    resolution: {integrity: sha512-B2JdRMwCGv+VpIRj3CYVQBx3muPDeE8y+HPgWqzrAHsO5/40BpwDFZeplIV790BaTqDVUDvZOKMSbuFM9zWC0w==}
+  /@lit-labs/ssr-dom-shim/1.1.0:
+    resolution: {integrity: sha512-92uQ5ARf7UXYrzaFcAX3T2rTvaS9Z1//ukV+DqjACM4c8s0ZBQd7ayJU5Dh2AFLD/Ayuyz4uMmxQec8q3U4Ong==}
+    dev: false
+
+  /@lit/reactive-element/1.6.1:
+    resolution: {integrity: sha512-va15kYZr7KZNNPZdxONGQzpUr+4sxVu7V/VG7a8mRfPPXUyhEYj5RzXCQmGrlP3tAh0L3HHm5AjBMFYRqlM9SA==}
+    dependencies:
+      '@lit-labs/ssr-dom-shim': 1.1.0
     dev: false
 
   /@rdfjs/types/1.0.1:
@@ -605,6 +867,12 @@
       '@types/node': 16.11.11
     dev: false
 
+  /@rdfjs/types/1.1.0:
+    resolution: {integrity: sha512-5zm8bN2/CC634dTcn/0AhTRLaQRjXDZs3QfcAsQKNturHT7XVWcKy/8p3P5gXl+YkZTAmy7T5M/LyiT/jbkENw==}
+    dependencies:
+      '@types/node': 18.16.1
+    dev: false
+
   /@sinonjs/commons/1.8.3:
     resolution: {integrity: sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==}
     dependencies:
@@ -654,8 +922,14 @@
   /@types/graceful-fs/4.1.5:
     resolution: {integrity: sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==}
     dependencies:
-      '@types/node': 16.11.11
-    dev: true
+      '@types/node': 18.16.1
+    dev: true
+
+  /@types/http-link-header/1.0.3:
+    resolution: {integrity: sha512-y8HkoD/vyid+5MrJ3aas0FvU3/BVBGcyG9kgxL0Zn4JwstA8CglFPnrR0RuzOjRCXwqzL5uxWC2IO7Ub0rMU2A==}
+    dependencies:
+      '@types/node': 18.16.1
+    dev: false
 
   /@types/istanbul-lib-coverage/2.0.3:
     resolution: {integrity: sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==}
@@ -680,8 +954,8 @@
       pretty-format: 27.4.0
     dev: true
 
-  /@types/jsonld/1.5.6:
-    resolution: {integrity: sha512-OUcfMjRie5IOrJulUQwVNvV57SOdKcTfBj3pjXNxzXqeOIrY2aGDNGW/Tlp83EQPkz4tCE6YWVrGuc/ZeaAQGg==}
+  /@types/jsonld/1.5.8:
+    resolution: {integrity: sha512-4l5t/jDnJpqZ+i7CLTTgPcT5BYXnAnwJupb07aAokPufCV0SjDHcwctUkSTuhIuSU9yHok+WOOngIGCtpL96gw==}
     dev: false
 
   /@types/n3/1.10.4:
@@ -694,10 +968,26 @@
   /@types/node/16.11.11:
     resolution: {integrity: sha512-KB0sixD67CeecHC33MYn+eYARkqTheIRNuu97y2XMjR7Wu3XibO1vaY6VBV6O/a89SPI81cEUIYT87UqUWlZNw==}
 
+  /@types/node/18.16.1:
+    resolution: {integrity: sha512-DZxSZWXxFfOlx7k7Rv4LAyiMroaxa3Ly/7OOzZO8cBNho0YzAi4qlbrx8W27JGqG57IgR/6J7r+nOJWw6kcvZA==}
+
   /@types/prettier/2.4.2:
     resolution: {integrity: sha512-ekoj4qOQYp7CvjX8ZDBgN86w3MqQhLE1hczEJbEIjgFEumDy+na/4AJAbLXfgEWFNB2pKadM5rPFtuSGMWK7xA==}
     dev: true
 
+  /@types/readable-stream/2.3.15:
+    resolution: {integrity: sha512-oM5JSKQCcICF1wvGgmecmHldZ48OZamtMxcGGVICOJA8o8cahXC1zEVAif8iwoc5j8etxFaRFnf095+CDsuoFQ==}
+    dependencies:
+      '@types/node': 18.16.1
+      safe-buffer: 5.1.2
+    dev: false
+
+  /@types/sparqljs/3.1.4:
+    resolution: {integrity: sha512-0MvCTEfveYJDkI91olLcDf/F3wMMbsxwNxiNZeglt4tbIFULd9pRpcacj1MuA+acFDkTnPXS9L7OqZNn/W1MAg==}
+    dependencies:
+      rdf-js: 4.0.2
+    dev: false
+
   /@types/stack-utils/2.0.1:
     resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==}
     dev: true
@@ -708,7 +998,6 @@
 
   /@types/yargs-parser/20.2.1:
     resolution: {integrity: sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==}
-    dev: true
 
   /@types/yargs/16.0.4:
     resolution: {integrity: sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==}
@@ -716,10 +1005,23 @@
       '@types/yargs-parser': 20.2.1
     dev: true
 
+  /@types/yargs/17.0.24:
+    resolution: {integrity: sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==}
+    dependencies:
+      '@types/yargs-parser': 20.2.1
+    dev: false
+
   /abab/2.0.5:
     resolution: {integrity: sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==}
     dev: true
 
+  /abort-controller/3.0.0:
+    resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==}
+    engines: {node: '>=6.5'}
+    dependencies:
+      event-target-shim: 5.0.1
+    dev: false
+
   /acorn-globals/6.0.0:
     resolution: {integrity: sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==}
     dependencies:
@@ -727,22 +1029,45 @@
       acorn-walk: 7.2.0
     dev: true
 
+  /acorn-jsx-walk/2.0.0:
+    resolution: {integrity: sha512-uuo6iJj4D4ygkdzd6jPtcxs8vZgDX9YFIkqczGImoypX2fQ4dVImmu3UzA4ynixCIMTrEOWW+95M2HuBaCEOVA==}
+    dev: false
+
+  /acorn-jsx/5.3.2_acorn@8.8.2:
+    resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
+    peerDependencies:
+      acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
+    dependencies:
+      acorn: 8.8.2
+    dev: false
+
+  /acorn-loose/8.3.0:
+    resolution: {integrity: sha512-75lAs9H19ldmW+fAbyqHdjgdCrz0pWGXKmnqFoh8PyVd1L2RIb4RzYrSjmopeqv3E1G3/Pimu6GgLlrGbrkF7w==}
+    engines: {node: '>=0.4.0'}
+    dependencies:
+      acorn: 8.8.2
+    dev: false
+
   /acorn-walk/7.2.0:
     resolution: {integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==}
     engines: {node: '>=0.4.0'}
     dev: true
 
+  /acorn-walk/8.2.0:
+    resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==}
+    engines: {node: '>=0.4.0'}
+    dev: false
+
   /acorn/7.4.1:
     resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==}
     engines: {node: '>=0.4.0'}
     hasBin: true
     dev: true
 
-  /acorn/8.6.0:
-    resolution: {integrity: sha512-U1riIR+lBSNi3IbxtaHOIKdH8sLFv3NYfNv8sg7ZsNhcfl4HF2++BfqqrNAxoCLQW1iiylOj76ecnaUxz+z9yw==}
+  /acorn/8.8.2:
+    resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==}
     engines: {node: '>=0.4.0'}
     hasBin: true
-    dev: true
 
   /agent-base/6.0.2:
     resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
@@ -753,12 +1078,12 @@
       - supports-color
     dev: true
 
-  /ajv/6.12.6:
-    resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
+  /ajv/8.12.0:
+    resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==}
     dependencies:
       fast-deep-equal: 3.1.3
-      fast-json-stable-stringify: 2.1.0
-      json-schema-traverse: 0.4.1
+      json-schema-traverse: 1.0.0
+      require-from-string: 2.0.2
       uri-js: 4.4.1
     dev: false
 
@@ -772,7 +1097,6 @@
   /ansi-regex/5.0.1:
     resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
     engines: {node: '>=8'}
-    dev: true
 
   /ansi-styles/3.2.1:
     resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
@@ -786,7 +1110,6 @@
     engines: {node: '>=8'}
     dependencies:
       color-convert: 2.0.1
-    dev: true
 
   /ansi-styles/5.2.0:
     resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==}
@@ -807,19 +1130,13 @@
       sprintf-js: 1.0.3
     dev: true
 
-  /asn1/0.2.6:
-    resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==}
-    dependencies:
-      safer-buffer: 2.1.2
-    dev: false
-
-  /assert-plus/1.0.0:
-    resolution: {integrity: sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=}
-    engines: {node: '>=0.8'}
+  /asynciterator/3.8.0:
+    resolution: {integrity: sha512-bD34LqKHJnkB77MHjL3hOAUOcy9dbB+3lHvL+EiJpD3k2Nyq3i1dCk5adMisB2rwlrHVu/+XRhOdPZL9hzpsfw==}
     dev: false
 
   /asynckit/0.4.0:
     resolution: {integrity: sha1-x57Zf380y48robyXkLzDZkdLS3k=}
+    dev: true
 
   /atob/2.1.2:
     resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==}
@@ -827,14 +1144,6 @@
     hasBin: true
     dev: true
 
-  /aws-sign2/0.7.0:
-    resolution: {integrity: sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=}
-    dev: false
-
-  /aws4/1.11.0:
-    resolution: {integrity: sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==}
-    dev: false
-
   /babel-jest/27.5.1_@babel+core@7.16.0:
     resolution: {integrity: sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==}
     engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
@@ -910,12 +1219,9 @@
 
   /balanced-match/1.0.2:
     resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
-    dev: true
-
-  /bcrypt-pbkdf/1.0.2:
-    resolution: {integrity: sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=}
-    dependencies:
-      tweetnacl: 0.14.5
+
+  /base64-js/1.5.1:
+    resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
     dev: false
 
   /brace-expansion/1.1.11:
@@ -923,7 +1229,6 @@
     dependencies:
       balanced-match: 1.0.2
       concat-map: 0.0.1
-    dev: true
 
   /braces/3.0.2:
     resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
@@ -965,6 +1270,20 @@
     resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
     dev: true
 
+  /buffer/6.0.3:
+    resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==}
+    dependencies:
+      base64-js: 1.5.1
+      ieee754: 1.2.1
+    dev: false
+
+  /busboy/1.6.0:
+    resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==}
+    engines: {node: '>=10.16.0'}
+    dependencies:
+      streamsearch: 1.1.0
+    dev: false
+
   /callsites/3.1.0:
     resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
     engines: {node: '>=6'}
@@ -988,10 +1307,6 @@
     resolution: {integrity: sha512-0CNTVCLZggSh7bc5VkX5WWPWO+cyZbNd07IHIsSXLia/eAq+r836hgk+8BKoEh7949Mda87VUOitx5OddVj64A==}
     dev: false
 
-  /caseless/0.12.0:
-    resolution: {integrity: sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=}
-    dev: false
-
   /chalk/2.4.2:
     resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
     engines: {node: '>=4'}
@@ -1007,7 +1322,6 @@
     dependencies:
       ansi-styles: 4.3.0
       supports-color: 7.2.0
-    dev: true
 
   /char-regex/1.0.2:
     resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==}
@@ -1050,25 +1364,28 @@
     engines: {node: '>=7.0.0'}
     dependencies:
       color-name: 1.1.4
-    dev: true
 
   /color-name/1.1.3:
-    resolution: {integrity: sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=}
+    resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==}
     dev: true
 
   /color-name/1.1.4:
     resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
-    dev: true
 
   /combined-stream/1.0.8:
     resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
     engines: {node: '>= 0.8'}
     dependencies:
       delayed-stream: 1.0.0
+    dev: true
+
+  /commander/10.0.1:
+    resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==}
+    engines: {node: '>=14'}
+    dev: false
 
   /concat-map/0.0.1:
-    resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=}
-    dev: true
+    resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
 
   /convert-source-map/1.8.0:
     resolution: {integrity: sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==}
@@ -1076,8 +1393,12 @@
       safe-buffer: 5.1.2
     dev: true
 
-  /core-util-is/1.0.2:
-    resolution: {integrity: sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=}
+  /cross-fetch/3.1.5:
+    resolution: {integrity: sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==}
+    dependencies:
+      node-fetch: 2.6.7
+    transitivePeerDependencies:
+      - encoding
     dev: false
 
   /cross-spawn/7.0.3:
@@ -1112,11 +1433,9 @@
       cssom: 0.3.8
     dev: true
 
-  /dashdash/1.14.1:
-    resolution: {integrity: sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=}
-    engines: {node: '>=0.10'}
-    dependencies:
-      assert-plus: 1.0.0
+  /data-uri-to-buffer/4.0.1:
+    resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==}
+    engines: {node: '>= 12'}
     dev: false
 
   /data-urls/2.0.0:
@@ -1165,6 +1484,42 @@
   /delayed-stream/1.0.0:
     resolution: {integrity: sha1-3zrhmayt+31ECqrgsp4icrJOxhk=}
     engines: {node: '>=0.4.0'}
+    dev: true
+
+  /dependency-cruiser/12.12.0:
+    resolution: {integrity: sha512-3DB6m6bVVR50o8CZWa4yBklm2SxfDi5gHPlDmS9v4Vdng2uJxPFezM2yH9PlsJ6GlQ7tpOiiYp/gOXUr/R+KGQ==}
+    engines: {node: ^14||^16||>=18}
+    hasBin: true
+    dependencies:
+      acorn: 8.8.2
+      acorn-jsx: 5.3.2_acorn@8.8.2
+      acorn-jsx-walk: 2.0.0
+      acorn-loose: 8.3.0
+      acorn-walk: 8.2.0
+      ajv: 8.12.0
+      chalk: 4.1.2
+      commander: 10.0.1
+      enhanced-resolve: 5.13.0
+      figures: 3.2.0
+      get-stream: 6.0.1
+      glob: 7.2.0
+      handlebars: 4.7.7
+      ignore: 5.2.4
+      indent-string: 4.0.0
+      interpret: 3.1.1
+      is-installed-globally: 0.4.0
+      json5: 2.2.3
+      lodash: 4.17.21
+      prompts: 2.4.2
+      rechoir: 0.8.0
+      safe-regex: 2.1.1
+      semver: 7.5.0
+      semver-try-require: 6.2.2
+      teamcity-service-messages: 0.1.14
+      tsconfig-paths-webpack-plugin: 4.0.1
+      watskeburt: 0.11.1
+      wrap-ansi: 7.0.0
+    dev: false
 
   /detect-newline/3.1.0:
     resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==}
@@ -1181,6 +1536,18 @@
     engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
     dev: true
 
+  /dom-serializer/2.0.0:
+    resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
+    dependencies:
+      domelementtype: 2.3.0
+      domhandler: 5.0.3
+      entities: 4.5.0
+    dev: false
+
+  /domelementtype/2.3.0:
+    resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==}
+    dev: false
+
   /domexception/2.0.1:
     resolution: {integrity: sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==}
     engines: {node: '>=8'}
@@ -1188,11 +1555,19 @@
       webidl-conversions: 5.0.0
     dev: true
 
-  /ecc-jsbn/0.1.2:
-    resolution: {integrity: sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=}
-    dependencies:
-      jsbn: 0.1.1
-      safer-buffer: 2.1.2
+  /domhandler/5.0.3:
+    resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
+    engines: {node: '>= 4'}
+    dependencies:
+      domelementtype: 2.3.0
+    dev: false
+
+  /domutils/3.0.1:
+    resolution: {integrity: sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==}
+    dependencies:
+      dom-serializer: 2.0.0
+      domelementtype: 2.3.0
+      domhandler: 5.0.3
     dev: false
 
   /electron-to-chromium/1.4.5:
@@ -1206,7 +1581,19 @@
 
   /emoji-regex/8.0.0:
     resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
-    dev: true
+
+  /enhanced-resolve/5.13.0:
+    resolution: {integrity: sha512-eyV8f0y1+bzyfh8xAwW/WTSZpLbjhqc4ne9eGSH4Zo2ejdyiNG9pU6mf9DG8a7+Auk6MFTlNOT4Y2y/9k8GKVg==}
+    engines: {node: '>=10.13.0'}
+    dependencies:
+      graceful-fs: 4.2.9
+      tapable: 2.2.1
+    dev: false
+
+  /entities/4.5.0:
+    resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
+    engines: {node: '>=0.12'}
+    dev: false
 
   /error-ex/1.3.2:
     resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==}
@@ -1418,9 +1805,8 @@
     dev: true
 
   /escape-string-regexp/1.0.5:
-    resolution: {integrity: sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=}
+    resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
     engines: {node: '>=0.8.0'}
-    dev: true
 
   /escape-string-regexp/2.0.0:
     resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==}
@@ -1456,6 +1842,16 @@
     engines: {node: '>=0.10.0'}
     dev: true
 
+  /event-target-shim/5.0.1:
+    resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==}
+    engines: {node: '>=6'}
+    dev: false
+
+  /events/3.3.0:
+    resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==}
+    engines: {node: '>=0.8.x'}
+    dev: false
+
   /execa/5.1.1:
     resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
     engines: {node: '>=10'}
@@ -1486,21 +1882,13 @@
       jest-message-util: 27.5.1
     dev: true
 
-  /extend/3.0.2:
-    resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==}
-    dev: false
-
-  /extsprintf/1.3.0:
-    resolution: {integrity: sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=}
-    engines: {'0': node >=0.6.0}
-    dev: false
-
   /fast-deep-equal/3.1.3:
     resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
     dev: false
 
   /fast-json-stable-stringify/2.1.0:
     resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
+    dev: true
 
   /fast-levenshtein/2.0.6:
     resolution: {integrity: sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=}
@@ -1512,6 +1900,21 @@
       bser: 2.1.1
     dev: true
 
+  /fetch-blob/3.2.0:
+    resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==}
+    engines: {node: ^12.20 || >= 14.13}
+    dependencies:
+      node-domexception: 1.0.0
+      web-streams-polyfill: 3.2.1
+    dev: false
+
+  /figures/3.2.0:
+    resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==}
+    engines: {node: '>=8'}
+    dependencies:
+      escape-string-regexp: 1.0.5
+    dev: false
+
   /fill-range/7.0.1:
     resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
     engines: {node: '>=8'}
@@ -1527,19 +1930,6 @@
       path-exists: 4.0.0
     dev: true
 
-  /forever-agent/0.6.1:
-    resolution: {integrity: sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=}
-    dev: false
-
-  /form-data/2.3.3:
-    resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==}
-    engines: {node: '>= 0.12'}
-    dependencies:
-      asynckit: 0.4.0
-      combined-stream: 1.0.8
-      mime-types: 2.1.34
-    dev: false
-
   /form-data/3.0.1:
     resolution: {integrity: sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==}
     engines: {node: '>= 6'}
@@ -1549,9 +1939,15 @@
       mime-types: 2.1.34
     dev: true
 
+  /formdata-polyfill/4.0.10:
+    resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==}
+    engines: {node: '>=12.20.0'}
+    dependencies:
+      fetch-blob: 3.2.0
+    dev: false
+
   /fs.realpath/1.0.0:
-    resolution: {integrity: sha1-FQStJSMVjKpA20onh8sBQRmU6k8=}
-    dev: true
+    resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
 
   /fsevents/2.3.2:
     resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
@@ -1563,7 +1959,6 @@
 
   /function-bind/1.1.1:
     resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==}
-    dev: true
 
   /gensync/1.0.0-beta.2:
     resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
@@ -1583,13 +1978,6 @@
   /get-stream/6.0.1:
     resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==}
     engines: {node: '>=10'}
-    dev: true
-
-  /getpass/0.1.7:
-    resolution: {integrity: sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=}
-    dependencies:
-      assert-plus: 1.0.0
-    dev: false
 
   /glob/7.2.0:
     resolution: {integrity: sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==}
@@ -1600,51 +1988,56 @@
       minimatch: 3.0.4
       once: 1.4.0
       path-is-absolute: 1.0.1
-    dev: true
+
+  /global-dirs/3.0.1:
+    resolution: {integrity: sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==}
+    engines: {node: '>=10'}
+    dependencies:
+      ini: 2.0.0
+    dev: false
 
   /globals/11.12.0:
     resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
     engines: {node: '>=4'}
     dev: true
 
-  /graceful-fs/4.2.8:
-    resolution: {integrity: sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==}
-    dev: true
-
   /graceful-fs/4.2.9:
     resolution: {integrity: sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==}
-    dev: true
-
-  /har-schema/2.0.0:
-    resolution: {integrity: sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=}
-    engines: {node: '>=4'}
-    dev: false
-
-  /har-validator/5.1.5:
-    resolution: {integrity: sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==}
-    engines: {node: '>=6'}
-    deprecated: this library is no longer supported
-    dependencies:
-      ajv: 6.12.6
-      har-schema: 2.0.0
+
+  /handlebars/4.7.7:
+    resolution: {integrity: sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==}
+    engines: {node: '>=0.4.7'}
+    hasBin: true
+    dependencies:
+      minimist: 1.2.8
+      neo-async: 2.6.2
+      source-map: 0.6.1
+      wordwrap: 1.0.0
+    optionalDependencies:
+      uglify-js: 3.17.4
     dev: false
 
   /has-flag/3.0.0:
-    resolution: {integrity: sha1-tdRU3CGZriJWmfNGfloH87lVuv0=}
+    resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
     engines: {node: '>=4'}
     dev: true
 
   /has-flag/4.0.0:
     resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
     engines: {node: '>=8'}
-    dev: true
 
   /has/1.0.3:
     resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
     engines: {node: '>= 0.4.0'}
     dependencies:
       function-bind: 1.1.1
-    dev: true
+
+  /hash.js/1.1.7:
+    resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==}
+    dependencies:
+      inherits: 2.0.4
+      minimalistic-assert: 1.0.1
+    dev: false
 
   /html-encoding-sniffer/2.0.1:
     resolution: {integrity: sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==}
@@ -1657,6 +2050,20 @@
     resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==}
     dev: true
 
+  /htmlparser2/8.0.2:
+    resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==}
+    dependencies:
+      domelementtype: 2.3.0
+      domhandler: 5.0.3
+      domutils: 3.0.1
+      entities: 4.5.0
+    dev: false
+
+  /http-link-header/1.1.1:
+    resolution: {integrity: sha512-mW3N/rTYpCn99s1do0zx6nzFZSwLH9HGfUM4ZqLWJ16ylmYaC2v5eYGqrNTQlByx8AzUgGI+V/32gXPugs1+Sw==}
+    engines: {node: '>=6.0.0'}
+    dev: false
+
   /http-proxy-agent/4.0.1:
     resolution: {integrity: sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==}
     engines: {node: '>= 6'}
@@ -1668,15 +2075,6 @@
       - supports-color
     dev: true
 
-  /http-signature/1.2.0:
-    resolution: {integrity: sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=}
-    engines: {node: '>=0.8', npm: '>=1.3.7'}
-    dependencies:
-      assert-plus: 1.0.0
-      jsprim: 1.4.2
-      sshpk: 1.17.0
-    dev: false
-
   /https-proxy-agent/5.0.0:
     resolution: {integrity: sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==}
     engines: {node: '>= 6'}
@@ -1699,8 +2097,17 @@
       safer-buffer: 2.1.2
     dev: true
 
-  /immutable/4.0.0:
-    resolution: {integrity: sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==}
+  /ieee754/1.2.1:
+    resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
+    dev: false
+
+  /ignore/5.2.4:
+    resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==}
+    engines: {node: '>= 4'}
+    dev: false
+
+  /immutable/4.3.0:
+    resolution: {integrity: sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg==}
     dev: false
 
   /import-local/3.0.3:
@@ -1717,47 +2124,66 @@
     engines: {node: '>=0.8.19'}
     dev: true
 
+  /indent-string/4.0.0:
+    resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==}
+    engines: {node: '>=8'}
+    dev: false
+
   /inflight/1.0.6:
-    resolution: {integrity: sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=}
+    resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
     dependencies:
       once: 1.4.0
       wrappy: 1.0.2
-    dev: true
 
   /inherits/2.0.4:
     resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
 
+  /ini/2.0.0:
+    resolution: {integrity: sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==}
+    engines: {node: '>=10'}
+    dev: false
+
+  /interpret/3.1.1:
+    resolution: {integrity: sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==}
+    engines: {node: '>=10.13.0'}
+    dev: false
+
   /is-arrayish/0.2.1:
     resolution: {integrity: sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=}
     dev: true
 
-  /is-core-module/2.8.0:
-    resolution: {integrity: sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==}
-    dependencies:
-      has: 1.0.3
-    dev: true
-
   /is-core-module/2.8.1:
     resolution: {integrity: sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==}
     dependencies:
       has: 1.0.3
-    dev: true
 
   /is-fullwidth-code-point/3.0.0:
     resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
     engines: {node: '>=8'}
-    dev: true
 
   /is-generator-fn/2.1.0:
     resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==}
     engines: {node: '>=6'}
     dev: true
 
+  /is-installed-globally/0.4.0:
+    resolution: {integrity: sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==}
+    engines: {node: '>=10'}
+    dependencies:
+      global-dirs: 3.0.1
+      is-path-inside: 3.0.3
+    dev: false
+
   /is-number/7.0.0:
     resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
     engines: {node: '>=0.12.0'}
     dev: true
 
+  /is-path-inside/3.0.3:
+    resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==}
+    engines: {node: '>=8'}
+    dev: false
+
   /is-potential-custom-element-name/1.0.1:
     resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
     dev: true
@@ -1765,19 +2191,15 @@
   /is-stream/2.0.1:
     resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
     engines: {node: '>=8'}
-    dev: true
 
   /is-typedarray/1.0.0:
     resolution: {integrity: sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=}
+    dev: true
 
   /isexe/2.0.0:
     resolution: {integrity: sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=}
     dev: true
 
-  /isstream/0.1.2:
-    resolution: {integrity: sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=}
-    dev: false
-
   /istanbul-lib-coverage/3.2.0:
     resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==}
     engines: {node: '>=8'}
@@ -1840,7 +2262,7 @@
       '@jest/environment': 27.5.1
       '@jest/test-result': 27.5.1
       '@jest/types': 27.5.1
-      '@types/node': 16.11.11
+      '@types/node': 18.16.1
       chalk: 4.1.2
       co: 4.6.0
       dedent: 0.7.0
@@ -1975,7 +2397,7 @@
       '@jest/environment': 27.5.1
       '@jest/fake-timers': 27.5.1
       '@jest/types': 27.5.1
-      '@types/node': 16.11.11
+      '@types/node': 18.16.1
       jest-mock: 27.5.1
       jest-util: 27.5.1
       jsdom: 16.7.0
@@ -1993,7 +2415,7 @@
       '@jest/environment': 27.5.1
       '@jest/fake-timers': 27.5.1
       '@jest/types': 27.5.1
-      '@types/node': 16.11.11
+      '@types/node': 18.16.1
       jest-mock: 27.5.1
       jest-util: 27.5.1
     dev: true
@@ -2014,7 +2436,7 @@
     dependencies:
       '@jest/types': 27.5.1
       '@types/graceful-fs': 4.1.5
-      '@types/node': 16.11.11
+      '@types/node': 18.16.1
       anymatch: 3.1.2
       fb-watchman: 2.0.1
       graceful-fs: 4.2.9
@@ -2036,7 +2458,7 @@
       '@jest/source-map': 27.5.1
       '@jest/test-result': 27.5.1
       '@jest/types': 27.5.1
-      '@types/node': 16.11.11
+      '@types/node': 18.16.1
       chalk: 4.1.2
       co: 4.6.0
       expect: 27.5.1
@@ -2091,7 +2513,7 @@
     engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
     dependencies:
       '@jest/types': 27.5.1
-      '@types/node': 16.11.11
+      '@types/node': 18.16.1
     dev: true
 
   /jest-pnp-resolver/1.2.2_jest-resolve@27.5.1:
@@ -2133,7 +2555,7 @@
       jest-pnp-resolver: 1.2.2_jest-resolve@27.5.1
       jest-util: 27.5.1
       jest-validate: 27.5.1
-      resolve: 1.20.0
+      resolve: 1.22.0
       resolve.exports: 1.1.0
       slash: 3.0.0
     dev: true
@@ -2147,7 +2569,7 @@
       '@jest/test-result': 27.5.1
       '@jest/transform': 27.5.1
       '@jest/types': 27.5.1
-      '@types/node': 16.11.11
+      '@types/node': 18.16.1
       chalk: 4.1.2
       emittery: 0.8.1
       graceful-fs: 4.2.9
@@ -2204,7 +2626,7 @@
     resolution: {integrity: sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==}
     engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
     dependencies:
-      '@types/node': 16.11.11
+      '@types/node': 18.16.1
       graceful-fs: 4.2.9
     dev: true
 
@@ -2233,7 +2655,7 @@
       jest-util: 27.5.1
       natural-compare: 1.4.0
       pretty-format: 27.5.1
-      semver: 7.3.5
+      semver: 7.5.0
     transitivePeerDependencies:
       - supports-color
     dev: true
@@ -2246,7 +2668,7 @@
       '@types/node': 16.11.11
       chalk: 4.1.2
       ci-info: 3.3.0
-      graceful-fs: 4.2.8
+      graceful-fs: 4.2.9
       picomatch: 2.3.0
     dev: true
 
@@ -2255,7 +2677,7 @@
     engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
     dependencies:
       '@jest/types': 27.5.1
-      '@types/node': 16.11.11
+      '@types/node': 18.16.1
       chalk: 4.1.2
       ci-info: 3.3.0
       graceful-fs: 4.2.9
@@ -2280,7 +2702,7 @@
     dependencies:
       '@jest/test-result': 27.5.1
       '@jest/types': 27.5.1
-      '@types/node': 16.11.11
+      '@types/node': 18.16.1
       ansi-escapes: 4.3.2
       chalk: 4.1.2
       jest-util: 27.5.1
@@ -2291,7 +2713,7 @@
     resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==}
     engines: {node: '>= 10.13.0'}
     dependencies:
-      '@types/node': 16.11.11
+      '@types/node': 18.16.1
       merge-stream: 2.0.0
       supports-color: 8.1.1
     dev: true
@@ -2329,10 +2751,6 @@
       esprima: 4.0.1
     dev: true
 
-  /jsbn/0.1.1:
-    resolution: {integrity: sha1-peZUwuWi3rXyAdls77yoDA7y9RM=}
-    dev: false
-
   /jsdom/16.7.0:
     resolution: {integrity: sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==}
     engines: {node: '>=10'}
@@ -2343,7 +2761,7 @@
         optional: true
     dependencies:
       abab: 2.0.5
-      acorn: 8.6.0
+      acorn: 8.8.2
       acorn-globals: 6.0.0
       cssom: 0.4.4
       cssstyle: 2.3.0
@@ -2385,16 +2803,8 @@
     resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==}
     dev: true
 
-  /json-schema-traverse/0.4.1:
-    resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
-    dev: false
-
-  /json-schema/0.4.0:
-    resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==}
-    dev: false
-
-  /json-stringify-safe/5.0.1:
-    resolution: {integrity: sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=}
+  /json-schema-traverse/1.0.0:
+    resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
     dev: false
 
   /json5/2.2.0:
@@ -2402,35 +2812,80 @@
     engines: {node: '>=6'}
     hasBin: true
     dependencies:
-      minimist: 1.2.5
-    dev: true
-
-  /jsonld/2.0.2:
-    resolution: {integrity: sha512-/TQzRe75/3h2khu57IUojha5oat+M82bm8RYw0jLhlmmPrW/kTWAZ9nGzKPfZWnPYnVVJJMQVc/pU8HCmpv9xg==}
+      minimist: 1.2.8
+    dev: true
+
+  /json5/2.2.3:
+    resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
     engines: {node: '>=6'}
-    dependencies:
+    hasBin: true
+
+  /jsonld-context-parser/2.3.0:
+    resolution: {integrity: sha512-c6w2GE57O26eWFjcPX6k6G86ootsIfpuVwhZKjCll0bVoDGBxr1P4OuU+yvgfnh1GJhAGErolfC7W1BklLjWMg==}
+    hasBin: true
+    dependencies:
+      '@types/http-link-header': 1.0.3
+      '@types/node': 18.16.1
       canonicalize: 1.0.8
-      lru-cache: 5.1.1
-      rdf-canonize: 1.2.0
-      request: 2.88.2
-      semver: 6.3.0
-      xmldom: 0.1.19
+      cross-fetch: 3.1.5
+      http-link-header: 1.1.1
+      relative-to-absolute-iri: 1.0.7
+    transitivePeerDependencies:
+      - encoding
     dev: false
 
-  /jsprim/1.4.2:
-    resolution: {integrity: sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==}
-    engines: {node: '>=0.6.0'}
-    dependencies:
-      assert-plus: 1.0.0
-      extsprintf: 1.3.0
-      json-schema: 0.4.0
-      verror: 1.10.0
+  /jsonld-streaming-parser/3.2.0:
+    resolution: {integrity: sha512-lJR1SCT364PGpFrOQaY+ZQ7qDWqqiT3IMK+AvZ83fo0LvltFn8/UyXvIFc3RO7YcaEjLahAF0otCi8vOq21NtQ==}
+    dependencies:
+      '@bergos/jsonparse': 1.4.1
+      '@rdfjs/types': 1.1.0
+      '@types/http-link-header': 1.0.3
+      '@types/readable-stream': 2.3.15
+      buffer: 6.0.3
+      canonicalize: 1.0.8
+      http-link-header: 1.1.1
+      jsonld-context-parser: 2.3.0
+      rdf-data-factory: 1.1.1
+      readable-stream: 4.3.0
+    transitivePeerDependencies:
+      - encoding
+    dev: false
+
+  /jsonld/8.1.1:
+    resolution: {integrity: sha512-TbtV1hlnoDYxbscazbxcS7seDGV+pc0yktxpMySh0OBFvnLw/TIth0jiQtP/9r+ywuCbtj10XjDNBIkRgiyeUg==}
+    engines: {node: '>=14'}
+    dependencies:
+      '@digitalbazaar/http-client': 3.4.0
+      canonicalize: 1.0.8
+      lru-cache: 6.0.0
+      rdf-canonize: 3.3.0
+    transitivePeerDependencies:
+      - web-streams-polyfill
     dev: false
 
   /kleur/3.0.3:
     resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==}
     engines: {node: '>=6'}
-    dev: true
+
+  /ky-universal/0.11.0_ky@0.33.3:
+    resolution: {integrity: sha512-65KyweaWvk+uKKkCrfAf+xqN2/epw1IJDtlyCPxYffFCMR8u1sp2U65NtWpnozYfZxQ6IUzIlvUcw+hQ82U2Xw==}
+    engines: {node: '>=14.16'}
+    peerDependencies:
+      ky: '>=0.31.4'
+      web-streams-polyfill: '>=3.2.1'
+    peerDependenciesMeta:
+      web-streams-polyfill:
+        optional: true
+    dependencies:
+      abort-controller: 3.0.0
+      ky: 0.33.3
+      node-fetch: 3.3.1
+    dev: false
+
+  /ky/0.33.3:
+    resolution: {integrity: sha512-CasD9OCEQSFIam2U8efFK81Yeg8vNMTBUqtMOHlrcWQHqUX3HeCl9Dr31u4toV7emlH8Mymk5+9p0lL6mKb/Xw==}
+    engines: {node: '>=14.16'}
+    dev: false
 
   /leven/3.1.0:
     resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==}
@@ -2449,25 +2904,26 @@
     resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
     dev: true
 
-  /lit-element/3.1.1:
-    resolution: {integrity: sha512-14ClnMAU8EXnzC+M2/KDd3SFmNUn1QUw1+GxWkEMwGV3iaH8ObunMlO5svzvaWlkSV0WlxJCi40NGnDVJ2XZKQ==}
-    dependencies:
-      '@lit/reactive-element': 1.1.1
-      lit-html: 2.1.1
+  /lit-element/3.3.1:
+    resolution: {integrity: sha512-Gl+2409uXWbf7n6cCl7Kzasm7zjT9xmdwi2BhLNi70sRKAgRkqueDu5mSIH3hPYMM0/vqBCdPXod3NbGkRA2ww==}
+    dependencies:
+      '@lit-labs/ssr-dom-shim': 1.1.0
+      '@lit/reactive-element': 1.6.1
+      lit-html: 2.7.2
     dev: false
 
-  /lit-html/2.1.1:
-    resolution: {integrity: sha512-E4BImK6lopAYanJpvcGaAG8kQFF1ccIulPu2BRNZI7acFB6i4ujjjsnaPVFT1j/4lD9r8GKih0Y8d7/LH8SeyQ==}
+  /lit-html/2.7.2:
+    resolution: {integrity: sha512-ZJCfKlA2XELu5tn7XuzOziGFGvf1SeQm+ngLWoJ8bXtSkRrrR3ms6SWy+gsdxeYwySLij5xAhdd2C3EX0ftxdQ==}
     dependencies:
       '@types/trusted-types': 2.0.2
     dev: false
 
-  /lit/2.1.3:
-    resolution: {integrity: sha512-46KtKy7iDoY3wZ5VSqBlXll6J/tli5gRMPFRWi5qQ01lvIqcO+dYQwb1l1NYZjbzcHnGnCKrMb8nDv7/ZE4Y4g==}
-    dependencies:
-      '@lit/reactive-element': 1.1.1
-      lit-element: 3.1.1
-      lit-html: 2.1.1
+  /lit/2.7.2:
+    resolution: {integrity: sha512-9QnZmG5mIKPRja96cpndMclLSi0Qrz2BXD6EbqNqCKMMjOWVm/BwAeXufFk2jqFsNmY07HOzU8X+8aTSVt3yrA==}
+    dependencies:
+      '@lit/reactive-element': 1.6.1
+      lit-element: 3.3.1
+      lit-html: 2.7.2
     dev: false
 
   /locate-path/5.0.0:
@@ -2483,20 +2939,12 @@
 
   /lodash/4.17.21:
     resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
-    dev: true
-
-  /lru-cache/5.1.1:
-    resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
-    dependencies:
-      yallist: 3.1.1
-    dev: false
 
   /lru-cache/6.0.0:
     resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
     engines: {node: '>=10'}
     dependencies:
       yallist: 4.0.0
-    dev: true
 
   /make-dir/3.1.0:
     resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==}
@@ -2519,6 +2967,16 @@
     resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
     dev: true
 
+  /microdata-rdf-streaming-parser/2.0.1:
+    resolution: {integrity: sha512-oEEYP3OwPGOtoE4eIyJvX1eJXI7VkGR4gKYqpEufaRXc2ele/Tkid/KMU3Los13wGrOq6woSxLEGOYSHzpRvwA==}
+    dependencies:
+      '@rdfjs/types': 1.1.0
+      htmlparser2: 8.0.2
+      rdf-data-factory: 1.1.1
+      readable-stream: 4.3.0
+      relative-to-absolute-iri: 1.0.7
+    dev: false
+
   /micromatch/4.0.4:
     resolution: {integrity: sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==}
     engines: {node: '>=8.6'}
@@ -2530,32 +2988,44 @@
   /mime-db/1.51.0:
     resolution: {integrity: sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==}
     engines: {node: '>= 0.6'}
+    dev: true
 
   /mime-types/2.1.34:
     resolution: {integrity: sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==}
     engines: {node: '>= 0.6'}
     dependencies:
       mime-db: 1.51.0
+    dev: true
 
   /mimic-fn/2.1.0:
     resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
     engines: {node: '>=6'}
     dev: true
 
+  /minimalistic-assert/1.0.1:
+    resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==}
+    dev: false
+
   /minimatch/3.0.4:
     resolution: {integrity: sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==}
     dependencies:
       brace-expansion: 1.1.11
-    dev: true
-
-  /minimist/1.2.5:
-    resolution: {integrity: sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==}
-    dev: true
+
+  /minimist/1.2.8:
+    resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
 
   /ms/2.1.2:
     resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
     dev: true
 
+  /n3/1.16.4:
+    resolution: {integrity: sha512-jtC53efM5/q4BYC3qBnegn1MJDKXHH9PEd6gVDNpIicbgXS6gkANz4DdI0jt4aLvza1xSjCcni33riXWvfoEdw==}
+    engines: {node: '>=12.0'}
+    dependencies:
+      queue-microtask: 1.2.3
+      readable-stream: 4.3.0
+    dev: false
+
   /nanoid/3.2.0:
     resolution: {integrity: sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==}
     engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
@@ -2566,9 +3036,34 @@
     resolution: {integrity: sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=}
     dev: true
 
-  /node-forge/0.10.0:
-    resolution: {integrity: sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==}
-    engines: {node: '>= 6.0.0'}
+  /neo-async/2.6.2:
+    resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==}
+    dev: false
+
+  /node-domexception/1.0.0:
+    resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==}
+    engines: {node: '>=10.5.0'}
+    dev: false
+
+  /node-fetch/2.6.7:
+    resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==}
+    engines: {node: 4.x || >=6.0.0}
+    peerDependencies:
+      encoding: ^0.1.0
+    peerDependenciesMeta:
+      encoding:
+        optional: true
+    dependencies:
+      whatwg-url: 5.0.0
+    dev: false
+
+  /node-fetch/3.3.1:
+    resolution: {integrity: sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow==}
+    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+    dependencies:
+      data-uri-to-buffer: 4.0.1
+      fetch-blob: 3.2.0
+      formdata-polyfill: 4.0.10
     dev: false
 
   /node-int64/0.4.0:
@@ -2595,15 +3090,10 @@
     resolution: {integrity: sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==}
     dev: true
 
-  /oauth-sign/0.9.0:
-    resolution: {integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==}
-    dev: false
-
   /once/1.4.0:
-    resolution: {integrity: sha1-WDsap3WWHUsROsF9nFC6753Xa9E=}
+    resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
     dependencies:
       wrappy: 1.0.2
-    dev: true
 
   /onetime/5.1.2:
     resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==}
@@ -2663,9 +3153,8 @@
     dev: true
 
   /path-is-absolute/1.0.1:
-    resolution: {integrity: sha1-F0uSaHNVNP+8es5r9TpanhtcX18=}
+    resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
     engines: {node: '>=0.10.0'}
-    dev: true
 
   /path-key/3.1.1:
     resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
@@ -2674,11 +3163,6 @@
 
   /path-parse/1.0.7:
     resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
-    dev: true
-
-  /performance-now/2.1.0:
-    resolution: {integrity: sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=}
-    dev: false
 
   /picocolors/1.0.0:
     resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
@@ -2734,36 +3218,54 @@
       react-is: 17.0.2
     dev: true
 
+  /process/0.11.10:
+    resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==}
+    engines: {node: '>= 0.6.0'}
+    dev: false
+
+  /promise-polyfill/1.1.6:
+    resolution: {integrity: sha512-7rrONfyLkDEc7OJ5QBkqa4KI4EBhCd340xRuIUPGCfu13znS+vx+VDdrT9ODAJHlXm7w4lbxN3DRjyv58EuzDg==}
+    dev: false
+
   /prompts/2.4.2:
     resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==}
     engines: {node: '>= 6'}
     dependencies:
       kleur: 3.0.3
       sisteransi: 1.0.5
-    dev: true
 
   /psl/1.8.0:
     resolution: {integrity: sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==}
+    dev: true
 
   /punycode/2.1.1:
     resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==}
     engines: {node: '>=6'}
 
-  /qs/6.5.3:
-    resolution: {integrity: sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==}
-    engines: {node: '>=0.6'}
-    dev: false
-
   /queue-microtask/1.2.3:
     resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
     dev: false
 
-  /rdf-canonize/1.2.0:
-    resolution: {integrity: sha512-MQdcRDz4+82nUrEb3hNQangBDpmep15uMmnWclGi/1KS0bNVc8oHpoNI0PFLHZsvwgwRzH31bO1JAScqUAstvw==}
-    engines: {node: '>=6'}
-    dependencies:
-      node-forge: 0.10.0
-      semver: 6.3.0
+  /rdf-canonize/3.3.0:
+    resolution: {integrity: sha512-gfSNkMua/VWC1eYbSkVaL/9LQhFeOh0QULwv7Or0f+po8pMgQ1blYQFe1r9Mv2GJZXw88Cz/drnAnB9UlNnHfQ==}
+    engines: {node: '>=12'}
+    dependencies:
+      setimmediate: 1.0.5
+    dev: false
+
+  /rdf-data-factory/1.1.1:
+    resolution: {integrity: sha512-0HoLx7lbBlNd2YTmNKin0txgiYmAV56eVU823at8cG2+iD0Ia5kcRNDpzZy6I/HCtFTymHvTfdhHTzm3ak3Jpw==}
+    dependencies:
+      '@rdfjs/types': 1.1.0
+    dev: false
+
+  /rdf-isomorphic/1.3.1:
+    resolution: {integrity: sha512-6uIhsXTVp2AtO6f41PdnRV5xZsa0zVZQDTBdn0br+DZuFf5M/YD+T6m8hKDUnALI6nFL/IujTMLgEs20MlNidQ==}
+    dependencies:
+      '@rdfjs/types': 1.1.0
+      hash.js: 1.1.7
+      rdf-string: 1.6.3
+      rdf-terms: 1.9.1
     dev: false
 
   /rdf-js/4.0.2:
@@ -2772,12 +3274,85 @@
       '@rdfjs/types': 1.0.1
     dev: false
 
+  /rdf-parse/2.3.2:
+    resolution: {integrity: sha512-TOeI7FKlyr/GupfGaXZvpMLzvByOrtwt4zHLMuuy3deNGse9QyhHsspVraZam491sIgBogdchzcUqkf2WXnAsg==}
+    dependencies:
+      '@comunica/actor-http-fetch': 2.6.9
+      '@comunica/actor-http-proxy': 2.6.9
+      '@comunica/actor-rdf-parse-html': 2.6.8
+      '@comunica/actor-rdf-parse-html-microdata': 2.6.8
+      '@comunica/actor-rdf-parse-html-rdfa': 2.6.8
+      '@comunica/actor-rdf-parse-html-script': 2.6.8
+      '@comunica/actor-rdf-parse-jsonld': 2.6.9
+      '@comunica/actor-rdf-parse-n3': 2.6.8
+      '@comunica/actor-rdf-parse-rdfxml': 2.6.8
+      '@comunica/actor-rdf-parse-shaclc': 2.6.8
+      '@comunica/actor-rdf-parse-xml-rdfa': 2.6.8
+      '@comunica/bus-http': 2.6.9
+      '@comunica/bus-init': 2.6.8
+      '@comunica/bus-rdf-parse': 2.6.8
+      '@comunica/bus-rdf-parse-html': 2.6.8
+      '@comunica/config-query-sparql': 2.6.0
+      '@comunica/core': 2.6.8
+      '@comunica/mediator-combine-pipeline': 2.6.8
+      '@comunica/mediator-combine-union': 2.6.8
+      '@comunica/mediator-number': 2.6.8
+      '@comunica/mediator-race': 2.6.8
+      '@rdfjs/types': 1.0.1
+      readable-stream: 4.3.0
+      stream-to-string: 1.2.1
+    transitivePeerDependencies:
+      - encoding
+    dev: false
+
+  /rdf-string/1.6.3:
+    resolution: {integrity: sha512-HIVwQ2gOqf+ObsCLSUAGFZMIl3rh9uGcRf1KbM85UDhKqP+hy6qj7Vz8FKt3GA54RiThqK3mNcr66dm1LP0+6g==}
+    dependencies:
+      '@rdfjs/types': 1.1.0
+      rdf-data-factory: 1.1.1
+    dev: false
+
+  /rdf-terms/1.9.1:
+    resolution: {integrity: sha512-GrE8CbQSvuVEFRCywMu6VOgV1AFE6X+nFYcAhEc5pwYKI13bUvz4voiVufQiy3V8rzQKu21Sgl+dS2qcJavy7w==}
+    dependencies:
+      '@rdfjs/types': 1.1.0
+      rdf-data-factory: 1.1.1
+      rdf-string: 1.6.3
+    dev: false
+
+  /rdfa-streaming-parser/2.0.1:
+    resolution: {integrity: sha512-7Yyaj030LO7iQ38Wh/RNLVeYrVFJeyx3dpCK7C1nvX55eIN/gE4HWfbg4BYI9X7Bd+eUIUMVeiKYLmYjV6apow==}
+    dependencies:
+      '@rdfjs/types': 1.1.0
+      htmlparser2: 8.0.2
+      rdf-data-factory: 1.1.1
+      readable-stream: 4.3.0
+      relative-to-absolute-iri: 1.0.7
+    dev: false
+
+  /rdfxml-streaming-parser/2.2.2:
+    resolution: {integrity: sha512-IUYdbajjjI2dNuzoMjJyVD61jfjvYuk4WHLPNMn/gr0o96/BFsRTH8q2WIA6eYkNepCEEPlCEon21sihmIrb2g==}
+    dependencies:
+      '@rdfjs/types': 1.1.0
+      '@types/readable-stream': 2.3.15
+      buffer: 6.0.3
+      rdf-data-factory: 1.1.1
+      readable-stream: 4.3.0
+      relative-to-absolute-iri: 1.0.7
+      saxes: 6.0.0
+      validate-iri: 1.0.1
+    dev: false
+
   /react-is/17.0.2:
     resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==}
     dev: true
 
-  /readable-stream/3.6.0:
-    resolution: {integrity: sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==}
+  /readable-stream-node-to-web/1.0.1:
+    resolution: {integrity: sha512-OGzi2VKLa8H259kAx7BIwuRrXHGcxeHj4RdASSgEGBP9Q2wowdPvBc65upF4Q9O05qWgKqBw1+9PiLTtObl7uQ==}
+    dev: false
+
+  /readable-stream/3.6.2:
+    resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==}
     engines: {node: '>= 6'}
     dependencies:
       inherits: 2.0.4
@@ -2785,31 +3360,37 @@
       util-deprecate: 1.0.2
     dev: false
 
-  /request/2.88.2:
-    resolution: {integrity: sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==}
-    engines: {node: '>= 6'}
-    deprecated: request has been deprecated, see https://github.com/request/request/issues/3142
-    dependencies:
-      aws-sign2: 0.7.0
-      aws4: 1.11.0
-      caseless: 0.12.0
-      combined-stream: 1.0.8
-      extend: 3.0.2
-      forever-agent: 0.6.1
-      form-data: 2.3.3
-      har-validator: 5.1.5
-      http-signature: 1.2.0
-      is-typedarray: 1.0.0
-      isstream: 0.1.2
-      json-stringify-safe: 5.0.1
-      mime-types: 2.1.34
-      oauth-sign: 0.9.0
-      performance-now: 2.1.0
-      qs: 6.5.3
-      safe-buffer: 5.2.1
-      tough-cookie: 2.5.0
-      tunnel-agent: 0.6.0
-      uuid: 3.4.0
+  /readable-stream/4.3.0:
+    resolution: {integrity: sha512-MuEnA0lbSi7JS8XM+WNJlWZkHAAdm7gETHdFK//Q/mChGyj2akEFtdLZh32jSdkWGbRwCW9pn6g3LWDdDeZnBQ==}
+    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    dependencies:
+      abort-controller: 3.0.0
+      buffer: 6.0.3
+      events: 3.3.0
+      process: 0.11.10
+    dev: false
+
+  /readable-web-to-node-stream/3.0.2:
+    resolution: {integrity: sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==}
+    engines: {node: '>=8'}
+    dependencies:
+      readable-stream: 3.6.2
+    dev: false
+
+  /rechoir/0.8.0:
+    resolution: {integrity: sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==}
+    engines: {node: '>= 10.13.0'}
+    dependencies:
+      resolve: 1.22.0
+    dev: false
+
+  /regexp-tree/0.1.27:
+    resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==}
+    hasBin: true
+    dev: false
+
+  /relative-to-absolute-iri/1.0.7:
+    resolution: {integrity: sha512-Xjyl4HmIzg2jzK/Un2gELqbcE8Fxy85A/aLSHE6PE/3+OGsFwmKVA1vRyGaz6vLWSqLDMHA+5rjD/xbibSQN1Q==}
     dev: false
 
   /require-directory/2.1.1:
@@ -2817,6 +3398,11 @@
     engines: {node: '>=0.10.0'}
     dev: true
 
+  /require-from-string/2.0.2:
+    resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
+    engines: {node: '>=0.10.0'}
+    dev: false
+
   /resolve-cwd/3.0.0:
     resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==}
     engines: {node: '>=8'}
@@ -2834,13 +3420,6 @@
     engines: {node: '>=10'}
     dev: true
 
-  /resolve/1.20.0:
-    resolution: {integrity: sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==}
-    dependencies:
-      is-core-module: 2.8.0
-      path-parse: 1.0.7
-    dev: true
-
   /resolve/1.22.0:
     resolution: {integrity: sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==}
     hasBin: true
@@ -2848,7 +3427,6 @@
       is-core-module: 2.8.1
       path-parse: 1.0.7
       supports-preserve-symlinks-flag: 1.0.0
-    dev: true
 
   /rimraf/3.0.2:
     resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
@@ -2867,14 +3445,20 @@
 
   /safe-buffer/5.1.2:
     resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
-    dev: true
 
   /safe-buffer/5.2.1:
     resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
     dev: false
 
+  /safe-regex/2.1.1:
+    resolution: {integrity: sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==}
+    dependencies:
+      regexp-tree: 0.1.27
+    dev: false
+
   /safer-buffer/2.1.2:
     resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
+    dev: true
 
   /sax/1.2.4:
     resolution: {integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==}
@@ -2887,9 +3471,24 @@
       xmlchars: 2.2.0
     dev: true
 
+  /saxes/6.0.0:
+    resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==}
+    engines: {node: '>=v12.22.7'}
+    dependencies:
+      xmlchars: 2.2.0
+    dev: false
+
+  /semver-try-require/6.2.2:
+    resolution: {integrity: sha512-Pyr1mG/kyBxL2+hNfU/VPRhBRdm/+EJAyWlusn7t9NDRkZEvsbwPjlocZ4ji0TD4ALPmW9ZkrzMQADjrRCDQ5w==}
+    engines: {node: ^14||^16||>=18}
+    dependencies:
+      semver: 7.5.0
+    dev: false
+
   /semver/6.3.0:
     resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==}
     hasBin: true
+    dev: true
 
   /semver/7.3.5:
     resolution: {integrity: sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==}
@@ -2899,6 +3498,24 @@
       lru-cache: 6.0.0
     dev: true
 
+  /semver/7.5.0:
+    resolution: {integrity: sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==}
+    engines: {node: '>=10'}
+    hasBin: true
+    dependencies:
+      lru-cache: 6.0.0
+
+  /setimmediate/1.0.5:
+    resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==}
+    dev: false
+
+  /shaclc-parse/1.3.0:
+    resolution: {integrity: sha512-DOaN9xEMFVRhqmMHhGH5g68/0h93fuJu9oERNgQxDDSYkHVo9SCduVldqHhKFpqUgxwWEoDh1BpN6aHXVU2u1A==}
+    dependencies:
+      '@rdfjs/types': 1.1.0
+      n3: 1.16.4
+    dev: false
+
   /shebang-command/2.0.0:
     resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
     engines: {node: '>=8'}
@@ -2917,7 +3534,6 @@
 
   /sisteransi/1.0.5:
     resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
-    dev: true
 
   /slash/3.0.0:
     resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
@@ -2944,40 +3560,45 @@
     dev: true
 
   /source-map/0.5.7:
-    resolution: {integrity: sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=}
+    resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==}
     engines: {node: '>=0.10.0'}
     dev: true
 
   /source-map/0.6.1:
     resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
     engines: {node: '>=0.10.0'}
-    dev: true
 
   /source-map/0.7.3:
     resolution: {integrity: sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==}
     engines: {node: '>= 8'}
     dev: true
 
+  /sparqlalgebrajs/4.0.5:
+    resolution: {integrity: sha512-upGjNvjl5QfEFTBTzp65Lt7D5zsXrVpgJw+4fYgwZdtscegMBM6s+4PNhWaGnuQ80gQyEtD+r4WE2l/yWA+r9A==}
+    hasBin: true
+    dependencies:
+      '@rdfjs/types': 1.1.0
+      '@types/sparqljs': 3.1.4
+      fast-deep-equal: 3.1.3
+      minimist: 1.2.8
+      rdf-data-factory: 1.1.1
+      rdf-isomorphic: 1.3.1
+      rdf-string: 1.6.3
+      sparqljs: 3.6.2
+    dev: false
+
+  /sparqljs/3.6.2:
+    resolution: {integrity: sha512-KQEJPaOMeeDpdYYuiFb3JEErRLL8XqX4G7sdhZyHC6Qn4+PEMUff/EjUGkwcJ6aCC0JCTIgxDpRdE3+GFXpdxw==}
+    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    hasBin: true
+    dependencies:
+      rdf-data-factory: 1.1.1
+    dev: false
+
   /sprintf-js/1.0.3:
     resolution: {integrity: sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=}
     dev: true
 
-  /sshpk/1.17.0:
-    resolution: {integrity: sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==}
-    engines: {node: '>=0.10.0'}
-    hasBin: true
-    dependencies:
-      asn1: 0.2.6
-      assert-plus: 1.0.0
-      bcrypt-pbkdf: 1.0.2
-      dashdash: 1.14.1
-      ecc-jsbn: 0.1.2
-      getpass: 0.1.7
-      jsbn: 0.1.1
-      safer-buffer: 2.1.2
-      tweetnacl: 0.14.5
-    dev: false
-
   /stack-utils/2.0.5:
     resolution: {integrity: sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==}
     engines: {node: '>=10'}
@@ -2985,6 +3606,17 @@
       escape-string-regexp: 2.0.0
     dev: true
 
+  /stream-to-string/1.2.1:
+    resolution: {integrity: sha512-WsvTDNF8UYs369Yko3pcdTducQtYpzEZeOV7cTuReyFvOoA9S/DLJ6sYK+xPafSPHhUMpaxiljKYnT6JSFztIA==}
+    dependencies:
+      promise-polyfill: 1.1.6
+    dev: false
+
+  /streamsearch/1.1.0:
+    resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==}
+    engines: {node: '>=10.0.0'}
+    dev: false
+
   /string-length/4.0.2:
     resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==}
     engines: {node: '>=10'}
@@ -3000,7 +3632,6 @@
       emoji-regex: 8.0.0
       is-fullwidth-code-point: 3.0.0
       strip-ansi: 6.0.1
-    dev: true
 
   /string_decoder/1.3.0:
     resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
@@ -3013,7 +3644,11 @@
     engines: {node: '>=8'}
     dependencies:
       ansi-regex: 5.0.1
-    dev: true
+
+  /strip-bom/3.0.0:
+    resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
+    engines: {node: '>=4'}
+    dev: false
 
   /strip-bom/4.0.0:
     resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==}
@@ -3044,6 +3679,11 @@
       - supports-color
     dev: true
 
+  /sub-events/1.9.0:
+    resolution: {integrity: sha512-dnFBayilG9Ku0k/lNs1Y7WV4kv91+ovCoeBV3uIYrY49DylvBb6z9d9ED2ctcrvX2YlReFalpCgJNtSgmrOaJg==}
+    engines: {node: '>=10.0.0'}
+    dev: false
+
   /supports-color/5.5.0:
     resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
     engines: {node: '>=4'}
@@ -3056,7 +3696,6 @@
     engines: {node: '>=8'}
     dependencies:
       has-flag: 4.0.0
-    dev: true
 
   /supports-color/8.1.1:
     resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==}
@@ -3076,12 +3715,20 @@
   /supports-preserve-symlinks-flag/1.0.0:
     resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
     engines: {node: '>= 0.4'}
-    dev: true
 
   /symbol-tree/3.2.4:
     resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
     dev: true
 
+  /tapable/2.2.1:
+    resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==}
+    engines: {node: '>=6'}
+    dev: false
+
+  /teamcity-service-messages/0.1.14:
+    resolution: {integrity: sha512-29aQwaHqm8RMX74u2o/h1KbMLP89FjNiMxD9wbF2BbWOnbM+q+d1sCEC+MqCc4QW3NJykn77OMpTFw/xTHIc0w==}
+    dev: false
+
   /terminal-link/2.1.1:
     resolution: {integrity: sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==}
     engines: {node: '>=8'}
@@ -3119,14 +3766,6 @@
       is-number: 7.0.0
     dev: true
 
-  /tough-cookie/2.5.0:
-    resolution: {integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==}
-    engines: {node: '>=0.8'}
-    dependencies:
-      psl: 1.8.0
-      punycode: 2.1.1
-    dev: false
-
   /tough-cookie/4.0.0:
     resolution: {integrity: sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==}
     engines: {node: '>=6'}
@@ -3136,6 +3775,10 @@
       universalify: 0.1.2
     dev: true
 
+  /tr46/0.0.3:
+    resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
+    dev: false
+
   /tr46/2.1.0:
     resolution: {integrity: sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==}
     engines: {node: '>=8'}
@@ -3143,7 +3786,7 @@
       punycode: 2.1.1
     dev: true
 
-  /ts-jest/27.1.3_1e2406a8ca2ae3dc934d01f9ee2aebbb:
+  /ts-jest/27.1.3_dysankgkflr5ze2nah464kxlxm:
     resolution: {integrity: sha512-6Nlura7s6uM9BVUAoqLH7JHyMXjz8gluryjpPXxr3IxZdAXnU6FhjvVLHFtfd1vsE1p8zD1OJfskkc0jhTSnkA==}
     engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
     hasBin: true
@@ -3177,20 +3820,28 @@
       yargs-parser: 20.2.9
     dev: true
 
+  /tsconfig-paths-webpack-plugin/4.0.1:
+    resolution: {integrity: sha512-m5//KzLoKmqu2MVix+dgLKq70MnFi8YL8sdzQZ6DblmCdfuq/y3OqvJd5vMndg2KEVCOeNz8Es4WVZhYInteLw==}
+    engines: {node: '>=10.13.0'}
+    dependencies:
+      chalk: 4.1.2
+      enhanced-resolve: 5.13.0
+      tsconfig-paths: 4.2.0
+    dev: false
+
+  /tsconfig-paths/4.2.0:
+    resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==}
+    engines: {node: '>=6'}
+    dependencies:
+      json5: 2.2.3
+      minimist: 1.2.8
+      strip-bom: 3.0.0
+    dev: false
+
   /tslib/2.3.1:
     resolution: {integrity: sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==}
     dev: true
 
-  /tunnel-agent/0.6.0:
-    resolution: {integrity: sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=}
-    dependencies:
-      safe-buffer: 5.2.1
-    dev: false
-
-  /tweetnacl/0.14.5:
-    resolution: {integrity: sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=}
-    dev: false
-
   /type-check/0.3.2:
     resolution: {integrity: sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=}
     engines: {node: '>= 0.8.0'}
@@ -3220,6 +3871,21 @@
     hasBin: true
     dev: true
 
+  /uglify-js/3.17.4:
+    resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==}
+    engines: {node: '>=0.8.0'}
+    hasBin: true
+    requiresBuild: true
+    dev: false
+    optional: true
+
+  /undici/5.22.0:
+    resolution: {integrity: sha512-fR9RXCc+6Dxav4P9VV/sp5w3eFiSdOjJYsbtWfd4s5L5C4ogyuVpdKIVHeW0vV1MloM65/f7W45nR9ZxwVdyiA==}
+    engines: {node: '>=14.0'}
+    dependencies:
+      busboy: 1.6.0
+    dev: false
+
   /universalify/0.1.2:
     resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==}
     engines: {node: '>= 4.0.0'}
@@ -3232,13 +3898,7 @@
     dev: false
 
   /util-deprecate/1.0.2:
-    resolution: {integrity: sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=}
-    dev: false
-
-  /uuid/3.4.0:
-    resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==}
-    deprecated: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.
-    hasBin: true
+    resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
     dev: false
 
   /v8-to-istanbul/8.1.0:
@@ -3250,13 +3910,8 @@
       source-map: 0.7.3
     dev: true
 
-  /verror/1.10.0:
-    resolution: {integrity: sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=}
-    engines: {'0': node >=0.6.0}
-    dependencies:
-      assert-plus: 1.0.0
-      core-util-is: 1.0.2
-      extsprintf: 1.3.0
+  /validate-iri/1.0.1:
+    resolution: {integrity: sha512-gLXi7351CoyVVQw8XE5sgpYawRKatxE7kj/xmCxXOZS1kMdtcqC0ILIqLuVEVnAUQSL/evOGG3eQ+8VgbdnstA==}
     dev: false
 
   /vite/2.8.1_stylus@0.56.0:
@@ -3303,6 +3958,27 @@
       makeerror: 1.0.12
     dev: true
 
+  /watskeburt/0.11.1:
+    resolution: {integrity: sha512-pRg7lw1R5kazren0jhcWSWNNfv3HE5Mzggj9MaruziQYMpxLJL1BrcwJWFSDwgOVbQrmtUZNgbbkKSv6SIyLew==}
+    engines: {node: ^14||^16||>=18}
+    hasBin: true
+    dependencies:
+      commander: 10.0.1
+    dev: false
+
+  /web-streams-polyfill/3.2.1:
+    resolution: {integrity: sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==}
+    engines: {node: '>= 8'}
+    dev: false
+
+  /web-streams-ponyfill/1.4.2:
+    resolution: {integrity: sha512-LCHW+fE2UBJ2vjhqJujqmoxh1ytEDEr0dPO3CabMdMDJPKmsaxzS90V1Ar6LtNE5VHLqxR4YMEj1i4lzMAccIA==}
+    dev: false
+
+  /webidl-conversions/3.0.1:
+    resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
+    dev: false
+
   /webidl-conversions/5.0.0:
     resolution: {integrity: sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==}
     engines: {node: '>=8'}
@@ -3323,6 +3999,13 @@
     resolution: {integrity: sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==}
     dev: true
 
+  /whatwg-url/5.0.0:
+    resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
+    dependencies:
+      tr46: 0.0.3
+      webidl-conversions: 3.0.1
+    dev: false
+
   /whatwg-url/8.7.0:
     resolution: {integrity: sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==}
     engines: {node: '>=10'}
@@ -3345,6 +4028,10 @@
     engines: {node: '>=0.10.0'}
     dev: true
 
+  /wordwrap/1.0.0:
+    resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==}
+    dev: false
+
   /wrap-ansi/7.0.0:
     resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
     engines: {node: '>=10'}
@@ -3352,11 +4039,9 @@
       ansi-styles: 4.3.0
       string-width: 4.2.3
       strip-ansi: 6.0.1
-    dev: true
 
   /wrappy/1.0.2:
-    resolution: {integrity: sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=}
-    dev: true
+    resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
 
   /write-file-atomic/3.0.3:
     resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==}
@@ -3386,26 +4071,14 @@
 
   /xmlchars/2.2.0:
     resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==}
-    dev: true
-
-  /xmldom/0.1.19:
-    resolution: {integrity: sha1-Yx/Ad3bv2EEYvyUXGzftTQdaCrw=}
-    engines: {node: '>=0.1'}
-    deprecated: Deprecated due to CVE-2021-21366 resolved in 0.5.0
-    dev: false
 
   /y18n/5.0.8:
     resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
     engines: {node: '>=10'}
     dev: true
 
-  /yallist/3.1.1:
-    resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
-    dev: false
-
   /yallist/4.0.0:
     resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
-    dev: true
 
   /yargs-parser/20.2.9:
     resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==}
@@ -3424,15 +4097,3 @@
       y18n: 5.0.8
       yargs-parser: 20.2.9
     dev: true
-
-  github.com/rdfjs/N3.js/088006449c9e8275351db604b3d184071fef31a7:
-    resolution: {tarball: https://codeload.github.com/rdfjs/N3.js/tar.gz/088006449c9e8275351db604b3d184071fef31a7}
-    name: n3
-    version: 1.13.0
-    engines: {node: '>=8.0'}
-    prepare: true
-    requiresBuild: true
-    dependencies:
-      queue-microtask: 1.2.3
-      readable-stream: 3.6.0
-    dev: false
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ConfiguredSources.ts	Fri May 05 21:27:24 2023 -0700
@@ -0,0 +1,64 @@
+import { NamedNode } from "n3";
+import { SubEvent } from "sub-events";
+import { MultiStore } from "./MultiStore";
+import { SourceGraph } from "./SourceGraph";
+import { ViewConfig } from "./layout/ViewConfig";
+
+// Connect <streamed-graph>, <sg-source>, <sg-view>, MultiStore, and ViewConfig.
+// Makes the (single) MultiStore and the (updated as needed) ViewConfig.
+
+// This is poorly named since it deals in both the <sg-source> elements that you
+// "configured" plus the set of SourceGraph objs that are actually connected to remote graphs.
+
+// sic private- this is just for documenting the interface more clearly
+interface IConfiguredSources {
+  // outputs
+  graph: MultiStore; // const- only the graph contents will change
+  viewConfig: ViewConfig;
+
+  // methods
+  newSourceGraph: (s: SourceGraph) => void;
+  lostSourceGraph: (s: SourceGraph) => void;
+  viewUriChanged: (v: NamedNode) => void;
+
+  // events
+  viewConfigChanged: SubEvent<ViewConfig>;
+}
+
+export class ConfiguredSources implements IConfiguredSources {
+  graph: MultiStore;
+  viewConfig: ViewConfig;
+
+  viewConfigChanged: SubEvent<ViewConfig> = new SubEvent();
+
+  private viewUri: NamedNode = new NamedNode("empty-view-config");
+
+  constructor() {
+    this.graph = new MultiStore();
+    this.graph.graphChanged.subscribe(() => this.viewConfigMaybeChanged());
+    this.viewConfig = new ViewConfig(this.graph, this.viewUri);
+  }
+
+  private viewConfigMaybeChanged() {
+    this.viewConfig = new ViewConfig(this.graph, this.viewUri);
+    this.viewConfigChanged.emit(this.viewConfig);
+  }
+
+  newSourceGraph(s: SourceGraph) {
+    this.graph.newStore(s);
+    this.viewConfigMaybeChanged();
+  }
+  
+  lostSourceGraph(s: SourceGraph) {
+    throw new Error("notimplemented");
+    this.viewConfigMaybeChanged();
+  }
+  
+  viewUriChanged(v: NamedNode) {
+    if (v && v == this.viewUri) {
+      return;
+    }
+    this.viewUri = v;
+    this.viewConfigMaybeChanged();
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/MultiStore.ts	Fri May 05 21:27:24 2023 -0700
@@ -0,0 +1,218 @@
+import { EventEmitter } from "events";
+import {
+  BlankNode,
+  OTerm,
+  Quad,
+  QuadPredicate,
+  Store,
+  Term,
+  extractListOptions,
+} from "n3";
+import * as RDF from "rdf-js";
+import { SubEvent } from "sub-events";
+import { Patch } from "./Patch";
+import { SourceGraph } from "./SourceGraph";
+
+// queries over multiple Store objects
+export class MultiStore implements Store {
+  // emitted when there's been a net change to the graph data
+  graphChanged: SubEvent<Patch> = new SubEvent();
+
+  // sources of statements
+  private stores: Store[] = [];
+  private tempCombinedGraph: Store;
+
+  constructor() {
+    this.tempCombinedGraph = new Store();
+  }
+
+  newStore(s: SourceGraph) {
+    this.stores.push(s.store);
+    const p = new Patch(); // todo
+    s.sourceGraphChanged.subscribe((p) => {
+      console.log("patchlife1: ");
+      this.sourceGraphDataChanged(p); // todo
+    });
+  }
+
+  lostStore(s: Store) {
+    throw new Error("notimplemented");
+  }
+
+  sourceGraphDataChanged(p: Patch) {
+    console.log("patchlife2: multistore saw a graph change", p);
+
+    this.tempCombinedGraph = new Store();
+    for (let st of this.stores) {
+      for (let q of st.getQuads(null, null, null, null)) {
+        this.tempCombinedGraph.addQuad(q);
+      }
+    }
+    console.log("patchlife3: tempgraph is rebuilt");
+    this.graphChanged.emit(p);
+  }
+
+  //
+  // Store interface follows:
+  //
+  forEach(qfn: (qfn: Quad) => void, s: OTerm, p: OTerm, o: OTerm, g: OTerm) {
+    this.tempCombinedGraph.forEach(qfn, s, p, o, g);
+  }
+  countQuads(s: OTerm, p: OTerm, o: OTerm, g: OTerm): number {
+    return this.tempCombinedGraph.countQuads(s, p, o, g);
+    // const seen: Set<Quad> = new Set();
+    // let count = 0;
+    // for (let src of this.sources.currentSourceGraphs) {
+    //   for (let q of src.store.getQuads(s, p, o, g)) {
+    //     if (!seen.has(q)) {
+    //       count++;
+    //       seen.add(q);
+    //     }
+    //   }
+    // }
+    // return count;
+  }
+
+  get size(): number {
+    return this.countQuads(null, null, null, null);
+  }
+  has(quad: Quad): boolean {
+    throw new Error("notimplemented");
+  }
+  getQuads(
+    subject: OTerm,
+    predicate: OTerm,
+    object: OTerm | OTerm[],
+    graph: OTerm
+  ): Quad[] {
+    return this.tempCombinedGraph.getQuads(subject, predicate, object, graph);
+  }
+  match(
+    subject?: Term | null,
+    predicate?: Term | null,
+    object?: Term | null,
+    graph?: Term | null
+  ): RDF.Stream<Quad> & RDF.DatasetCore<Quad, Quad> {
+    throw new Error("notimplemented");
+  }
+
+  every(
+    callback: QuadPredicate<Quad>,
+    subject: OTerm,
+    predicate: OTerm,
+    object: OTerm,
+    graph: OTerm
+  ): boolean {
+    throw new Error("notimplemented");
+  }
+  some(
+    callback: QuadPredicate<Quad>,
+    subject: OTerm,
+    predicate: OTerm,
+    object: OTerm,
+    graph: OTerm
+  ): boolean {
+    throw new Error("notimplemented");
+  }
+  getSubjects(
+    predicate: OTerm,
+    object: OTerm,
+    graph: OTerm
+  ): Array<Quad["subject"]> {
+    throw new Error("notimplemented");
+  }
+  forSubjects(
+    callback: (result: Quad["subject"]) => void,
+    predicate: OTerm,
+    object: OTerm,
+    graph: OTerm
+  ): void {
+    throw new Error("notimplemented");
+  }
+  getPredicates(
+    subject: OTerm,
+    object: OTerm,
+    graph: OTerm
+  ): Array<Quad["predicate"]> {
+    throw new Error("notimplemented");
+    return [];
+  }
+  forPredicates(
+    callback: (result: Quad["predicate"]) => void,
+    subject: OTerm,
+    object: OTerm,
+    graph: OTerm
+  ): void {
+    throw new Error("notimplemented");
+  }
+  getObjects(
+    subject: OTerm,
+    predicate: OTerm,
+    graph: OTerm
+  ): Array<Quad["object"]> {
+    return this.tempCombinedGraph.getObjects(subject, predicate, graph);
+  }
+  forObjects(
+    callback: (result: Quad["object"]) => void,
+    subject: OTerm,
+    predicate: OTerm,
+    graph: OTerm
+  ): void {
+    throw new Error("notimplemented");
+  }
+  getGraphs(
+    subject: OTerm,
+    predicate: OTerm,
+    object: OTerm
+  ): Array<Quad["graph"]> {
+    throw new Error("notimplemented");
+  }
+  forGraphs(
+    callback: (result: Quad["graph"]) => void,
+    subject: OTerm,
+    predicate: OTerm,
+    object: OTerm
+  ): void {
+    throw new Error("notimplemented");
+  }
+  extractLists(options?: extractListOptions): Record<string, RDF.Term[]> {
+    throw new Error("notimplemented");
+  }
+  [Symbol.iterator](): Iterator<Quad> {
+    throw new Error("notimplemented");
+  }
+
+  add(): this {
+    throw new Error("MultiStore is readonly");
+  }
+  addQuad() {
+    throw new Error("notimplemented");
+  }
+  addQuads(): void {
+    throw new Error("MultiStore is readonly");
+  }
+  delete(): this {
+    throw new Error("MultiStore is readonly");
+  }
+  import(): EventEmitter {
+    throw new Error("MultiStore is readonly");
+  }
+  removeQuad(): void {
+    throw new Error("MultiStore is readonly");
+  }
+  removeQuads(): void {
+    throw new Error("MultiStore is readonly");
+  }
+  remove(): EventEmitter {
+    throw new Error("MultiStore is readonly");
+  }
+  removeMatches(): EventEmitter {
+    throw new Error("MultiStore is readonly");
+  }
+  deleteGraph(): EventEmitter {
+    throw new Error("MultiStore is readonly");
+  }
+  createBlankNode(): BlankNode {
+    throw new Error("MultiStore is readonly");
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Patch.ts	Fri May 05 21:27:24 2023 -0700
@@ -0,0 +1,27 @@
+import { Quad, Store } from "n3";
+import { Stream } from "rdf-js";
+
+export class Patch {
+  delQuads: Quad[] = [];
+  addQuads: Quad[] = [];
+  toString(): string {
+    return `Patch -${this.delQuads.length} +${this.addQuads.length}`;
+  }
+  constructor() { }
+
+  // fill `addQuads` with this stream
+  public async streamImport(quadStream: Stream): Promise<void> {
+    return new Promise((resolve, reject) => {
+      quadStream.on("data", (quad) => {
+        this.addQuads.push(quad);
+      });
+      quadStream.on("error", reject);
+      quadStream.on("end", resolve);
+    });
+  }
+
+  public applyToStore(s: Store) {
+    s.removeQuads(this.delQuads);
+    s.addQuads(this.addQuads);
+  }
+}
--- a/src/README	Fri May 05 21:14:49 2023 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-layout/ -> everything that doesn't involve html
-render/ -> everything that does involve html
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/SourceGraph.ts	Fri May 05 21:27:24 2023 -0700
@@ -0,0 +1,91 @@
+import { JsonLdParser } from "jsonld-streaming-parser";
+import { Parser, Store } from "n3";
+import { SubEvent } from "sub-events";
+import { Patch } from "./Patch";
+
+// Possibly-changing graph for one source. Maintains its own dataset.
+// Read-only.
+//
+// Rename to RemoteGraph? RemoteStore? SyncedStore? PatchableGraph?
+export class SourceGraph {
+  store: Store; // const; do not rebuild
+  isCurrent: boolean = false;
+  sourceGraphChanged: SubEvent<Patch> = new SubEvent();
+  constructor(public url: string /* immutable */) {
+    this.store = new Store();
+  }
+
+  dispose() {}
+
+  // Call this first, after you've subscribed to `sourceGraphChanged`. This call may
+  // synchronously fire change events.
+  //
+  async reloadRdf() {
+    const resp = await fetch(this.url);
+    const ctype = resp.headers.get("content-type");
+    if (ctype?.startsWith("text/event-stream")) {
+      await this.reloadEventStream();
+    } else {
+      await this.reloadSimpleFile(resp);
+    }
+  }
+
+  private async reloadEventStream(): Promise<void> {
+    return new Promise((res, rej) => {
+      //  todo deal with reconnects
+      const ev = new EventSource(this.url);
+      let firstPatch = true;
+      // clear store here?
+
+      // maybe the event messages should be 'add' and 'del',
+      // for less parsing and clearer order of ops.
+      ev.addEventListener("patch", async (ev) => {
+        const patchMsg = JSON.parse(ev.data);
+
+        const p = new Patch();
+
+        const parser = new JsonLdParser();
+        parser.write(JSON.stringify(patchMsg.patch.adds));
+        parser.end();
+
+        await p.streamImport(parser);
+        this.isCurrent = true;
+
+        p.applyToStore(this.store);
+        console.log("patchlife0: eventsream store changed");
+        this.sourceGraphChanged.emit(p);
+        if (firstPatch) {
+          firstPatch = false;
+          res();
+        }
+      });
+    });
+  }
+
+  private async reloadSimpleFile(resp: Response) {
+    const bodyText = await resp.text();
+    const parser = new Parser({ format: "application/trig" });
+    await new Promise<void>((res, rej) => {
+      parser.parse(bodyText, (error, quad, prefixes) => {
+        if (error) {
+          console.log("parse ~ error:", error);
+          rej(error);
+          return;
+        }
+        if (quad) {
+          this.store.addQuad(quad); // prob want to do this as one or a small number of patches
+        } else {
+          res();
+        }
+      });
+    });
+    this.isCurrent = true;
+    // this may have to fire per addQuad call for correctness, or else we batch the adds where no readers can see them in advance.
+    console.log("patchlife0: simple file store changed");
+    this.sourceGraphChanged.emit(new Patch());
+  }
+
+  quadCount(): number {
+    return this.store.countQuads(null, null, null, null);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/elements/graph-view/GraphView.ts	Fri May 05 21:27:24 2023 -0700
@@ -0,0 +1,242 @@
+import Immutable from "immutable";
+import { LitElement, PropertyValues, TemplateResult, html } from "lit";
+import { customElement, property } from "lit/decorators.js";
+import { NamedNode, Quad, Store, Term } from "n3";
+import { MultiStore } from "../../MultiStore";
+import { Patch } from "../../Patch";
+import {
+  AlignedTable,
+  FreeStatements,
+  Layout,
+  PredRow,
+  SubjRow,
+} from "../../layout/Layout";
+import { ViewConfig } from "../../layout/ViewConfig";
+import { uniqueSortedTerms } from "../../layout/rdf_value";
+import { SuffixLabels } from "../../layout/suffixLabels";
+import { graphViewStyle, pageStyle } from "../../style";
+import { NodeDisplay } from "./NodeDisplay";
+type UriSet = Immutable.Set<NamedNode>;
+
+@customElement("graph-view")
+export class GraphView extends LitElement {
+  @property() graph: MultiStore | null = null;
+  @property() viewEl: HTMLElement | null = null;
+
+  viewConfig: ViewConfig | null = null;
+
+  nodeDisplay: NodeDisplay | null = null;
+  constructor() {
+    super();
+  }
+
+  static styles = [pageStyle, graphViewStyle];
+  update(changedProperties: PropertyValues) {
+    if (changedProperties.has("graph") && this.graph) {
+      // const viewUri = new NamedNode(this.viewEl?.getAttribute('uri'))
+      const viewUri = new NamedNode(new URL("#view", document.baseURI).href);
+      this.viewConfig = new ViewConfig(this.graph, viewUri);
+
+      // "when viewconfig is updated..."
+      setTimeout(()=>this.requestUpdate(), 1000)
+
+      this.graph.graphChanged.subscribe(this.onChange?.bind(this));
+    }
+    super.update(changedProperties);
+  }
+
+  onChange(p: Patch) {
+    this.requestUpdate();
+  }
+
+  render() {
+    if (!this.graph) {
+      return;
+    }
+    return this.makeTemplate(this.graph);
+  }
+
+  makeTemplate(graph: MultiStore): TemplateResult {
+    if (!this.viewConfig) {
+      throw new Error();
+    }
+    const layout = new Layout(this.viewConfig);
+    const lr = layout.plan(graph);
+
+    const labels = new SuffixLabels();
+    this._addLabelsForAllTerms(graph, labels);
+    labels.planDisplayForNode(this.viewConfig.viewRoot); // todo shoudltn be needed
+    this.nodeDisplay = new NodeDisplay(labels);
+    let viewTitle = html` (no view)`;
+    viewTitle = html` using view
+      <a href="${this.viewConfig.viewRoot.value}"
+        >{this.nodeDisplay.render(this.viewConfig.viewRoot)}</a
+      >`;
+    return html`
+      <section>
+        <h2>View: ${viewTitle}</h2>
+        <div>
+          <!-- todo: graphs and provenance.
+            These statements are all in the
+            <span data-bind="html: $root.createCurie(graphUri())">...</span> graph.-->
+        </div>
+        ${lr.sections.map(this._renderSection.bind(this))}
+      </section>
+    `;
+  }
+
+  _addLabelsForAllTerms(graph: Store, labels: SuffixLabels) {
+    graph.forEach(
+      (q: Quad) => {
+        if (q.subject.termType === "NamedNode") {
+          labels.planDisplayForNode(q.subject);
+        }
+        if (q.predicate.termType === "NamedNode") {
+          labels.planDisplayForNode(q.predicate);
+        }
+        if (q.object.termType === "NamedNode") {
+          labels.planDisplayForNode(q.object);
+        }
+        if (q.object.termType === "Literal" && q.object.datatype) {
+          labels.planDisplayForNode(q.object.datatype);
+        }
+      },
+      null,
+      null,
+      null,
+      null
+    );
+  }
+
+  _renderSection(section: AlignedTable | FreeStatements) {
+    if ((section as any).columnHeaders) {
+      return this._renderAlignedTable(section as AlignedTable);
+    } else {
+      return this._renderFreeStatements(section as FreeStatements);
+    }
+  }
+
+  _renderAlignedTable(section: AlignedTable): TemplateResult {
+    const nodeDisplay = this.nodeDisplay;
+    if (!nodeDisplay) throw new Error();
+    const tableTypes: NamedNode[][] = [];
+    const typeHeads: TemplateResult[] = [];
+    const heads: TemplateResult[] = [];
+    for (let ch of section.columnHeaders) {
+      const colSpan = 1; //todo
+      typeHeads.push(
+        html`<th colspan="${colSpan}">
+          ${ch.rdfTypes.map((n) => nodeDisplay.render(n))}
+        </th>`
+      );
+
+      tableTypes.push(ch.rdfTypes);
+      heads.push(html`<th>${nodeDisplay.render(ch.pred)}</th>`);
+    }
+
+    const cells = [];
+
+    for (let rowIndex in section.rows) {
+      const headerCol = nodeDisplay.render(section.rowHeaders[rowIndex]);
+      const bodyCols = [];
+      for (let cellObjs of section.rows[rowIndex]) {
+        const display = cellObjs.map(
+          (t) => html`<div>${nodeDisplay.render(t)}</div>`
+        );
+        bodyCols.push(html`<td>${display}</td>`);
+      }
+      cells.push(
+        html`<tr>
+          <th>${headerCol}</th>
+          ${bodyCols}
+        </tr>`
+      );
+    }
+    const tableTypesUnique = uniqueSortedTerms(tableTypes.flat());
+    const typesDisplay = html`${tableTypesUnique.length == 1 ? "type" : "types"}
+    ${tableTypesUnique.map((n) => nodeDisplay.render(n))}`;
+
+    return html`
+      <div>[icon] Resources of ${typesDisplay}</div>
+      <div class="typeBlockScroll">
+        <table class="typeBlock">
+          <thead>
+            <tr>
+              <th></th>
+              ${typeHeads}
+            </tr>
+            <tr>
+              <th>Subject</th>
+              ${heads}
+            </tr>
+          </thead>
+          <tbody>
+            ${cells}
+          </tbody>
+        </table>
+      </div>
+    `;
+  }
+
+  _renderFreeStatements(section: FreeStatements): TemplateResult {
+    const subjects: NamedNode[] = [];
+    let subjPreds = Immutable.Map<NamedNode, UriSet>();
+
+    return html`<div class="spoGrid">
+      grid has rowcount ${section.subjRows.length}
+      ${section.subjRows.map(this._subjPredObjsBlock.bind(this))}
+    </div>`;
+  }
+
+  _subjPredObjsBlock(row: SubjRow): TemplateResult {
+    return html`
+      <div class="subject">
+        ${this.nodeDisplay?.render(row.subj)}
+        <!-- todo: special section for uri/type-and-icon/label/comment -->
+        <div>${row.predRows.map(this._predObjsBlock.bind(this))}</div>
+      </div>
+    `;
+  }
+
+  _predObjsBlock(row: PredRow): TemplateResult {
+    return html`
+      <div class="predicate">
+        ${this.nodeDisplay?.render(row.pred)}
+        <div>${row.objs.map(this._objCell.bind(this))}</div>
+      </div>
+    `;
+  }
+
+  _objCell(obj: Term): TemplateResult {
+    return html`
+      <div class="object">
+        ${this.nodeDisplay?.render(obj)}
+        <!-- indicate what source or graph said this stmt -->
+      </div>
+    `;
+  }
+
+  _drawObj(obj: Term): TemplateResult {
+    return html` <div>${this.nodeDisplay?.render(obj)}</div> `;
+  }
+
+  _drawColumnHead(pred: NamedNode): TemplateResult {
+    return html` <th>${this.nodeDisplay?.render(pred)}</th> `;
+  }
+
+  //   return html`
+  //     <div>[icon] Resources of type ${typeNames}</div>
+  //     <div class="typeBlockScroll">
+  //       <table class="typeBlock">
+  //         ${this._thead(layout)} ${layout.subjs.map(this._instanceRow(layout))}
+  //       </table>
+  //     </div>
+  //   `;
+  // }
+}
+
+declare global {
+  interface HTMLElementTagNameMap {
+    "graph-view": GraphView;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/elements/graph-view/NodeDisplay.ts	Fri May 05 21:27:24 2023 -0700
@@ -0,0 +1,55 @@
+import { html, TemplateResult } from "lit";
+import { Literal, NamedNode, Term, Util } from "n3";
+import { SuffixLabels } from "../../layout/suffixLabels";
+
+export class NodeDisplay {
+  labels: SuffixLabels;
+  constructor(labels: SuffixLabels) {
+    this.labels = labels;
+  }
+  render(n: Term | NamedNode): TemplateResult {
+    if (Util.isLiteral(n)) {
+      n = n as Literal;
+      let dtPart: any = "";
+      if (n.datatype &&
+        n.datatype.value != "http://www.w3.org/2001/XMLSchema#string" && // boring
+        n.datatype.value !=
+        "http://www.w3.org/1999/02/22-rdf-syntax-ns#langString" //  boring
+      ) {
+        dtPart = html`
+          ^^<span class="literalType"> ${this.render(n.datatype)} </span>
+        `;
+      }
+      return html` <span class="literal">${n.value}${dtPart}</span> `;
+    }
+
+    if (Util.isNamedNode(n)) {
+      n = n as NamedNode;
+      let shortened = false;
+      let uriValue: string = n.value;
+      for (let [long, short] of [
+        ["http://www.w3.org/1999/02/22-rdf-syntax-ns#", "rdf:"],
+        ["http://www.w3.org/2000/01/rdf-schema#", "rdfs:"],
+        ["http://purl.org/dc/elements/1.1/", "dc:"],
+        ["http://www.w3.org/2001/XMLSchema#", "xsd:"],
+      ]) {
+        if (uriValue.startsWith(long)) {
+          uriValue = short + uriValue.substr(long.length);
+          shortened = true;
+          break;
+        }
+      }
+      if (!shortened) {
+        let dn: string | undefined = this.labels.getLabelForNode(uriValue);
+        if (dn === undefined) {
+          throw new Error(`dn=${dn}`);
+        }
+        uriValue = dn;
+      }
+
+      return html` <a class="graphUri" href="${n.value}">${uriValue}</a> `;
+    }
+
+    return html` [${n.termType} ${n.value}] `;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/elements/streamed-graph/SgSource.ts	Fri May 05 21:27:24 2023 -0700
@@ -0,0 +1,74 @@
+import { LitElement } from "lit";
+import { customElement, property } from "lit/decorators.js";
+import { SubEvent } from "sub-events";
+import { SourceGraph } from "../../SourceGraph";
+
+export interface SgSourceStatus {
+  url: string;
+  isCurrent: boolean;
+  quadCount: number;
+}
+
+/*
+Invisible elem used for configuring a <streamed-graph>.
+URL can be to a simple files or SSE patch stream. Wait for
+newSourceGraphAvailable events to access the rdf data.
+
+This obj doesn't care about `sourceGraphChanged` events. It just
+builds and replaces SourceGraph objs. See `ConfiguredSources`.
+*/
+@customElement("sg-source")
+export class SgSource extends LitElement {
+  @property() url: string = ""; // mutable
+
+  @property() sourceGraph: SourceGraph | null = null; // rebuilt when url changes
+
+  removingSourceGraph: SubEvent<SourceGraph> = new SubEvent();
+  newSourceGraph: SubEvent<SourceGraph> = new SubEvent();
+
+  async connectedCallback() {
+    // incorrect callback- this should rerun when the attribute changes too
+    super.connectedCallback();
+    await this.onUrlChange();
+  }
+
+  private async onUrlChange() {
+    this.removeExistingSourceGraph(this.sourceGraph);
+    if (this.url) {
+      this.sourceGraph = new SourceGraph(this.url);
+      
+      this.newSourceGraph.emit(this.sourceGraph);
+      await this.sourceGraph.reloadRdf();
+    } else {
+      this.sourceGraph = null;
+    }
+  }
+
+  private removeExistingSourceGraph(s: SourceGraph | null) {
+    if (!s) return;
+    this.removingSourceGraph.emit(s);
+    s.dispose();
+  }
+
+  isCurrent(): boolean {
+    return this.sourceGraph ? this.sourceGraph.isCurrent : false;
+  }
+
+  quadCount(): number {
+    return this.sourceGraph ? this.sourceGraph.quadCount() : 0;
+  }
+
+  status(): SgSourceStatus {
+    return {
+      url: this.url || "<empty>",
+      isCurrent: this.isCurrent(),
+      quadCount: this.quadCount(),
+    };
+  }
+}
+
+declare global {
+  interface HTMLElementTagNameMap {
+    "sg-source": SgSource;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/elements/streamed-graph/SgView.ts	Fri May 05 21:27:24 2023 -0700
@@ -0,0 +1,25 @@
+import { LitElement, PropertyValueMap } from "lit";
+import { customElement, property } from "lit/decorators.js";
+import { NamedNode } from "n3";
+import { SubEvent } from "sub-events";
+
+/*
+Invisible elem used for configuring a <streamed-graph>.
+*/
+@customElement("sg-view")
+export class SgView extends LitElement {
+  @property() uri: string = "";
+  viewUriChanged: SubEvent<NamedNode> = new SubEvent();
+  update(changes: PropertyValueMap<this>) {
+    super.update(changes);
+    if (changes.has("uri")) {
+      this.viewUriChanged.emit(new NamedNode(this.uri));
+    }
+  }
+}
+
+declare global {
+  interface HTMLElementTagNameMap {
+    "sg-view": SgView;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/elements/streamed-graph/StreamedGraph.ts	Fri May 05 21:27:24 2023 -0700
@@ -0,0 +1,116 @@
+import { LitElement, PropertyValueMap, TemplateResult, html } from "lit";
+import { customElement, property, state } from "lit/decorators.js";
+import { NamedNode } from "n3";
+import { ConfiguredSources } from "../../ConfiguredSources";
+import { MultiStore } from "../../MultiStore";
+import { SourceGraph } from "../../SourceGraph";
+import { ViewConfig } from "../../layout/ViewConfig";
+import { addFontToRootPage, streamedGraphStyle } from "../../style";
+import { SgSource, SgSourceStatus } from "./SgSource";
+import { SgView } from "./SgView";
+export { GraphView } from "../graph-view/GraphView";
+export { SgView } from "./SgView"; // workaround for vite mystery
+
+// Top object, and the visible/expandable element you put on your page.
+// Routes sg-source and sg-view changes to ConfiguredSources.
+@customElement("streamed-graph")
+export class StreamedGraph extends LitElement {
+  sources: ConfiguredSources;
+
+  // consumers read this
+  graph: MultiStore; // exists from ctor time, mutated in place
+
+  @property() viewConfig: ViewConfig; // immutable, rebuilt when page or graph changes (in relevant ways)
+  @state() statusSummary: TemplateResult[] = [html`...`];
+
+  // @state() viewDirty: number = 0;
+  static styles = [streamedGraphStyle];
+  constructor() {
+    super();
+    this.sources = new ConfiguredSources();
+    this.graph = this.sources.graph;
+
+    this.sources.graph.graphChanged.subscribe((p) => {
+      this.updateStatusSummary();
+    });
+
+    this.sources.viewConfigChanged.subscribe((vc) => {
+      this.viewConfig = vc;
+      // this.viewDirty++;
+    });
+    this.viewConfig = this.sources.viewConfig;
+  }
+
+  firstUpdated(ch: PropertyValueMap<this>): void {
+    super.firstUpdated(ch);
+    this.scanChildNodesOnce();
+    addFontToRootPage();
+  }
+
+  scanChildNodesOnce() {
+    for (let el of this.children || []) {
+      if (el.tagName == "SG-SOURCE") {
+        this.onSgSourceChild(el as SgSource);
+      } else if (el.tagName == "SG-VIEW") {
+        this.onSgViewChild(el as SgView);
+      } else {
+        throw new Error(`streamed-graph has unknown child ${el.tagName}`);
+      }
+    }
+    this.updateStatusSummary();
+  }
+
+  private onSgViewChild(el: SgView) {
+    el.viewUriChanged.subscribe((u: NamedNode) => {
+      this.sources.viewUriChanged(u);
+    });
+
+    const viewUri = new NamedNode(el.uri || "no-view");
+    this.sources.viewUriChanged(viewUri);
+  }
+
+  private onSgSourceChild(el: SgSource) {
+    el.newSourceGraph.subscribe((s: SourceGraph) => {
+      this.sources.newSourceGraph(s);
+    });
+
+    const st = el.sourceGraph;
+    if (st) {
+      this.sources.newSourceGraph(st);
+    }
+  }
+
+  updateStatusSummary() {
+    const displayStatus = (st: SgSourceStatus): TemplateResult => {
+      const shortName = st.url.replace(/.*[\/#]([^\.]*).*/, "$1");
+      return html`[${shortName}
+        <span class="isCurrent isCurrent-${st.isCurrent}">
+          ${st.isCurrent ? "✓" : "…"}
+        </span>
+        ${st.quadCount}] `;
+    };
+
+    this.statusSummary = Array.from(this.children)
+      .filter((ch) => ch.tagName == "SG-SOURCE")
+      .map((el: Element) => (el as SgSource).status())
+      .map(displayStatus);
+  }
+
+  render() {
+    return html`
+      <details open>
+        <summary>StreamedGraph: ${this.statusSummary}</summary>
+        <graph-view
+          .graph=${this.graph}
+          .viewConfig=${this.viewConfig}
+        ></graph-view>
+      </details>
+    `;
+  }
+}
+
+declare global {
+  interface HTMLElementTagNameMap {
+    "streamed-graph": StreamedGraph;
+  }
+}
--- a/src/index.ts	Fri May 05 21:14:49 2023 -0700
+++ b/src/index.ts	Fri May 05 21:27:24 2023 -0700
@@ -1,3 +1,5 @@
-import { StreamedGraph } from "./render/StreamedGraph";
+import { StreamedGraph } from "./elements/streamed-graph/StreamedGraph";
+import { SgSource } from "./elements/streamed-graph/SgSource";
+import { SgView } from "./elements/streamed-graph/SgView";
 
-export {StreamedGraph}
+export { StreamedGraph, SgSource, SgView };
--- a/src/layout/Layout.ts	Fri May 05 21:14:49 2023 -0700
+++ b/src/layout/Layout.ts	Fri May 05 21:27:24 2023 -0700
@@ -220,9 +220,12 @@
   return out;
 }
 
-function freeStatmentsSection(stmts: Quad[]): FreeStatements {
+function freeStatmentsSection(viewConfig: ViewConfig, stmts: Quad[]): FreeStatements {
   const subjs: NamedNode[] = [];
   stmts.forEach((q) => {
+    if (viewConfig.freeStatementsHidePred.has(q.predicate)) {
+      return;
+    }
     subjs.push(q.subject as NamedNode);
   });
   return {
@@ -230,7 +233,7 @@
       const preds: NamedNode[] = [];
       let po = Immutable.Map<NamedNode, Term[]>();
       stmts.forEach((q) => {
-        if (q.subject.equals(subj)) {
+        if (q.subject.equals(subj) && !viewConfig.freeStatementsHidePred.has(q.predicate)) {
           const p = q.predicate as NamedNode;
           preds.push(p);
           po = addToValues(po, p, q.object as NamedNode);
@@ -248,7 +251,7 @@
 
 // The description of how this page should look: sections, tables, etc.
 export class Layout {
-  constructor(public viewConfig?: ViewConfig) {}
+  constructor(public viewConfig: ViewConfig) {}
 
   private groupAllStatements(
     graph: Store,
@@ -273,6 +276,7 @@
   }
 
   private generateSections(
+    viewConfig: ViewConfig,
     tableBuilders: AlignedTableBuilder[],
     ungrouped: Quad[]
   ): (AlignedTable | FreeStatements)[] {
@@ -283,13 +287,13 @@
       }
     }
     if (ungrouped.length) {
-      sections.push(freeStatmentsSection(ungrouped));
+      sections.push(freeStatmentsSection(viewConfig, ungrouped));
     }
     return sections;
   }
 
   plan(graph: Store): LayoutResult {
-    const vcTables = this.viewConfig ? this.viewConfig.tables : [];
+    const vcTables = this.viewConfig.tables;
     const tableBuilders = vcTables.map(
       (t) => new AlignedTableBuilder(t.primary, t.joins, t.links)
     );
@@ -297,6 +301,6 @@
     const tablesWantingSubject = subjectsToTablesMap(graph, tableBuilders);
     const ungrouped: Quad[] = [];
     this.groupAllStatements(graph, tablesWantingSubject, ungrouped);
-    return { sections: this.generateSections(tableBuilders, ungrouped) };
+    return { sections: this.generateSections(this.viewConfig, tableBuilders, ungrouped) };
   }
 }
--- a/src/layout/StreamedGraphClient.ts	Fri May 05 21:14:49 2023 -0700
+++ b/src/layout/StreamedGraphClient.ts	Fri May 05 21:27:24 2023 -0700
@@ -1,3 +1,6 @@
+// this got rewritten in SourceGraph.ts
+
+
 import { eachJsonLdQuad } from "./json_ld_quads";
 import { Store } from "n3";
 
--- a/src/layout/ViewConfig.ts	Fri May 05 21:14:49 2023 -0700
+++ b/src/layout/ViewConfig.ts	Fri May 05 21:27:24 2023 -0700
@@ -1,8 +1,8 @@
-// Load requested view (rdf data) and provide access to it
-import { DataFactory, NamedNode, Store } from "n3";
-import { fetchAndParse, n3Graph } from "./fetchAndParse";
-import { EX, RDF } from "./namespaces";
-import { labelOrTail, uriValue } from "./rdf_value";
+import Immutable from "immutable"; // mostly using this for the builtin equals() testing, since NamedNode(x)!=NamedNode(x)
+import { DataFactory, NamedNode, Quad_Predicate, Term } from "n3";
+import { MultiStore } from "../MultiStore";
+import { EX } from "./namespaces";
+import { uriValue } from "./rdf_value";
 const Uri = DataFactory.namedNode;
 
 function firstElem<E>(seq: Iterable<E>): E {
@@ -24,63 +24,75 @@
   links: Link[];
 }
 
+// High-level guide to how to draw the page, independent of the graph data.
+// Layout.ts turns this plus the actual graph data into a structure that's
+// close to the final render.
 export class ViewConfig {
-  graph: Store;
-  viewRoot!: NamedNode;
-  url?: string;
-  tables: TableDesc[] = [];
+  viewRoot: NamedNode; // this structure...
+  graph: MultiStore; // in this graph...
+  tables: TableDesc[] = []; // populates all the rest of these fields for use by Layout
+  freeStatementsHidePred: Immutable.Set<Quad_Predicate> = Immutable.Set();
 
-  constructor() {
-    this.graph = new Store();
+  constructor(graph: MultiStore, viewUri: NamedNode) {
+    this.graph = graph;
+    this.viewRoot = viewUri;
+    // todo
+    const here = "https://bigasterisk.com/lanscape/";
+    if (this.viewRoot.value.startsWith(here)) {
+      this.viewRoot = new NamedNode(this.viewRoot.value.slice(here.length));
+    }
+    // todo: might need to reread if graph changes
+    this.read();
   }
 
-  async readFromUrl(url: string | "") {
-    if (!url) {
-      return;
+  private read() {
+    for (let table of this.graph.getObjects(this.viewRoot, EX("table"), null)) {
+      const t = this.readTable(table);
+      this.tables.push(t);
     }
-    this.url = url;
-    await fetchAndParse(url, this.graph);
+    this.tables.sort();
 
-    this._read();
-  }
-
-  async readFromGraph(n3: string) {
-    this.graph = await n3Graph(n3);
-    this._read();
+    this.readHides();
   }
 
-  _read() {
-    this.viewRoot = firstElem(
-      this.graph.getSubjects(RDF("type"), EX("View"), null)
-    ) as NamedNode;
-    for (let table of this.graph.getObjects(this.viewRoot, EX("table"), null)) {
-      const tableType = uriValue(this.graph, table, EX("primaryType"));
-      const joins: NamedNode[] = [];
-      for (let joinType of this.graph.getObjects(table, EX("joinType"), null)) {
-        joins.push(joinType as NamedNode);
+  private readHides() {
+    for (let hideInstruction of this.graph.getObjects(
+      this.viewRoot,
+      EX("freeStatementsHide"),
+      null
+    )) {
+      for (let pred of this.graph.getObjects(
+        hideInstruction,
+        EX("predicate"),
+        null
+      )) {
+        this.freeStatementsHidePred = this.freeStatementsHidePred.add(
+          pred as Quad_Predicate
+        );
       }
-      joins.sort();
+    }
+  }
 
-      const links: Link[] = [];
-      for (let linkDesc of this.graph.getObjects(table, EX("link"), null)) {
-        links.push({
-          pred: uriValue(this.graph, linkDesc, EX("predicate")),
-        });
-      }
+  private readTable(table: Term): TableDesc {
+    const tableType = uriValue(this.graph, table, EX("primaryType"));
+    const joins: NamedNode[] = [];
+    for (let joinType of this.graph.getObjects(table, EX("joinType"), null)) {
+      joins.push(joinType as NamedNode);
+    }
+    joins.sort();
 
-      this.tables.push({
-        uri: table as NamedNode,
-        primary: tableType,
-        joins: joins,
-        links: links,
+    const links: Link[] = [];
+    for (let linkDesc of this.graph.getObjects(table, EX("link"), null)) {
+      links.push({
+        pred: uriValue(this.graph, linkDesc, EX("predicate")),
       });
     }
-    this.tables.sort();
-  }
 
-  label(): string {
-    return this.url !== undefined
-      ? labelOrTail(this.graph, Uri(this.url))
-      : "unnamed";
+    return {
+      uri: table as NamedNode,
+      primary: tableType,
+      joins: joins,
+      links: links,
+    };
   }
 }
--- a/src/layout/json_ld_quads.ts	Fri May 05 21:14:49 2023 -0700
+++ b/src/layout/json_ld_quads.ts	Fri May 05 21:27:24 2023 -0700
@@ -1,3 +1,5 @@
+// unused?
+
 import * as jsonld from "jsonld";
 import { JsonLd, JsonLdArray } from "jsonld/jsonld-spec";
 import { Quad, NamedNode, DataFactory } from "n3";
--- a/src/layout/suffixLabels.ts	Fri May 05 21:14:49 2023 -0700
+++ b/src/layout/suffixLabels.ts	Fri May 05 21:27:24 2023 -0700
@@ -52,7 +52,13 @@
     // one child (since we'll see it again if that one wasn't
     // enough).
     const clashNode: DisplayNode = this.displayNodes.get(curs.usedBy!)!;
-    const nextLeftSeg = curs.children.entries().next().value;
+    const e = curs.children.entries()
+    const n = e.next()
+    if (n.done) {
+      return; // todo - this ignores the bad url
+      throw new Error()
+    }
+    const nextLeftSeg = n.value
     if (nextLeftSeg[1].usedBy) {
       throw new Error("unexpected");
     }
--- a/src/render/GraphView.ts	Fri May 05 21:14:49 2023 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,202 +0,0 @@
-import Immutable from "immutable";
-import { html, TemplateResult } from "lit";
-import { NamedNode, Quad, Store, Term } from "n3";
-import {
-  AlignedTable,
-  FreeStatements,
-  Layout,
-  PredRow,
-  SubjRow,
-} from "../layout/Layout";
-import { uniqueSortedTerms } from "../layout/rdf_value";
-import { SuffixLabels } from "../layout/suffixLabels";
-import { ViewConfig } from "../layout/ViewConfig";
-import { NodeDisplay } from "./NodeDisplay";
-
-type UriSet = Immutable.Set<NamedNode>;
-
-export class GraphView {
-  nodeDisplay!: NodeDisplay;
-  constructor(
-    public dataSourceUrls: string[],
-    public graph: Store,
-    public viewConfig?: ViewConfig
-  ) {}
-
-  async makeTemplate(): Promise<TemplateResult> {
-    const layout = new Layout(this.viewConfig);
-    const lr = layout.plan(this.graph);
-
-    const labels = new SuffixLabels();
-    this._addLabelsForAllTerms(this.graph, labels);
-
-    this.nodeDisplay = new NodeDisplay(labels);
-    let viewTitle = html` (no view)`;
-    if (this.viewConfig?.url) {
-      viewTitle = html` using view
-        <a href="${this.viewConfig?.url}">${this.viewConfig?.label()}</a>`;
-    }
-    return html`
-      <section>
-        <h2>
-          Current graph (<a href="${this.dataSourceUrls[0]}"
-            >${this.dataSourceUrls[0]}</a
-          >)${viewTitle}
-        </h2>
-        <div>
-          <!-- todo: graphs and provenance.
-            These statements are all in the
-            <span data-bind="html: $root.createCurie(graphUri())">...</span> graph.-->
-        </div>
-        ${lr.sections.map(this._renderSection.bind(this))}
-      </section>
-    `;
-  }
-
-  _addLabelsForAllTerms(graph: Store, labels: SuffixLabels) {
-    graph.forEach(
-      (q: Quad) => {
-        if (q.subject.termType === "NamedNode") {
-          labels.planDisplayForNode(q.subject);
-        }
-        if (q.predicate.termType === "NamedNode") {
-          labels.planDisplayForNode(q.predicate);
-        }
-        if (q.object.termType === "NamedNode") {
-          labels.planDisplayForNode(q.object);
-        }
-        if (q.object.termType === "Literal" && q.object.datatype) {
-          labels.planDisplayForNode(q.object.datatype);
-        }
-      },
-      null,
-      null,
-      null,
-      null
-    );
-  }
-
-  _renderSection(section: AlignedTable | FreeStatements) {
-    if ((section as any).columnHeaders) {
-      return this._renderAlignedTable(section as AlignedTable);
-    } else {
-      return this._renderFreeStatements(section as FreeStatements);
-    }
-  }
-
-  _renderAlignedTable(section: AlignedTable): TemplateResult {
-    const tableTypes: NamedNode[][] = [];
-    const typeHeads: TemplateResult[] = [];
-    const heads: TemplateResult[] = [];
-    for (let ch of section.columnHeaders) {
-      const colSpan = 1; //todo
-      typeHeads.push(
-        html`<th colspan="${colSpan}">
-          ${ch.rdfTypes.map((n) => this.nodeDisplay.render(n))}
-        </th>`
-      );
-
-      tableTypes.push(ch.rdfTypes);
-      heads.push(html`<th>${this.nodeDisplay.render(ch.pred)}</th>`);
-    }
-
-    const cells = [];
-
-    for (let rowIndex in section.rows) {
-      const headerCol = this.nodeDisplay.render(section.rowHeaders[rowIndex]);
-      const bodyCols = [];
-      for (let cellObjs of section.rows[rowIndex]) {
-        const display = cellObjs.map(
-          (t) => html`<div>${this.nodeDisplay.render(t)}</div>`
-        );
-        bodyCols.push(html`<td>${display}</td>`);
-      }
-      cells.push(
-        html`<tr>
-          <th>${headerCol}</th>
-          ${bodyCols}
-        </tr>`
-      );
-    }
-    const tableTypesUnique = uniqueSortedTerms(tableTypes.flat());
-    const typesDisplay = html`${tableTypesUnique.length == 1 ? "type" : "types"}
-    ${tableTypesUnique.map((n) => this.nodeDisplay.render(n))}`;
-
-    return html`
-      <div>[icon] Resources of ${typesDisplay}</div>
-      <div class="typeBlockScroll">
-        <table class="typeBlock">
-          <thead>
-            <tr>
-              <th></th>
-              ${typeHeads}
-            </tr>
-            <tr>
-              <th>Subject</th>
-              ${heads}
-            </tr>
-          </thead>
-          <tbody>
-            ${cells}
-          </tbody>
-        </table>
-      </div>
-    `;
-  }
-
-  _renderFreeStatements(section: FreeStatements): TemplateResult {
-    const subjects: NamedNode[] = [];
-    let subjPreds = Immutable.Map<NamedNode, UriSet>();
-
-    return html`<div class="spoGrid">
-      grid has rowcount ${section.subjRows.length}
-      ${section.subjRows.map(this._subjPredObjsBlock.bind(this))}
-    </div>`;
-  }
-
-  _subjPredObjsBlock(row: SubjRow): TemplateResult {
-    return html`
-      <div class="subject">
-        ${this.nodeDisplay.render(row.subj)}
-        <!-- todo: special section for uri/type-and-icon/label/comment -->
-        <div>${row.predRows.map(this._predObjsBlock.bind(this))}</div>
-      </div>
-    `;
-  }
-
-  _predObjsBlock(row: PredRow): TemplateResult {
-    return html`
-      <div class="predicate">
-        ${this.nodeDisplay.render(row.pred)}
-        <div>${row.objs.map(this._objCell.bind(this))}</div>
-      </div>
-    `;
-  }
-
-  _objCell(obj: Term): TemplateResult {
-    return html`
-      <div class="object">
-        ${this.nodeDisplay.render(obj)}
-        <!-- indicate what source or graph said this stmt -->
-      </div>
-    `;
-  }
-
-  _drawObj(obj: Term): TemplateResult {
-    return html` <div>${this.nodeDisplay.render(obj)}</div> `;
-  }
-
-  _drawColumnHead(pred: NamedNode): TemplateResult {
-    return html` <th>${this.nodeDisplay.render(pred)}</th> `;
-  }
-
-  //   return html`
-  //     <div>[icon] Resources of type ${typeNames}</div>
-  //     <div class="typeBlockScroll">
-  //       <table class="typeBlock">
-  //         ${this._thead(layout)} ${layout.subjs.map(this._instanceRow(layout))}
-  //       </table>
-  //     </div>
-  //   `;
-  // }
-}
--- a/src/render/NodeDisplay.ts	Fri May 05 21:14:49 2023 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-import { html, TemplateResult } from "lit";
-import { Literal, NamedNode, Term, Util } from "n3";
-import { SuffixLabels } from "../layout/suffixLabels";
-
-export class NodeDisplay {
-  labels: SuffixLabels;
-  constructor(labels: SuffixLabels) {
-    this.labels = labels;
-  }
-  render(n: Term | NamedNode): TemplateResult {
-    if (Util.isLiteral(n)) {
-      n = n as Literal;
-      let dtPart: any = "";
-      if (n.datatype &&
-        n.datatype.value != "http://www.w3.org/2001/XMLSchema#string" && // boring
-        n.datatype.value !=
-        "http://www.w3.org/1999/02/22-rdf-syntax-ns#langString" //  boring
-      ) {
-        dtPart = html`
-          ^^<span class="literalType"> ${this.render(n.datatype)} </span>
-        `;
-      }
-      return html` <span class="literal">${n.value}${dtPart}</span> `;
-    }
-
-    if (Util.isNamedNode(n)) {
-      n = n as NamedNode;
-      let shortened = false;
-      let uriValue: string = n.value;
-      for (let [long, short] of [
-        ["http://www.w3.org/1999/02/22-rdf-syntax-ns#", "rdf:"],
-        ["http://www.w3.org/2000/01/rdf-schema#", "rdfs:"],
-        ["http://purl.org/dc/elements/1.1/", "dc:"],
-        ["http://www.w3.org/2001/XMLSchema#", "xsd:"],
-      ]) {
-        if (uriValue.startsWith(long)) {
-          uriValue = short + uriValue.substr(long.length);
-          shortened = true;
-          break;
-        }
-      }
-      if (!shortened) {
-        let dn: string | undefined = this.labels.getLabelForNode(uriValue);
-        if (dn === undefined) {
-          throw new Error(`dn=${dn}`);
-        }
-        uriValue = dn;
-      }
-
-      return html` <a class="graphUri" href="${n.value}">${uriValue}</a> `;
-    }
-
-    return html` [${n.termType} ${n.value}] `;
-  }
-}
--- a/src/render/StreamedGraph.ts	Fri May 05 21:14:49 2023 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,152 +0,0 @@
-import { html, LitElement, render, TemplateResult } from "lit";
-import { customElement, property } from "lit/decorators.js";
-import { Store } from "n3";
-import { StreamedGraphClient } from "../layout/StreamedGraphClient";
-import { ViewConfig } from "../layout/ViewConfig";
-import { GraphView } from "./GraphView";
-import { addFontToRootPage, style } from "./style";
-
-export interface VersionedGraph {
-  version: number;
-  store: Store;
-}
-
-@customElement("streamed-graph")
-export class StreamedGraph extends LitElement {
-  @property({ type: String })
-  url: string = "";
-  @property({ type: String })
-  view: string = "";
-  @property({ type: Object })
-  graph!: VersionedGraph;
-
-  @property({ type: Boolean })
-  expanded: boolean = false;
-
-  @property({ type: String })
-  status: string = "";
-
-  sg!: StreamedGraphClient;
-  graphViewDirty = true;
-
-  static styles = style;
-
-  render() {
-    const expandAction = this.expanded ? "-" : "+";
-    return html`
-      <div id="ui">
-        <span class="expander"
-          ><button @click="${this.toggleExpand}">${expandAction}</button></span
-        >
-        StreamedGraph <a href="${this.url}">[source]</a>: ${this.status}
-      </div>
-      <div id="graphView"></div>
-    `;
-  }
-
-  connectedCallback() {
-    super.connectedCallback();
-    addFontToRootPage();
-    const emptyStore = new Store();
-    this.graph = { version: -1, store: emptyStore };
-
-    this._onUrl(this.url); // todo: watch for changes and rebuild
-    if (this.expanded) {
-      this.redrawGraph();
-    }
-  }
-
-  toggleExpand() {
-    this.expanded = !this.expanded;
-    if (this.expanded) {
-      this.redrawGraph();
-    } else {
-      this.graphViewDirty = false;
-      this._graphAreaClose();
-    }
-  }
-
-  redrawGraph() {
-    this.graphViewDirty = true;
-    const rl: () => Promise<void> = this._redrawLater.bind(this);
-    requestAnimationFrame(rl);
-  }
-
-  _onUrl(url: string) {
-    if (this.sg) {
-      this.sg.close();
-    }
-    this.sg = new StreamedGraphClient(
-      url,
-      this.onGraphChanged.bind(this),
-      (st) => {
-        this.status = st;
-      },
-      [], //window.NS,
-      []
-    );
-  }
-
-  onGraphChanged() {
-    this.graph = {
-      version: this.graph.version + 1,
-      store: this.sg.store,
-    };
-    if (this.expanded) {
-      this.redrawGraph();
-    }
-    this.dispatchEvent(
-      new CustomEvent("graph-changed", { detail: { graph: this.graph } })
-    );
-  }
-
-  async _redrawLater() {
-    if (!this.graphViewDirty) return;
-
-    if ((this.graph as VersionedGraph).store && this.graph.store) {
-      const vc = new ViewConfig();
-      if (this.view) {
-        await vc.readFromUrl(this.view); // too often!
-      }
-
-      await this._graphAreaShowGraph(
-        new GraphView([this.url], this.graph.store, vc)
-      );
-      this.graphViewDirty = false;
-    } else {
-      this._graphAreaShowPending();
-    }
-  }
-
-  _graphAreaClose() {
-    this._setGraphArea(html``);
-  }
-
-  _graphAreaShowPending() {
-    this._setGraphArea(html` <span>waiting for data...</span> `);
-  }
-
-  async _graphAreaShowGraph(graphView: GraphView) {
-    this._setGraphArea(await graphView.makeTemplate());
-  }
-
-  _setGraphArea(tmpl: TemplateResult) {
-    const el = this.shadowRoot?.getElementById("graphView");
-    if (!el) {
-      return;
-    }
-    render(tmpl, el);
-  }
-}
-
-declare global {
-  interface HTMLElementTagNameMap {
-    "streamed-graph": StreamedGraph;
-  }
-}
-
-// // allow child nodes to combine a few graphs and statics
-// //<streamed-graph id="timebankGraph"  graph="{{graph}}" expanded="true">
-// //  <member-graph url="graph/timebank/events"></member-graph>
-// //  <member-graph url="/some/static.n3"></member-graph>
-// //</streamed-graph>
--- a/src/render/style.ts	Fri May 05 21:14:49 2023 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,166 +0,0 @@
-import { css } from 'lit';
-
-export function addFontToRootPage() {
-  const content = `
-  @font-face {
-    font-family: 'Allerta';
-    font-style: normal;
-    font-weight: 400;
-    font-display: swap;
-    src: url(https://fonts.gstatic.com/s/allerta/v11/TwMO-IAHRlkbx940YnYXTQ.ttf) format('truetype');
-  }`;
-
-  if (!document.getElementById('allerta-style')) {
-    var head = document.head || document.getElementsByTagName('head')[0],
-      style = document.createElement('style');
-    style.id = 'allerta-style';
-    style.type = 'text/css';
-    style.innerText = content;
-    head.appendChild(style);
-  }
-}
-
-
-export const style = css`
-:host {
-  display: flex;
-  flex-direction: column;
-  padding: 2px 0;
-}
-#ui {
-  display: inline-block;
-  width: 30em;
-}
-#ui button {
-  width: 2em;
-}
-#ui .expander {
-  display: inline-block;
-  padding: 3px;
-}
-#graphView section {
-  padding: 4px;
-}
-#graphView .spoGrid {
-  display: flex;
-  flex-direction: column;
-}
-#graphView .subject,
-#graphView .predicate {
-  display: flex;
-  align-items: baseline;
-}
-#graphView .predicate,
-#graphView .object {
-  margin-left: 5px;
-}
-#graphView .literal {
-  display: inline-block;
-  margin: 3px;
-  padding: 4px;
-}
-#graphView .literalType {
-  vertical-align: super;
-  font-size: 80%;
-}
-#graphView .resource {
-  display: inline-block;
-  margin: 2px;
-  padding: 1px 6px;
-}
-#graphView .predicate > a::before {
-  padding-right: 2px;
-  content: '━';
-  font-weight: bolder;
-  font-size: 125%;
-}
-#graphView .predicate > a::after {
-  content: '🠪';
-}
-#graphView table.typeBlock {
-  border-collapse: collapse;
-}
-#graphView table.typeBlock td {
-  white-space: nowrap;
-}
-#graphView table tr:nth-child(even) td:nth-child(even) { background: #1a191c; }
-#graphView table tr:nth-child(even) td:nth-child(odd) { background: #181719; }
-#graphView table tr:nth-child(odd) td:nth-child(even) { background: #201e22; }
-#graphView table tr:nth-child(odd) td:nth-child(odd) { background: #1e1c1e; }
-#graphView table td,#graphView table th {
-  vertical-align:top;
-}
-#graphView table.typeBlock td .literal {
-  padding-top: 1px;
-  padding-bottom: 1px;
-}
-#graphView .typeBlockScroll {
-  overflow-x: auto;
-  max-width: 100%;
-}
-a {
-  color: #b1b1fd;
-  text-shadow: 1px 1px 0px rgba(4,0,255,0.58);
-  text-decoration-color: rgba(0,0,119,0.078);
-}
-body.rdfBrowsePage {
-  background: #000;
-  color: #fff;
-  font-size: 12px;
-}
-#ui {
-  border: 1px solid #808080;
-  background: #000;
-  color: #fff;
-  font-family: 'Allerta', sans-serif;
-}
-#graphView {
-  background: #000;
-  color: #fff;
-  font-family: 'Allerta', sans-serif;
-}
-#graphView section {
-  border: 1px solid #808080;
-}
-#graphView .subject {
-  border-top: 1px solid #2f2f2f;
-}
-#graphView .literal {
-  border: 1px solid #808080;
-  border-radius: 9px;
-  font-size: 115%;
-  font-family: monospace;
-}
-#graphView .subject > .node {
-  border: 2px solid #448d44;
-}
-#graphView .resource {
-  border-radius: 6px;
-  background: #add8e6;
-}
-#graphView .predicate > a {
-  color: #e49dfb;
-}
-#graphView .comment {
-  color: #008000;
-}
-#graphView table.typeBlock th {
-  border: 2px #333 outset;
-  background: #1f1f1f;
-}
-#graphView table.typeBlock td {
-  border: 2px #4a4a4a outset;
-  background: #2b2b2b;
-}
-/*
-for my pages serving rdf data, not necessarily part of browse/
-*/
-.served-resources {
-  margin-top: 4em;
-  padding-top: 1em;
-  border-top: 1px solid #808080;
-}
-.served-resources a {
-  padding-right: 2em;
-}
-  `;
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/style.ts	Fri May 05 21:27:24 2023 -0700
@@ -0,0 +1,187 @@
+import { css } from "lit";
+
+export function addFontToRootPage() {
+  const content = `
+  @font-face {
+    font-family: 'Allerta';
+    font-style: normal;
+    font-weight: 400;
+    font-display: swap;
+    src: url(https://fonts.gstatic.com/s/allerta/v11/TwMO-IAHRlkbx940YnYXTQ.ttf) format('truetype');
+  }`;
+
+  if (!document.getElementById("allerta-style")) {
+    var head = document.head || document.getElementsByTagName("head")[0],
+      style = document.createElement("style");
+    style.id = "allerta-style";
+    style.type = "text/css";
+    style.innerText = content;
+    head.appendChild(style);
+  }
+}
+
+export const pageStyle = css`
+  a {
+    color: #b1b1fd;
+    text-shadow: 1px 1px 0px rgba(4, 0, 255, 0.58);
+    text-decoration-color: rgba(0, 0, 119, 0.078);
+  }
+  body.rdfBrowsePage {
+    background: #000;
+    color: #fff;
+    font-size: 12px;
+  }
+
+  /*
+  for my pages serving rdf data, not necessarily part of browse/
+  */
+  .served-resources {
+    margin-top: 4em;
+    padding-top: 1em;
+    border-top: 1px solid #808080;
+  }
+  .served-resources a {
+    padding-right: 2em;
+  }
+`;
+
+export const streamedGraphStyle =   css`
+:host {
+  display: inline-block;
+  min-width: 30em;
+  padding: 0 0 0 1em;
+  border: 1px solid #808080;
+  background: #000;
+  color: #fff;
+  font-family: 'Allerta', sans-serif;
+
+    display: flex;
+    flex-direction: column;
+    padding: 2px 0;
+  
+}
+.isCurrent {
+  font-weight: bold;
+  font-size: 167%;
+  display: inline-block;
+  height: 1.4em;
+  vertical-align: middle;
+}
+.isCurrent-true {
+  color: green;
+}
+.isCurrent-false {
+  color: orange;
+}
+`;
+
+export const graphViewStyle = css`
+  section {
+    padding: 4px;
+  }
+  .spoGrid {
+    display: flex;
+    flex-direction: column;
+  }
+  .subject,
+  .predicate {
+    display: flex;
+    align-items: baseline;
+  }
+  .predicate,
+  .object {
+    margin-left: 5px;
+  }
+  .literal {
+    display: inline-block;
+    margin: 3px;
+    padding: 4px;
+  }
+  .literalType {
+    vertical-align: super;
+    font-size: 80%;
+  }
+  .resource {
+    display: inline-block;
+    margin: 2px;
+    padding: 1px 6px;
+  }
+  .predicate > a::before {
+    padding-right: 2px;
+    content: "━";
+    font-weight: bolder;
+    font-size: 125%;
+  }
+  .predicate > a::after {
+    content: "🠪";
+  }
+  table.typeBlock {
+    border-collapse: collapse;
+  }
+  table.typeBlock td {
+    white-space: nowrap;
+  }
+  table tr:nth-child(even) td:nth-child(even) {
+    background: #1a191c;
+  }
+  table tr:nth-child(even) td:nth-child(odd) {
+    background: #181719;
+  }
+  table tr:nth-child(odd) td:nth-child(even) {
+    background: #201e22;
+  }
+  table tr:nth-child(odd) td:nth-child(odd) {
+    background: #1e1c1e;
+  }
+  table td,
+  table th {
+    vertical-align: top;
+  }
+  table.typeBlock td .literal {
+    padding-top: 1px;
+    padding-bottom: 1px;
+  }
+  .typeBlockScroll {
+    overflow-x: auto;
+    max-width: 100%;
+  }
+  /* ------------------ */
+  :host {
+    background: #000;
+    color: #fff;
+    font-family: "Allerta", sans-serif;
+  }
+  section {
+    border: 1px solid #808080;
+  }
+  .subject {
+    border-top: 1px solid #2f2f2f;
+  }
+  .literal {
+    border: 1px solid #808080;
+    border-radius: 9px;
+    font-size: 115%;
+    font-family: monospace;
+  }
+  .subject > .node {
+    border: 2px solid #448d44;
+  }
+  .resource {
+    border-radius: 6px;
+    background: #add8e6;
+  }
+  .predicate > a {
+    color: #e49dfb;
+  }
+  .comment {
+    color: #008000;
+  }
+  table.typeBlock th {
+    border: 2px #333 outset;
+    background: #1f1f1f;
+  }
+  table.typeBlock td {
+    border: 2px #4a4a4a outset;
+    background: #2b2b2b;
+  }
+`;
--- a/tasks.py	Fri May 05 21:14:49 2023 -0700
+++ b/tasks.py	Fri May 05 21:27:24 2023 -0700
@@ -1,3 +1,4 @@
+import os
 from invoke import task  # pytype: disable=import-error
 
 
@@ -32,4 +33,9 @@
 
 @task
 def dev(ctx):
-    ctx.run('pnpm dev')
\ No newline at end of file
+    ctx.run('pnpm dev')
+
+@task
+def deps(ctx):
+    ctx.run('node_modules/.bin/depcruise --config .dependency-cruiser.js -T dot src | dot -Tsvg > deps.svg')
+    print(f"browse to file://{os.path.abspath('deps.svg')}")
\ No newline at end of file