From 863105bc10af7a62011f35e38dfb0481d21c6e1b Mon Sep 17 00:00:00 2001 From: mgerhardy Date: Fri, 28 Jun 2024 11:47:58 +0000 Subject: [PATCH] Deployed e72bb6b with MkDocs version: 1.6.0 --- .nojekyll | 0 404.html | 1097 +++ Basics/index.html | 1429 ++++ CHANGELOG/index.html | 2740 +++++++ Compilation/index.html | 1352 ++++ Configuration/index.html | 1597 ++++ CubicSurfaceExtractor1.png | Bin 0 -> 11954 bytes CubicSurfaceExtractor2.png | Bin 0 -> 13766 bytes CubicSurfaceExtractor3.png | Bin 0 -> 16120 bytes Dependencies/index.html | 1297 ++++ FormatSpec/index.html | 1324 ++++ Formats/index.html | 1790 +++++ LUAScript/index.html | 2219 ++++++ Material/index.html | 1288 ++++ MinecraftAndVoxatron.jpg | Bin 0 -> 113536 bytes Palette/index.html | 1166 +++ ShaderTool/index.html | 1257 +++ Translation/index.html | 1216 +++ VisualTests/index.html | 1385 ++++ assets/images/favicon.png | Bin 0 -> 1870 bytes assets/javascripts/bundle.ad660dcc.min.js | 29 + assets/javascripts/bundle.ad660dcc.min.js.map | 7 + assets/javascripts/lunr/min/lunr.ar.min.js | 1 + assets/javascripts/lunr/min/lunr.da.min.js | 18 + assets/javascripts/lunr/min/lunr.de.min.js | 18 + assets/javascripts/lunr/min/lunr.du.min.js | 18 + assets/javascripts/lunr/min/lunr.el.min.js | 1 + assets/javascripts/lunr/min/lunr.es.min.js | 18 + assets/javascripts/lunr/min/lunr.fi.min.js | 18 + assets/javascripts/lunr/min/lunr.fr.min.js | 18 + assets/javascripts/lunr/min/lunr.he.min.js | 1 + assets/javascripts/lunr/min/lunr.hi.min.js | 1 + assets/javascripts/lunr/min/lunr.hu.min.js | 18 + assets/javascripts/lunr/min/lunr.hy.min.js | 1 + assets/javascripts/lunr/min/lunr.it.min.js | 18 + assets/javascripts/lunr/min/lunr.ja.min.js | 1 + assets/javascripts/lunr/min/lunr.jp.min.js | 1 + assets/javascripts/lunr/min/lunr.kn.min.js | 1 + assets/javascripts/lunr/min/lunr.ko.min.js | 1 + assets/javascripts/lunr/min/lunr.multi.min.js | 1 + assets/javascripts/lunr/min/lunr.nl.min.js | 18 + assets/javascripts/lunr/min/lunr.no.min.js | 18 + assets/javascripts/lunr/min/lunr.pt.min.js | 18 + assets/javascripts/lunr/min/lunr.ro.min.js | 18 + assets/javascripts/lunr/min/lunr.ru.min.js | 18 + assets/javascripts/lunr/min/lunr.sa.min.js | 1 + .../lunr/min/lunr.stemmer.support.min.js | 1 + assets/javascripts/lunr/min/lunr.sv.min.js | 18 + assets/javascripts/lunr/min/lunr.ta.min.js | 1 + assets/javascripts/lunr/min/lunr.te.min.js | 1 + assets/javascripts/lunr/min/lunr.th.min.js | 1 + assets/javascripts/lunr/min/lunr.tr.min.js | 18 + assets/javascripts/lunr/min/lunr.vi.min.js | 1 + assets/javascripts/lunr/min/lunr.zh.min.js | 1 + assets/javascripts/lunr/tinyseg.js | 206 + assets/javascripts/lunr/wordcut.js | 6708 +++++++++++++++++ .../workers/search.b8dbb3d2.min.js | 42 + .../workers/search.b8dbb3d2.min.js.map | 7 + assets/stylesheets/main.6543a935.min.css | 1 + assets/stylesheets/main.6543a935.min.css.map | 1 + assets/stylesheets/palette.06af60db.min.css | 1 + .../stylesheets/palette.06af60db.min.css.map | 1 + complement.png | Bin 0 -> 3577 bytes difference.png | Bin 0 -> 3976 bytes img/coordinate_system.png | Bin 0 -> 3091 bytes img/favicon.ico | Bin 0 -> 18158 bytes img/grass.png | Bin 0 -> 34721 bytes img/lua-cover.png | Bin 0 -> 31002 bytes img/lua-grid.png | Bin 0 -> 18399 bytes img/lua-noise.png | Bin 0 -> 26405 bytes img/lua-pyramid.png | Bin 0 -> 21271 bytes img/lua-thicken-after.png | Bin 0 -> 33106 bytes img/lua-thicken-before.png | Bin 0 -> 34805 bytes img/voxconvert-ui.png | Bin 0 -> 23476 bytes img/voxedit-animation.png | Bin 0 -> 3064 bytes img/voxedit-asset.png | Bin 0 -> 23823 bytes img/voxedit-brushes.png | Bin 0 -> 7354 bytes img/voxedit-camera.png | Bin 0 -> 5945 bytes img/voxedit-console.png | Bin 0 -> 4679 bytes img/voxedit-cvars.png | Bin 0 -> 32215 bytes img/voxedit-filedialog.png | Bin 0 -> 20238 bytes img/voxedit-keybindings.png | Bin 0 -> 28256 bytes img/voxedit-lsystem.png | Bin 0 -> 8657 bytes img/voxedit-memento.png | Bin 0 -> 8705 bytes img/voxedit-nodeinspector-edit.png | Bin 0 -> 3501 bytes img/voxedit-nodeinspector-scene.png | Bin 0 -> 12452 bytes img/voxedit-options.png | Bin 0 -> 27060 bytes img/voxedit-palette.png | Bin 0 -> 14207 bytes img/voxedit-rendersettings.png | Bin 0 -> 8038 bytes img/voxedit-scene.png | Bin 0 -> 8108 bytes img/voxedit-scripts.png | Bin 0 -> 5779 bytes img/voxedit-timeline.png | Bin 0 -> 7057 bytes img/voxedit-tools-scene.png | Bin 0 -> 6436 bytes img/voxedit-trees.png | Bin 0 -> 4768 bytes img/voxedit-viewport.png | Bin 0 -> 53023 bytes img/win-envvars.png | Bin 0 -> 20313 bytes img/win-visualstudio-configure.png | Bin 0 -> 10563 bytes img/win-visualstudio-install.png | Bin 0 -> 7558 bytes img/win-visualstudio-workloads.png | Bin 0 -> 5147 bytes index.html | 1227 +++ intersection.png | Bin 0 -> 3582 bytes search/search_index.json | 1 + sitemap.xml | 3 + sitemap.xml.gz | Bin 0 -> 127 bytes theme/main.html | 24 + thumbnailer/Examples/index.html | 1253 +++ thumbnailer/Index/index.html | 1226 +++ union.png | Bin 0 -> 3696 bytes voxconvert/Configuration/index.html | 1142 +++ voxconvert/Examples/index.html | 1748 +++++ voxconvert/Index/index.html | 1160 +++ voxconvert/Screenshots/index.html | 1143 +++ voxconvert/Usage/index.html | 1294 ++++ voxedit/Configuration/index.html | 1145 +++ voxedit/Controls/index.html | 1156 +++ voxedit/Features/index.html | 1164 +++ voxedit/Index/index.html | 1163 +++ voxedit/Screenshots/index.html | 1141 +++ voxedit/Usage/index.html | 1593 ++++ 119 files changed, 46030 insertions(+) create mode 100644 .nojekyll create mode 100644 404.html create mode 100644 Basics/index.html create mode 100644 CHANGELOG/index.html create mode 100644 Compilation/index.html create mode 100644 Configuration/index.html create mode 100644 CubicSurfaceExtractor1.png create mode 100644 CubicSurfaceExtractor2.png create mode 100644 CubicSurfaceExtractor3.png create mode 100644 Dependencies/index.html create mode 100644 FormatSpec/index.html create mode 100644 Formats/index.html create mode 100644 LUAScript/index.html create mode 100644 Material/index.html create mode 100644 MinecraftAndVoxatron.jpg create mode 100644 Palette/index.html create mode 100644 ShaderTool/index.html create mode 100644 Translation/index.html create mode 100644 VisualTests/index.html create mode 100644 assets/images/favicon.png create mode 100644 assets/javascripts/bundle.ad660dcc.min.js create mode 100644 assets/javascripts/bundle.ad660dcc.min.js.map create mode 100644 assets/javascripts/lunr/min/lunr.ar.min.js create mode 100644 assets/javascripts/lunr/min/lunr.da.min.js create mode 100644 assets/javascripts/lunr/min/lunr.de.min.js create mode 100644 assets/javascripts/lunr/min/lunr.du.min.js create mode 100644 assets/javascripts/lunr/min/lunr.el.min.js create mode 100644 assets/javascripts/lunr/min/lunr.es.min.js create mode 100644 assets/javascripts/lunr/min/lunr.fi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.fr.min.js create mode 100644 assets/javascripts/lunr/min/lunr.he.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hu.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hy.min.js create mode 100644 assets/javascripts/lunr/min/lunr.it.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ja.min.js create mode 100644 assets/javascripts/lunr/min/lunr.jp.min.js create mode 100644 assets/javascripts/lunr/min/lunr.kn.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ko.min.js create mode 100644 assets/javascripts/lunr/min/lunr.multi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.nl.min.js create mode 100644 assets/javascripts/lunr/min/lunr.no.min.js create mode 100644 assets/javascripts/lunr/min/lunr.pt.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ro.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ru.min.js create mode 100644 assets/javascripts/lunr/min/lunr.sa.min.js create mode 100644 assets/javascripts/lunr/min/lunr.stemmer.support.min.js create mode 100644 assets/javascripts/lunr/min/lunr.sv.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ta.min.js create mode 100644 assets/javascripts/lunr/min/lunr.te.min.js create mode 100644 assets/javascripts/lunr/min/lunr.th.min.js create mode 100644 assets/javascripts/lunr/min/lunr.tr.min.js create mode 100644 assets/javascripts/lunr/min/lunr.vi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.zh.min.js create mode 100644 assets/javascripts/lunr/tinyseg.js create mode 100644 assets/javascripts/lunr/wordcut.js create mode 100644 assets/javascripts/workers/search.b8dbb3d2.min.js create mode 100644 assets/javascripts/workers/search.b8dbb3d2.min.js.map create mode 100644 assets/stylesheets/main.6543a935.min.css create mode 100644 assets/stylesheets/main.6543a935.min.css.map create mode 100644 assets/stylesheets/palette.06af60db.min.css create mode 100644 assets/stylesheets/palette.06af60db.min.css.map create mode 100644 complement.png create mode 100644 difference.png create mode 100644 img/coordinate_system.png create mode 100644 img/favicon.ico create mode 100644 img/grass.png create mode 100644 img/lua-cover.png create mode 100644 img/lua-grid.png create mode 100644 img/lua-noise.png create mode 100644 img/lua-pyramid.png create mode 100644 img/lua-thicken-after.png create mode 100644 img/lua-thicken-before.png create mode 100644 img/voxconvert-ui.png create mode 100644 img/voxedit-animation.png create mode 100644 img/voxedit-asset.png create mode 100644 img/voxedit-brushes.png create mode 100644 img/voxedit-camera.png create mode 100644 img/voxedit-console.png create mode 100644 img/voxedit-cvars.png create mode 100644 img/voxedit-filedialog.png create mode 100644 img/voxedit-keybindings.png create mode 100644 img/voxedit-lsystem.png create mode 100644 img/voxedit-memento.png create mode 100644 img/voxedit-nodeinspector-edit.png create mode 100644 img/voxedit-nodeinspector-scene.png create mode 100644 img/voxedit-options.png create mode 100644 img/voxedit-palette.png create mode 100644 img/voxedit-rendersettings.png create mode 100644 img/voxedit-scene.png create mode 100644 img/voxedit-scripts.png create mode 100644 img/voxedit-timeline.png create mode 100644 img/voxedit-tools-scene.png create mode 100644 img/voxedit-trees.png create mode 100644 img/voxedit-viewport.png create mode 100644 img/win-envvars.png create mode 100644 img/win-visualstudio-configure.png create mode 100644 img/win-visualstudio-install.png create mode 100644 img/win-visualstudio-workloads.png create mode 100644 index.html create mode 100644 intersection.png create mode 100644 search/search_index.json create mode 100644 sitemap.xml create mode 100644 sitemap.xml.gz create mode 100644 theme/main.html create mode 100644 thumbnailer/Examples/index.html create mode 100644 thumbnailer/Index/index.html create mode 100644 union.png create mode 100644 voxconvert/Configuration/index.html create mode 100644 voxconvert/Examples/index.html create mode 100644 voxconvert/Index/index.html create mode 100644 voxconvert/Screenshots/index.html create mode 100644 voxconvert/Usage/index.html create mode 100644 voxedit/Configuration/index.html create mode 100644 voxedit/Controls/index.html create mode 100644 voxedit/Features/index.html create mode 100644 voxedit/Index/index.html create mode 100644 voxedit/Screenshots/index.html create mode 100644 voxedit/Usage/index.html diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000000..e69de29bb2 diff --git a/404.html b/404.html new file mode 100644 index 0000000000..55695e6f5e --- /dev/null +++ b/404.html @@ -0,0 +1,1097 @@ + + + + + + + + + + + + + + + + + + + + + + + vengi - voxel tools + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ +

404 - Not found

+ +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Basics/index.html b/Basics/index.html new file mode 100644 index 0000000000..27f26c2627 --- /dev/null +++ b/Basics/index.html @@ -0,0 +1,1429 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + Basic - vengi - voxel tools + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

Basics

+

Build

+

See compilation and dependencies.

+

Coordinate system

+

We are using the default opengl right handed coordinate system with x going right, y going upwards and z point towards you.

+

We are using column major matrices.

+

image

+

Unittests

+

If you are going to contribute, make sure that you are adding unittests, too. I won't make promises about not breaking anything +if there aren't unittests that are telling me that I've broken something.

+

To add a unittest, each module (src/modules/XXX) has a tests/ subdirectory. The CMakeLists.txt in the module directory adds the source files from that folder.

+
set(TEST_SRCS
+  [...]
+)
+gtest_suite_begin(tests-${LIB} TEMPLATE ${ROOT_DIR}/src/modules/core/tests/main.cpp.in)
+gtest_suite_sources(tests-${LIB} ${TEST_SRCS})
+gtest_suite_deps(tests-${LIB} ${LIB})
+gtest_suite_end(tests-${LIB})
+
+

Coding style

+

Rule of thumb - stick to the existing coding style - you can also use the clang-format settings to format your code. In general +you should not include any whitespace or formatting changes if they don't belong to your code changes.

+

If you do a formatting change, this should not be mixed with code changes - make a dedicated commit for the formatting.

+

Avoid using the STL were possible - see Orthodox C++.

+

Commit messages

+

Commit messages should match the usual git commit message guidelines. Keep the summary short - put an UPPERCASE prefix in front +of it and try to explain why the change was made - not what you changed (because that is part of the commit diff already).

+

The prefix is usually the module name. E.g. if you are changing code in src/modules/voxelformat the prefix would be VOXELFORMAT. A commit message could look like this:

+
VOXELFORMAT: summary
+
+detail message line 1
+detail message line 2
+
+

Modules

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDescription
appBasic application classes
commandBind c++ functionality to console commands
commonluaBasic lua bindings and helper
coreString, collections and other foundation classes
httpHttp download module
imageImage loading and writing
ioStream and file handling
mathBased on glm
metrictelegraf, influx and other metrics
noiseDifferent noise implementations
palettePalette formats and helper
renderGeneral renderer implementations and helpers
scenegraphScene graph and scene graph node implementation
testcoreVisual test helpers
uiDearImgui based ui code
util
videoWindow and renderer module
voxelThe voxel engine code based on PolyVox
voxelcollectionBrowse online and local voxel collections
voxelfontTTF font to voxel
voxelformatSeveral volume and mesh based file formats to load or generate voxels
voxelgeneratorLUA generator, space colonization, tree- and shape generators
voxelpathtracerPath tracer
voxelrenderVoxel renderer
voxelutilPathfinding, raycasting, image and general util functions
+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/CHANGELOG/index.html b/CHANGELOG/index.html new file mode 100644 index 0000000000..a39b3bea74 --- /dev/null +++ b/CHANGELOG/index.html @@ -0,0 +1,2740 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + Changelog - vengi - voxel tools + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + + + + + +
+
+ + + + + + + +

Changelog

+

A more detailed changelog can be found on github.

+

Join our discord server.

+

See the documentation for further details.

+

Known issues.

+

0.0.33 (2024-XX-XX)

+

General:

+
    +
  • Fixed invalid log levels
  • +
  • Added a new node type for named points
  • +
  • Improved 3zh format support
  • +
  • Added support for ase and aseprite format
  • +
  • Added cvar voxformat_emptypaletteindex
  • +
  • Create walk and jump animations with the new animate.lua script
  • +
+

VoxConvert:

+
    +
  • Added a basic UI for voxconvert
  • +
  • Removed --dump and added --json <full> to generate a scene graph structure
  • +
+

VoxBrowser:

+
    +
  • Removed standalone application - it's integrated in voxedit now
  • +
+

VoxEdit:

+
    +
  • Improved brush support
  • +
  • Fixed loading voxel collection assets
  • +
  • Gradient paint brush mode
  • +
  • Fixed invalid voxel erasing in plane brush
  • +
  • Extrude with preview (plane brush)
  • +
+

0.0.32 (2024-05-29)

+

General:

+
    +
  • Add meshoptimizer support (new cvar voxformat_optimize)
  • +
  • Fixed missing region shift for vxl (Command and Conquer)
  • +
  • Fixed MagicaVoxel vox file loading for files that don't contain instances, but only models
  • +
  • Added vxc thumbnail support
  • +
  • Fixed a translation related crash for all apps on windows
  • +
+

VoxEdit:

+
    +
  • Converted the text-voxel-rendering into a new brush
  • +
  • Fixed undo node transform changes as first action
  • +
+

0.0.31 (2024-05-09)

+

General:

+
    +
  • Fixed memory leak in fbx loading
  • +
  • Added support for starmade templates smtpl format
  • +
  • Fixed merging of nodes when pivots are used
  • +
  • Added support for litematic Minecraft
  • +
  • Extended supported Minecraft materials
  • +
  • Extended lua bindings for key frames and transforms
  • +
  • Extended lua bindings for http requests
  • +
  • Fixed face culling for negative scale values
  • +
  • Added command and cvar dialogs to the help menus
  • +
  • Added cubzh version 5 (older version) support
  • +
  • Added support for writing uncompressed qubicle qb files
  • +
  • Fixed qubicle qb version number
  • +
  • Added basic support for rooms.xyz thing file support
  • +
  • Optimized file dialog for large directories
  • +
  • Added translation support (po files)
  • +
  • Fixed error in up-scaling volumes
  • +
  • Fixed x-axis flip for cubzh 3zh files
  • +
  • Added cvar voxformat_rgbweightedaverage to control the color contributions for a triangle
  • +
  • Added the ability to upload crash dumps
  • +
  • Improved support for reference nodes in a lot of formats
  • +
  • Improved pivot support in a lot of formats
  • +
+

VoxConvert:

+
    +
  • Added zip archive support for --input
  • +
  • Added the ability to export into slices with --slice when --output is a png file
  • +
+

VoxEdit:

+
    +
  • Added support for browsing the remote voxel collections to the asset panel
  • +
  • Added modelmerge all parameter to merge all nodes at once
  • +
  • Added presentation command to cycle through all models in a scene
  • +
  • Improved position panel to edit transforms
  • +
  • Improved start-up times
  • +
  • Pasting from a different palette will search the closest colors
  • +
  • Fixed off-by-one error in ve_regionsizes cvar handling
  • +
  • Re-enabled the yocto-pathtracer panels again
  • +
  • Moved some ui elements into other panels
  • +
  • Improved stamp brush features
  • +
  • Fixed brush regression in combination with the override mode
  • +
  • Added pathfinder brush preview
  • +
+

Thumbnailer:

+
    +
  • Fixed logic error in skipping camera nodes
  • +
+

Packaging:

+
    +
  • Renamed AppStream package to io.github.vengi_voxel.vengi.voxedit for DBUS compatibility
  • +
+

0.0.30 (2024-03-23)

+

General:

+
    +
  • Fixed material saving and loading for vengi format
  • +
  • Fixed off-by-one in palette material property handling
  • +
  • Fixed extrude on region boundaries
  • +
  • Added dialogs to recover from previous crash by resetting all config values
  • +
+

VoxBrowser:

+
    +
  • Optimizations for huge voxel collections
  • +
  • Fixed some download url assembling errors for some online collections
  • +
+

VoxEdit:

+
    +
  • Fixed segfault when activating simplified mode
  • +
  • Fixed spanning AABB
  • +
  • Fixed crash on deleting reference nodes after duplication
  • +
  • Fixed pivot handling issue for reference nodes
  • +
  • Spurious reference nodes were visible in edit mode
  • +
  • Fixed a few memento state handling errors in terms of key frames and pivot points
  • +
  • Fixed memento state handling errors for reference nodes
  • +
  • Disable a few of the new panels in simple mode again
  • +
  • Improved scene mode node selection
  • +
+

0.0.29 (2024-03-15)

+

General:

+
    +
  • Expose hollow() to lua bindings
  • +
  • Add lua sanity checker to the build pipelines
  • +
  • Fixed randomness in lua script similarcolor.lua
  • +
  • Fixed error in voxelizer handling off-by-one cases in negative vertex coordinates
  • +
  • Fixed vxl/hva loading and saving
  • +
  • Fixed missing pcubes write support
  • +
  • Support palette materials
  • +
  • Optimized qubicle QB color quantization
  • +
  • Import magicavoxel materials
  • +
  • Improved GLTF material support
  • +
  • Made the smooth normals for the cubic mesh extractor optional (voxformat_withnormals)
  • +
  • Improved texture coordinates for mesh exports
  • +
  • Improved bash completion script creation
  • +
  • Improved scene camera centering
  • +
  • Fixed Anima Toon (scn) volume loading support
  • +
  • Palette optimizations
  • +
  • Improved StarMade sment, smd2 and smd3 support
  • +
+

VoxBrowser:

+
    +
  • New tool to browse voxel collections
  • +
+

VoxConvert:

+
    +
  • Added --print-formats parameter to print all formats as json the ease the parsing for third party tools
  • +
  • Support multiple --output parameters to write one (or more) input files into different formats in one step
  • +
+

VoxEdit:

+
    +
  • Auto create key frames when transform is modified via gizmo, too
  • +
  • Fixed an error in interpolating between the key frames
  • +
  • Fixed an error while trying to remove unused colors from a re-sorted palette
  • +
  • Fixed missing outline for dark voxels
  • +
  • Update paint features
  • +
  • Added more features to the palette panel (e.g. duplicating and removing colors)
  • +
  • Allow to bind the left- and right-scrolling mouse wheel
  • +
  • Improved draw color brush darken/brighten to create new colors if needed (and possible)
  • +
  • Fixed voxel placing on using the camera view manipulator
  • +
  • Fixed grid culling for orthographic projections
  • +
  • Selection in ortho fixed side view spans the whole size of the volume
  • +
  • Updated key bindings
  • +
  • Added popup for renaming a node
  • +
  • Fixed a few palette panel issues for sorting and re-ordering
  • +
  • Improved grid rendering
  • +
  • Added new models to the new-scene-dialog
  • +
+

Thumbnailer:

+
    +
  • Don't render camera frustums for the thumbnails
  • +
  • Allow to change the camera mode (top, left, right, ...)
  • +
+

0.0.28 (2024-01-17)

+
+

moved the github project into an organization named vengi-voxel - the url changed to https://github.com/vengi-voxel/vengi.

+
+

General:

+
    +
  • Improved SLAB5/6 support of kvx, kv6, kfa and vox
  • +
  • Don't fill the inner voxels of the SLAB5/6 models anymore
  • +
  • Improved palette support for plane and volume import
  • +
  • Fixed an error in de-duplicating Magicavoxel models
  • +
  • Allow one to save/convert only visible nodes
  • +
  • ply format got support for converting polygons into triangles
  • +
  • Show the full application name as window title
  • +
  • Improved esc handling for menus and popups
  • +
  • Added support for particube pcubes and 3zh support
  • +
  • Added support for Photoshop ase palette
  • +
  • Added support for Paintshop Pro (JASC) pal palette
  • +
  • Extended support for the Gimp gpl palette format to support the Aseprite alpha channel extension
  • +
  • Added support to collect anonymous metrics (disabled by default)
  • +
  • Added support to align all models in a scene - useful for rendering all models for an overview
  • +
  • Extended lua bindings
  • +
  • Added automatic bash and zsh completion generation for all apps. Just use e.g. vengi-voxconvert --completion bash (or zsh)
  • +
  • Calculate normals for the cubic mesh extractor, too
  • +
  • Added support for cubzh b64 maps
  • +
  • Fixed endian issue on big endian machines in gltf loading
  • +
  • Fixed non-flipped uv coordinates for some gltf files
  • +
+

VoxConvert:

+
    +
  • Improved --export-models to work with the output format given by --output
  • +
  • Added --filter-property to filter by node property key<:value>
  • +
+

VoxEdit:

+
    +
  • Added alternative split-object implementation and expose it to the editor tool panel
  • +
  • Fixed split dialog appearing too late
  • +
  • Added shader for marching cubes
  • +
  • Fixed selection handling
  • +
  • Added tip of the day dialog
  • +
  • Resize to selection
  • +
  • Fixed palette panel issue if you changed the order of colors
  • +
  • Added more templates to the new-scene-dialog
  • +
  • Made the new-scene-dialog scrollable
  • +
  • Allow one to change the transform of a node with updating the children
  • +
  • Fixed a few crashes
  • +
  • Improved gizmo settings panel
  • +
  • Added the console next to the animation timeline panel
  • +
  • Improved color themes (especially the light theme)
  • +
  • Only show the brush panel if in edit mode
  • +
  • Converted the script brush back to a normal panel
  • +
  • Automatically reference all child nodes when creating a new reference
  • +
  • Allow one to switch between cubes and marching cubes rendering in the editor
  • +
  • Added clear and fill commands
  • +
  • Preview for the line brush
  • +
  • Allow to render the bones
  • +
+

Thumbnailer:

+
    +
  • Add a few more command line options to control the camera
  • +
+

0.0.27 (2023-09-19)

+

Breaking changes:

+
    +
  • Renamed globals for lua scripts. Added a g_ prefix to them. You have to adopt your scripts + to work with the latest version with vengi (if you use them):
      +
    • scenegraph is now g_scenegraph
    • +
    • palettemgr is now g_palette
    • +
    • noise is now g_noise
    • +
    • cmd is now g_cmd
    • +
    • var is now g_var
    • +
    • XvecX is now g_XvecX (ivec3 is for example g_ivec3)
    • +
    +
  • +
+

General:

+
    +
  • Added cvar voxformat_pointcloudsize for point cloud formats
  • +
  • Added Polygon File Format (ply) mesh and point cloud support (ascii and binary)
  • +
  • Fixed regression with GLTF exports
  • +
  • Added a new lua script to slice a node into smaller pieces
  • +
  • Expose shape generators to lua
  • +
  • Fixed color intensity handling for kvx files
  • +
  • Added write support for kvx format (used in e.g. voxel doom and eduke3d)
  • +
  • Added support for Voxel3D v3a format
  • +
+

VoxEdit:

+
    +
  • Fixed regression about not rendering the shape volumes anymore
  • +
  • Implemented scene graph panel drag and drop popup
  • +
  • Added brush support and new editing features
  • +
  • Fixed spurious crashes for windows
  • +
+

0.0.26 (2023-08-13)

+

General:

+
    +
  • Fixed pivot handling in VXR format
  • +
  • Allow one to export the GLTF vertex colors as byte values
  • +
  • Added NeuQuant color quantization algorithm
  • +
  • Optimized GLTF and MD2 import
  • +
  • Fixed Quake1 texture handling
  • +
  • General optimizations
  • +
  • Added a new voxelization algorithm and a cvar to use it (set voxformat_voxelizemode to 1)
  • +
  • Fixed issues with importing images with a depth-map
  • +
  • Fixed regression for reading minecraft voxel data
  • +
  • Added support for loading Lospec palettes
  • +
+

VoxEdit:

+
    +
  • Improved shape handling a lot
  • +
  • Added (disabled) pathtracer support (Yocto/GL)
  • +
  • Fixed rendering order of overlapping bounding boxes for the active node
  • +
  • Added warning popup to split volumes into smaller pieces
  • +
+

0.0.25 (2023-07-28)

+

General:

+
    +
  • Fixed invalid x axis handling for Sandbox VXM format
  • +
  • Fixed pivot handling in VXR/VXA format
  • +
  • Support model references to build a complex scene
  • +
  • Extended GLTF support to animation import and export as well as normal export
  • +
  • Fixed missing base color support for GLTF
  • +
  • Support for some parts of VoxelMax format
  • +
  • Fixed Sandbox VXA version 3 support
  • +
  • Fixed volume rotation issues
  • +
  • Fixed volume merging issues
  • +
  • Added Quake2 Model (md2) support
  • +
  • Removed cvar voxformat_marchingcubes and replaced with voxel_meshmode (set to 1 to use marching cubes)
  • +
  • Added new lua script gradient.lua
  • +
  • Improved csm and nvm format support
  • +
  • Added lua script for generating mazes
  • +
  • Added the ability to easily scale a volume up
  • +
  • Unified naming of commands and parameters (layer is model now, ...)
  • +
  • Added VoxelBuilder (vbx) support
  • +
  • Fixed missing group transform handling for MagicaVoxel files
  • +
  • Added support for MagicaVoxel xraw format
  • +
  • Added alpha support for MagicaVoxel materials
  • +
  • Added support for loading Sandbox VXM format version 3
  • +
  • Added new lua script and extended lua api to replace palettes, resize volumes and move voxels
  • +
+

VoxConvert:

+
    +
  • Fixed --input handling if the value is a directory
  • +
  • Added option --wildcard to specify a wildcard in cases where the --input value is a directory
  • +
  • Added --surface-only parameter that removes any non surface voxel.
  • +
  • Added --dump-mesh to also show mesh details (like vertex count).
  • +
+

VoxEdit:

+
    +
  • Allow one to export selections only
  • +
  • Started to support different keymaps (blender, qubicle, magicavoxel and vengi own)
  • +
  • Added support for multiple animations in one scene
  • +
  • Allow one to duplicate all scene graph nodes
  • +
  • (Re-)implemented WASD controls in camera eye mode
  • +
  • Fixed copy&paste errors with multiple selections
  • +
  • Updated new scene dialog to include the templates
  • +
  • Improved font quality
  • +
  • Fixed a few crashes
  • +
  • Added hollow functionality to remove invisible voxels
  • +
  • Preview of modifier shapes in edit mode
  • +
+

Thumbnailer:

+
    +
  • Improved camera placement
  • +
  • Fixed threading issue with the mesh extraction for the renderer that could lead to black thumbnails
  • +
  • Don't render cameras for the thumbnails
  • +
+

0.0.24 (2023-03-12)

+

General:

+
    +
  • Support using palette cvar as a destination palette again by setting voxformat_createpalette to false
  • +
  • Added new image formats from SOIL2 (DDS, PKM, PVR)
  • +
  • Added FBX read support
  • +
  • Improved texture lookup for mesh formats
  • +
  • Added multiple color reduction algorithms and expose them to the user by the cvar core_colorreduction
  • +
  • Fixed several issues with AceOfSpades vxl format - switched to libvxl for loading and saving
  • +
  • Fixed splitting volumes even if not needed (off-by-one error)
  • +
  • Fixed multi-monitor support
  • +
  • Fixed colors in the tree generator
  • +
  • Improved the key binding handling and made it more flexible
  • +
  • Added support for loading minetest mts files
  • +
  • Fixed Command&Conquer vxl format writing issue
  • +
  • Added own format with the extension vengi
  • +
  • Added basic alpha support
  • +
  • Fixed saving the keybindings with multi click
  • +
  • Improved keybinding and ui setting saving (added a version)
  • +
  • Fixed invalid transform on re-parenting a node
  • +
  • Refactored the file dialog
  • +
  • Fixed issue in saving MagicaVoxel vox files under some special conditions
  • +
  • Implemented basic transparency support for voxels
  • +
  • Fixed invalid clamping for uv based pixel lookup (mesh imports)
  • +
  • Update renderer to only use uniform buffers
  • +
  • Fixed rendering issue for windows users
  • +
  • Fixed fullscreen issues for windows users
  • +
  • Extended lua script bindings to Allow one to render text as voxels
  • +
  • Support GLES3 rendering
  • +
+

VoxConvert:

+
    +
  • Show supported palette and image formats in help screen (--help)
  • +
+

VoxEdit:

+
    +
  • Disable animation window if there are no animations to show
  • +
  • Allow one to show the color picker in the palette panel
  • +
  • Reworked the modifiers panel
  • +
  • Made undo/redo more visible
  • +
  • Switched the camera modifier to the right side of the viewport
  • +
  • Fixed diffuse and ambient color settings mix-up
  • +
  • Merged layer and scene graph panel into one
  • +
  • Several gizmo related fixes and improvements
  • +
  • Added simple UI mode which removes some panels
  • +
  • Fixed a few memento (undo/redo) related issues
  • +
  • Added templates to the menu (robo, chess, head and chr_knight)
  • +
  • Allow one to control the amount of viewports
  • +
  • Allow one to define pre-defined region sizes (see ve_regionsizes cvar)
  • +
  • Some ui actions are only available in edit mode
  • +
  • Edit mode has support for the gizmo now - you can shift the volume boundaries
  • +
  • Highlight copy&paste volume region
  • +
  • Visually disable some buttons if they won't work in the current mode anyway
  • +
  • Don't execute actions for hidden nodes
  • +
  • New keybindings
  • +
  • Allow one to sort the palette colors by hue, saturation or brightness
  • +
  • Allow one to select and drag keyframes in the animation timeline
  • +
  • Export animations as AVI
  • +
  • Allow one to import a whole directory into a scene
  • +
  • Allow one to select all node types in the scene graph panel
  • +
  • Allow one to edit node properties
  • +
  • Added voxel cursor tooltips about the position in the volume
  • +
  • WASM/HTML5 port
  • +
+

0.0.23 (2022-12-17)

+

General:

+
    +
  • Improved big endian support for voxel formats
  • +
  • Improved VXL format default palette support
  • +
  • Improved QBCL scene graph support
  • +
  • Improved voxelization vertex color support
  • +
  • Fixed VOX root node handling
  • +
  • Fixed QBCL and GOX thumbnail handling
  • +
  • Removed unused code
  • +
  • Added support for VXA version 3
  • +
  • (Re-)added support for marching cubes
  • +
  • Fixed a bug in Ace of Spades VXL loading
  • +
+

VoxEdit:

+
    +
  • Added support for embedding screenshots in formats that support it
  • +
  • Allow one to export palettes
  • +
  • Allow one to change color intensity of the whole palette
  • +
  • Allow one to voxelize text
  • +
  • Fixed orthographic cameras
  • +
  • Massive performance increase when using multiple viewports
  • +
  • More than 10 times gpu memory reduction
  • +
  • Render the camera nodes in scene mode
  • +
+

Thumbnailer:

+
    +
  • Added support for turntable rendering
  • +
+

0.0.22 (2022-10-31)

+

General:

+
    +
  • Improved GLTF format support
  • +
  • Improved VXL format support
  • +
  • Improved Qubicle QB support
  • +
  • Fixed block id parsing for StarMade voxel models
  • +
  • Major improvements in scene graph transform handling
  • +
  • Improved voxelization of meshes with voxels
  • +
  • Added kv6 write support
  • +
  • Added slab6 vox write support
  • +
  • Fixed saving black colors for cubeworld
  • +
  • Fixed saving palette index 0 for binvox
  • +
  • Fixed Sandbox VXM palette issue
  • +
  • Fixed QBCL saving
  • +
  • Improved qbt scene graph support
  • +
  • Improved vox saving with multiple palettes
  • +
  • Improved the file dialog size and special dir handling
  • +
  • Improved dark mode support
  • +
  • Improved palette support for some formats
  • +
+

Packaging:

+
    +
  • There is a snap package available now (io.github.vengi-voxel.vengi.voxedit)
  • +
+

VoxEdit:

+
    +
  • Fixed layer color selection if you have multiple layers
  • +
  • Fixed moving nodes in the scene graph panel
  • +
  • Fixed transforms in scene graph mode (translation, rotation)
  • +
  • Allow one to add group and camera nodes
  • +
  • Don't just quit the application if you have unsaved data in your scene
  • +
+

0.0.21 (2022-09-05)

+

General:

+
    +
  • Added support for minecraft 1.13 region files
  • +
  • Added support for loading minecraft level.dat (only with supported region files)
  • +
  • Added support for WorldEdit schematics
  • +
  • Added support for Minecraft nbt files
  • +
  • Added support for StarMade voxel models
  • +
  • Added support for Quake1 and UFO:Alien Invasion
  • +
  • Reduced memory footprint for voxelizing huge meshes
  • +
  • Support wrap mode texture settings for gltf voxelization
  • +
  • Improved sanity check for Qubicle Binary format support
  • +
  • Fixed texture lookup error in gltf voxelization
  • +
  • Extended lua vector bindings and Allow one to import heightmaps
  • +
  • Improved the file dialog filters
  • +
  • Added new lua scripts and extended lua integration in voxconvert
  • +
  • Added support for RGB (pal) and Gimp (gpl) palette loading
  • +
  • Improved the Command & Conquer VXL format support
  • +
+

VoxEdit:

+
    +
  • Fixed resetting the camera in eye mode
  • +
  • New asset panel
  • +
  • Place images, models and colors via drag and drop into the scene
  • +
  • Extended scene mode modifiers to allow resizing the volumes (double click in scene mode)
  • +
  • Fixed updating the locked axis plane on change
  • +
  • Fixed scene graph node panel width
  • +
  • Fixed mesh extraction on chunk boundaries
  • +
  • Fixed new volume dialog input handling
  • +
  • Fixed cursor being invisible with bloom disabled
  • +
  • Fixed cursor face being on the wrong side of the voxel at the volume edges
  • +
  • Fixed last opened files with spaces in their names
  • +
  • Fixed loading files from command line again
  • +
  • Allow one to select scene graph node from the animation timeline
  • +
  • Fixed deleting key frames
  • +
  • Improved adding new key frames
  • +
+

0.0.20 (2022-06-14)

+

General:

+
    +
  • Added support for minecraft schematic
  • +
  • Refactored and extended the lua script integration
  • +
  • Implemented applying depth/height map to a 2d plane
  • +
  • Added support for new magicavoxel format (animations)
  • +
  • Preserve node hierarchy when saving vxr
  • +
  • GLTF voxelization
  • +
  • Allow one to enable certain renderer features
  • +
  • Expose more noise functions to the lua scripts
  • +
  • Expose more volume functions to the lua scripts
  • +
  • Allow one to delete voxels from within a lua script
  • +
  • Improved splitting of volumes (target volume size)
  • +
  • Expose more region functions to the lua scripts
  • +
  • Added more lua example scripts
  • +
  • Improved color sampling for voxelization
  • +
  • Started to support different palettes in one scene
  • +
  • Fixed vxc support
  • +
  • Load the palette from the source file
  • +
  • Fixed vxm file path when saving vxr
  • +
  • Save vxmc (version 12) now
  • +
  • Changed default ambient color and gamma values
  • +
  • Improved osx dmg file and app bundles
  • +
+

VoxEdit:

+
    +
  • Fixed start problems on some systems with multisampled framebuffers
  • +
  • Allow one to drag and drop colors from the palette
  • +
  • Change between the edit and scene mode is now bound to tab
  • +
  • Updated imgizmo to support clicking the view cube
  • +
  • Cursor is no volume anymore but a plane
  • +
  • Implemented plane filling
  • +
  • Added extrude feature
  • +
  • Allow one to place a single voxel
  • +
  • Fixed keyboard input errors that made the ui unusable
  • +
  • Don't reload the last opened file with every start
  • +
+

VoxConvert:

+
    +
  • Extended --dump to also show the key frames and the voxel count
  • +
  • Removed --src-palette (src palette is always used)
  • +
+

0.0.19 (2022-03-27)

+

General:

+
    +
  • Replaced minecraft support with own implementation
  • +
  • Added support for Sandbox VXA format (via VXR) and improved VXR
  • +
  • Allow one to change the ui colors via cvar (ui_style)
  • +
  • Added bloom render support for vox and vxm
  • +
  • Added support for loading key frames if the format supports it
  • +
  • Improved apple support in file dialog
  • +
  • The palette handling was refactored
  • +
  • Allow one to save the MATL chunk in magicavoxel vox files
  • +
  • Ability to scale exported mesh with different values for each axis
  • +
  • Added stl voxelization support
  • +
  • Allow one to modify the camera zoom min/max values
  • +
  • Allow one to load different sizes for AoS VXL files
  • +
  • Lerp the camera zooming
  • +
  • Added support for GLTF export
  • +
  • Added experimental export support for FBX ascii
  • +
  • Increased the max scene graph model nodes from 256 to 1024
  • +
+

VoxEdit:

+
    +
  • Added new command to fill hollows in models
  • +
  • Fixed escape key not closing the dialogs
  • +
  • Added support for drag and drop the nodes of the scene graph
  • +
  • Scene graph rendering improved
  • +
  • Removed noise panel (use the lua scripts for noise support)
  • +
  • Fixed a lot of undo/redo cases and improved the test cases a lot
  • +
  • Fixed viewport screenshot creation (now also bound to F5)
  • +
  • Added dialog to configure the mesh and voxel format settings for loading/saving
  • +
  • Improved the palette panel
  • +
  • Improved the gizmo for translation and rotation
  • +
  • Open in scene mode as default
  • +
+

VoxConvert:

+
    +
  • Added --image-as-plane and --image-as-heightmap parameters
  • +
  • Allow one to create a palette from input files
  • +
+

0.0.18 (2022-02-12)

+
+

renamed the github project to vengi - the url changed to https://github.com/vengi-voxel/vengi.

+
+

Build:

+
    +
  • Removed own cmake unity-build implementation
  • +
  • Fixed build when GAMES was set to OFF
  • +
+

General:

+
    +
  • Extended qbcl format support
  • +
  • Fixed color conversion issue when importing palettes from voxel models
  • +
  • Voxelization of obj meshes now also fills the inner parts of the mesh with voxels
  • +
  • Fixed magicavoxel pivot issue (sometimes wrong positions)
  • +
  • Added support for sandbox vxc format
  • +
  • Added support for sandbox vxt format
  • +
  • Added new example lua scripts
  • +
+

VoxConvert:

+
    +
  • --input can now also handle directories
  • +
+

VoxEdit:

+
    +
  • Added context actions to scene graph panel
  • +
  • Fixed mouse input issues in fullscreen mode
  • +
  • Fixed script editor placement
  • +
+

0.0.17 (2022-01-23)

+

General:

+
    +
  • Fixed relative path handling for registered paths
  • +
  • Stop event loop if window is minimized (reduce cpu usage)
  • +
  • Support scene graphs in the voxel formats
  • +
  • Fixed a few issues with the magicavoxel vox format (switched to ogt_vox)
  • +
  • Load properties from supported voxel formats (vxr, vox, gox)
  • +
  • Added support for loading minecraft region files (used enkimi)
  • +
  • Fixed vxm pivot and black color issue
  • +
  • Added obj voxelization
  • +
  • Improved obj export
  • +
  • Improved file dialog
  • +
+

VoxConvert:

+
    +
  • Added --crop parameter that reduces the volumes to their real voxel sizes
  • +
  • Added --split option to cut volumes into smaller pieces
  • +
  • Added --export-models to export all the models of a scene into single files
  • +
  • Added --dump to dump the scene graph of the input file
  • +
  • Added --resize to resize the volumes by the given x, y and z values
  • +
+

VoxEdit:

+
    +
  • Fixed torus shape
  • +
  • Added scene graph panel
  • +
  • Fixed an issue that delayed the start by a few seconds
  • +
+

0.0.16 (2021-12-27)

+

General:

+
    +
  • Fixed magicavoxel vox file saving
  • +
  • Added support for old magicavoxel (pre RIFF) format
  • +
  • Fixed bugs in binvox support
  • +
  • Fixed save dir for vxm files when saving vxr
  • +
  • Save vxm version 5 (with included pivot)
  • +
  • Support bigger volumes for magicavoxel files
  • +
+

VoxConvert:

+
    +
  • Fixed --force handling for target files
  • +
  • Allow one to operate on multiple input files
  • +
  • Added --translate command line option
  • +
  • Added --pivot command line option
  • +
  • nippon palette is not loaded if --src-palette is used and it's no hard error anymore if this fails
  • +
+

VoxEdit:

+
    +
  • Add recently used files to the ui
  • +
+

0.0.15 (2021-12-18)

+

General:

+
    +
  • Fixed missing vxm (version 4) saving support
  • +
  • Fixed missing palette value for vxm saving
  • +
  • Added support for loading only the palettes
  • +
  • Added support for goxel gox file format
  • +
  • Added support for sproxel csv file format
  • +
  • Added support for a lot more image formats
  • +
  • Improved lod creation for thin surface voxels
  • +
  • Fixed vxr9 load support
  • +
  • Added support for writing vxr files
  • +
+

VoxConvert:

+
    +
  • Added option to keep the input file palette and don't perform quantization
  • +
  • Allow one to export the palette to png
  • +
  • Allow one to generate models from heightmap images
  • +
  • Allow one to run lua scripts to modify volumes
  • +
  • Allow one to export or convert only single layers (--filter)
  • +
  • Allow one to mirror and rotate the volumes
  • +
+

Thumbnailer:

+
    +
  • Try to use the built-in palette for models
  • +
+

VoxEdit:

+
    +
  • Allow one to import palettes from volume formats, too
  • +
  • Implemented camera panning
  • +
  • Added more layer merge functions
  • +
+

0.0.14 (2021-11-21)

+

General:

+
    +
  • License for our own voxel models is now CC-BY-SA
  • +
  • Support loading just the thumbnails from voxel formats
  • +
  • Support bigger volume sizes for a few formats
  • +
  • Don't pollute the home directory with build dir settings
  • +
  • Fixed gamma handling in shaders
  • +
  • Added bookmark support to the ui dialog
  • +
+

Thumbnailer:

+
    +
  • Added qbcl thumbnail support
  • +
+

VoxEdit:

+
    +
  • Render the inactive layer in grayscale mode
  • +
+

0.0.13 (2021-10-29)

+

General:

+
    +
  • Logfile support added
  • +
  • Fixed windows DLL handling for animation hot reloading
  • +
+

UI:

+
    +
  • Fixed log notifications taking away the focus from the current widget
  • +
+

VoxEdit:

+
    +
  • Fixed windows OpenGL error while rendering the viewport
  • +
+

0.0.12 (2021-10-26)

+

General:

+
    +
  • Fixed a few windows compilation issues
  • +
  • Fixed issues in the automated build pipelines to produce windows binaries
  • +
+

0.0.11 (2021-10-25)

+

General:

+
    +
  • Added url command
  • +
  • Reduced memory allocations per frame
  • +
  • Added key bindings dialog
  • +
  • Added notifications for warnings and errors in the ui
  • +
  • Fixed Sandbox Voxedit VXM v12 loading and added saving support
  • +
  • Fixed MagicaVoxel vox file rotation handling
  • +
+

VoxEdit:

+
    +
  • Removed old ui and switched to dearimgui
  • +
  • Added lua script editor
  • +
  • Added noise api support to the lua scripts
  • +
+

0.0.10 (2021-09-19)

+

General:

+
    +
  • Added --version and -v commandline option to show the current version of each application
  • +
  • Fixed texture coordinate indices for multi layer obj exports
  • +
  • Improved magicavoxel transform support for some models
  • +
  • Fixed magicavoxel x-axis handling
  • +
  • Support newer versions of vxm and vxr
  • +
  • Fixed bug in file dialog which prevents you to delete characters #77
  • +
+

VoxEdit:

+
    +
  • Improved scene edit mode
  • +
  • Progress on the ui conversion to dearimgui
  • +
+

Tools:

+
    +
  • Rewrote the ai debugger
  • +
+

0.0.9 (2020-10-03)

+

General:

+
    +
  • Fixed obj texcoord export: Sampling the borders of the texel now
  • +
  • Added multi object support to obj export
  • +
+

0.0.8 (2020-09-30)

+

General:

+
    +
  • Added obj and ply export support
  • +
  • Restructured the documentation
  • +
  • Improved font support for imgui ui
  • +
+

Backend:

+
    +
  • Reworked ai debugging network protocol
  • +
  • Optimized behaviour tree filters
  • +
+

0.0.7 (2020-09-15)

+

General:

+
    +
  • Fixed wrong-name-for-symlinks shown
  • +
  • Added support for writing qef files
  • +
  • Added lua script interface to generate voxels
  • +
  • Added stacktrace support for windows
  • +
  • Refactored module structure (split app and core)
  • +
  • Optimized character animations
  • +
  • Hot reload character animation C++ source changes in debug builds
  • +
  • Added quaternion lua support
  • +
  • Updated external dependencies
  • +
  • Refactored lua bindings
  • +
  • Support Chronovox-Studio files (csm)
  • +
  • Support Nick's Voxel Model files (nvm)
  • +
  • Support more versions of the vxm format
  • +
+

VoxEdit:

+
    +
  • Converted some voxel generation functions to lua
  • +
  • Implemented new voxel generator scripts
  • +
+

0.0.6 (2020-08-02)

+

General:

+
    +
  • Fixed gamma cvar usage
  • +
  • Enable vsync by default
  • +
  • Updated external dependencies
  • +
  • Activated OpenCL in a few tools
  • +
  • Added symlink support to virtual filesystem
  • +
+

VoxEdit:

+
    +
  • Fixed loading palette lua script with material definitions
  • +
  • Fixed error in resetting mirror axis
  • +
  • Fixed noise generation
  • +
  • Reduced palette widget size
  • +
  • Fixed palette widget being invisible on some dpi scales
  • +
+

0.0.5 (2020-07-26)

+

Client:

+
    +
  • Fixed movement
  • +
+

Server:

+
    +
  • Fixed visibility check
  • +
  • Fixed segfault while removing npcs
  • +
+

VoxEdit:

+
    +
  • Started to add scene mode edit support (move volumes)
  • +
+

VoxConvert:

+
    +
  • Support different palette files (cvar palette)
  • +
  • Support writing outside the registered application paths
  • +
  • Allow one to overwrite existing files
  • +
+

General:

+
    +
  • Switched to qb as default volume format
  • +
  • Improved scene graph support for Magicavoxel vox files
  • +
  • Fixed invisible voxels for qb and qbt (Qubicle) volume format
  • +
  • Support automatic loading different volume formats for assets
  • +
  • Support Command&Conquer vxl files
  • +
  • Support Ace of Spades map files (vxl)
  • +
  • Support Qubicle exchange format (qef)
  • +
  • Perform mesh extraction in dedicated threads for simple volume rendering
  • +
  • Improved gizmo rendering and translation support
  • +
  • Fixed memory leaks on shutdown
  • +
  • Improved profiling support via tracy
  • +
+

0.0.4 (2020-06-07)

+

General:

+
    +
  • Added support for writing binvox files
  • +
  • Added support for reading kvx (Build-Engine) and kv6 (SLAB6) voxel volumes
  • +
  • Performed some AFL hardening on voxel format code
  • +
  • Don't execute keybindings if the console is active
  • +
  • Added basic shader storage buffer support
  • +
  • Reduced voxel vertex size from 16 to 8 bytes
  • +
  • Apply checkerboard pattern to water surface
  • +
  • Improved tracy profiling support
  • +
  • A few highdpi fixes
  • +
+

Server:

+
    +
  • Allow one to specify the database port
  • +
  • Fixed loading database chunks
  • +
+

VoxEdit:

+
    +
  • Added scale console command to produce LODs
  • +
+

VoxConvert:

+
    +
  • Added ability to merge all layers into one
  • +
+

0.0.3 (2020-05-17)

+

Assets:

+
    +
  • Added music tracks
  • +
  • Updated and added some new voxel models
  • +
+

VoxEdit:

+
    +
  • Made some commands available to the ui
  • +
  • Tweak thicken command
  • +
  • Updated default tree generation ui values
  • +
  • Save layers to all supported formats
  • +
  • Fixed tree generation issue for some tree types
  • +
  • Changed default reference position to be at the center bottom
  • +
  • Reduced max supported volume size
  • +
+

General:

+
    +
  • Print stacktraces on asserts
  • +
  • Improved tree generation (mainly used in voxedit)
  • +
  • Fixed a few asserts in debug mode for the microsoft stl
  • +
  • Added debian package support
  • +
  • Fixed a few undefined behaviour issues and integer overflows that could lead to problems
  • +
  • Reorganized some modules to speed up compilation and linking times
  • +
  • Improved audio support
  • +
  • Fixed timing issues
  • +
  • Fixed invalid GL states after deleting objects
  • +
+

VoxConvert:

+
    +
  • Added a new tool to convert different voxel volumes between supported formats + Currently supported are cub (CubeWorld), vox (MagicaVoxel), vmx (VoxEdit Sandbox), binvox + and qb/qbt (Qubicle)
  • +
+

Client:

+
    +
  • Added footstep and ambience sounds
  • +
+

0.0.2 (2020-05-06)

+

VoxEdit:

+
    +
  • Static linked VC++ Runtime
  • +
  • Extract voxels by color into own layers
  • +
  • Updated tree and noise windows
  • +
  • Implemented thicken console command
  • +
  • Escape abort modifier action
  • +
  • Added L-System panel
  • +
+

General:

+
    +
  • Fixed binvox header parsing
  • +
  • Improved compilation speed
  • +
  • Fixed compile errors with locally installed glm 0.9.9
  • +
  • Fixed setup-documentation errors
  • +
  • Fixed shader pipeline rebuilds if included shader files were modified
  • +
  • Improved palm tree generator
  • +
  • Optimized mesh extraction for the world (streaming volumes)
  • +
  • Added new voxel models
  • +
  • (Re-)added Tracy profiler support and removed own imgui-based implementation
  • +
  • Fixed writing of key bindings
  • +
  • Improved compile speed and further removed the STL from a lot of places
  • +
  • Updated all dependencies to their latest version
  • +
+

Server/Client:

+
    +
  • Added DBChunkPersister
  • +
  • Built-in HTTP server to download the chunks
  • +
  • Replaced ui for the client
  • +
+

Voxel rendering:

+
    +
  • Implemented reflection for water surfaces
  • +
  • Apply checkerboard pattern to voxel surfaces
  • +
  • Up-scaling effect for new voxel chunks while they pop in
  • +
  • Optimized rendering by not using one giant vbo
  • +
+

0.0.1 "Initial Release" (2020-02-08)

+

VoxEdit:

+
    +
  • initial release
  • +
+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Compilation/index.html b/Compilation/index.html new file mode 100644 index 0000000000..2ca4ee9815 --- /dev/null +++ b/Compilation/index.html @@ -0,0 +1,1352 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + Building - vengi - voxel tools + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

Building

+

The project should work on Linux, Windows and OSX. It should work with any ide that is either supported by cmake or has direct cmake support. Personally I'm using vscode with clangd at the moment. But also the command line with plain old make.

+

Linux

+

There is a Makefile wrapper around the build system. You can just run make in the project root folder.

+

Every project has some extra CMake targets. There are e.g. voxedit-run, voxedit-debug and voxedit-perf if the needed tools were found during cmake's configure phase.

+

That means that you can compile a single target by typing make voxedit, run it by typing make voxedit-run, debug it by typing make voxedit-debug and profile it by +typing make voxedit-perf. There are also other targets for valgrind - just use the tab completion in the build folder to get a list.

+

Windows

+

The project can be built with every ide that supports cmake. QTCreator, Eclipse CDT, vscode or Visual Studio. Just install cmake, generate the project files, and open them in your ide.

+
+

Set up ninja to speed up the whole build-link-run cycle a lot!

+
+

Visual Studio Code

+ +

Inside vscode you have to install the c++ plugins. The easiest might be to install the c++ plugins from microsoft. Just make sure the cmake plugin is part of the collection.

+

If you have problems with the intellisense plugin from microsoft, you can also use the clangd plugin.

+

Open your git clone directory in vscode and let it configure via cmake. It will pick ninja and the visual studio compiler automatically.

+

Make

+

In order to use the Makefile, you should install ninja (see above), gnu make, start Native Tools Command Prompt from your start menu, and just run make in that shell in your git clone directory. Keep in mind that ninja, make and cmake must be available via PATH environment variable.

+

Check out the Linux section about more details regarding the Makefile targets.

+
+
+

Here is a step-by-step guide from a user to compile vengi on a windows machine via command line make. After you've downloaded the above mentioned software, run the following steps:

+
    +
  • Install CMake
  • +
  • Win+R > type sysdm.cpl > Advanced > Environment Variables...
  • +
  • Click "New" and add this to your PATH: C:/Program Files (x86)/GnuWin32/bin
  • +
  • Add ninja.exe to PATH or if you're lazy paste it into C:/Program Files (x86)/GnuWin32/bin
  • +
  • Install Visual Studio Community
  • +
  • You need to add at least 2 Workloads before installation: "MSVC" & "C++ Address Sanitizer"
  • +
  • Navigate find the C/C++ compiler cl.exe somewhere in C:/Program Files/Microsoft Visual Studio/<year>/Community/VC/Tools/MSVC/<version>/bin/Hostx64/x64/cl.exe and copy this path. Example: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.38.33130/bin/Hostx64/x64/cl.exe
  • +
  • Copy the path in the folder address bar and add 3 more environment variables CC and CMAKE_C_COMPILER and CMAKE_CXX_COMPILERwith this path value.
  • +
  • Then add just the directory (without cl.exe) into the PATH environment variable
  • +
  • Open Visual Studio Community > Skip Sign-In > Skip this for Now
  • +
  • Restart computer
  • +
  • Windows > Search > x64 > open: x64 Native Tools Command Prompt for VS 2022
  • +
  • cd to the vengi folder
  • +
  • Type make to configure and build or build specific targets like make voxedit or make voxconvert
  • +
+

Environment vars +Add workloads +Select workloads +Installation

+

If you want to go further, install vcpkg - see dependencies for the command line - but you can skip here if you don't want vcpkg.

+
+

Mac

+

You can generate your xcode project via cmake or build like this:

+
mkdir build
+cd build
+cmake ..
+cmake --build .
+
+

If you are using the cmake Makefile generator, you get the same targets as for Linux above. You can also just type make voxedit-run to compile and run only VoxEdit.

+

Hints

+

If you encounter any problems, it's also a good start to check out the build pipelines of the project. +This is always the most up-to-date information about how-to-build-the-project that you will find. But +also please don't hesitate to ask for help on our discord server.

+

Enforce bundled libs

+

You can enforce the use of the bundled libs by putting a <LIB>_LOCAL=1 in your cmake cache. +Example: By putting LUA54_LOCAL=1 into your cmake cache, you enforce the use of the bundled lua sources from contrib/libs/lua54.

+

Build doxygen

+

Run make doc from the project root to execute doxygen. After that install the mcss theme as described here: mcss.mosra.cz/documentation/.

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Configuration/index.html b/Configuration/index.html new file mode 100644 index 0000000000..58998a7634 --- /dev/null +++ b/Configuration/index.html @@ -0,0 +1,1597 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + Configuration - vengi - voxel tools + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

Configuration

+

Variables

+

The engine can get configured by so called cvars (configuration variables). These variables can be modified from within +the game via key bindings, built-in console, the ui or scripts.

+

To get a list of supported cvars (they might differ from application to application), type the command cvarlist to the +built-in console - or execute the application with --help (Example: vengi-voxedit.exe --help).

+

The variables can get their initial value from various sources. The highest order is the command line. If you specify it on +the command line, every other method will not be used. If the engine finds the cvar name in your environment variables, this +one will take precedence over the one the is found in the configuration file. Next is the configuration file - this one will +take precedence over the default settings that are specified in the code.

+

The environment variable can be either lower case or upper case. For example it will work if you have CL_GAMMA or cl_gamma +exported. The lower case variant has the higher priority.

+

Commandline

+
./vengi-voxvonvert -set voxformat_scale 2.0 [...]
+
+

Environment

+
export VOXFORMAT_SCALE=2.0
+./vengi-voxconvert [...]
+
+

Configuration file

+
    +
  • Linux: ~/.local/share/vengi/voxconvert/voxconvert.vars
  • +
  • Windows: C:/Users/bob/AppData/Roaming/vengi/voxconvert/voxconvert.vars
  • +
  • Mac: /Users/bob/Library/Application Support/vengi/voxconvert/voxconvert.vars
  • +
+

Search paths

+

You can get a list of search paths by calling the particular application with the --help parameter on the command line. This will print a list of search paths. You can even add your own paths by setting the cvar core_path.

+
+

For packagers it might be interesting to set the PKGDATADIR cmake variable.

+
+

Commands

+

To get a list of supported commands (they might differ from application to application), type the command cmdlist to the built-in console.

+

You can also get a list when doing ./vengi-app --help on the command line.

+

Key bindings

+

You can also modify or add key bindings to commands. Type bindlist to the console to get a list of the current active bindings +(and also here: they might differ from application to application). The command bind can be used to configure keybindings on-the-fly. These bindings are saved to a file on shutdown.

+

VoxEdit has an ui panel to show the configured keybindings - see controls for more details.

+

Logging

+

You can either log via syslog (on unix) or to stdout (this might of course differ from platform to platform).

+

The log level is configured by the core_loglevel variable. The lower the value, the more you see. 1 is the highest log level +(trace), where 5 is the lowest log level (error).

+
    +
  • trace: 1
  • +
  • debug: 2
  • +
  • info: 3
  • +
  • warn: 4
  • +
  • error: 5
  • +
+

General

+

To get a rough usage overview, you can start any application with --help. It will print out the commands and configuration variables +with a description and hints how to modify/use them.

+

Video settings

+ + + + + + + + + + + + + + + + + + + + + +
NameDescription
cl_vsyncenable or disable v-sync
cl_gammatweak the gamma value that is applied last on rendering
cl_displaythe display index if you are using multiple monitors [0-numDisplays)
+

Voxel settings

+

A few cvars exists to tweak the export or import of several formats.

+

Some of these settings are only for voxel format, others are only for the mesh formats like ply, gltf, stl, fbx and obj.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDescriptionExample
core_colorreductionThis can be used to tweak the color reduction by switching to a different algorithm. Possible values are Octree, Wu, NeuQuant, KMeans and MedianCut. This is useful for mesh based formats or RGBA based formats like e.g. AceOfSpades vxl.Octree
voxel_meshmodeSet to 1 to use the marching cubes algorithm to produce the mesh0/1
voxformat_ambientocclusionDon't export extra quads for ambient occlusion voxelstrue/false
voxformat_colorasfloatExport the vertex colors as float or - if set to false - as byte values (GLTF/Unreal)true/false
voxformat_createpaletteSetting this to false will use use the palette configured by palette cvar and use those colors as a target. This is mostly useful for meshes with either texture or vertex colors or when importing rgba colors. This is not used for palette based formats - but also for RGBA based formats.true/false
voxformat_emptypaletteindexBy default this is -1 which means that no color is skipped. Pick 0-255 to remove that palette index from the final saved file. NOTE: this only works for formats that don't force the empty voxel to be 0 or 255 (or any other index) already
voxformat_fillhollowFill the inner parts of completely close objects, when voxelizing a mesh format. To fill the inner parts for non mesh formats, you can use the fillhollow.lua script.true/false
voxformat_gltf_khr_materials_pbrspecularglossinessApply KHR_materials_pbrSpecularGlossiness extension on saving gltf filestrue/false
voxformat_gltf_khr_materials_specularApply KHR_materials_specular extension on saving gltf filestrue/false
voxformat_mergequadsMerge similar quads to optimize the meshtrue/false
voxformat_mergeMerge all models into one objecttrue/false
voxformat_optimizeApply mesh optimizations when saving mesh based formatstrue/false
voxformat_pointcloudsizeSpecify the side length for the voxels when loading a point cloud1
voxformat_qbtpalettemodeUse palette mode in qubicle qbt exporttrue/false
voxformat_qbtmergecompoundsMerge compounds in qbt exporttrue/false
voxformat_qbsavelefthandedSave qubicle format as left handedtrue/false
voxformat_qbsavecompressedSave qubicle with RLE compressiontrue/false
voxformat_reuseverticesReuse vertices or always create new onestrue/false
voxformat_rgbflattenfactorTo flatten the RGB colors when importing volumes (0-255) from RGBA or mesh based formats1
voxformat_rgbweightedaverageIf multiple triangles contribute to the same voxel the color values are averaged based on their area contributiontrue/false
voxformat_scaleScale the vertices for voxelization on all axis by the given factor1.0
voxformat_scale_xScale the vertices for voxelization on X axis by the given factor1.0
voxformat_scale_yScale the vertices for voxelization on Y axis by the given factor1.0
voxformat_scale_zScale the vertices for voxelization on Z axis by the given factor1.0
voxformat_withmaterialsExport material properties for formats that supports thistrue/false
voxformat_transform_meshApply the keyframe transform to the meshtrue/false
voxformat_quadsExport to quadstrue/false
voxformat_voxcreategroupsMagicavoxel vox groupstrue/false
voxformat_voxcreatelayersMagicavoxel vox layerstrue/false
voxformat_voxelizemode0 = high quality, 1 = faster and less memory0/1
voxformat_vxlnormaltypeNormal type for VXL format - 2 (TS) or 4 (RedAlert2)2/4
voxformat_withcolorExport vertex colorstrue/false
voxformat_withnormalsExport smoothed normals for cubic surface meshes (marching cubes always uses normals)true/false
voxformat_withtexcoordsExport texture coordinatestrue/false
+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/CubicSurfaceExtractor1.png b/CubicSurfaceExtractor1.png new file mode 100644 index 0000000000000000000000000000000000000000..e9c64e409e7e0da768d796481da6dbee5a826060 GIT binary patch literal 11954 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 Oh_0rgM&`L2_x}&;rLC#} literal 0 HcmV?d00001 diff --git a/CubicSurfaceExtractor2.png b/CubicSurfaceExtractor2.png new file mode 100644 index 0000000000000000000000000000000000000000..6c67154b14b963d8e375078251a6a19baa8a3491 GIT binary patch literal 13766 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 literal 0 HcmV?d00001 diff --git a/Dependencies/index.html b/Dependencies/index.html new file mode 100644 index 0000000000..d2fad0a7b8 --- /dev/null +++ b/Dependencies/index.html @@ -0,0 +1,1297 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + Dependencies - vengi - voxel tools + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

Dependencies

+
    +
  • cmake
  • +
  • ninja-build or make
  • +
  • compiler (see compilation docs)
  • +
+

Libraries

+
    +
  • development headers/libs for
  • +
  • glm
  • +
  • lua >= 5.4
  • +
  • sdl2 > 2.0.16
  • +
  • gtest (and gmock)
  • +
  • freetype2 (optional)
  • +
+

Some of these dependencies might not be available as packages in your toolchain - most +of them are also bundled with the application. But local installed headers always have +the higher priority. Usually you don't have to install anything of these.

+

Debian

+
apt-get install binutils-dev libunwind-dev libglm-dev lua5.4 liblua5.4-dev libfreetype-dev libsdl2-dev wayland-protocols pkg-config
+
+

Arch

+
pacman -Sy git make cmake ninja sdl2 clang
+
+

Brew

+
brew install sdl2 freetype cmake ninja pkg-config
+
+

Windows

+
vcpkg install pkg-config sdl2 lua glm glslang gtest freetype
+
+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/FormatSpec/index.html b/FormatSpec/index.html new file mode 100644 index 0000000000..d92eab7aa6 --- /dev/null +++ b/FormatSpec/index.html @@ -0,0 +1,1324 @@ + + + + + + + + + + + + + + + + + + + + + + + VENGI File Format Specification - vengi - voxel tools + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

VENGI File Format Specification

+

Everything is stored in little endian.

+

Overview

+

The VENGI format is designed to store scene graph data including node properties, animations, voxel data, and palette information. The data is stored in a compressed format using ZIP compression.

+

File Structure

+

A VENGI file consists of the following main sections:

+
    +
  1. Magic Number: A 4-byte identifier VENG.
  2. +
  3. Zip data: zlib header (0x78, 0xDA)
      +
    • Version: A 4-byte version number. The current supported version is 3.
    • +
    • Scene Graph Data: Contains information about the scene graph nodes.
    • +
    +
  4. +
+

Node Structure

+

Nodes are composed of data chunks that each start with a FourCC code.

+
    +
  • NODE: Indicates the beginning of a scene graph node.
      +
    • PROP: Contains properties of a node (only present if there are properties).
    • +
    • DATA: Contains voxel data of a node (only if type is Model).
    • +
    • PALC: Contains palette colors (only present if PALI is not).
    • +
    • PALI: Contains a palette identifier (only present if PALC is not).
    • +
    • ANIM: Contains animation data for a node.
        +
      • KEYF[]: Contains keyframe data for an animation.
      • +
      • ENDA: Marks the end of an animation chunk.
      • +
      +
    • +
    • NODE[]: child nodes (only present if there are child nodes)
    • +
    • ENDN: Marks the end of a node chunk.
    • +
    +
  • +
+

Detailed Format Description

+

Magic Number and Version

+
    +
  • Magic Number: 0x56454E47 ('VENG')
  • +
  • Version: 4-byte unsigned integer (current version: 3 - already part of the compressed data)
  • +
  • Root node: The scene graph root node
  • +
+

Scene Graph Nodes

+

Each node chunk begins with the NODE FourCC and includes the following information:

+
    +
  • Node Name: String (16-bit length prefix, followed by UTF-8 encoded string)
  • +
  • Node Type: String (16-bit length prefix, followed by UTF-8 encoded string)
  • +
  • Node ID: 4-byte signed integer
  • +
  • Reference Node ID: 4-byte signed integer (for referenced nodes - -1 if no node is referenced)
  • +
  • Visibility: 1-byte boolean
  • +
  • Lock State: 1-byte boolean
  • +
  • Color: 4-byte ABGR value
  • +
  • Pivot: Three 4-byte floats (x, y, z)
  • +
  • Properties: Properties chunk - optional if the node doesn't have any properties
  • +
  • Palette: Palette chunk
  • +
  • Data: Data chunk
  • +
  • Animations: n-Animation chunks
  • +
  • Child nodes: Node chunk
  • +
+

Node types are:

+
    +
  • Root
  • +
  • Model
  • +
  • ModelReference
  • +
  • Group
  • +
  • Camera
  • +
  • Point
  • +
+

Each node has the FourCC ENDN at its end

+
+

You should not rely on the order of chunks when loading a vengi file.

+
+

Node Properties

+

Node properties are stored in the PROP chunk.

+
+

Note: This chunk is only available if the node has properties.

+
+
    +
  • FourCC: PROP
  • +
  • Property Count: 4-byte unsigned integer
  • +
  • Properties: For each property:
      +
    • Key: String (16-bit length prefix, followed by UTF-8 encoded string)
    • +
    • Value: String (16-bit length prefix, followed by UTF-8 encoded string)
    • +
    +
  • +
+

Voxel Data

+

Voxel data is stored in the DATA chunk.

+
+

Note: This chunk is only available if the node is a model node.

+
+
    +
  • FourCC: DATA
  • +
  • Region: Six 4-byte signed integers (lowerX, lowerY, lowerZ, upperX, upperY, upperZ)
  • +
  • Voxel Information: For each voxel in the region:
      +
    • Air: 1-byte boolean (true if air, false if solid)
    • +
    • Color: 1-byte unsigned integer (only if not air)
    • +
    +
  • +
+

The voxel data is stored like this:

+
for(x = mins.x; x <= maxs.x; ++x)
+ for(y = mins.y; y <= maxs.y; ++y)
+  for(z = mins.z; z <= maxs.z; ++z)
+   writeVoxelInformation(x, y, z)
+
+

Palette Colors

+

Palette colors are stored in the PALC chunk (or in PALI - see below):

+
    +
  • FourCC: PALC
  • +
  • Color Count: 4-byte unsigned integer
  • +
  • Colors: For each color:
      +
    • ABGR: 4-byte unsigned integer
    • +
    +
  • +
  • Emit Colors: For each color (deprecated):
      +
    • ABGR: 4-byte unsigned integer (always 0)
    • +
    +
  • +
  • Indices: For each color:
      +
    • Index: 1-byte unsigned integer
    • +
    +
  • +
  • Material Count: 4-byte unsigned integer
  • +
  • Materials: For each material:
      +
    • Type: 4-byte unsigned integer
    • +
    • Property Count: 1-byte unsigned integer
    • +
    • Properties: For each property:
        +
      • Name: String (16-bit length prefix, followed by UTF-8 encoded string)
      • +
      • Value: 4-byte float
      • +
      +
    • +
    +
  • +
+

Palette Identifier

+

Palette identifier is stored in the PALI chunk.

+
+

Note: This is only used if the palette is a built-in vengi [palette] (Palette.md) - otherwise the PALC chunk is used.

+
+
    +
  • FourCC: PALI
  • +
  • Palette Name: String (16-bit length prefix, followed by UTF-8 encoded string)
  • +
+

This is used for internal palettes.

+

Animations

+

Animations are stored in the ANIM chunk:

+
    +
  • FourCC: ANIM
  • +
  • Animation Name: String (16-bit length prefix, followed by UTF-8 encoded string)
  • +
  • Keyframes: Each keyframe starts with the KEYF chunk:
      +
    • FourCC: KEYF
    • +
    • Frame Index: 4-byte unsigned integer
    • +
    • Long Rotation: 1-byte boolean
    • +
    • Interpolation Type: String (16-bit length prefix, followed by UTF-8 encoded string)
    • +
    • Local Matrix: Sixteen 4-byte floats (4x4 matrix in row-major order)
    • +
    +
  • +
+

The end of the animation chunk is marked by the ENDA FourCC.

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Formats/index.html b/Formats/index.html new file mode 100644 index 0000000000..137c1545c0 --- /dev/null +++ b/Formats/index.html @@ -0,0 +1,1790 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + Formats - vengi - voxel tools + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

Formats

+

Voxel formats

+
+

The vengi format is the best supported format. Saving into any other format might lose several details from your scene. This depends on the capabilities of the format and the completeness of the implementation for supporting that particular format.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameExtensionLoadingSavingThumbnailsPaletteAnimations
AceOfSpadeskv6XXX
AceOfSpadesvxlXXX
AnimaToonscnXXX
BinVoxbinvoxXX
Build enginekvxXXX
ChronovoxcsmX
CubeWorldcubXXX
Cubzh3zhXXXX
Cubzh Worldb64X
GoxelgoxXXXX
MagicaVoxelvoxXXX
Magicavoxel XRAWxrawXXX
Minecraft level datdatX
Minecraft regionmcaXX
Minecraft schematicschematicXX
MinetestmtsXX
Nicks Voxel ModelnvmX
ParticubespcubesXXXX
Qubicle BinaryqbXXX
Qubicle Binary TreeqbtXXX
Qubicle ExchangeqefXX
Qubicle ProjectqbclXXXX
Rooms.xyz ThingthingXX
SLAB6 voxvoxXXX
Sandbox VoxEdit CollectionvxcXX
Sandbox VoxEdit HierarchyvxrXXX
Sandbox VoxEdit ModelvxmXXX
Sandbox VoxEdit TilemapvxtX
Sproxel csvcsvXXX
StarMade BlueprintsmentXX
StarMade TemplatesmtplXXX
Tiberian SunvxlXXXX
VengivengiXXXX
Voxel3Dv3aXX
VoxelBuildervbxX
VoxelMaxvmax.zipXXX
asepriteasepriteXX
+

Mesh formats

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameExtensionLoadingSavingAnimations
FBXfbxXX
GL Transmission FormatgltfXXX
Polygon File FormatplyXX
Quake 1bspX
Quake 2 Modelmd2X
Standard Triangle LanguagestlXX
UFO:Alien InvasionbspX
Wavefront ObjectobjXX
+

Point cloud support for ply and gtlf is implemented, too.

+

Palettes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameExtensionLoadingSaving
CSV PalettecsvXX
Gimp PalettegplXX
JASC PalettepalXX
Photoshop PaletteaseXX
Portable Network GraphicspngXX
Qubicle PaletteqsmX
RGB PalettepalXX
+
+

The gpl format also supports the Aseprite extension for alpha values

+
+

Images/textures

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameExtension
Bitmapbmp
DDSdds
Graphics Interchange Formatgif
JPEGjpeg
PKMpkm
PVRpvr
Photoshoppsd
Portable Anymappnm
Portable Network Graphicspng
Radiance rgbEhdr
Softimage PICpic
Targa image filetga
+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/LUAScript/index.html b/LUAScript/index.html new file mode 100644 index 0000000000..a49d2a30c7 --- /dev/null +++ b/LUAScript/index.html @@ -0,0 +1,2219 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + Scripting api - vengi - voxel tools + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + + + + + +
+
+ + + + + + + +

Scripting api

+

There is a console command (called xs) in voxedit and a command line parameter in voxconvert to execute lua scripts for generating voxels. This command expects the lua script filename (.lua can be omitted) and the additional arguments for the main() method.

+
+
+

If you are new to lua you can read more about it on lua-users.

+
+
+
+

voxedit

+

Calling xs <script> help (in the script console) will print the supported arguments for the given script file in voxedit.

+
+
+
+

voxconvert

+

./vengi-voxconvert --script "<script> help" --scriptcolor 1 --input in.qb --output out.qb

+

--scriptcolor defines the color palette index that is given to the script as parameter.

+
+
+

By default the script files will be searched in a scripts folder next to where the binary is located and in the usual search paths (see configuration for more details). You can also give the full path to the script file.

+

There are two functions in each script. One is called arguments and one main. arguments returns a list of parameters for the main function. The default parameters for main are node, region and color. color is the palette index starting from 0.

+

Examples

+

Without parameters

+
function main(node, region, color)
+    local volume = node:volume()
+    local mins = region:mins()
+    local maxs = region:maxs()
+    for x = mins.x, maxs.x do
+        for y = mins.y, maxs.y do
+            for z = mins.z, maxs.z do
+                volume:setVoxel(x, y, z, color)
+            end
+        end
+    end
+end
+
+

Execute this via console xs scriptfile

+

With one parameter

+
function arguments()
+    return {
+        { name = 'n', desc = 'height level delta', type = 'int', default = '2' }
+    }
+end
+
+function main(node, region, color, n)
+    [...]
+end
+
+

Execute this via console xs scriptfile 1 where 1 will be the value of n. Omitting the 1 will add the default value from the argument list.

+

Download a file and import it

+
local function basename(str)
+    local name = string.gsub(str, "(.*/)(.*)", "%2")
+    return name
+end
+
+function main(_, _, _)
+    local url = "https://github.com/vengi-voxel/vengi/raw/9c101f32b84f949ed82f7545883e80a318760580/data/voxel/guybrush.vox"
+    local filename = basename(url)
+    local stream = g_http.get(url)
+    g_import.scene(filename, stream)
+end
+
+

Find the best palette match

+
function main(node, region, color)
+    -- find match (palette index) for red in the current palette (RGB value)
+    -- this value can be used in e.g. volume:setVoxel(x, y, z, match)
+    local match = node:palette():match(255, 0, 0)
+    [...]
+end
+
+

This will find the best match in the currently used palette and return the index.

+

Arguments

+

Supported types are:

+
    +
  • +

    int: min, max values are supported, too

    +
  • +
  • +

    float: min, max values are supported, too

    +
  • +
  • +

    enum: enum as a property specifies a list of string separated by ,

    +
  • +
  • +

    str: string input

    +
  • +
  • +

    colorindex: a color index from current palette (clamped)

    +
  • +
  • +

    bool:

    +
  • +
+

The description field is just for the user interface of the script parameter list.

+

A default value can get set, too.

+

The order in the arguments table defines the order in which the arguments are passed over to the script.

+

SceneGraph

+

g_scenegraph lets you access different nodes or create new ones.

+

The functions are:

+
    +
  • +

    align(): Allow to align all nodes on the floor next to each other without overlapping.

    +
  • +
  • +

    new(name, [region], [visible]): Creates a new node with the given name, the size and position according to the region and an optional visible parameter. If region is given a model is created - otherwise a group node.

    +
  • +
  • +

    get([nodeId]): Returns the node for the given nodeId - if the nodeId is not given, it will return the current active node. Which by default is the node for the volume the script is currently executed for.

    +
  • +
  • +

    nodeIds(): Returns a table with all node ids of the current scene graph.

    +
  • +
+
local allNodeIds = g_scenegraph.nodeIds()
+for i, nodeId in ipairs(allNodeIds) do
+  -- Do something with each nodeId
+end
+
+
    +
  • updateTransforms(): Update the key frame transforms when they are dirty after changing values (see Keyframe)
  • +
+

SceneGraphNode

+
    +
  • +

    addAnimation(string): Add a new animation

    +
  • +
  • +

    addKeyFrame(frame): Add a new key frame for frame number and return it. E.g. addFrame(20) will add a new key frame for the frame 20.

    +
  • +
  • +

    id(): Returns the id of the current node

    +
  • +
  • +

    isModel(): Returns true if the node is a model node (it has a volume attached)

    +
  • +
  • +

    isReference(): Returns true if the node is a model reference

    +
  • +
  • +

    keyFrame(keyFrameIdx): Returns an existing keyframe (see below)

    +
  • +
  • +

    keyFrameForFrame(frame): Returns an existing keyframe that has a frame number <= the given frame

    +
  • +
  • +

    name(): Returns the current name of the node.

    +
  • +
  • +

    setName(string): Set the name of the node.

    +
  • +
  • +

    palette(): Returns the current palette of the node.

    +
  • +
  • +

    parent(): Returns the id of the parent node - or -1 if no parent exists (root node)

    +
  • +
  • +

    setAnimation(string): Activate the animation

    +
  • +
  • +

    setPalette(palette, [remap]): Change the palette or if remap is given and is true it remaps to the new palette

    +
  • +
  • +

    setPivot(vec3), setPivot(x, y, z):

    +
  • +
  • +

    volume(): Gives you access to the volume of the node.

    +
  • +
+

Access these functions like this:

+
local scenegraphnode = [...]
+local name = scenegraphnode:name()
+
+

Keyframe

+
+

Valid interpolation strings

+
    +
  • Instant
  • +
  • Linear
  • +
  • QuadEaseIn
  • +
  • QuadEaseOut
  • +
  • QuadEaseInOut
  • +
  • CubicEaseIn
  • +
  • CubicEaseOut
  • +
  • CubicEaseInOut
  • +
+
+
    +
  • +

    index(): Returns the key frame index

    +
  • +
  • +

    frame(): Returns the frame for this key frame object

    +
  • +
  • +

    interpolation(): Returns interpolation string

    +
  • +
  • +

    setInterpolation(string): Set the interpolation for this key frame - must be a valid string

    +
  • +
  • +

    localScale(): Returns the local scale vector

    +
  • +
  • +

    setLocalScale(vec3), setLocalScale(x, y, z):

    +
  • +
  • +

    localOrientation(): Returns a quaternion object

    +
  • +
  • +

    setLocalOrientation(quat), setLocalOrientation(x, y, z, w):

    +
  • +
  • +

    localTranslation(): Returns a vec3 object

    +
  • +
  • +

    setLocalTranslation(vec3), setLocalTranslation(x, y, z):

    +
  • +
  • +

    worldScale(): Returns a vec3 object

    +
  • +
  • +

    setWorldScale(vec3), setWorldScale(x, y, z):

    +
  • +
  • +

    worldOrientation(): Returns a quaternion object

    +
  • +
  • +

    setWorldOrientation(quat), setWorldOrientation(x, y, z, w):

    +
  • +
  • +

    worldTranslation(): Returns a vec3 object

    +
  • +
  • +

    setWorldTranslation(vec3), setWorldTranslation(x, y, z):

    +
  • +
+
+

NOTE After you've modified something on a key frame, you have to call g_scenegraph.updateTransforms()!

+
+

Palette and material

+

The node palette (node:palette()) has several methods to work with colors. E.g. to find a closest possible match for the given palette index.

+

The functions are:

+
    +
  • +

    color(paletteIndex): Pushes the vec4 of the color behind the palette index (0-255) as float values between 0.0 and 1.0.

    +
  • +
  • +

    colors(): Returns the palette RGBA colors as vec4 values.

    +
  • +
  • +

    load(palette): Allows to load a built-in palette or a filename to a supported palette format.

    +
  • +
  • +

    material(paletteIndex, material): Get the value of the material property for the given palette index.

    +
    +

    Valid material names

    +
    +
  • +
  • +

    match(r, g, b): Returns the closest possible palette color match for the given RGB (0-255) color. The returned palette index is in the range 0-255. This value can then be used for the setVoxel method.

    +
  • +
  • +

    setColor(paletteIndex, red, green, blue, [alpha]): Change the color of a palette entry to the given rgba values in the range [0-255].

    +
  • +
  • +

    setMaterial(paletteIndex, material, value): Set the value of the material property for the given palette index.

    +
    +

    Valid material names

    +
    +
  • +
  • +

    similar(paletteindex, [coloramount]): Return a table with similar colors given by their palette index.

    +
  • +
+

They are available as e.g. palette:color([...]), palette:match([...]) and so on.

+

You can create new palettes with the g_palette global by calling e.g.

+
local pal = g_palette.new()
+pal.load("built-in:minecraft")
+
+

Noise

+

The global g_noise supports a few noise generators:

+
    +
  • +

    noise2(v), noise3(v), noise4(v): Simplex noise. Uses the given vec2, vec3 or vec4 and returns a float value between 0.0 and 1.0.

    +
  • +
  • +

    fBm2(v, octaves, lacunarity, gain), fBm3(v, octaves, lacunarity, gain), fBm4(v, octaves, lacunarity, gain): Simplex noise fractal brownian motion sum. Uses the given vec2, vec3 or vec4 and returns a float value between 0.0 and 1.0.

    +
  • +
  • +

    ridgedMF2(v, offset, octaves, lacunarity, gain), ridgedMF3(v, offset, octaves, lacunarity, gain), ridgedMF4(v, offset, octaves, lacunarity, gain): Simplex ridged multi-fractal noise sum. Uses the given vec2, vec3 or vec4 and returns a float value between 0.0 and 1.0.

    +
  • +
  • +

    swissTurbulence(vec2, offset, octaves, lacunarity, gain, warp): blog post

    +
  • +
  • +

    voronoi(vec3, [frequency, seed, enableDistance]): Voronoi noise.

    +
  • +
  • +

    worley2(v), worley3(v): Simplex cellular/worley noise. Uses the given vec2 or vec3 and returns a float value between 0.0 and 1.0.

    +
  • +
+

They are available as e.g. g_noise.noise2([...]), g_noise.fBm3([...]) and so on.

+

Shape

+

The global g_shape supports a few shape generators:

+
    +
  • +

    cylinder(centerBottom, axis, radius, height, voxel): Create a cylinder at the given position. The position is the center of the bottom plate with the given axis (y is default) as the direction.

    +
  • +
  • +

    torus(center, minorRadius, majorRadius, voxel): Create a torus at the given position with the position being the center of the object.

    +
  • +
  • +

    ellipse(centerBottom, axis, width, height, depth, voxel): Create an ellipse at the given position. The position is the center of the bottom plate with the given axis (y is default) as the direction.

    +
  • +
  • +

    dome(centerBottom, axis, negative, width, height, depth, voxel): Create a dome at the given position. The position is the center of the bottom plate with the given axis (y is default) as the direction. negative: if true the dome will be placed in the negative direction of the axis.

    +
  • +
  • +

    cone(centerBottom, axis, negative, width, height, depth, voxel): Create a cone at the given position. The position is the center of the bottom plate with the given axis (y is default) as the direction. negative: if true the cone will be placed in the negative direction of the axis.

    +
  • +
  • +

    line(start, end, voxel): Create a line.

    +
  • +
  • +

    cube(position, width, height, depth, voxel): Create a cube with the given dimensions. The position is the lower left corner.

    +
  • +
  • +

    bezier(start, end, control, voxel): Create a bezier curve with the given start, end and control point

    +
  • +
+

They are available as e.g. g_shape.line([...]), g_shape.ellipse([...]) and so on.

+

Region

+
    +
  • +

    contains(region): Check whether the current region contains the given one. The test is inclusive such that a region is considered to be inside of itself.

    +
  • +
  • +

    intersects(region): Check whether the current region intersects with the given one.

    +
  • +
  • +

    mins(): The lower boundary of the region (inclusive).

    +
  • +
  • +

    maxs(): The upper boundary of the region (inclusive).

    +
  • +
  • +

    size(): The size of the region in voxels (ivec3).

    +
  • +
  • +

    setMins(mins): The lower boundary of the region - given as ivec3 (atm only available for palettes created with new).

    +
  • +
  • +

    setMaxs(maxs): The upper boundary of the region - given as ivec3 (atm only available for palettes created with new).

    +
  • +
  • +

    x(): The lower x boundary of the region.

    +
  • +
  • +

    y(): The lower y boundary of the region.

    +
  • +
  • +

    z(): The lower z bounary of the region.

    +
  • +
  • +

    width(): The width of the region measured in voxels.

    +
  • +
  • +

    height(): The height of the region measured in voxels.

    +
  • +
  • +

    depth(): The depth of the region measured in voxels.

    +
  • +
+

Access these functions like this:

+
local region = [...]
+local mins = region:mins()
+
+

To create new regions, you can use the g_region.new function which needs the lower and upper boundaries. For example

+
local myregion = g_region.new(0, 0, 0, 1, 1, 1) -- creates a region with 8 voxels
+
+
local myregion = g_region.new(0, 0, 0, 0, 0, 0) -- creates a region with 1 voxels
+
+

Volume

+
    +
  • +

    voxel(x, y, z): Returns the palette index of the voxel at the given position in the volume [0-255]. Or -1 if there is no voxel.

    +
  • +
  • +

    region(): Return the region of the volume.

    +
  • +
  • +

    text(ttffont, text, [x], [y], [z], [size=16], [thickness=1], [spacing=0]): Renders the given text. x, y, and z are the region lower boundary coordinates by default.

    +
  • +
  • +

    fillHollow([color]): Tries to fill all hollows in the volume.

    +
  • +
  • +

    hollow(): Removes non visible voxels.

    +
  • +
  • +

    importHeightmap(filename, [underground], [surface]): Imports the given image as heightmap into the current volume. Use the underground and surface voxel colors for this (or pick some defaults if they were not specified). Also see importColoredHeightmap if you want to colorize your surface.

    +
  • +
  • +

    importColoredHeightmap(filename, [underground]): Imports the given image as heightmap into the current volume. Use the underground voxel colors for this and determine the surface colors from the RGB channel of the given image. Other than with importHeightmap the height is encoded in the alpha channel with this method.

    +
  • +
  • +

    crop(): Crop the volume and remove empty spaces.

    +
  • +
  • +

    mirrorAxis([axis]): Mirror along the given axis - y is default.

    +
  • +
  • +

    move(x, [y], [z]): Move the voxels by the given units without modifying the boundaries of the volume.

    +
  • +
  • +

    rotateAxis([axis]): Rotate along the given axis - y is default.

    +
  • +
  • +

    translate(x, [y, z]): Translates the region of the volume. Keep in mind that this is not supported by every output format.

    +
  • +
  • +

    resize(x, [y, z, extendMins]): Resize the volume by the given sizes. If extendsMins is true the region dimensions are also increased on the lower corner.

    +
  • +
  • +

    setVoxel(x, y, z, color): Set the given color at the given coordinates in the volume. color must be in the range [0-255] or -1 to delete the voxel.

    +
  • +
+

Access these functions like this:

+
local volume = [...]
+local region = volume:region()
+
+

Vectors

+

Available vector types are vec2, vec3, vec4 and their integer types ivec2, ivec3, ivec4.

+

Access these functions like this:

+
local v1 = g_ivec3.new(1, 1, 1)
+
+

There are 3 possible components for this vector. You can also call g_ivec3.new(1) to fill all three values with a one. Or call it like this: g_ivec3.new(1, 2) to create a vector with the three components of 1, 2, 2.

+

Quaternion

+

For creating quaternions, you can use g_quat.new()

+
    +
  • +

    rotateXYZ(x, y, z): Rotates the object along the X, Y, and Z axes by the specified angles.

    +
  • +
  • +

    rotateXY(x, y)

    +
  • +
  • +

    rotateYZ(y, z)

    +
  • +
  • +

    rotateXZ(x, z)

    +
  • +
  • +

    rotateX(x): Rotates the object along the X axis by the specified angle.

    +
  • +
  • +

    rotateY(y): Rotates the object along the Y axis by the specified angle.

    +
  • +
  • +

    rotateZ(z): Rotates the object along the Z axis by the specified angle.

    +
  • +
+

HTTP

+

You can perform http requests from within the lua script to query apis or download files

+
local stream, responseHeaders = g_http.get("https://example.localhost")
+local str = stream:readString()
+print(str)
+for k, v in pairs(responseHeaders) do
+    print("key: " .. k .. ", value: " .. v)
+end
+
+
local requestHeaders = {}
+local stream, responseHeaders = g_http.get("https://example.localhost", requestHeaders)
+
+
local body = "my body"
+local stream, responseHeaders = g_http.post("https://example.localhost", body)
+local str = stream:readString()
+print(str)
+for k, v in pairs(responseHeaders) do
+    print("key: " .. k .. ", value: " .. v)
+end
+
+

Importer

+

g_import is a global that offers the ability to load images and palettes or imports scene graphs/formats from e.g. http downloads.

+
    +
  • +

    image(filename, stream): Returns an image that was loaded.

    +
  • +
  • +

    palette(filename, stream): Returns a palette that was loaded.

    +
  • +
  • +

    importScene(filename, stream): Imports the scene from the given stream into the existing scene (g_scenegraph).

    +
  • +
  • +

    importImageAsPlane(filename, image): Imports the given image as plane into the current scene graph and returns the node.

    +
  • +
+

Image

+
    +
  • name(): Returns the name of the image
  • +
+

Streams

+

When using e.g. the g_http requests, you get stream objects as return values.

+
    +
  • +

    readString([0-terminated:false]): Reads a string from the stream. If the optional parameter 0-terminated is set to true, it reads until a null character is encountered otherwise it will read the whole stream as a string.

    +
  • +
  • +

    readUInt8(): Reads an unsigned 8-bit integer from the stream.

    +
  • +
  • +

    readInt8(): Reads a signed 8-bit integer from the stream.

    +
  • +
  • +

    readUInt16(): Reads an unsigned 16-bit integer from the stream.

    +
  • +
  • +

    readInt16(): Reads a signed 16-bit integer from the stream.

    +
  • +
  • +

    readUInt32(): Reads an unsigned 32-bit integer from the stream.

    +
  • +
  • +

    readInt32(): Reads a signed 32-bit integer from the stream.

    +
  • +
  • +

    readUInt64(): Reads an unsigned 64-bit integer from the stream.

    +
  • +
  • +

    readInt64(): Reads a signed 64-bit integer from the stream.

    +
  • +
  • +

    readFloat(): Reads a 32-bit floating-point number from the stream.

    +
  • +
  • +

    readDouble(): Reads a 64-bit floating-point number from the stream.

    +
  • +
  • +

    writeString(str, [0-terminated:true]): Writes a string to the stream. If the optional parameter 0-terminated is set to true, it writes a null character at the end of the string.

    +
  • +
  • +

    writeUInt8(value): Writes an unsigned 8-bit integer to the stream.

    +
  • +
  • +

    writeInt8(value): Writes a signed 8-bit integer to the stream.

    +
  • +
  • +

    writeUInt16(value): Writes an unsigned 16-bit integer to the stream.

    +
  • +
  • +

    writeInt16(value): Writes a signed 16-bit integer to the stream.

    +
  • +
  • +

    writeUInt32(value): Writes an unsigned 32-bit integer to the stream.

    +
  • +
  • +

    writeInt32(value): Writes a signed 32-bit integer to the stream.

    +
  • +
  • +

    writeUInt64(value): Writes an unsigned 64-bit integer to the stream.

    +
  • +
  • +

    writeInt64(value): Writes a signed 64-bit integer to the stream.

    +
  • +
  • +

    writeFloat(value): Writes a 32-bit floating-point number to the stream.

    +
  • +
  • +

    writeDouble(value): Writes a 64-bit floating-point number to the stream.

    +
  • +
  • +

    eos(): returns whether the stream has reached its end

    +
  • +
  • +

    seek(offset, mode): change the position in the stream

    +
  • +
  • +

    tell(): returns the current position in the stream

    +
  • +
  • +

    pos(): alias for tell()

    +
  • +
  • +

    size(): returns the size of the stream

    +
  • +
+

Cvar

+
g_var.int("cl_gamma")
+
+
    +
  • +

    str(): Returns the string value of the cvar

    +
  • +
  • +

    bool(): Returns the bool value of the cvar

    +
  • +
  • +

    int(): Returns the int value of the cvar

    +
  • +
  • +

    float(): Returns the float values of the cvar

    +
  • +
  • +

    setStr(value: string): Sets the string value of the cvar

    +
  • +
  • +

    setBool(value: bool): Sets the bool value of the cvar

    +
  • +
  • +

    setInt(value: number): Sets the int value of the cvar

    +
  • +
  • +

    setFloat(value: number): Sets the float values of the cvar

    +
  • +
+
+

To get a full list of cvars use the console command cvarlist.

+
+

Command

+
g_cmd.execute("echo test")
+
+
    +
  • execute(cmdline: string): Execute any of the known commands
  • +
+
+

To get a full list of commands use the console command cmdlist.

+
+

Logging

+

To use the built-in logging facilities use g_log with info, debug, warn and error

+

Other useful information

+
    +
  • y going upwards - see basics for further details.
  • +
+

Available scripts

+

animate.lua

+

Add animations to an existing model if you name the nodes properly.

+

xs animate.lua

+

cover.lua

+

Generates a new voxel on top of others with the current selected color and the specified height.

+

cover

+

xs cover.lua 1

+

grass.lua

+

Generate grass on top of voxels.

+

grass

+

xs grass.lua

+

grid.lua

+

Generates a grid with given color, thickness and size.

+

grid

+

xs grid.lua 1 1 5 5 5

+

noise.lua

+

Generates perlin noise with the frequency and amplitude as parameters with the current selected color.

+

noise

+

xs noise.lua 0.3 1.0

+

pyramid.lua

+

Generates a pyramid with the current selected color and with each level being 3 voxels high.

+

pyramid

+

xs pyramid.lua 3

+

thicken.lua

+

Thickens the voxel - take 1 voxel and convert to 8 voxels (creates a new node for the result).

+

thickenbefore thickenafter

+

xs thicken.lua 1

+

others

+

There are other scripts available in the repository.

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Material/index.html b/Material/index.html new file mode 100644 index 0000000000..8963dbf6e4 --- /dev/null +++ b/Material/index.html @@ -0,0 +1,1288 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + Material - vengi - voxel tools + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

Material

+

Each color entry in the palette can have several material properties. Most of them are not handled in the vengi renderers, but can be useful when exporting the voxels to other formats.

+

Materials

+
+

The material support in vengi is modelled after magicavoxel.

+
+

The following material names are imported from magicavoxel and a few of them are exported to the GLTF-format.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Material nameGLTF mapping
metalpbrMetallicRoughness
roughnessKHR_materials_pbrSpecularGlossiness, pbrMetallicRoughness
specularKHR_materials_specular
indexOfRefractionKHR_materials_ior
attenuationKHR_materials_volume
flux
emitEmission texture
lowDynamicRange
densityKHR_materials_pbrSpecularGlossiness
sp
glossinessKHR_materials_pbrSpecularGlossiness
media
+

You can also modify these values via scripting.

+

GLTF extensions

+

Some of the material properties are exported to GLTF 2.0 or some of the extensions:

+ + + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/MinecraftAndVoxatron.jpg b/MinecraftAndVoxatron.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4c23d3c1d1202127bd791eda41102a22109a8ffd GIT binary patch literal 113536 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 JoW+F?M4F%nQ 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%0DeeB`H2CHH{{Ux6K2F}aZWb>aU_=D@tA$B1 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 literal 0 HcmV?d00001 diff --git a/Palette/index.html b/Palette/index.html new file mode 100644 index 0000000000..0a6dc9f523 --- /dev/null +++ b/Palette/index.html @@ -0,0 +1,1166 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + Palette - vengi - voxel tools + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

Palette

+

The engine is built around a palette of 256 colors. Custom palettes are supported. The images should have a 1x256 pixel dimension.

+

You can import palettes from a lot of different image, palette or voxel volume formats (if supported).

+

Each color entry can get material properties.

+

The palette can usually be specified by the cvar palette and can either be a full path to a png file or an identifier. +If you decide to use the identifier - e.g. nippon the palette cvar is set to this value and the engine will automatically search +all registered file system paths for a file named palette-nippon.png.

+

There are several built-in palettes available that can also be used as an identifier.

+
    +
  • built-in:commandandconquer
  • +
  • built-in:magicavoxel
  • +
  • built-in:minecraft
  • +
  • built-in:nippon
  • +
  • built-in:quake1
  • +
  • built-in:starmade
  • +
+

You can also download and import palettes from Lospec by specifying a palette like this:

+
    +
  • lospec:paletteid
  • +
+

This would try to download a palette with the id paletteid from lospec.com in the Gimp (gpl) format and automatically imports it.

+

There are several color or palette related cvars available:

+
    +
  • voxformat_createpalette: Allows you to disable the palette creation and use the palette specified via palette cvar
  • +
  • core_colorreduction: Allows you to specify a color reduction value when e.g. importing RGB(A) based voxel or mesh formats. Possible values are: Octree, Wu, MedianCut, KMeans, NeuQuant.
  • +
+

You can find the detailed description and more cvars by using e.g. the voxconvert --help parameter

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/ShaderTool/index.html b/ShaderTool/index.html new file mode 100644 index 0000000000..231a71da06 --- /dev/null +++ b/ShaderTool/index.html @@ -0,0 +1,1257 @@ + + + + + + + + + + + + + + + + + + + + + + + + + Shader integration - vengi - voxel tools + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

ShaderTool

+

This tool parses GLSL shader files (mainly *.vert, *.frag, *.geom and *.comp) and generates C++ source files for them.

+
+

You automatically get the shaders added back to the code after saving a shader file and trigger a re-build.

+
+

The cmake macros expect the shader source below the module in a shaders/ directory.

+
set(SHADERS first second)
+engine_generate_shaders(mymodulename ${SHADERS})
+
+

The shaders given in this example would be located at src/modules/mymodulename/shaders/first.*. The tool automatically detects the type of programs that should be connected in the final shader.

+

The code is generated into the build directory in generated/shaders.

+

Description

+

The generator uses ShaderTemplate.h.in and UniformBufferTemplate.h.in as a base to generate the C++ source files.

+

There are several variables in the template file that are replaced by the generator.

+
    +
  • $includes$
  • +
  • $namespace$
  • +
  • +

    $name$

    +
  • +
  • +

    $setters$

    +
  • +
  • $attributes$
  • +
  • $uniforms$
  • +
  • +

    $uniformarrayinfo$

    +
  • +
  • +

    $shutdown$

    +
  • +
  • $uniformbuffers$
  • +
+

The parser includes a preprocessor.

+

You can export constants from the GLSL shader code to the generated C++ code by using $constant.

+

Use $constant varname 42 to generate a method that returns 42 with a name getVarname

+

Branching / Feature toggles

+

Usually you don't have to use branching and uniforms for feature toggles. You can use cvars with the flag CV_SHADER set. If you are going to change one of these cvars, the shaders are recompiled with the value of the cvar given as preprocessor define.

+

This means that you can do stuff like:

+
#if cl_shadowmap == 1
+   [...]
+#else
+   [...]
+#endif
+
+

The #define of cl_shadowmap is done by the shader system at compile time.

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/Translation/index.html b/Translation/index.html new file mode 100644 index 0000000000..3899e4020f --- /dev/null +++ b/Translation/index.html @@ -0,0 +1,1216 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + Translation - vengi - voxel tools + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

Translation

+

The applications are directly reading po files.

+
+

What are po files? +po (portable object) files are used by the gettext translation system and a lot of tools exist to edit them (e.g. poedit)

+
+

To create a new translation you should use the pot file located in data/shared in the repository.

+

After you've created a new po file, copy them into any of the search paths (either directly, or in a folder named po) and give it the name as specified here.

+
+

Example: Name it after the pattern ll_CC where ll is an ISO-639 two-letter language code, and CC is an ISO-3166 two-letter country code.

+
+

If you create a new translation it would be nice if you would contribute it to the project.

+

Developers

+
+

Translators don't have to do this

+
+

Updating the pot file

+

After new string were added in the code, you have to update the pot file to make those strings available to the translators.

+

There is a Makefile target called pot - so if you have gnu make installed, just run make pot in the root of the project. Otherwise use the tool xgettext to extract the strings from the source code.

+

Mark strings as being translatable

+

use the _ macro to mark a string as being translatable. E.g. _("my string")

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/VisualTests/index.html b/VisualTests/index.html new file mode 100644 index 0000000000..a22c9702ac --- /dev/null +++ b/VisualTests/index.html @@ -0,0 +1,1385 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + Visual Tests - vengi - voxel tools + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

Visual Tests

+

These tests are dedicated test applications. They are no unit tests.

+

Unit tests are in their own module and available via

+
make tests
+
+

Run these test applications with

+
make __directoryname__-run
+
+

or by directly executing the generated binary after compiling them.

+

testbloom

+

A test application that applies bloom to an image

+

testcamera

+

Test camera options and collisions.

+

testglslcomp

+

Uses GLSL compute shader to render a circle.

+

testimgui

+

Test the dearimgui integration

+

testoctree

+

Renders the octree internals.

+

testoctreevisit

+

Visit the frustum in the octree.

+

testplane

+

Renders a plane object.

+

testshapebuilder

+

testtemplate

+

Just an empty template for new test applications.

+

testtexture

+

Renders a test 2d image.

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/assets/images/favicon.png b/assets/images/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..1cf13b9f9d978896599290a74f77d5dbe7d1655c GIT binary patch literal 1870 zcmV-U2eJ5xP)Gc)JR9QMau)O=X#!i9;T z37kk-upj^(fsR36MHs_+1RCI)NNu9}lD0S{B^g8PN?Ww(5|~L#Ng*g{WsqleV}|#l zz8@ri&cTzw_h33bHI+12+kK6WN$h#n5cD8OQt`5kw6p~9H3()bUQ8OS4Q4HTQ=1Ol z_JAocz`fLbT2^{`8n~UAo=#AUOf=SOq4pYkt;XbC&f#7lb$*7=$na!mWCQ`dBQsO0 zLFBSPj*N?#u5&pf2t4XjEGH|=pPQ8xh7tpx;US5Cx_Ju;!O`ya-yF`)b%TEt5>eP1ZX~}sjjA%FJF?h7cX8=b!DZl<6%Cv z*G0uvvU+vmnpLZ2paivG-(cd*y3$hCIcsZcYOGh{$&)A6*XX&kXZd3G8m)G$Zz-LV z^GF3VAW^Mdv!)4OM8EgqRiz~*Cji;uzl2uC9^=8I84vNp;ltJ|q-*uQwGp2ma6cY7 z;`%`!9UXO@fr&Ebapfs34OmS9^u6$)bJxrucutf>`dKPKT%%*d3XlFVKunp9 zasduxjrjs>f8V=D|J=XNZp;_Zy^WgQ$9WDjgY=z@stwiEBm9u5*|34&1Na8BMjjgf3+SHcr`5~>oz1Y?SW^=K z^bTyO6>Gar#P_W2gEMwq)ot3; zREHn~U&Dp0l6YT0&k-wLwYjb?5zGK`W6S2v+K>AM(95m2C20L|3m~rN8dprPr@t)5lsk9Hu*W z?pS990s;Ez=+Rj{x7p``4>+c0G5^pYnB1^!TL=(?HLHZ+HicG{~4F1d^5Awl_2!1jICM-!9eoLhbbT^;yHcefyTAaqRcY zmuctDopPT!%k+}x%lZRKnzykr2}}XfG_ne?nRQO~?%hkzo;@RN{P6o`&mMUWBYMTe z6i8ChtjX&gXl`nvrU>jah)2iNM%JdjqoaeaU%yVn!^70x-flljp6Q5tK}5}&X8&&G zX3fpb3E(!rH=zVI_9Gjl45w@{(ITqngWFe7@9{mX;tO25Z_8 zQHEpI+FkTU#4xu>RkN>b3Tnc3UpWzPXWm#o55GKF09j^Mh~)K7{QqbO_~(@CVq! zS<8954|P8mXN2MRs86xZ&Q4EfM@JB94b=(YGuk)s&^jiSF=t3*oNK3`rD{H`yQ?d; ztE=laAUoZx5?RC8*WKOj`%LXEkgDd>&^Q4M^z`%u0rg-It=hLCVsq!Z%^6eB-OvOT zFZ28TN&cRmgU}Elrnk43)!>Z1FCPL2K$7}gwzIc48NX}#!A1BpJP?#v5wkNprhV** z?Cpalt1oH&{r!o3eSKc&ap)iz2BTn_VV`4>9M^b3;(YY}4>#ML6{~(4mH+?%07*qo IM6N<$f(jP3KmY&$ literal 0 HcmV?d00001 diff --git a/assets/javascripts/bundle.ad660dcc.min.js b/assets/javascripts/bundle.ad660dcc.min.js new file mode 100644 index 0000000000..0ffc0460a4 --- /dev/null +++ b/assets/javascripts/bundle.ad660dcc.min.js @@ -0,0 +1,29 @@ +"use strict";(()=>{var Fi=Object.create;var gr=Object.defineProperty;var ji=Object.getOwnPropertyDescriptor;var Wi=Object.getOwnPropertyNames,Dt=Object.getOwnPropertySymbols,Ui=Object.getPrototypeOf,xr=Object.prototype.hasOwnProperty,no=Object.prototype.propertyIsEnumerable;var oo=(e,t,r)=>t in e?gr(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,R=(e,t)=>{for(var r in t||(t={}))xr.call(t,r)&&oo(e,r,t[r]);if(Dt)for(var r of Dt(t))no.call(t,r)&&oo(e,r,t[r]);return e};var io=(e,t)=>{var r={};for(var o in e)xr.call(e,o)&&t.indexOf(o)<0&&(r[o]=e[o]);if(e!=null&&Dt)for(var o of Dt(e))t.indexOf(o)<0&&no.call(e,o)&&(r[o]=e[o]);return r};var yr=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Di=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of Wi(t))!xr.call(e,n)&&n!==r&&gr(e,n,{get:()=>t[n],enumerable:!(o=ji(t,n))||o.enumerable});return e};var Vt=(e,t,r)=>(r=e!=null?Fi(Ui(e)):{},Di(t||!e||!e.__esModule?gr(r,"default",{value:e,enumerable:!0}):r,e));var ao=(e,t,r)=>new Promise((o,n)=>{var i=p=>{try{s(r.next(p))}catch(c){n(c)}},a=p=>{try{s(r.throw(p))}catch(c){n(c)}},s=p=>p.done?o(p.value):Promise.resolve(p.value).then(i,a);s((r=r.apply(e,t)).next())});var co=yr((Er,so)=>{(function(e,t){typeof Er=="object"&&typeof so!="undefined"?t():typeof define=="function"&&define.amd?define(t):t()})(Er,function(){"use strict";function e(r){var o=!0,n=!1,i=null,a={text:!0,search:!0,url:!0,tel:!0,email:!0,password:!0,number:!0,date:!0,month:!0,week:!0,time:!0,datetime:!0,"datetime-local":!0};function s(H){return!!(H&&H!==document&&H.nodeName!=="HTML"&&H.nodeName!=="BODY"&&"classList"in H&&"contains"in H.classList)}function p(H){var mt=H.type,ze=H.tagName;return!!(ze==="INPUT"&&a[mt]&&!H.readOnly||ze==="TEXTAREA"&&!H.readOnly||H.isContentEditable)}function c(H){H.classList.contains("focus-visible")||(H.classList.add("focus-visible"),H.setAttribute("data-focus-visible-added",""))}function l(H){H.hasAttribute("data-focus-visible-added")&&(H.classList.remove("focus-visible"),H.removeAttribute("data-focus-visible-added"))}function f(H){H.metaKey||H.altKey||H.ctrlKey||(s(r.activeElement)&&c(r.activeElement),o=!0)}function u(H){o=!1}function h(H){s(H.target)&&(o||p(H.target))&&c(H.target)}function w(H){s(H.target)&&(H.target.classList.contains("focus-visible")||H.target.hasAttribute("data-focus-visible-added"))&&(n=!0,window.clearTimeout(i),i=window.setTimeout(function(){n=!1},100),l(H.target))}function A(H){document.visibilityState==="hidden"&&(n&&(o=!0),te())}function te(){document.addEventListener("mousemove",J),document.addEventListener("mousedown",J),document.addEventListener("mouseup",J),document.addEventListener("pointermove",J),document.addEventListener("pointerdown",J),document.addEventListener("pointerup",J),document.addEventListener("touchmove",J),document.addEventListener("touchstart",J),document.addEventListener("touchend",J)}function ie(){document.removeEventListener("mousemove",J),document.removeEventListener("mousedown",J),document.removeEventListener("mouseup",J),document.removeEventListener("pointermove",J),document.removeEventListener("pointerdown",J),document.removeEventListener("pointerup",J),document.removeEventListener("touchmove",J),document.removeEventListener("touchstart",J),document.removeEventListener("touchend",J)}function J(H){H.target.nodeName&&H.target.nodeName.toLowerCase()==="html"||(o=!1,ie())}document.addEventListener("keydown",f,!0),document.addEventListener("mousedown",u,!0),document.addEventListener("pointerdown",u,!0),document.addEventListener("touchstart",u,!0),document.addEventListener("visibilitychange",A,!0),te(),r.addEventListener("focus",h,!0),r.addEventListener("blur",w,!0),r.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&r.host?r.host.setAttribute("data-js-focus-visible",""):r.nodeType===Node.DOCUMENT_NODE&&(document.documentElement.classList.add("js-focus-visible"),document.documentElement.setAttribute("data-js-focus-visible",""))}if(typeof window!="undefined"&&typeof document!="undefined"){window.applyFocusVisiblePolyfill=e;var t;try{t=new CustomEvent("focus-visible-polyfill-ready")}catch(r){t=document.createEvent("CustomEvent"),t.initCustomEvent("focus-visible-polyfill-ready",!1,!1,{})}window.dispatchEvent(t)}typeof document!="undefined"&&e(document)})});var Yr=yr((Rt,Kr)=>{/*! + * clipboard.js v2.0.11 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */(function(t,r){typeof Rt=="object"&&typeof Kr=="object"?Kr.exports=r():typeof define=="function"&&define.amd?define([],r):typeof Rt=="object"?Rt.ClipboardJS=r():t.ClipboardJS=r()})(Rt,function(){return function(){var e={686:function(o,n,i){"use strict";i.d(n,{default:function(){return Ii}});var a=i(279),s=i.n(a),p=i(370),c=i.n(p),l=i(817),f=i.n(l);function u(V){try{return document.execCommand(V)}catch(_){return!1}}var h=function(_){var O=f()(_);return u("cut"),O},w=h;function A(V){var _=document.documentElement.getAttribute("dir")==="rtl",O=document.createElement("textarea");O.style.fontSize="12pt",O.style.border="0",O.style.padding="0",O.style.margin="0",O.style.position="absolute",O.style[_?"right":"left"]="-9999px";var j=window.pageYOffset||document.documentElement.scrollTop;return O.style.top="".concat(j,"px"),O.setAttribute("readonly",""),O.value=V,O}var te=function(_,O){var j=A(_);O.container.appendChild(j);var D=f()(j);return u("copy"),j.remove(),D},ie=function(_){var O=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body},j="";return typeof _=="string"?j=te(_,O):_ instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(_==null?void 0:_.type)?j=te(_.value,O):(j=f()(_),u("copy")),j},J=ie;function H(V){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?H=function(O){return typeof O}:H=function(O){return O&&typeof Symbol=="function"&&O.constructor===Symbol&&O!==Symbol.prototype?"symbol":typeof O},H(V)}var mt=function(){var _=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},O=_.action,j=O===void 0?"copy":O,D=_.container,Y=_.target,ke=_.text;if(j!=="copy"&&j!=="cut")throw new Error('Invalid "action" value, use either "copy" or "cut"');if(Y!==void 0)if(Y&&H(Y)==="object"&&Y.nodeType===1){if(j==="copy"&&Y.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if(j==="cut"&&(Y.hasAttribute("readonly")||Y.hasAttribute("disabled")))throw new Error(`Invalid "target" attribute. You can't cut text from elements with "readonly" or "disabled" attributes`)}else throw new Error('Invalid "target" value, use a valid Element');if(ke)return J(ke,{container:D});if(Y)return j==="cut"?w(Y):J(Y,{container:D})},ze=mt;function Ie(V){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?Ie=function(O){return typeof O}:Ie=function(O){return O&&typeof Symbol=="function"&&O.constructor===Symbol&&O!==Symbol.prototype?"symbol":typeof O},Ie(V)}function _i(V,_){if(!(V instanceof _))throw new TypeError("Cannot call a class as a function")}function ro(V,_){for(var O=0;O<_.length;O++){var j=_[O];j.enumerable=j.enumerable||!1,j.configurable=!0,"value"in j&&(j.writable=!0),Object.defineProperty(V,j.key,j)}}function Ai(V,_,O){return _&&ro(V.prototype,_),O&&ro(V,O),V}function Ci(V,_){if(typeof _!="function"&&_!==null)throw new TypeError("Super expression must either be null or a function");V.prototype=Object.create(_&&_.prototype,{constructor:{value:V,writable:!0,configurable:!0}}),_&&br(V,_)}function br(V,_){return br=Object.setPrototypeOf||function(j,D){return j.__proto__=D,j},br(V,_)}function Hi(V){var _=Pi();return function(){var j=Wt(V),D;if(_){var Y=Wt(this).constructor;D=Reflect.construct(j,arguments,Y)}else D=j.apply(this,arguments);return ki(this,D)}}function ki(V,_){return _&&(Ie(_)==="object"||typeof _=="function")?_:$i(V)}function $i(V){if(V===void 0)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return V}function Pi(){if(typeof Reflect=="undefined"||!Reflect.construct||Reflect.construct.sham)return!1;if(typeof Proxy=="function")return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(V){return!1}}function Wt(V){return Wt=Object.setPrototypeOf?Object.getPrototypeOf:function(O){return O.__proto__||Object.getPrototypeOf(O)},Wt(V)}function vr(V,_){var O="data-clipboard-".concat(V);if(_.hasAttribute(O))return _.getAttribute(O)}var Ri=function(V){Ci(O,V);var _=Hi(O);function O(j,D){var Y;return _i(this,O),Y=_.call(this),Y.resolveOptions(D),Y.listenClick(j),Y}return Ai(O,[{key:"resolveOptions",value:function(){var D=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};this.action=typeof D.action=="function"?D.action:this.defaultAction,this.target=typeof D.target=="function"?D.target:this.defaultTarget,this.text=typeof D.text=="function"?D.text:this.defaultText,this.container=Ie(D.container)==="object"?D.container:document.body}},{key:"listenClick",value:function(D){var Y=this;this.listener=c()(D,"click",function(ke){return Y.onClick(ke)})}},{key:"onClick",value:function(D){var Y=D.delegateTarget||D.currentTarget,ke=this.action(Y)||"copy",Ut=ze({action:ke,container:this.container,target:this.target(Y),text:this.text(Y)});this.emit(Ut?"success":"error",{action:ke,text:Ut,trigger:Y,clearSelection:function(){Y&&Y.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(D){return vr("action",D)}},{key:"defaultTarget",value:function(D){var Y=vr("target",D);if(Y)return document.querySelector(Y)}},{key:"defaultText",value:function(D){return vr("text",D)}},{key:"destroy",value:function(){this.listener.destroy()}}],[{key:"copy",value:function(D){var Y=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body};return J(D,Y)}},{key:"cut",value:function(D){return w(D)}},{key:"isSupported",value:function(){var D=arguments.length>0&&arguments[0]!==void 0?arguments[0]:["copy","cut"],Y=typeof D=="string"?[D]:D,ke=!!document.queryCommandSupported;return Y.forEach(function(Ut){ke=ke&&!!document.queryCommandSupported(Ut)}),ke}}]),O}(s()),Ii=Ri},828:function(o){var n=9;if(typeof Element!="undefined"&&!Element.prototype.matches){var i=Element.prototype;i.matches=i.matchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.oMatchesSelector||i.webkitMatchesSelector}function a(s,p){for(;s&&s.nodeType!==n;){if(typeof s.matches=="function"&&s.matches(p))return s;s=s.parentNode}}o.exports=a},438:function(o,n,i){var a=i(828);function s(l,f,u,h,w){var A=c.apply(this,arguments);return l.addEventListener(u,A,w),{destroy:function(){l.removeEventListener(u,A,w)}}}function p(l,f,u,h,w){return typeof l.addEventListener=="function"?s.apply(null,arguments):typeof u=="function"?s.bind(null,document).apply(null,arguments):(typeof l=="string"&&(l=document.querySelectorAll(l)),Array.prototype.map.call(l,function(A){return s(A,f,u,h,w)}))}function c(l,f,u,h){return function(w){w.delegateTarget=a(w.target,f),w.delegateTarget&&h.call(l,w)}}o.exports=p},879:function(o,n){n.node=function(i){return i!==void 0&&i instanceof HTMLElement&&i.nodeType===1},n.nodeList=function(i){var a=Object.prototype.toString.call(i);return i!==void 0&&(a==="[object NodeList]"||a==="[object HTMLCollection]")&&"length"in i&&(i.length===0||n.node(i[0]))},n.string=function(i){return typeof i=="string"||i instanceof String},n.fn=function(i){var a=Object.prototype.toString.call(i);return a==="[object Function]"}},370:function(o,n,i){var a=i(879),s=i(438);function p(u,h,w){if(!u&&!h&&!w)throw new Error("Missing required arguments");if(!a.string(h))throw new TypeError("Second argument must be a String");if(!a.fn(w))throw new TypeError("Third argument must be a Function");if(a.node(u))return c(u,h,w);if(a.nodeList(u))return l(u,h,w);if(a.string(u))return f(u,h,w);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function c(u,h,w){return u.addEventListener(h,w),{destroy:function(){u.removeEventListener(h,w)}}}function l(u,h,w){return Array.prototype.forEach.call(u,function(A){A.addEventListener(h,w)}),{destroy:function(){Array.prototype.forEach.call(u,function(A){A.removeEventListener(h,w)})}}}function f(u,h,w){return s(document.body,u,h,w)}o.exports=p},817:function(o){function n(i){var a;if(i.nodeName==="SELECT")i.focus(),a=i.value;else if(i.nodeName==="INPUT"||i.nodeName==="TEXTAREA"){var s=i.hasAttribute("readonly");s||i.setAttribute("readonly",""),i.select(),i.setSelectionRange(0,i.value.length),s||i.removeAttribute("readonly"),a=i.value}else{i.hasAttribute("contenteditable")&&i.focus();var p=window.getSelection(),c=document.createRange();c.selectNodeContents(i),p.removeAllRanges(),p.addRange(c),a=p.toString()}return a}o.exports=n},279:function(o){function n(){}n.prototype={on:function(i,a,s){var p=this.e||(this.e={});return(p[i]||(p[i]=[])).push({fn:a,ctx:s}),this},once:function(i,a,s){var p=this;function c(){p.off(i,c),a.apply(s,arguments)}return c._=a,this.on(i,c,s)},emit:function(i){var a=[].slice.call(arguments,1),s=((this.e||(this.e={}))[i]||[]).slice(),p=0,c=s.length;for(p;p{"use strict";/*! + * escape-html + * Copyright(c) 2012-2013 TJ Holowaychuk + * Copyright(c) 2015 Andreas Lubbe + * Copyright(c) 2015 Tiancheng "Timothy" Gu + * MIT Licensed + */var ts=/["'&<>]/;ei.exports=rs;function rs(e){var t=""+e,r=ts.exec(t);if(!r)return t;var o,n="",i=0,a=0;for(i=r.index;i0&&i[i.length-1])&&(c[0]===6||c[0]===2)){r=0;continue}if(c[0]===3&&(!i||c[1]>i[0]&&c[1]=e.length&&(e=void 0),{value:e&&e[o++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function N(e,t){var r=typeof Symbol=="function"&&e[Symbol.iterator];if(!r)return e;var o=r.call(e),n,i=[],a;try{for(;(t===void 0||t-- >0)&&!(n=o.next()).done;)i.push(n.value)}catch(s){a={error:s}}finally{try{n&&!n.done&&(r=o.return)&&r.call(o)}finally{if(a)throw a.error}}return i}function q(e,t,r){if(r||arguments.length===2)for(var o=0,n=t.length,i;o1||s(u,h)})})}function s(u,h){try{p(o[u](h))}catch(w){f(i[0][3],w)}}function p(u){u.value instanceof nt?Promise.resolve(u.value.v).then(c,l):f(i[0][2],u)}function c(u){s("next",u)}function l(u){s("throw",u)}function f(u,h){u(h),i.shift(),i.length&&s(i[0][0],i[0][1])}}function mo(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t=e[Symbol.asyncIterator],r;return t?t.call(e):(e=typeof de=="function"?de(e):e[Symbol.iterator](),r={},o("next"),o("throw"),o("return"),r[Symbol.asyncIterator]=function(){return this},r);function o(i){r[i]=e[i]&&function(a){return new Promise(function(s,p){a=e[i](a),n(s,p,a.done,a.value)})}}function n(i,a,s,p){Promise.resolve(p).then(function(c){i({value:c,done:s})},a)}}function k(e){return typeof e=="function"}function ft(e){var t=function(o){Error.call(o),o.stack=new Error().stack},r=e(t);return r.prototype=Object.create(Error.prototype),r.prototype.constructor=r,r}var zt=ft(function(e){return function(r){e(this),this.message=r?r.length+` errors occurred during unsubscription: +`+r.map(function(o,n){return n+1+") "+o.toString()}).join(` + `):"",this.name="UnsubscriptionError",this.errors=r}});function qe(e,t){if(e){var r=e.indexOf(t);0<=r&&e.splice(r,1)}}var Fe=function(){function e(t){this.initialTeardown=t,this.closed=!1,this._parentage=null,this._finalizers=null}return e.prototype.unsubscribe=function(){var t,r,o,n,i;if(!this.closed){this.closed=!0;var a=this._parentage;if(a)if(this._parentage=null,Array.isArray(a))try{for(var s=de(a),p=s.next();!p.done;p=s.next()){var c=p.value;c.remove(this)}}catch(A){t={error:A}}finally{try{p&&!p.done&&(r=s.return)&&r.call(s)}finally{if(t)throw t.error}}else a.remove(this);var l=this.initialTeardown;if(k(l))try{l()}catch(A){i=A instanceof zt?A.errors:[A]}var f=this._finalizers;if(f){this._finalizers=null;try{for(var u=de(f),h=u.next();!h.done;h=u.next()){var w=h.value;try{fo(w)}catch(A){i=i!=null?i:[],A instanceof zt?i=q(q([],N(i)),N(A.errors)):i.push(A)}}}catch(A){o={error:A}}finally{try{h&&!h.done&&(n=u.return)&&n.call(u)}finally{if(o)throw o.error}}}if(i)throw new zt(i)}},e.prototype.add=function(t){var r;if(t&&t!==this)if(this.closed)fo(t);else{if(t instanceof e){if(t.closed||t._hasParent(this))return;t._addParent(this)}(this._finalizers=(r=this._finalizers)!==null&&r!==void 0?r:[]).push(t)}},e.prototype._hasParent=function(t){var r=this._parentage;return r===t||Array.isArray(r)&&r.includes(t)},e.prototype._addParent=function(t){var r=this._parentage;this._parentage=Array.isArray(r)?(r.push(t),r):r?[r,t]:t},e.prototype._removeParent=function(t){var r=this._parentage;r===t?this._parentage=null:Array.isArray(r)&&qe(r,t)},e.prototype.remove=function(t){var r=this._finalizers;r&&qe(r,t),t instanceof e&&t._removeParent(this)},e.EMPTY=function(){var t=new e;return t.closed=!0,t}(),e}();var Tr=Fe.EMPTY;function qt(e){return e instanceof Fe||e&&"closed"in e&&k(e.remove)&&k(e.add)&&k(e.unsubscribe)}function fo(e){k(e)?e():e.unsubscribe()}var $e={onUnhandledError:null,onStoppedNotification:null,Promise:void 0,useDeprecatedSynchronousErrorHandling:!1,useDeprecatedNextContext:!1};var ut={setTimeout:function(e,t){for(var r=[],o=2;o0},enumerable:!1,configurable:!0}),t.prototype._trySubscribe=function(r){return this._throwIfClosed(),e.prototype._trySubscribe.call(this,r)},t.prototype._subscribe=function(r){return this._throwIfClosed(),this._checkFinalizedStatuses(r),this._innerSubscribe(r)},t.prototype._innerSubscribe=function(r){var o=this,n=this,i=n.hasError,a=n.isStopped,s=n.observers;return i||a?Tr:(this.currentObservers=null,s.push(r),new Fe(function(){o.currentObservers=null,qe(s,r)}))},t.prototype._checkFinalizedStatuses=function(r){var o=this,n=o.hasError,i=o.thrownError,a=o.isStopped;n?r.error(i):a&&r.complete()},t.prototype.asObservable=function(){var r=new F;return r.source=this,r},t.create=function(r,o){return new Eo(r,o)},t}(F);var Eo=function(e){re(t,e);function t(r,o){var n=e.call(this)||this;return n.destination=r,n.source=o,n}return t.prototype.next=function(r){var o,n;(n=(o=this.destination)===null||o===void 0?void 0:o.next)===null||n===void 0||n.call(o,r)},t.prototype.error=function(r){var o,n;(n=(o=this.destination)===null||o===void 0?void 0:o.error)===null||n===void 0||n.call(o,r)},t.prototype.complete=function(){var r,o;(o=(r=this.destination)===null||r===void 0?void 0:r.complete)===null||o===void 0||o.call(r)},t.prototype._subscribe=function(r){var o,n;return(n=(o=this.source)===null||o===void 0?void 0:o.subscribe(r))!==null&&n!==void 0?n:Tr},t}(g);var _r=function(e){re(t,e);function t(r){var o=e.call(this)||this;return o._value=r,o}return Object.defineProperty(t.prototype,"value",{get:function(){return this.getValue()},enumerable:!1,configurable:!0}),t.prototype._subscribe=function(r){var o=e.prototype._subscribe.call(this,r);return!o.closed&&r.next(this._value),o},t.prototype.getValue=function(){var r=this,o=r.hasError,n=r.thrownError,i=r._value;if(o)throw n;return this._throwIfClosed(),i},t.prototype.next=function(r){e.prototype.next.call(this,this._value=r)},t}(g);var Lt={now:function(){return(Lt.delegate||Date).now()},delegate:void 0};var _t=function(e){re(t,e);function t(r,o,n){r===void 0&&(r=1/0),o===void 0&&(o=1/0),n===void 0&&(n=Lt);var i=e.call(this)||this;return i._bufferSize=r,i._windowTime=o,i._timestampProvider=n,i._buffer=[],i._infiniteTimeWindow=!0,i._infiniteTimeWindow=o===1/0,i._bufferSize=Math.max(1,r),i._windowTime=Math.max(1,o),i}return t.prototype.next=function(r){var o=this,n=o.isStopped,i=o._buffer,a=o._infiniteTimeWindow,s=o._timestampProvider,p=o._windowTime;n||(i.push(r),!a&&i.push(s.now()+p)),this._trimBuffer(),e.prototype.next.call(this,r)},t.prototype._subscribe=function(r){this._throwIfClosed(),this._trimBuffer();for(var o=this._innerSubscribe(r),n=this,i=n._infiniteTimeWindow,a=n._buffer,s=a.slice(),p=0;p0?e.prototype.schedule.call(this,r,o):(this.delay=o,this.state=r,this.scheduler.flush(this),this)},t.prototype.execute=function(r,o){return o>0||this.closed?e.prototype.execute.call(this,r,o):this._execute(r,o)},t.prototype.requestAsyncId=function(r,o,n){return n===void 0&&(n=0),n!=null&&n>0||n==null&&this.delay>0?e.prototype.requestAsyncId.call(this,r,o,n):(r.flush(this),0)},t}(vt);var So=function(e){re(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t}(gt);var Hr=new So(To);var Oo=function(e){re(t,e);function t(r,o){var n=e.call(this,r,o)||this;return n.scheduler=r,n.work=o,n}return t.prototype.requestAsyncId=function(r,o,n){return n===void 0&&(n=0),n!==null&&n>0?e.prototype.requestAsyncId.call(this,r,o,n):(r.actions.push(this),r._scheduled||(r._scheduled=bt.requestAnimationFrame(function(){return r.flush(void 0)})))},t.prototype.recycleAsyncId=function(r,o,n){var i;if(n===void 0&&(n=0),n!=null?n>0:this.delay>0)return e.prototype.recycleAsyncId.call(this,r,o,n);var a=r.actions;o!=null&&((i=a[a.length-1])===null||i===void 0?void 0:i.id)!==o&&(bt.cancelAnimationFrame(o),r._scheduled=void 0)},t}(vt);var Mo=function(e){re(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t.prototype.flush=function(r){this._active=!0;var o=this._scheduled;this._scheduled=void 0;var n=this.actions,i;r=r||n.shift();do if(i=r.execute(r.state,r.delay))break;while((r=n[0])&&r.id===o&&n.shift());if(this._active=!1,i){for(;(r=n[0])&&r.id===o&&n.shift();)r.unsubscribe();throw i}},t}(gt);var me=new Mo(Oo);var M=new F(function(e){return e.complete()});function Yt(e){return e&&k(e.schedule)}function kr(e){return e[e.length-1]}function Xe(e){return k(kr(e))?e.pop():void 0}function He(e){return Yt(kr(e))?e.pop():void 0}function Bt(e,t){return typeof kr(e)=="number"?e.pop():t}var xt=function(e){return e&&typeof e.length=="number"&&typeof e!="function"};function Gt(e){return k(e==null?void 0:e.then)}function Jt(e){return k(e[ht])}function Xt(e){return Symbol.asyncIterator&&k(e==null?void 0:e[Symbol.asyncIterator])}function Zt(e){return new TypeError("You provided "+(e!==null&&typeof e=="object"?"an invalid object":"'"+e+"'")+" where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.")}function Gi(){return typeof Symbol!="function"||!Symbol.iterator?"@@iterator":Symbol.iterator}var er=Gi();function tr(e){return k(e==null?void 0:e[er])}function rr(e){return lo(this,arguments,function(){var r,o,n,i;return Nt(this,function(a){switch(a.label){case 0:r=e.getReader(),a.label=1;case 1:a.trys.push([1,,9,10]),a.label=2;case 2:return[4,nt(r.read())];case 3:return o=a.sent(),n=o.value,i=o.done,i?[4,nt(void 0)]:[3,5];case 4:return[2,a.sent()];case 5:return[4,nt(n)];case 6:return[4,a.sent()];case 7:return a.sent(),[3,2];case 8:return[3,10];case 9:return r.releaseLock(),[7];case 10:return[2]}})})}function or(e){return k(e==null?void 0:e.getReader)}function W(e){if(e instanceof F)return e;if(e!=null){if(Jt(e))return Ji(e);if(xt(e))return Xi(e);if(Gt(e))return Zi(e);if(Xt(e))return Lo(e);if(tr(e))return ea(e);if(or(e))return ta(e)}throw Zt(e)}function Ji(e){return new F(function(t){var r=e[ht]();if(k(r.subscribe))return r.subscribe(t);throw new TypeError("Provided object does not correctly implement Symbol.observable")})}function Xi(e){return new F(function(t){for(var r=0;r=2;return function(o){return o.pipe(e?b(function(n,i){return e(n,i,o)}):le,Te(1),r?Be(t):zo(function(){return new ir}))}}function Fr(e){return e<=0?function(){return M}:y(function(t,r){var o=[];t.subscribe(T(r,function(n){o.push(n),e=2,!0))}function pe(e){e===void 0&&(e={});var t=e.connector,r=t===void 0?function(){return new g}:t,o=e.resetOnError,n=o===void 0?!0:o,i=e.resetOnComplete,a=i===void 0?!0:i,s=e.resetOnRefCountZero,p=s===void 0?!0:s;return function(c){var l,f,u,h=0,w=!1,A=!1,te=function(){f==null||f.unsubscribe(),f=void 0},ie=function(){te(),l=u=void 0,w=A=!1},J=function(){var H=l;ie(),H==null||H.unsubscribe()};return y(function(H,mt){h++,!A&&!w&&te();var ze=u=u!=null?u:r();mt.add(function(){h--,h===0&&!A&&!w&&(f=Wr(J,p))}),ze.subscribe(mt),!l&&h>0&&(l=new at({next:function(Ie){return ze.next(Ie)},error:function(Ie){A=!0,te(),f=Wr(ie,n,Ie),ze.error(Ie)},complete:function(){w=!0,te(),f=Wr(ie,a),ze.complete()}}),W(H).subscribe(l))})(c)}}function Wr(e,t){for(var r=[],o=2;oe.next(document)),e}function $(e,t=document){return Array.from(t.querySelectorAll(e))}function P(e,t=document){let r=fe(e,t);if(typeof r=="undefined")throw new ReferenceError(`Missing element: expected "${e}" to be present`);return r}function fe(e,t=document){return t.querySelector(e)||void 0}function Re(){var e,t,r,o;return(o=(r=(t=(e=document.activeElement)==null?void 0:e.shadowRoot)==null?void 0:t.activeElement)!=null?r:document.activeElement)!=null?o:void 0}var xa=S(d(document.body,"focusin"),d(document.body,"focusout")).pipe(_e(1),Q(void 0),m(()=>Re()||document.body),B(1));function et(e){return xa.pipe(m(t=>e.contains(t)),K())}function kt(e,t){return C(()=>S(d(e,"mouseenter").pipe(m(()=>!0)),d(e,"mouseleave").pipe(m(()=>!1))).pipe(t?Ht(r=>Me(+!r*t)):le,Q(e.matches(":hover"))))}function Bo(e,t){if(typeof t=="string"||typeof t=="number")e.innerHTML+=t.toString();else if(t instanceof Node)e.appendChild(t);else if(Array.isArray(t))for(let r of t)Bo(e,r)}function x(e,t,...r){let o=document.createElement(e);if(t)for(let n of Object.keys(t))typeof t[n]!="undefined"&&(typeof t[n]!="boolean"?o.setAttribute(n,t[n]):o.setAttribute(n,""));for(let n of r)Bo(o,n);return o}function sr(e){if(e>999){let t=+((e-950)%1e3>99);return`${((e+1e-6)/1e3).toFixed(t)}k`}else return e.toString()}function wt(e){let t=x("script",{src:e});return C(()=>(document.head.appendChild(t),S(d(t,"load"),d(t,"error").pipe(v(()=>$r(()=>new ReferenceError(`Invalid script: ${e}`))))).pipe(m(()=>{}),L(()=>document.head.removeChild(t)),Te(1))))}var Go=new g,ya=C(()=>typeof ResizeObserver=="undefined"?wt("https://unpkg.com/resize-observer-polyfill"):I(void 0)).pipe(m(()=>new ResizeObserver(e=>e.forEach(t=>Go.next(t)))),v(e=>S(Ke,I(e)).pipe(L(()=>e.disconnect()))),B(1));function ce(e){return{width:e.offsetWidth,height:e.offsetHeight}}function ge(e){let t=e;for(;t.clientWidth===0&&t.parentElement;)t=t.parentElement;return ya.pipe(E(r=>r.observe(t)),v(r=>Go.pipe(b(o=>o.target===t),L(()=>r.unobserve(t)))),m(()=>ce(e)),Q(ce(e)))}function Tt(e){return{width:e.scrollWidth,height:e.scrollHeight}}function cr(e){let t=e.parentElement;for(;t&&(e.scrollWidth<=t.scrollWidth&&e.scrollHeight<=t.scrollHeight);)t=(e=t).parentElement;return t?e:void 0}function Jo(e){let t=[],r=e.parentElement;for(;r;)(e.clientWidth>r.clientWidth||e.clientHeight>r.clientHeight)&&t.push(r),r=(e=r).parentElement;return t.length===0&&t.push(document.documentElement),t}function Ue(e){return{x:e.offsetLeft,y:e.offsetTop}}function Xo(e){let t=e.getBoundingClientRect();return{x:t.x+window.scrollX,y:t.y+window.scrollY}}function Zo(e){return S(d(window,"load"),d(window,"resize")).pipe(Le(0,me),m(()=>Ue(e)),Q(Ue(e)))}function pr(e){return{x:e.scrollLeft,y:e.scrollTop}}function De(e){return S(d(e,"scroll"),d(window,"scroll"),d(window,"resize")).pipe(Le(0,me),m(()=>pr(e)),Q(pr(e)))}var en=new g,Ea=C(()=>I(new IntersectionObserver(e=>{for(let t of e)en.next(t)},{threshold:0}))).pipe(v(e=>S(Ke,I(e)).pipe(L(()=>e.disconnect()))),B(1));function tt(e){return Ea.pipe(E(t=>t.observe(e)),v(t=>en.pipe(b(({target:r})=>r===e),L(()=>t.unobserve(e)),m(({isIntersecting:r})=>r))))}function tn(e,t=16){return De(e).pipe(m(({y:r})=>{let o=ce(e),n=Tt(e);return r>=n.height-o.height-t}),K())}var lr={drawer:P("[data-md-toggle=drawer]"),search:P("[data-md-toggle=search]")};function rn(e){return lr[e].checked}function Je(e,t){lr[e].checked!==t&&lr[e].click()}function Ve(e){let t=lr[e];return d(t,"change").pipe(m(()=>t.checked),Q(t.checked))}function wa(e,t){switch(e.constructor){case HTMLInputElement:return e.type==="radio"?/^Arrow/.test(t):!0;case HTMLSelectElement:case HTMLTextAreaElement:return!0;default:return e.isContentEditable}}function Ta(){return S(d(window,"compositionstart").pipe(m(()=>!0)),d(window,"compositionend").pipe(m(()=>!1))).pipe(Q(!1))}function on(){let e=d(window,"keydown").pipe(b(t=>!(t.metaKey||t.ctrlKey)),m(t=>({mode:rn("search")?"search":"global",type:t.key,claim(){t.preventDefault(),t.stopPropagation()}})),b(({mode:t,type:r})=>{if(t==="global"){let o=Re();if(typeof o!="undefined")return!wa(o,r)}return!0}),pe());return Ta().pipe(v(t=>t?M:e))}function xe(){return new URL(location.href)}function pt(e,t=!1){if(G("navigation.instant")&&!t){let r=x("a",{href:e.href});document.body.appendChild(r),r.click(),r.remove()}else location.href=e.href}function nn(){return new g}function an(){return location.hash.slice(1)}function sn(e){let t=x("a",{href:e});t.addEventListener("click",r=>r.stopPropagation()),t.click()}function Sa(e){return S(d(window,"hashchange"),e).pipe(m(an),Q(an()),b(t=>t.length>0),B(1))}function cn(e){return Sa(e).pipe(m(t=>fe(`[id="${t}"]`)),b(t=>typeof t!="undefined"))}function $t(e){let t=matchMedia(e);return ar(r=>t.addListener(()=>r(t.matches))).pipe(Q(t.matches))}function pn(){let e=matchMedia("print");return S(d(window,"beforeprint").pipe(m(()=>!0)),d(window,"afterprint").pipe(m(()=>!1))).pipe(Q(e.matches))}function Nr(e,t){return e.pipe(v(r=>r?t():M))}function zr(e,t){return new F(r=>{let o=new XMLHttpRequest;return o.open("GET",`${e}`),o.responseType="blob",o.addEventListener("load",()=>{o.status>=200&&o.status<300?(r.next(o.response),r.complete()):r.error(new Error(o.statusText))}),o.addEventListener("error",()=>{r.error(new Error("Network error"))}),o.addEventListener("abort",()=>{r.complete()}),typeof(t==null?void 0:t.progress$)!="undefined"&&(o.addEventListener("progress",n=>{var i;if(n.lengthComputable)t.progress$.next(n.loaded/n.total*100);else{let a=(i=o.getResponseHeader("Content-Length"))!=null?i:0;t.progress$.next(n.loaded/+a*100)}}),t.progress$.next(5)),o.send(),()=>o.abort()})}function Ne(e,t){return zr(e,t).pipe(v(r=>r.text()),m(r=>JSON.parse(r)),B(1))}function ln(e,t){let r=new DOMParser;return zr(e,t).pipe(v(o=>o.text()),m(o=>r.parseFromString(o,"text/html")),B(1))}function mn(e,t){let r=new DOMParser;return zr(e,t).pipe(v(o=>o.text()),m(o=>r.parseFromString(o,"text/xml")),B(1))}function fn(){return{x:Math.max(0,scrollX),y:Math.max(0,scrollY)}}function un(){return S(d(window,"scroll",{passive:!0}),d(window,"resize",{passive:!0})).pipe(m(fn),Q(fn()))}function dn(){return{width:innerWidth,height:innerHeight}}function hn(){return d(window,"resize",{passive:!0}).pipe(m(dn),Q(dn()))}function bn(){return z([un(),hn()]).pipe(m(([e,t])=>({offset:e,size:t})),B(1))}function mr(e,{viewport$:t,header$:r}){let o=t.pipe(Z("size")),n=z([o,r]).pipe(m(()=>Ue(e)));return z([r,t,n]).pipe(m(([{height:i},{offset:a,size:s},{x:p,y:c}])=>({offset:{x:a.x-p,y:a.y-c+i},size:s})))}function Oa(e){return d(e,"message",t=>t.data)}function Ma(e){let t=new g;return t.subscribe(r=>e.postMessage(r)),t}function vn(e,t=new Worker(e)){let r=Oa(t),o=Ma(t),n=new g;n.subscribe(o);let i=o.pipe(X(),ne(!0));return n.pipe(X(),Pe(r.pipe(U(i))),pe())}var La=P("#__config"),St=JSON.parse(La.textContent);St.base=`${new URL(St.base,xe())}`;function ye(){return St}function G(e){return St.features.includes(e)}function Ee(e,t){return typeof t!="undefined"?St.translations[e].replace("#",t.toString()):St.translations[e]}function Se(e,t=document){return P(`[data-md-component=${e}]`,t)}function ae(e,t=document){return $(`[data-md-component=${e}]`,t)}function _a(e){let t=P(".md-typeset > :first-child",e);return d(t,"click",{once:!0}).pipe(m(()=>P(".md-typeset",e)),m(r=>({hash:__md_hash(r.innerHTML)})))}function gn(e){if(!G("announce.dismiss")||!e.childElementCount)return M;if(!e.hidden){let t=P(".md-typeset",e);__md_hash(t.innerHTML)===__md_get("__announce")&&(e.hidden=!0)}return C(()=>{let t=new g;return t.subscribe(({hash:r})=>{e.hidden=!0,__md_set("__announce",r)}),_a(e).pipe(E(r=>t.next(r)),L(()=>t.complete()),m(r=>R({ref:e},r)))})}function Aa(e,{target$:t}){return t.pipe(m(r=>({hidden:r!==e})))}function xn(e,t){let r=new g;return r.subscribe(({hidden:o})=>{e.hidden=o}),Aa(e,t).pipe(E(o=>r.next(o)),L(()=>r.complete()),m(o=>R({ref:e},o)))}function Pt(e,t){return t==="inline"?x("div",{class:"md-tooltip md-tooltip--inline",id:e,role:"tooltip"},x("div",{class:"md-tooltip__inner md-typeset"})):x("div",{class:"md-tooltip",id:e,role:"tooltip"},x("div",{class:"md-tooltip__inner md-typeset"}))}function yn(...e){return x("div",{class:"md-tooltip2",role:"tooltip"},x("div",{class:"md-tooltip2__inner md-typeset"},e))}function En(e,t){if(t=t?`${t}_annotation_${e}`:void 0,t){let r=t?`#${t}`:void 0;return x("aside",{class:"md-annotation",tabIndex:0},Pt(t),x("a",{href:r,class:"md-annotation__index",tabIndex:-1},x("span",{"data-md-annotation-id":e})))}else return x("aside",{class:"md-annotation",tabIndex:0},Pt(t),x("span",{class:"md-annotation__index",tabIndex:-1},x("span",{"data-md-annotation-id":e})))}function wn(e){return x("button",{class:"md-clipboard md-icon",title:Ee("clipboard.copy"),"data-clipboard-target":`#${e} > code`})}function qr(e,t){let r=t&2,o=t&1,n=Object.keys(e.terms).filter(p=>!e.terms[p]).reduce((p,c)=>[...p,x("del",null,c)," "],[]).slice(0,-1),i=ye(),a=new URL(e.location,i.base);G("search.highlight")&&a.searchParams.set("h",Object.entries(e.terms).filter(([,p])=>p).reduce((p,[c])=>`${p} ${c}`.trim(),""));let{tags:s}=ye();return x("a",{href:`${a}`,class:"md-search-result__link",tabIndex:-1},x("article",{class:"md-search-result__article md-typeset","data-md-score":e.score.toFixed(2)},r>0&&x("div",{class:"md-search-result__icon md-icon"}),r>0&&x("h1",null,e.title),r<=0&&x("h2",null,e.title),o>0&&e.text.length>0&&e.text,e.tags&&e.tags.map(p=>{let c=s?p in s?`md-tag-icon md-tag--${s[p]}`:"md-tag-icon":"";return x("span",{class:`md-tag ${c}`},p)}),o>0&&n.length>0&&x("p",{class:"md-search-result__terms"},Ee("search.result.term.missing"),": ",...n)))}function Tn(e){let t=e[0].score,r=[...e],o=ye(),n=r.findIndex(l=>!`${new URL(l.location,o.base)}`.includes("#")),[i]=r.splice(n,1),a=r.findIndex(l=>l.scoreqr(l,1)),...p.length?[x("details",{class:"md-search-result__more"},x("summary",{tabIndex:-1},x("div",null,p.length>0&&p.length===1?Ee("search.result.more.one"):Ee("search.result.more.other",p.length))),...p.map(l=>qr(l,1)))]:[]];return x("li",{class:"md-search-result__item"},c)}function Sn(e){return x("ul",{class:"md-source__facts"},Object.entries(e).map(([t,r])=>x("li",{class:`md-source__fact md-source__fact--${t}`},typeof r=="number"?sr(r):r)))}function Qr(e){let t=`tabbed-control tabbed-control--${e}`;return x("div",{class:t,hidden:!0},x("button",{class:"tabbed-button",tabIndex:-1,"aria-hidden":"true"}))}function On(e){return x("div",{class:"md-typeset__scrollwrap"},x("div",{class:"md-typeset__table"},e))}function Ca(e){var o;let t=ye(),r=new URL(`../${e.version}/`,t.base);return x("li",{class:"md-version__item"},x("a",{href:`${r}`,class:"md-version__link"},e.title,((o=t.version)==null?void 0:o.alias)&&e.aliases.length>0&&x("span",{class:"md-version__alias"},e.aliases[0])))}function Mn(e,t){var o;let r=ye();return e=e.filter(n=>{var i;return!((i=n.properties)!=null&&i.hidden)}),x("div",{class:"md-version"},x("button",{class:"md-version__current","aria-label":Ee("select.version")},t.title,((o=r.version)==null?void 0:o.alias)&&t.aliases.length>0&&x("span",{class:"md-version__alias"},t.aliases[0])),x("ul",{class:"md-version__list"},e.map(Ca)))}var Ha=0;function ka(e){let t=z([et(e),kt(e)]).pipe(m(([o,n])=>o||n),K()),r=C(()=>Jo(e)).pipe(oe(De),ct(1),m(()=>Xo(e)));return t.pipe(Ae(o=>o),v(()=>z([t,r])),m(([o,n])=>({active:o,offset:n})),pe())}function $a(e,t){let{content$:r,viewport$:o}=t,n=`__tooltip2_${Ha++}`;return C(()=>{let i=new g,a=new _r(!1);i.pipe(X(),ne(!1)).subscribe(a);let s=a.pipe(Ht(c=>Me(+!c*250,Hr)),K(),v(c=>c?r:M),E(c=>c.id=n),pe());z([i.pipe(m(({active:c})=>c)),s.pipe(v(c=>kt(c,250)),Q(!1))]).pipe(m(c=>c.some(l=>l))).subscribe(a);let p=a.pipe(b(c=>c),ee(s,o),m(([c,l,{size:f}])=>{let u=e.getBoundingClientRect(),h=u.width/2;if(l.role==="tooltip")return{x:h,y:8+u.height};if(u.y>=f.height/2){let{height:w}=ce(l);return{x:h,y:-16-w}}else return{x:h,y:16+u.height}}));return z([s,i,p]).subscribe(([c,{offset:l},f])=>{c.style.setProperty("--md-tooltip-host-x",`${l.x}px`),c.style.setProperty("--md-tooltip-host-y",`${l.y}px`),c.style.setProperty("--md-tooltip-x",`${f.x}px`),c.style.setProperty("--md-tooltip-y",`${f.y}px`),c.classList.toggle("md-tooltip2--top",f.y<0),c.classList.toggle("md-tooltip2--bottom",f.y>=0)}),a.pipe(b(c=>c),ee(s,(c,l)=>l),b(c=>c.role==="tooltip")).subscribe(c=>{let l=ce(P(":scope > *",c));c.style.setProperty("--md-tooltip-width",`${l.width}px`),c.style.setProperty("--md-tooltip-tail","0px")}),a.pipe(K(),be(me),ee(s)).subscribe(([c,l])=>{l.classList.toggle("md-tooltip2--active",c)}),z([a.pipe(b(c=>c)),s]).subscribe(([c,l])=>{l.role==="dialog"?(e.setAttribute("aria-controls",n),e.setAttribute("aria-haspopup","dialog")):e.setAttribute("aria-describedby",n)}),a.pipe(b(c=>!c)).subscribe(()=>{e.removeAttribute("aria-controls"),e.removeAttribute("aria-describedby"),e.removeAttribute("aria-haspopup")}),ka(e).pipe(E(c=>i.next(c)),L(()=>i.complete()),m(c=>R({ref:e},c)))})}function lt(e,{viewport$:t},r=document.body){return $a(e,{content$:new F(o=>{let n=e.title,i=yn(n);return o.next(i),e.removeAttribute("title"),r.append(i),()=>{i.remove(),e.setAttribute("title",n)}}),viewport$:t})}function Pa(e,t){let r=C(()=>z([Zo(e),De(t)])).pipe(m(([{x:o,y:n},i])=>{let{width:a,height:s}=ce(e);return{x:o-i.x+a/2,y:n-i.y+s/2}}));return et(e).pipe(v(o=>r.pipe(m(n=>({active:o,offset:n})),Te(+!o||1/0))))}function Ln(e,t,{target$:r}){let[o,n]=Array.from(e.children);return C(()=>{let i=new g,a=i.pipe(X(),ne(!0));return i.subscribe({next({offset:s}){e.style.setProperty("--md-tooltip-x",`${s.x}px`),e.style.setProperty("--md-tooltip-y",`${s.y}px`)},complete(){e.style.removeProperty("--md-tooltip-x"),e.style.removeProperty("--md-tooltip-y")}}),tt(e).pipe(U(a)).subscribe(s=>{e.toggleAttribute("data-md-visible",s)}),S(i.pipe(b(({active:s})=>s)),i.pipe(_e(250),b(({active:s})=>!s))).subscribe({next({active:s}){s?e.prepend(o):o.remove()},complete(){e.prepend(o)}}),i.pipe(Le(16,me)).subscribe(({active:s})=>{o.classList.toggle("md-tooltip--active",s)}),i.pipe(ct(125,me),b(()=>!!e.offsetParent),m(()=>e.offsetParent.getBoundingClientRect()),m(({x:s})=>s)).subscribe({next(s){s?e.style.setProperty("--md-tooltip-0",`${-s}px`):e.style.removeProperty("--md-tooltip-0")},complete(){e.style.removeProperty("--md-tooltip-0")}}),d(n,"click").pipe(U(a),b(s=>!(s.metaKey||s.ctrlKey))).subscribe(s=>{s.stopPropagation(),s.preventDefault()}),d(n,"mousedown").pipe(U(a),ee(i)).subscribe(([s,{active:p}])=>{var c;if(s.button!==0||s.metaKey||s.ctrlKey)s.preventDefault();else if(p){s.preventDefault();let l=e.parentElement.closest(".md-annotation");l instanceof HTMLElement?l.focus():(c=Re())==null||c.blur()}}),r.pipe(U(a),b(s=>s===o),Ge(125)).subscribe(()=>e.focus()),Pa(e,t).pipe(E(s=>i.next(s)),L(()=>i.complete()),m(s=>R({ref:e},s)))})}function Ra(e){return e.tagName==="CODE"?$(".c, .c1, .cm",e):[e]}function Ia(e){let t=[];for(let r of Ra(e)){let o=[],n=document.createNodeIterator(r,NodeFilter.SHOW_TEXT);for(let i=n.nextNode();i;i=n.nextNode())o.push(i);for(let i of o){let a;for(;a=/(\(\d+\))(!)?/.exec(i.textContent);){let[,s,p]=a;if(typeof p=="undefined"){let c=i.splitText(a.index);i=c.splitText(s.length),t.push(c)}else{i.textContent=s,t.push(i);break}}}}return t}function _n(e,t){t.append(...Array.from(e.childNodes))}function fr(e,t,{target$:r,print$:o}){let n=t.closest("[id]"),i=n==null?void 0:n.id,a=new Map;for(let s of Ia(t)){let[,p]=s.textContent.match(/\((\d+)\)/);fe(`:scope > li:nth-child(${p})`,e)&&(a.set(p,En(p,i)),s.replaceWith(a.get(p)))}return a.size===0?M:C(()=>{let s=new g,p=s.pipe(X(),ne(!0)),c=[];for(let[l,f]of a)c.push([P(".md-typeset",f),P(`:scope > li:nth-child(${l})`,e)]);return o.pipe(U(p)).subscribe(l=>{e.hidden=!l,e.classList.toggle("md-annotation-list",l);for(let[f,u]of c)l?_n(f,u):_n(u,f)}),S(...[...a].map(([,l])=>Ln(l,t,{target$:r}))).pipe(L(()=>s.complete()),pe())})}function An(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return An(t)}}function Cn(e,t){return C(()=>{let r=An(e);return typeof r!="undefined"?fr(r,e,t):M})}var Hn=Vt(Yr());var Fa=0;function kn(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return kn(t)}}function ja(e){return ge(e).pipe(m(({width:t})=>({scrollable:Tt(e).width>t})),Z("scrollable"))}function $n(e,t){let{matches:r}=matchMedia("(hover)"),o=C(()=>{let n=new g,i=n.pipe(Fr(1));n.subscribe(({scrollable:c})=>{c&&r?e.setAttribute("tabindex","0"):e.removeAttribute("tabindex")});let a=[];if(Hn.default.isSupported()&&(e.closest(".copy")||G("content.code.copy")&&!e.closest(".no-copy"))){let c=e.closest("pre");c.id=`__code_${Fa++}`;let l=wn(c.id);c.insertBefore(l,e),G("content.tooltips")&&a.push(lt(l,{viewport$}))}let s=e.closest(".highlight");if(s instanceof HTMLElement){let c=kn(s);if(typeof c!="undefined"&&(s.classList.contains("annotate")||G("content.code.annotate"))){let l=fr(c,e,t);a.push(ge(s).pipe(U(i),m(({width:f,height:u})=>f&&u),K(),v(f=>f?l:M)))}}return $(":scope > span[id]",e).length&&e.classList.add("md-code__content"),ja(e).pipe(E(c=>n.next(c)),L(()=>n.complete()),m(c=>R({ref:e},c)),Pe(...a))});return G("content.lazy")?tt(e).pipe(b(n=>n),Te(1),v(()=>o)):o}function Wa(e,{target$:t,print$:r}){let o=!0;return S(t.pipe(m(n=>n.closest("details:not([open])")),b(n=>e===n),m(()=>({action:"open",reveal:!0}))),r.pipe(b(n=>n||!o),E(()=>o=e.open),m(n=>({action:n?"open":"close"}))))}function Pn(e,t){return C(()=>{let r=new g;return r.subscribe(({action:o,reveal:n})=>{e.toggleAttribute("open",o==="open"),n&&e.scrollIntoView()}),Wa(e,t).pipe(E(o=>r.next(o)),L(()=>r.complete()),m(o=>R({ref:e},o)))})}var Rn=".node circle,.node ellipse,.node path,.node polygon,.node rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}marker{fill:var(--md-mermaid-edge-color)!important}.edgeLabel .label rect{fill:#0000}.label{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.label foreignObject{line-height:normal;overflow:visible}.label div .edgeLabel{color:var(--md-mermaid-label-fg-color)}.edgeLabel,.edgeLabel rect,.label div .edgeLabel{background-color:var(--md-mermaid-label-bg-color)}.edgeLabel,.edgeLabel rect{fill:var(--md-mermaid-label-bg-color);color:var(--md-mermaid-edge-color)}.edgePath .path,.flowchart-link{stroke:var(--md-mermaid-edge-color);stroke-width:.05rem}.edgePath .arrowheadPath{fill:var(--md-mermaid-edge-color);stroke:none}.cluster rect{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}.cluster span{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}g #flowchart-circleEnd,g #flowchart-circleStart,g #flowchart-crossEnd,g #flowchart-crossStart,g #flowchart-pointEnd,g #flowchart-pointStart{stroke:none}g.classGroup line,g.classGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.classGroup text{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.classLabel .box{fill:var(--md-mermaid-label-bg-color);background-color:var(--md-mermaid-label-bg-color);opacity:1}.classLabel .label{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.node .divider{stroke:var(--md-mermaid-node-fg-color)}.relation{stroke:var(--md-mermaid-edge-color)}.cardinality{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.cardinality text{fill:inherit!important}defs #classDiagram-compositionEnd,defs #classDiagram-compositionStart,defs #classDiagram-dependencyEnd,defs #classDiagram-dependencyStart,defs #classDiagram-extensionEnd,defs #classDiagram-extensionStart{fill:var(--md-mermaid-edge-color)!important;stroke:var(--md-mermaid-edge-color)!important}defs #classDiagram-aggregationEnd,defs #classDiagram-aggregationStart{fill:var(--md-mermaid-label-bg-color)!important;stroke:var(--md-mermaid-edge-color)!important}g.stateGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.stateGroup .state-title{fill:var(--md-mermaid-label-fg-color)!important;font-family:var(--md-mermaid-font-family)}g.stateGroup .composit{fill:var(--md-mermaid-label-bg-color)}.nodeLabel,.nodeLabel p{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}a .nodeLabel{text-decoration:underline}.node circle.state-end,.node circle.state-start,.start-state{fill:var(--md-mermaid-edge-color);stroke:none}.end-state-inner,.end-state-outer{fill:var(--md-mermaid-edge-color)}.end-state-inner,.node circle.state-end{stroke:var(--md-mermaid-label-bg-color)}.transition{stroke:var(--md-mermaid-edge-color)}[id^=state-fork] rect,[id^=state-join] rect{fill:var(--md-mermaid-edge-color)!important;stroke:none!important}.statediagram-cluster.statediagram-cluster .inner{fill:var(--md-default-bg-color)}.statediagram-cluster rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.statediagram-state rect.divider{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}defs #statediagram-barbEnd{stroke:var(--md-mermaid-edge-color)}.attributeBoxEven,.attributeBoxOdd{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.entityBox{fill:var(--md-mermaid-label-bg-color);stroke:var(--md-mermaid-node-fg-color)}.entityLabel{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.relationshipLabelBox{fill:var(--md-mermaid-label-bg-color);fill-opacity:1;background-color:var(--md-mermaid-label-bg-color);opacity:1}.relationshipLabel{fill:var(--md-mermaid-label-fg-color)}.relationshipLine{stroke:var(--md-mermaid-edge-color)}defs #ONE_OR_MORE_END *,defs #ONE_OR_MORE_START *,defs #ONLY_ONE_END *,defs #ONLY_ONE_START *,defs #ZERO_OR_MORE_END *,defs #ZERO_OR_MORE_START *,defs #ZERO_OR_ONE_END *,defs #ZERO_OR_ONE_START *{stroke:var(--md-mermaid-edge-color)!important}defs #ZERO_OR_MORE_END circle,defs #ZERO_OR_MORE_START circle{fill:var(--md-mermaid-label-bg-color)}.actor{fill:var(--md-mermaid-sequence-actor-bg-color);stroke:var(--md-mermaid-sequence-actor-border-color)}text.actor>tspan{fill:var(--md-mermaid-sequence-actor-fg-color);font-family:var(--md-mermaid-font-family)}line{stroke:var(--md-mermaid-sequence-actor-line-color)}.actor-man circle,.actor-man line{fill:var(--md-mermaid-sequence-actorman-bg-color);stroke:var(--md-mermaid-sequence-actorman-line-color)}.messageLine0,.messageLine1{stroke:var(--md-mermaid-sequence-message-line-color)}.note{fill:var(--md-mermaid-sequence-note-bg-color);stroke:var(--md-mermaid-sequence-note-border-color)}.loopText,.loopText>tspan,.messageText,.noteText>tspan{stroke:none;font-family:var(--md-mermaid-font-family)!important}.messageText{fill:var(--md-mermaid-sequence-message-fg-color)}.loopText,.loopText>tspan{fill:var(--md-mermaid-sequence-loop-fg-color)}.noteText>tspan{fill:var(--md-mermaid-sequence-note-fg-color)}#arrowhead path{fill:var(--md-mermaid-sequence-message-line-color);stroke:none}.loopLine{fill:var(--md-mermaid-sequence-loop-bg-color);stroke:var(--md-mermaid-sequence-loop-border-color)}.labelBox{fill:var(--md-mermaid-sequence-label-bg-color);stroke:none}.labelText,.labelText>span{fill:var(--md-mermaid-sequence-label-fg-color);font-family:var(--md-mermaid-font-family)}.sequenceNumber{fill:var(--md-mermaid-sequence-number-fg-color)}rect.rect{fill:var(--md-mermaid-sequence-box-bg-color);stroke:none}rect.rect+text.text{fill:var(--md-mermaid-sequence-box-fg-color)}defs #sequencenumber{fill:var(--md-mermaid-sequence-number-bg-color)!important}";var Br,Da=0;function Va(){return typeof mermaid=="undefined"||mermaid instanceof Element?wt("https://unpkg.com/mermaid@10/dist/mermaid.min.js"):I(void 0)}function In(e){return e.classList.remove("mermaid"),Br||(Br=Va().pipe(E(()=>mermaid.initialize({startOnLoad:!1,themeCSS:Rn,sequence:{actorFontSize:"16px",messageFontSize:"16px",noteFontSize:"16px"}})),m(()=>{}),B(1))),Br.subscribe(()=>ao(this,null,function*(){e.classList.add("mermaid");let t=`__mermaid_${Da++}`,r=x("div",{class:"mermaid"}),o=e.textContent,{svg:n,fn:i}=yield mermaid.render(t,o),a=r.attachShadow({mode:"closed"});a.innerHTML=n,e.replaceWith(r),i==null||i(a)})),Br.pipe(m(()=>({ref:e})))}var Fn=x("table");function jn(e){return e.replaceWith(Fn),Fn.replaceWith(On(e)),I({ref:e})}function Na(e){let t=e.find(r=>r.checked)||e[0];return S(...e.map(r=>d(r,"change").pipe(m(()=>P(`label[for="${r.id}"]`))))).pipe(Q(P(`label[for="${t.id}"]`)),m(r=>({active:r})))}function Wn(e,{viewport$:t,target$:r}){let o=P(".tabbed-labels",e),n=$(":scope > input",e),i=Qr("prev");e.append(i);let a=Qr("next");return e.append(a),C(()=>{let s=new g,p=s.pipe(X(),ne(!0));z([s,ge(e),tt(e)]).pipe(U(p),Le(1,me)).subscribe({next([{active:c},l]){let f=Ue(c),{width:u}=ce(c);e.style.setProperty("--md-indicator-x",`${f.x}px`),e.style.setProperty("--md-indicator-width",`${u}px`);let h=pr(o);(f.xh.x+l.width)&&o.scrollTo({left:Math.max(0,f.x-16),behavior:"smooth"})},complete(){e.style.removeProperty("--md-indicator-x"),e.style.removeProperty("--md-indicator-width")}}),z([De(o),ge(o)]).pipe(U(p)).subscribe(([c,l])=>{let f=Tt(o);i.hidden=c.x<16,a.hidden=c.x>f.width-l.width-16}),S(d(i,"click").pipe(m(()=>-1)),d(a,"click").pipe(m(()=>1))).pipe(U(p)).subscribe(c=>{let{width:l}=ce(o);o.scrollBy({left:l*c,behavior:"smooth"})}),r.pipe(U(p),b(c=>n.includes(c))).subscribe(c=>c.click()),o.classList.add("tabbed-labels--linked");for(let c of n){let l=P(`label[for="${c.id}"]`);l.replaceChildren(x("a",{href:`#${l.htmlFor}`,tabIndex:-1},...Array.from(l.childNodes))),d(l.firstElementChild,"click").pipe(U(p),b(f=>!(f.metaKey||f.ctrlKey)),E(f=>{f.preventDefault(),f.stopPropagation()})).subscribe(()=>{history.replaceState({},"",`#${l.htmlFor}`),l.click()})}return G("content.tabs.link")&&s.pipe(Ce(1),ee(t)).subscribe(([{active:c},{offset:l}])=>{let f=c.innerText.trim();if(c.hasAttribute("data-md-switching"))c.removeAttribute("data-md-switching");else{let u=e.offsetTop-l.y;for(let w of $("[data-tabs]"))for(let A of $(":scope > input",w)){let te=P(`label[for="${A.id}"]`);if(te!==c&&te.innerText.trim()===f){te.setAttribute("data-md-switching",""),A.click();break}}window.scrollTo({top:e.offsetTop-u});let h=__md_get("__tabs")||[];__md_set("__tabs",[...new Set([f,...h])])}}),s.pipe(U(p)).subscribe(()=>{for(let c of $("audio, video",e))c.pause()}),Na(n).pipe(E(c=>s.next(c)),L(()=>s.complete()),m(c=>R({ref:e},c)))}).pipe(Qe(se))}function Un(e,{viewport$:t,target$:r,print$:o}){return S(...$(".annotate:not(.highlight)",e).map(n=>Cn(n,{target$:r,print$:o})),...$("pre:not(.mermaid) > code",e).map(n=>$n(n,{target$:r,print$:o})),...$("pre.mermaid",e).map(n=>In(n)),...$("table:not([class])",e).map(n=>jn(n)),...$("details",e).map(n=>Pn(n,{target$:r,print$:o})),...$("[data-tabs]",e).map(n=>Wn(n,{viewport$:t,target$:r})),...$("[title]",e).filter(()=>G("content.tooltips")).map(n=>lt(n,{viewport$:t})))}function za(e,{alert$:t}){return t.pipe(v(r=>S(I(!0),I(!1).pipe(Ge(2e3))).pipe(m(o=>({message:r,active:o})))))}function Dn(e,t){let r=P(".md-typeset",e);return C(()=>{let o=new g;return o.subscribe(({message:n,active:i})=>{e.classList.toggle("md-dialog--active",i),r.textContent=n}),za(e,t).pipe(E(n=>o.next(n)),L(()=>o.complete()),m(n=>R({ref:e},n)))})}var qa=0;function Qa(e,t){document.body.append(e);let{width:r}=ce(e);e.style.setProperty("--md-tooltip-width",`${r}px`),e.remove();let o=cr(t),n=typeof o!="undefined"?De(o):I({x:0,y:0}),i=S(et(t),kt(t)).pipe(K());return z([i,n]).pipe(m(([a,s])=>{let{x:p,y:c}=Ue(t),l=ce(t),f=t.closest("table");return f&&t.parentElement&&(p+=f.offsetLeft+t.parentElement.offsetLeft,c+=f.offsetTop+t.parentElement.offsetTop),{active:a,offset:{x:p-s.x+l.width/2-r/2,y:c-s.y+l.height+8}}}))}function Vn(e){let t=e.title;if(!t.length)return M;let r=`__tooltip_${qa++}`,o=Pt(r,"inline"),n=P(".md-typeset",o);return n.innerHTML=t,C(()=>{let i=new g;return i.subscribe({next({offset:a}){o.style.setProperty("--md-tooltip-x",`${a.x}px`),o.style.setProperty("--md-tooltip-y",`${a.y}px`)},complete(){o.style.removeProperty("--md-tooltip-x"),o.style.removeProperty("--md-tooltip-y")}}),S(i.pipe(b(({active:a})=>a)),i.pipe(_e(250),b(({active:a})=>!a))).subscribe({next({active:a}){a?(e.insertAdjacentElement("afterend",o),e.setAttribute("aria-describedby",r),e.removeAttribute("title")):(o.remove(),e.removeAttribute("aria-describedby"),e.setAttribute("title",t))},complete(){o.remove(),e.removeAttribute("aria-describedby"),e.setAttribute("title",t)}}),i.pipe(Le(16,me)).subscribe(({active:a})=>{o.classList.toggle("md-tooltip--active",a)}),i.pipe(ct(125,me),b(()=>!!e.offsetParent),m(()=>e.offsetParent.getBoundingClientRect()),m(({x:a})=>a)).subscribe({next(a){a?o.style.setProperty("--md-tooltip-0",`${-a}px`):o.style.removeProperty("--md-tooltip-0")},complete(){o.style.removeProperty("--md-tooltip-0")}}),Qa(o,e).pipe(E(a=>i.next(a)),L(()=>i.complete()),m(a=>R({ref:e},a)))}).pipe(Qe(se))}function Ka({viewport$:e}){if(!G("header.autohide"))return I(!1);let t=e.pipe(m(({offset:{y:n}})=>n),Ye(2,1),m(([n,i])=>[nMath.abs(i-n.y)>100),m(([,[n]])=>n),K()),o=Ve("search");return z([e,o]).pipe(m(([{offset:n},i])=>n.y>400&&!i),K(),v(n=>n?r:I(!1)),Q(!1))}function Nn(e,t){return C(()=>z([ge(e),Ka(t)])).pipe(m(([{height:r},o])=>({height:r,hidden:o})),K((r,o)=>r.height===o.height&&r.hidden===o.hidden),B(1))}function zn(e,{header$:t,main$:r}){return C(()=>{let o=new g,n=o.pipe(X(),ne(!0));o.pipe(Z("active"),We(t)).subscribe(([{active:a},{hidden:s}])=>{e.classList.toggle("md-header--shadow",a&&!s),e.hidden=s});let i=ue($("[title]",e)).pipe(b(()=>G("content.tooltips")),oe(a=>Vn(a)));return r.subscribe(o),t.pipe(U(n),m(a=>R({ref:e},a)),Pe(i.pipe(U(n))))})}function Ya(e,{viewport$:t,header$:r}){return mr(e,{viewport$:t,header$:r}).pipe(m(({offset:{y:o}})=>{let{height:n}=ce(e);return{active:o>=n}}),Z("active"))}function qn(e,t){return C(()=>{let r=new g;r.subscribe({next({active:n}){e.classList.toggle("md-header__title--active",n)},complete(){e.classList.remove("md-header__title--active")}});let o=fe(".md-content h1");return typeof o=="undefined"?M:Ya(o,t).pipe(E(n=>r.next(n)),L(()=>r.complete()),m(n=>R({ref:e},n)))})}function Qn(e,{viewport$:t,header$:r}){let o=r.pipe(m(({height:i})=>i),K()),n=o.pipe(v(()=>ge(e).pipe(m(({height:i})=>({top:e.offsetTop,bottom:e.offsetTop+i})),Z("bottom"))));return z([o,n,t]).pipe(m(([i,{top:a,bottom:s},{offset:{y:p},size:{height:c}}])=>(c=Math.max(0,c-Math.max(0,a-p,i)-Math.max(0,c+p-s)),{offset:a-i,height:c,active:a-i<=p})),K((i,a)=>i.offset===a.offset&&i.height===a.height&&i.active===a.active))}function Ba(e){let t=__md_get("__palette")||{index:e.findIndex(o=>matchMedia(o.getAttribute("data-md-color-media")).matches)},r=Math.max(0,Math.min(t.index,e.length-1));return I(...e).pipe(oe(o=>d(o,"change").pipe(m(()=>o))),Q(e[r]),m(o=>({index:e.indexOf(o),color:{media:o.getAttribute("data-md-color-media"),scheme:o.getAttribute("data-md-color-scheme"),primary:o.getAttribute("data-md-color-primary"),accent:o.getAttribute("data-md-color-accent")}})),B(1))}function Kn(e){let t=$("input",e),r=x("meta",{name:"theme-color"});document.head.appendChild(r);let o=x("meta",{name:"color-scheme"});document.head.appendChild(o);let n=$t("(prefers-color-scheme: light)");return C(()=>{let i=new g;return i.subscribe(a=>{if(document.body.setAttribute("data-md-color-switching",""),a.color.media==="(prefers-color-scheme)"){let s=matchMedia("(prefers-color-scheme: light)"),p=document.querySelector(s.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");a.color.scheme=p.getAttribute("data-md-color-scheme"),a.color.primary=p.getAttribute("data-md-color-primary"),a.color.accent=p.getAttribute("data-md-color-accent")}for(let[s,p]of Object.entries(a.color))document.body.setAttribute(`data-md-color-${s}`,p);for(let s=0;sa.key==="Enter"),ee(i,(a,s)=>s)).subscribe(({index:a})=>{a=(a+1)%t.length,t[a].click(),t[a].focus()}),i.pipe(m(()=>{let a=Se("header"),s=window.getComputedStyle(a);return o.content=s.colorScheme,s.backgroundColor.match(/\d+/g).map(p=>(+p).toString(16).padStart(2,"0")).join("")})).subscribe(a=>r.content=`#${a}`),i.pipe(be(se)).subscribe(()=>{document.body.removeAttribute("data-md-color-switching")}),Ba(t).pipe(U(n.pipe(Ce(1))),st(),E(a=>i.next(a)),L(()=>i.complete()),m(a=>R({ref:e},a)))})}function Yn(e,{progress$:t}){return C(()=>{let r=new g;return r.subscribe(({value:o})=>{e.style.setProperty("--md-progress-value",`${o}`)}),t.pipe(E(o=>r.next({value:o})),L(()=>r.complete()),m(o=>({ref:e,value:o})))})}var Gr=Vt(Yr());function Ga(e){e.setAttribute("data-md-copying","");let t=e.closest("[data-copy]"),r=t?t.getAttribute("data-copy"):e.innerText;return e.removeAttribute("data-md-copying"),r.trimEnd()}function Bn({alert$:e}){Gr.default.isSupported()&&new F(t=>{new Gr.default("[data-clipboard-target], [data-clipboard-text]",{text:r=>r.getAttribute("data-clipboard-text")||Ga(P(r.getAttribute("data-clipboard-target")))}).on("success",r=>t.next(r))}).pipe(E(t=>{t.trigger.focus()}),m(()=>Ee("clipboard.copied"))).subscribe(e)}function Gn(e,t){return e.protocol=t.protocol,e.hostname=t.hostname,e}function Ja(e,t){let r=new Map;for(let o of $("url",e)){let n=P("loc",o),i=[Gn(new URL(n.textContent),t)];r.set(`${i[0]}`,i);for(let a of $("[rel=alternate]",o)){let s=a.getAttribute("href");s!=null&&i.push(Gn(new URL(s),t))}}return r}function ur(e){return mn(new URL("sitemap.xml",e)).pipe(m(t=>Ja(t,new URL(e))),ve(()=>I(new Map)))}function Xa(e,t){if(!(e.target instanceof Element))return M;let r=e.target.closest("a");if(r===null)return M;if(r.target||e.metaKey||e.ctrlKey)return M;let o=new URL(r.href);return o.search=o.hash="",t.has(`${o}`)?(e.preventDefault(),I(new URL(r.href))):M}function Jn(e){let t=new Map;for(let r of $(":scope > *",e.head))t.set(r.outerHTML,r);return t}function Xn(e){for(let t of $("[href], [src]",e))for(let r of["href","src"]){let o=t.getAttribute(r);if(o&&!/^(?:[a-z]+:)?\/\//i.test(o)){t[r]=t[r];break}}return I(e)}function Za(e){for(let o of["[data-md-component=announce]","[data-md-component=container]","[data-md-component=header-topic]","[data-md-component=outdated]","[data-md-component=logo]","[data-md-component=skip]",...G("navigation.tabs.sticky")?["[data-md-component=tabs]"]:[]]){let n=fe(o),i=fe(o,e);typeof n!="undefined"&&typeof i!="undefined"&&n.replaceWith(i)}let t=Jn(document);for(let[o,n]of Jn(e))t.has(o)?t.delete(o):document.head.appendChild(n);for(let o of t.values()){let n=o.getAttribute("name");n!=="theme-color"&&n!=="color-scheme"&&o.remove()}let r=Se("container");return je($("script",r)).pipe(v(o=>{let n=e.createElement("script");if(o.src){for(let i of o.getAttributeNames())n.setAttribute(i,o.getAttribute(i));return o.replaceWith(n),new F(i=>{n.onload=()=>i.complete()})}else return n.textContent=o.textContent,o.replaceWith(n),M}),X(),ne(document))}function Zn({location$:e,viewport$:t,progress$:r}){let o=ye();if(location.protocol==="file:")return M;let n=ur(o.base);I(document).subscribe(Xn);let i=d(document.body,"click").pipe(We(n),v(([p,c])=>Xa(p,c)),pe()),a=d(window,"popstate").pipe(m(xe),pe());i.pipe(ee(t)).subscribe(([p,{offset:c}])=>{history.replaceState(c,""),history.pushState(null,"",p)}),S(i,a).subscribe(e);let s=e.pipe(Z("pathname"),v(p=>ln(p,{progress$:r}).pipe(ve(()=>(pt(p,!0),M)))),v(Xn),v(Za),pe());return S(s.pipe(ee(e,(p,c)=>c)),s.pipe(v(()=>e),Z("pathname"),v(()=>e),Z("hash")),e.pipe(K((p,c)=>p.pathname===c.pathname&&p.hash===c.hash),v(()=>i),E(()=>history.back()))).subscribe(p=>{var c,l;history.state!==null||!p.hash?window.scrollTo(0,(l=(c=history.state)==null?void 0:c.y)!=null?l:0):(history.scrollRestoration="auto",sn(p.hash),history.scrollRestoration="manual")}),e.subscribe(()=>{history.scrollRestoration="manual"}),d(window,"beforeunload").subscribe(()=>{history.scrollRestoration="auto"}),t.pipe(Z("offset"),_e(100)).subscribe(({offset:p})=>{history.replaceState(p,"")}),s}var ri=Vt(ti());function oi(e){let t=e.separator.split("|").map(n=>n.replace(/(\(\?[!=<][^)]+\))/g,"").length===0?"\uFFFD":n).join("|"),r=new RegExp(t,"img"),o=(n,i,a)=>`${i}${a}`;return n=>{n=n.replace(/[\s*+\-:~^]+/g," ").trim();let i=new RegExp(`(^|${e.separator}|)(${n.replace(/[|\\{}()[\]^$+*?.-]/g,"\\$&").replace(r,"|")})`,"img");return a=>(0,ri.default)(a).replace(i,o).replace(/<\/mark>(\s+)]*>/img,"$1")}}function It(e){return e.type===1}function dr(e){return e.type===3}function ni(e,t){let r=vn(e);return S(I(location.protocol!=="file:"),Ve("search")).pipe(Ae(o=>o),v(()=>t)).subscribe(({config:o,docs:n})=>r.next({type:0,data:{config:o,docs:n,options:{suggest:G("search.suggest")}}})),r}function ii({document$:e}){let t=ye(),r=Ne(new URL("../versions.json",t.base)).pipe(ve(()=>M)),o=r.pipe(m(n=>{let[,i]=t.base.match(/([^/]+)\/?$/);return n.find(({version:a,aliases:s})=>a===i||s.includes(i))||n[0]}));r.pipe(m(n=>new Map(n.map(i=>[`${new URL(`../${i.version}/`,t.base)}`,i]))),v(n=>d(document.body,"click").pipe(b(i=>!i.metaKey&&!i.ctrlKey),ee(o),v(([i,a])=>{if(i.target instanceof Element){let s=i.target.closest("a");if(s&&!s.target&&n.has(s.href)){let p=s.href;return!i.target.closest(".md-version")&&n.get(p)===a?M:(i.preventDefault(),I(p))}}return M}),v(i=>ur(new URL(i)).pipe(m(a=>{let p=xe().href.replace(t.base,i);return a.has(p.split("#")[0])?new URL(p):new URL(i)})))))).subscribe(n=>pt(n,!0)),z([r,o]).subscribe(([n,i])=>{P(".md-header__topic").appendChild(Mn(n,i))}),e.pipe(v(()=>o)).subscribe(n=>{var a;let i=__md_get("__outdated",sessionStorage);if(i===null){i=!0;let s=((a=t.version)==null?void 0:a.default)||"latest";Array.isArray(s)||(s=[s]);e:for(let p of s)for(let c of n.aliases.concat(n.version))if(new RegExp(p,"i").test(c)){i=!1;break e}__md_set("__outdated",i,sessionStorage)}if(i)for(let s of ae("outdated"))s.hidden=!1})}function ns(e,{worker$:t}){let{searchParams:r}=xe();r.has("q")&&(Je("search",!0),e.value=r.get("q"),e.focus(),Ve("search").pipe(Ae(i=>!i)).subscribe(()=>{let i=xe();i.searchParams.delete("q"),history.replaceState({},"",`${i}`)}));let o=et(e),n=S(t.pipe(Ae(It)),d(e,"keyup"),o).pipe(m(()=>e.value),K());return z([n,o]).pipe(m(([i,a])=>({value:i,focus:a})),B(1))}function ai(e,{worker$:t}){let r=new g,o=r.pipe(X(),ne(!0));z([t.pipe(Ae(It)),r],(i,a)=>a).pipe(Z("value")).subscribe(({value:i})=>t.next({type:2,data:i})),r.pipe(Z("focus")).subscribe(({focus:i})=>{i&&Je("search",i)}),d(e.form,"reset").pipe(U(o)).subscribe(()=>e.focus());let n=P("header [for=__search]");return d(n,"click").subscribe(()=>e.focus()),ns(e,{worker$:t}).pipe(E(i=>r.next(i)),L(()=>r.complete()),m(i=>R({ref:e},i)),B(1))}function si(e,{worker$:t,query$:r}){let o=new g,n=tn(e.parentElement).pipe(b(Boolean)),i=e.parentElement,a=P(":scope > :first-child",e),s=P(":scope > :last-child",e);Ve("search").subscribe(l=>s.setAttribute("role",l?"list":"presentation")),o.pipe(ee(r),Ur(t.pipe(Ae(It)))).subscribe(([{items:l},{value:f}])=>{switch(l.length){case 0:a.textContent=f.length?Ee("search.result.none"):Ee("search.result.placeholder");break;case 1:a.textContent=Ee("search.result.one");break;default:let u=sr(l.length);a.textContent=Ee("search.result.other",u)}});let p=o.pipe(E(()=>s.innerHTML=""),v(({items:l})=>S(I(...l.slice(0,10)),I(...l.slice(10)).pipe(Ye(4),Vr(n),v(([f])=>f)))),m(Tn),pe());return p.subscribe(l=>s.appendChild(l)),p.pipe(oe(l=>{let f=fe("details",l);return typeof f=="undefined"?M:d(f,"toggle").pipe(U(o),m(()=>f))})).subscribe(l=>{l.open===!1&&l.offsetTop<=i.scrollTop&&i.scrollTo({top:l.offsetTop})}),t.pipe(b(dr),m(({data:l})=>l)).pipe(E(l=>o.next(l)),L(()=>o.complete()),m(l=>R({ref:e},l)))}function is(e,{query$:t}){return t.pipe(m(({value:r})=>{let o=xe();return o.hash="",r=r.replace(/\s+/g,"+").replace(/&/g,"%26").replace(/=/g,"%3D"),o.search=`q=${r}`,{url:o}}))}function ci(e,t){let r=new g,o=r.pipe(X(),ne(!0));return r.subscribe(({url:n})=>{e.setAttribute("data-clipboard-text",e.href),e.href=`${n}`}),d(e,"click").pipe(U(o)).subscribe(n=>n.preventDefault()),is(e,t).pipe(E(n=>r.next(n)),L(()=>r.complete()),m(n=>R({ref:e},n)))}function pi(e,{worker$:t,keyboard$:r}){let o=new g,n=Se("search-query"),i=S(d(n,"keydown"),d(n,"focus")).pipe(be(se),m(()=>n.value),K());return o.pipe(We(i),m(([{suggest:s},p])=>{let c=p.split(/([\s-]+)/);if(s!=null&&s.length&&c[c.length-1]){let l=s[s.length-1];l.startsWith(c[c.length-1])&&(c[c.length-1]=l)}else c.length=0;return c})).subscribe(s=>e.innerHTML=s.join("").replace(/\s/g," ")),r.pipe(b(({mode:s})=>s==="search")).subscribe(s=>{switch(s.type){case"ArrowRight":e.innerText.length&&n.selectionStart===n.value.length&&(n.value=e.innerText);break}}),t.pipe(b(dr),m(({data:s})=>s)).pipe(E(s=>o.next(s)),L(()=>o.complete()),m(()=>({ref:e})))}function li(e,{index$:t,keyboard$:r}){let o=ye();try{let n=ni(o.search,t),i=Se("search-query",e),a=Se("search-result",e);d(e,"click").pipe(b(({target:p})=>p instanceof Element&&!!p.closest("a"))).subscribe(()=>Je("search",!1)),r.pipe(b(({mode:p})=>p==="search")).subscribe(p=>{let c=Re();switch(p.type){case"Enter":if(c===i){let l=new Map;for(let f of $(":first-child [href]",a)){let u=f.firstElementChild;l.set(f,parseFloat(u.getAttribute("data-md-score")))}if(l.size){let[[f]]=[...l].sort(([,u],[,h])=>h-u);f.click()}p.claim()}break;case"Escape":case"Tab":Je("search",!1),i.blur();break;case"ArrowUp":case"ArrowDown":if(typeof c=="undefined")i.focus();else{let l=[i,...$(":not(details) > [href], summary, details[open] [href]",a)],f=Math.max(0,(Math.max(0,l.indexOf(c))+l.length+(p.type==="ArrowUp"?-1:1))%l.length);l[f].focus()}p.claim();break;default:i!==Re()&&i.focus()}}),r.pipe(b(({mode:p})=>p==="global")).subscribe(p=>{switch(p.type){case"f":case"s":case"/":i.focus(),i.select(),p.claim();break}});let s=ai(i,{worker$:n});return S(s,si(a,{worker$:n,query$:s})).pipe(Pe(...ae("search-share",e).map(p=>ci(p,{query$:s})),...ae("search-suggest",e).map(p=>pi(p,{worker$:n,keyboard$:r}))))}catch(n){return e.hidden=!0,Ke}}function mi(e,{index$:t,location$:r}){return z([t,r.pipe(Q(xe()),b(o=>!!o.searchParams.get("h")))]).pipe(m(([o,n])=>oi(o.config)(n.searchParams.get("h"))),m(o=>{var a;let n=new Map,i=document.createNodeIterator(e,NodeFilter.SHOW_TEXT);for(let s=i.nextNode();s;s=i.nextNode())if((a=s.parentElement)!=null&&a.offsetHeight){let p=s.textContent,c=o(p);c.length>p.length&&n.set(s,c)}for(let[s,p]of n){let{childNodes:c}=x("span",null,p);s.replaceWith(...Array.from(c))}return{ref:e,nodes:n}}))}function as(e,{viewport$:t,main$:r}){let o=e.closest(".md-grid"),n=o.offsetTop-o.parentElement.offsetTop;return z([r,t]).pipe(m(([{offset:i,height:a},{offset:{y:s}}])=>(a=a+Math.min(n,Math.max(0,s-i))-n,{height:a,locked:s>=i+n})),K((i,a)=>i.height===a.height&&i.locked===a.locked))}function Jr(e,o){var n=o,{header$:t}=n,r=io(n,["header$"]);let i=P(".md-sidebar__scrollwrap",e),{y:a}=Ue(i);return C(()=>{let s=new g,p=s.pipe(X(),ne(!0)),c=s.pipe(Le(0,me));return c.pipe(ee(t)).subscribe({next([{height:l},{height:f}]){i.style.height=`${l-2*a}px`,e.style.top=`${f}px`},complete(){i.style.height="",e.style.top=""}}),c.pipe(Ae()).subscribe(()=>{for(let l of $(".md-nav__link--active[href]",e)){if(!l.clientHeight)continue;let f=l.closest(".md-sidebar__scrollwrap");if(typeof f!="undefined"){let u=l.offsetTop-f.offsetTop,{height:h}=ce(f);f.scrollTo({top:u-h/2})}}}),ue($("label[tabindex]",e)).pipe(oe(l=>d(l,"click").pipe(be(se),m(()=>l),U(p)))).subscribe(l=>{let f=P(`[id="${l.htmlFor}"]`);P(`[aria-labelledby="${l.id}"]`).setAttribute("aria-expanded",`${f.checked}`)}),as(e,r).pipe(E(l=>s.next(l)),L(()=>s.complete()),m(l=>R({ref:e},l)))})}function fi(e,t){if(typeof t!="undefined"){let r=`https://api.github.com/repos/${e}/${t}`;return Ct(Ne(`${r}/releases/latest`).pipe(ve(()=>M),m(o=>({version:o.tag_name})),Be({})),Ne(r).pipe(ve(()=>M),m(o=>({stars:o.stargazers_count,forks:o.forks_count})),Be({}))).pipe(m(([o,n])=>R(R({},o),n)))}else{let r=`https://api.github.com/users/${e}`;return Ne(r).pipe(m(o=>({repositories:o.public_repos})),Be({}))}}function ui(e,t){let r=`https://${e}/api/v4/projects/${encodeURIComponent(t)}`;return Ne(r).pipe(ve(()=>M),m(({star_count:o,forks_count:n})=>({stars:o,forks:n})),Be({}))}function di(e){let t=e.match(/^.+github\.com\/([^/]+)\/?([^/]+)?/i);if(t){let[,r,o]=t;return fi(r,o)}if(t=e.match(/^.+?([^/]*gitlab[^/]+)\/(.+?)\/?$/i),t){let[,r,o]=t;return ui(r,o)}return M}var ss;function cs(e){return ss||(ss=C(()=>{let t=__md_get("__source",sessionStorage);if(t)return I(t);if(ae("consent").length){let o=__md_get("__consent");if(!(o&&o.github))return M}return di(e.href).pipe(E(o=>__md_set("__source",o,sessionStorage)))}).pipe(ve(()=>M),b(t=>Object.keys(t).length>0),m(t=>({facts:t})),B(1)))}function hi(e){let t=P(":scope > :last-child",e);return C(()=>{let r=new g;return r.subscribe(({facts:o})=>{t.appendChild(Sn(o)),t.classList.add("md-source__repository--active")}),cs(e).pipe(E(o=>r.next(o)),L(()=>r.complete()),m(o=>R({ref:e},o)))})}function ps(e,{viewport$:t,header$:r}){return ge(document.body).pipe(v(()=>mr(e,{header$:r,viewport$:t})),m(({offset:{y:o}})=>({hidden:o>=10})),Z("hidden"))}function bi(e,t){return C(()=>{let r=new g;return r.subscribe({next({hidden:o}){e.hidden=o},complete(){e.hidden=!1}}),(G("navigation.tabs.sticky")?I({hidden:!1}):ps(e,t)).pipe(E(o=>r.next(o)),L(()=>r.complete()),m(o=>R({ref:e},o)))})}function ls(e,{viewport$:t,header$:r}){let o=new Map,n=$(".md-nav__link",e);for(let s of n){let p=decodeURIComponent(s.hash.substring(1)),c=fe(`[id="${p}"]`);typeof c!="undefined"&&o.set(s,c)}let i=r.pipe(Z("height"),m(({height:s})=>{let p=Se("main"),c=P(":scope > :first-child",p);return s+.8*(c.offsetTop-p.offsetTop)}),pe());return ge(document.body).pipe(Z("height"),v(s=>C(()=>{let p=[];return I([...o].reduce((c,[l,f])=>{for(;p.length&&o.get(p[p.length-1]).tagName>=f.tagName;)p.pop();let u=f.offsetTop;for(;!u&&f.parentElement;)f=f.parentElement,u=f.offsetTop;let h=f.offsetParent;for(;h;h=h.offsetParent)u+=h.offsetTop;return c.set([...p=[...p,l]].reverse(),u)},new Map))}).pipe(m(p=>new Map([...p].sort(([,c],[,l])=>c-l))),We(i),v(([p,c])=>t.pipe(jr(([l,f],{offset:{y:u},size:h})=>{let w=u+h.height>=Math.floor(s.height);for(;f.length;){let[,A]=f[0];if(A-c=u&&!w)f=[l.pop(),...f];else break}return[l,f]},[[],[...p]]),K((l,f)=>l[0]===f[0]&&l[1]===f[1])))))).pipe(m(([s,p])=>({prev:s.map(([c])=>c),next:p.map(([c])=>c)})),Q({prev:[],next:[]}),Ye(2,1),m(([s,p])=>s.prev.length{let i=new g,a=i.pipe(X(),ne(!0));if(i.subscribe(({prev:s,next:p})=>{for(let[c]of p)c.classList.remove("md-nav__link--passed"),c.classList.remove("md-nav__link--active");for(let[c,[l]]of s.entries())l.classList.add("md-nav__link--passed"),l.classList.toggle("md-nav__link--active",c===s.length-1)}),G("toc.follow")){let s=S(t.pipe(_e(1),m(()=>{})),t.pipe(_e(250),m(()=>"smooth")));i.pipe(b(({prev:p})=>p.length>0),We(o.pipe(be(se))),ee(s)).subscribe(([[{prev:p}],c])=>{let[l]=p[p.length-1];if(l.offsetHeight){let f=cr(l);if(typeof f!="undefined"){let u=l.offsetTop-f.offsetTop,{height:h}=ce(f);f.scrollTo({top:u-h/2,behavior:c})}}})}return G("navigation.tracking")&&t.pipe(U(a),Z("offset"),_e(250),Ce(1),U(n.pipe(Ce(1))),st({delay:250}),ee(i)).subscribe(([,{prev:s}])=>{let p=xe(),c=s[s.length-1];if(c&&c.length){let[l]=c,{hash:f}=new URL(l.href);p.hash!==f&&(p.hash=f,history.replaceState({},"",`${p}`))}else p.hash="",history.replaceState({},"",`${p}`)}),ls(e,{viewport$:t,header$:r}).pipe(E(s=>i.next(s)),L(()=>i.complete()),m(s=>R({ref:e},s)))})}function ms(e,{viewport$:t,main$:r,target$:o}){let n=t.pipe(m(({offset:{y:a}})=>a),Ye(2,1),m(([a,s])=>a>s&&s>0),K()),i=r.pipe(m(({active:a})=>a));return z([i,n]).pipe(m(([a,s])=>!(a&&s)),K(),U(o.pipe(Ce(1))),ne(!0),st({delay:250}),m(a=>({hidden:a})))}function gi(e,{viewport$:t,header$:r,main$:o,target$:n}){let i=new g,a=i.pipe(X(),ne(!0));return i.subscribe({next({hidden:s}){e.hidden=s,s?(e.setAttribute("tabindex","-1"),e.blur()):e.removeAttribute("tabindex")},complete(){e.style.top="",e.hidden=!0,e.removeAttribute("tabindex")}}),r.pipe(U(a),Z("height")).subscribe(({height:s})=>{e.style.top=`${s+16}px`}),d(e,"click").subscribe(s=>{s.preventDefault(),window.scrollTo({top:0})}),ms(e,{viewport$:t,main$:o,target$:n}).pipe(E(s=>i.next(s)),L(()=>i.complete()),m(s=>R({ref:e},s)))}function xi({document$:e,viewport$:t}){e.pipe(v(()=>$(".md-ellipsis")),oe(r=>tt(r).pipe(U(e.pipe(Ce(1))),b(o=>o),m(()=>r),Te(1))),b(r=>r.offsetWidth{let o=r.innerText,n=r.closest("a")||r;return n.title=o,lt(n,{viewport$:t}).pipe(U(e.pipe(Ce(1))),L(()=>n.removeAttribute("title")))})).subscribe(),e.pipe(v(()=>$(".md-status")),oe(r=>lt(r,{viewport$:t}))).subscribe()}function yi({document$:e,tablet$:t}){e.pipe(v(()=>$(".md-toggle--indeterminate")),E(r=>{r.indeterminate=!0,r.checked=!1}),oe(r=>d(r,"change").pipe(Dr(()=>r.classList.contains("md-toggle--indeterminate")),m(()=>r))),ee(t)).subscribe(([r,o])=>{r.classList.remove("md-toggle--indeterminate"),o&&(r.checked=!1)})}function fs(){return/(iPad|iPhone|iPod)/.test(navigator.userAgent)}function Ei({document$:e}){e.pipe(v(()=>$("[data-md-scrollfix]")),E(t=>t.removeAttribute("data-md-scrollfix")),b(fs),oe(t=>d(t,"touchstart").pipe(m(()=>t)))).subscribe(t=>{let r=t.scrollTop;r===0?t.scrollTop=1:r+t.offsetHeight===t.scrollHeight&&(t.scrollTop=r-1)})}function wi({viewport$:e,tablet$:t}){z([Ve("search"),t]).pipe(m(([r,o])=>r&&!o),v(r=>I(r).pipe(Ge(r?400:100))),ee(e)).subscribe(([r,{offset:{y:o}}])=>{if(r)document.body.setAttribute("data-md-scrolllock",""),document.body.style.top=`-${o}px`;else{let n=-1*parseInt(document.body.style.top,10);document.body.removeAttribute("data-md-scrolllock"),document.body.style.top="",n&&window.scrollTo(0,n)}})}Object.entries||(Object.entries=function(e){let t=[];for(let r of Object.keys(e))t.push([r,e[r]]);return t});Object.values||(Object.values=function(e){let t=[];for(let r of Object.keys(e))t.push(e[r]);return t});typeof Element!="undefined"&&(Element.prototype.scrollTo||(Element.prototype.scrollTo=function(e,t){typeof e=="object"?(this.scrollLeft=e.left,this.scrollTop=e.top):(this.scrollLeft=e,this.scrollTop=t)}),Element.prototype.replaceWith||(Element.prototype.replaceWith=function(...e){let t=this.parentNode;if(t){e.length===0&&t.removeChild(this);for(let r=e.length-1;r>=0;r--){let o=e[r];typeof o=="string"?o=document.createTextNode(o):o.parentNode&&o.parentNode.removeChild(o),r?t.insertBefore(this.previousSibling,o):t.replaceChild(o,this)}}}));function us(){return location.protocol==="file:"?wt(`${new URL("search/search_index.js",Xr.base)}`).pipe(m(()=>__index),B(1)):Ne(new URL("search/search_index.json",Xr.base))}document.documentElement.classList.remove("no-js");document.documentElement.classList.add("js");var ot=Yo(),jt=nn(),Ot=cn(jt),Zr=on(),Oe=bn(),hr=$t("(min-width: 960px)"),Si=$t("(min-width: 1220px)"),Oi=pn(),Xr=ye(),Mi=document.forms.namedItem("search")?us():Ke,eo=new g;Bn({alert$:eo});var to=new g;G("navigation.instant")&&Zn({location$:jt,viewport$:Oe,progress$:to}).subscribe(ot);var Ti;((Ti=Xr.version)==null?void 0:Ti.provider)==="mike"&&ii({document$:ot});S(jt,Ot).pipe(Ge(125)).subscribe(()=>{Je("drawer",!1),Je("search",!1)});Zr.pipe(b(({mode:e})=>e==="global")).subscribe(e=>{switch(e.type){case"p":case",":let t=fe("link[rel=prev]");typeof t!="undefined"&&pt(t);break;case"n":case".":let r=fe("link[rel=next]");typeof r!="undefined"&&pt(r);break;case"Enter":let o=Re();o instanceof HTMLLabelElement&&o.click()}});xi({viewport$:Oe,document$:ot});yi({document$:ot,tablet$:hr});Ei({document$:ot});wi({viewport$:Oe,tablet$:hr});var rt=Nn(Se("header"),{viewport$:Oe}),Ft=ot.pipe(m(()=>Se("main")),v(e=>Qn(e,{viewport$:Oe,header$:rt})),B(1)),ds=S(...ae("consent").map(e=>xn(e,{target$:Ot})),...ae("dialog").map(e=>Dn(e,{alert$:eo})),...ae("header").map(e=>zn(e,{viewport$:Oe,header$:rt,main$:Ft})),...ae("palette").map(e=>Kn(e)),...ae("progress").map(e=>Yn(e,{progress$:to})),...ae("search").map(e=>li(e,{index$:Mi,keyboard$:Zr})),...ae("source").map(e=>hi(e))),hs=C(()=>S(...ae("announce").map(e=>gn(e)),...ae("content").map(e=>Un(e,{viewport$:Oe,target$:Ot,print$:Oi})),...ae("content").map(e=>G("search.highlight")?mi(e,{index$:Mi,location$:jt}):M),...ae("header-title").map(e=>qn(e,{viewport$:Oe,header$:rt})),...ae("sidebar").map(e=>e.getAttribute("data-md-type")==="navigation"?Nr(Si,()=>Jr(e,{viewport$:Oe,header$:rt,main$:Ft})):Nr(hr,()=>Jr(e,{viewport$:Oe,header$:rt,main$:Ft}))),...ae("tabs").map(e=>bi(e,{viewport$:Oe,header$:rt})),...ae("toc").map(e=>vi(e,{viewport$:Oe,header$:rt,main$:Ft,target$:Ot})),...ae("top").map(e=>gi(e,{viewport$:Oe,header$:rt,main$:Ft,target$:Ot})))),Li=ot.pipe(v(()=>hs),Pe(ds),B(1));Li.subscribe();window.document$=ot;window.location$=jt;window.target$=Ot;window.keyboard$=Zr;window.viewport$=Oe;window.tablet$=hr;window.screen$=Si;window.print$=Oi;window.alert$=eo;window.progress$=to;window.component$=Li;})(); +//# sourceMappingURL=bundle.ad660dcc.min.js.map + diff --git a/assets/javascripts/bundle.ad660dcc.min.js.map b/assets/javascripts/bundle.ad660dcc.min.js.map new file mode 100644 index 0000000000..6d61170f1e --- /dev/null +++ b/assets/javascripts/bundle.ad660dcc.min.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": ["node_modules/focus-visible/dist/focus-visible.js", "node_modules/clipboard/dist/clipboard.js", "node_modules/escape-html/index.js", "src/templates/assets/javascripts/bundle.ts", "node_modules/rxjs/node_modules/tslib/tslib.es6.js", "node_modules/rxjs/src/internal/util/isFunction.ts", "node_modules/rxjs/src/internal/util/createErrorClass.ts", "node_modules/rxjs/src/internal/util/UnsubscriptionError.ts", "node_modules/rxjs/src/internal/util/arrRemove.ts", "node_modules/rxjs/src/internal/Subscription.ts", "node_modules/rxjs/src/internal/config.ts", "node_modules/rxjs/src/internal/scheduler/timeoutProvider.ts", "node_modules/rxjs/src/internal/util/reportUnhandledError.ts", "node_modules/rxjs/src/internal/util/noop.ts", "node_modules/rxjs/src/internal/NotificationFactories.ts", "node_modules/rxjs/src/internal/util/errorContext.ts", "node_modules/rxjs/src/internal/Subscriber.ts", "node_modules/rxjs/src/internal/symbol/observable.ts", "node_modules/rxjs/src/internal/util/identity.ts", "node_modules/rxjs/src/internal/util/pipe.ts", "node_modules/rxjs/src/internal/Observable.ts", "node_modules/rxjs/src/internal/util/lift.ts", "node_modules/rxjs/src/internal/operators/OperatorSubscriber.ts", "node_modules/rxjs/src/internal/scheduler/animationFrameProvider.ts", "node_modules/rxjs/src/internal/util/ObjectUnsubscribedError.ts", "node_modules/rxjs/src/internal/Subject.ts", "node_modules/rxjs/src/internal/BehaviorSubject.ts", "node_modules/rxjs/src/internal/scheduler/dateTimestampProvider.ts", "node_modules/rxjs/src/internal/ReplaySubject.ts", "node_modules/rxjs/src/internal/scheduler/Action.ts", "node_modules/rxjs/src/internal/scheduler/intervalProvider.ts", "node_modules/rxjs/src/internal/scheduler/AsyncAction.ts", "node_modules/rxjs/src/internal/Scheduler.ts", "node_modules/rxjs/src/internal/scheduler/AsyncScheduler.ts", "node_modules/rxjs/src/internal/scheduler/async.ts", "node_modules/rxjs/src/internal/scheduler/QueueAction.ts", "node_modules/rxjs/src/internal/scheduler/QueueScheduler.ts", "node_modules/rxjs/src/internal/scheduler/queue.ts", "node_modules/rxjs/src/internal/scheduler/AnimationFrameAction.ts", "node_modules/rxjs/src/internal/scheduler/AnimationFrameScheduler.ts", "node_modules/rxjs/src/internal/scheduler/animationFrame.ts", "node_modules/rxjs/src/internal/observable/empty.ts", "node_modules/rxjs/src/internal/util/isScheduler.ts", "node_modules/rxjs/src/internal/util/args.ts", "node_modules/rxjs/src/internal/util/isArrayLike.ts", "node_modules/rxjs/src/internal/util/isPromise.ts", "node_modules/rxjs/src/internal/util/isInteropObservable.ts", "node_modules/rxjs/src/internal/util/isAsyncIterable.ts", "node_modules/rxjs/src/internal/util/throwUnobservableError.ts", "node_modules/rxjs/src/internal/symbol/iterator.ts", "node_modules/rxjs/src/internal/util/isIterable.ts", "node_modules/rxjs/src/internal/util/isReadableStreamLike.ts", "node_modules/rxjs/src/internal/observable/innerFrom.ts", "node_modules/rxjs/src/internal/util/executeSchedule.ts", "node_modules/rxjs/src/internal/operators/observeOn.ts", "node_modules/rxjs/src/internal/operators/subscribeOn.ts", "node_modules/rxjs/src/internal/scheduled/scheduleObservable.ts", "node_modules/rxjs/src/internal/scheduled/schedulePromise.ts", "node_modules/rxjs/src/internal/scheduled/scheduleArray.ts", "node_modules/rxjs/src/internal/scheduled/scheduleIterable.ts", "node_modules/rxjs/src/internal/scheduled/scheduleAsyncIterable.ts", "node_modules/rxjs/src/internal/scheduled/scheduleReadableStreamLike.ts", "node_modules/rxjs/src/internal/scheduled/scheduled.ts", "node_modules/rxjs/src/internal/observable/from.ts", "node_modules/rxjs/src/internal/observable/of.ts", "node_modules/rxjs/src/internal/observable/throwError.ts", "node_modules/rxjs/src/internal/util/EmptyError.ts", "node_modules/rxjs/src/internal/util/isDate.ts", "node_modules/rxjs/src/internal/operators/map.ts", "node_modules/rxjs/src/internal/util/mapOneOrManyArgs.ts", "node_modules/rxjs/src/internal/util/argsArgArrayOrObject.ts", "node_modules/rxjs/src/internal/util/createObject.ts", "node_modules/rxjs/src/internal/observable/combineLatest.ts", "node_modules/rxjs/src/internal/operators/mergeInternals.ts", "node_modules/rxjs/src/internal/operators/mergeMap.ts", "node_modules/rxjs/src/internal/operators/mergeAll.ts", "node_modules/rxjs/src/internal/operators/concatAll.ts", "node_modules/rxjs/src/internal/observable/concat.ts", "node_modules/rxjs/src/internal/observable/defer.ts", "node_modules/rxjs/src/internal/observable/fromEvent.ts", "node_modules/rxjs/src/internal/observable/fromEventPattern.ts", "node_modules/rxjs/src/internal/observable/timer.ts", "node_modules/rxjs/src/internal/observable/merge.ts", "node_modules/rxjs/src/internal/observable/never.ts", "node_modules/rxjs/src/internal/util/argsOrArgArray.ts", "node_modules/rxjs/src/internal/operators/filter.ts", "node_modules/rxjs/src/internal/observable/zip.ts", "node_modules/rxjs/src/internal/operators/audit.ts", "node_modules/rxjs/src/internal/operators/auditTime.ts", "node_modules/rxjs/src/internal/operators/bufferCount.ts", "node_modules/rxjs/src/internal/operators/catchError.ts", "node_modules/rxjs/src/internal/operators/scanInternals.ts", "node_modules/rxjs/src/internal/operators/combineLatest.ts", "node_modules/rxjs/src/internal/operators/combineLatestWith.ts", "node_modules/rxjs/src/internal/operators/debounce.ts", "node_modules/rxjs/src/internal/operators/debounceTime.ts", "node_modules/rxjs/src/internal/operators/defaultIfEmpty.ts", "node_modules/rxjs/src/internal/operators/take.ts", "node_modules/rxjs/src/internal/operators/ignoreElements.ts", "node_modules/rxjs/src/internal/operators/mapTo.ts", "node_modules/rxjs/src/internal/operators/delayWhen.ts", "node_modules/rxjs/src/internal/operators/delay.ts", "node_modules/rxjs/src/internal/operators/distinctUntilChanged.ts", "node_modules/rxjs/src/internal/operators/distinctUntilKeyChanged.ts", "node_modules/rxjs/src/internal/operators/throwIfEmpty.ts", "node_modules/rxjs/src/internal/operators/endWith.ts", "node_modules/rxjs/src/internal/operators/finalize.ts", "node_modules/rxjs/src/internal/operators/first.ts", "node_modules/rxjs/src/internal/operators/takeLast.ts", "node_modules/rxjs/src/internal/operators/merge.ts", "node_modules/rxjs/src/internal/operators/mergeWith.ts", "node_modules/rxjs/src/internal/operators/repeat.ts", "node_modules/rxjs/src/internal/operators/scan.ts", "node_modules/rxjs/src/internal/operators/share.ts", "node_modules/rxjs/src/internal/operators/shareReplay.ts", "node_modules/rxjs/src/internal/operators/skip.ts", "node_modules/rxjs/src/internal/operators/skipUntil.ts", "node_modules/rxjs/src/internal/operators/startWith.ts", "node_modules/rxjs/src/internal/operators/switchMap.ts", "node_modules/rxjs/src/internal/operators/takeUntil.ts", "node_modules/rxjs/src/internal/operators/takeWhile.ts", "node_modules/rxjs/src/internal/operators/tap.ts", "node_modules/rxjs/src/internal/operators/throttle.ts", "node_modules/rxjs/src/internal/operators/throttleTime.ts", "node_modules/rxjs/src/internal/operators/withLatestFrom.ts", "node_modules/rxjs/src/internal/operators/zip.ts", "node_modules/rxjs/src/internal/operators/zipWith.ts", "src/templates/assets/javascripts/browser/document/index.ts", "src/templates/assets/javascripts/browser/element/_/index.ts", "src/templates/assets/javascripts/browser/element/focus/index.ts", "src/templates/assets/javascripts/browser/element/hover/index.ts", "src/templates/assets/javascripts/utilities/h/index.ts", "src/templates/assets/javascripts/utilities/round/index.ts", "src/templates/assets/javascripts/browser/script/index.ts", "src/templates/assets/javascripts/browser/element/size/_/index.ts", "src/templates/assets/javascripts/browser/element/size/content/index.ts", "src/templates/assets/javascripts/browser/element/offset/_/index.ts", "src/templates/assets/javascripts/browser/element/offset/content/index.ts", "src/templates/assets/javascripts/browser/element/visibility/index.ts", "src/templates/assets/javascripts/browser/toggle/index.ts", "src/templates/assets/javascripts/browser/keyboard/index.ts", "src/templates/assets/javascripts/browser/location/_/index.ts", "src/templates/assets/javascripts/browser/location/hash/index.ts", "src/templates/assets/javascripts/browser/media/index.ts", "src/templates/assets/javascripts/browser/request/index.ts", "src/templates/assets/javascripts/browser/viewport/offset/index.ts", "src/templates/assets/javascripts/browser/viewport/size/index.ts", "src/templates/assets/javascripts/browser/viewport/_/index.ts", "src/templates/assets/javascripts/browser/viewport/at/index.ts", "src/templates/assets/javascripts/browser/worker/index.ts", "src/templates/assets/javascripts/_/index.ts", "src/templates/assets/javascripts/components/_/index.ts", "src/templates/assets/javascripts/components/announce/index.ts", "src/templates/assets/javascripts/components/consent/index.ts", "src/templates/assets/javascripts/templates/tooltip/index.tsx", "src/templates/assets/javascripts/templates/annotation/index.tsx", "src/templates/assets/javascripts/templates/clipboard/index.tsx", "src/templates/assets/javascripts/templates/search/index.tsx", "src/templates/assets/javascripts/templates/source/index.tsx", "src/templates/assets/javascripts/templates/tabbed/index.tsx", "src/templates/assets/javascripts/templates/table/index.tsx", "src/templates/assets/javascripts/templates/version/index.tsx", "src/templates/assets/javascripts/components/tooltip2/index.ts", "src/templates/assets/javascripts/components/content/annotation/_/index.ts", "src/templates/assets/javascripts/components/content/annotation/list/index.ts", "src/templates/assets/javascripts/components/content/annotation/block/index.ts", "src/templates/assets/javascripts/components/content/code/_/index.ts", "src/templates/assets/javascripts/components/content/details/index.ts", "src/templates/assets/javascripts/components/content/mermaid/index.css", "src/templates/assets/javascripts/components/content/mermaid/index.ts", "src/templates/assets/javascripts/components/content/table/index.ts", "src/templates/assets/javascripts/components/content/tabs/index.ts", "src/templates/assets/javascripts/components/content/_/index.ts", "src/templates/assets/javascripts/components/dialog/index.ts", "src/templates/assets/javascripts/components/tooltip/index.ts", "src/templates/assets/javascripts/components/header/_/index.ts", "src/templates/assets/javascripts/components/header/title/index.ts", "src/templates/assets/javascripts/components/main/index.ts", "src/templates/assets/javascripts/components/palette/index.ts", "src/templates/assets/javascripts/components/progress/index.ts", "src/templates/assets/javascripts/integrations/clipboard/index.ts", "src/templates/assets/javascripts/integrations/sitemap/index.ts", "src/templates/assets/javascripts/integrations/instant/index.ts", "src/templates/assets/javascripts/integrations/search/highlighter/index.ts", "src/templates/assets/javascripts/integrations/search/worker/message/index.ts", "src/templates/assets/javascripts/integrations/search/worker/_/index.ts", "src/templates/assets/javascripts/integrations/version/index.ts", "src/templates/assets/javascripts/components/search/query/index.ts", "src/templates/assets/javascripts/components/search/result/index.ts", "src/templates/assets/javascripts/components/search/share/index.ts", "src/templates/assets/javascripts/components/search/suggest/index.ts", "src/templates/assets/javascripts/components/search/_/index.ts", "src/templates/assets/javascripts/components/search/highlight/index.ts", "src/templates/assets/javascripts/components/sidebar/index.ts", "src/templates/assets/javascripts/components/source/facts/github/index.ts", "src/templates/assets/javascripts/components/source/facts/gitlab/index.ts", "src/templates/assets/javascripts/components/source/facts/_/index.ts", "src/templates/assets/javascripts/components/source/_/index.ts", "src/templates/assets/javascripts/components/tabs/index.ts", "src/templates/assets/javascripts/components/toc/index.ts", "src/templates/assets/javascripts/components/top/index.ts", "src/templates/assets/javascripts/patches/ellipsis/index.ts", "src/templates/assets/javascripts/patches/indeterminate/index.ts", "src/templates/assets/javascripts/patches/scrollfix/index.ts", "src/templates/assets/javascripts/patches/scrolllock/index.ts", "src/templates/assets/javascripts/polyfills/index.ts"], + "sourcesContent": ["(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? factory() :\n typeof define === 'function' && define.amd ? define(factory) :\n (factory());\n}(this, (function () { 'use strict';\n\n /**\n * Applies the :focus-visible polyfill at the given scope.\n * A scope in this case is either the top-level Document or a Shadow Root.\n *\n * @param {(Document|ShadowRoot)} scope\n * @see https://github.com/WICG/focus-visible\n */\n function applyFocusVisiblePolyfill(scope) {\n var hadKeyboardEvent = true;\n var hadFocusVisibleRecently = false;\n var hadFocusVisibleRecentlyTimeout = null;\n\n var inputTypesAllowlist = {\n text: true,\n search: true,\n url: true,\n tel: true,\n email: true,\n password: true,\n number: true,\n date: true,\n month: true,\n week: true,\n time: true,\n datetime: true,\n 'datetime-local': true\n };\n\n /**\n * Helper function for legacy browsers and iframes which sometimes focus\n * elements like document, body, and non-interactive SVG.\n * @param {Element} el\n */\n function isValidFocusTarget(el) {\n if (\n el &&\n el !== document &&\n el.nodeName !== 'HTML' &&\n el.nodeName !== 'BODY' &&\n 'classList' in el &&\n 'contains' in el.classList\n ) {\n return true;\n }\n return false;\n }\n\n /**\n * Computes whether the given element should automatically trigger the\n * `focus-visible` class being added, i.e. whether it should always match\n * `:focus-visible` when focused.\n * @param {Element} el\n * @return {boolean}\n */\n function focusTriggersKeyboardModality(el) {\n var type = el.type;\n var tagName = el.tagName;\n\n if (tagName === 'INPUT' && inputTypesAllowlist[type] && !el.readOnly) {\n return true;\n }\n\n if (tagName === 'TEXTAREA' && !el.readOnly) {\n return true;\n }\n\n if (el.isContentEditable) {\n return true;\n }\n\n return false;\n }\n\n /**\n * Add the `focus-visible` class to the given element if it was not added by\n * the author.\n * @param {Element} el\n */\n function addFocusVisibleClass(el) {\n if (el.classList.contains('focus-visible')) {\n return;\n }\n el.classList.add('focus-visible');\n el.setAttribute('data-focus-visible-added', '');\n }\n\n /**\n * Remove the `focus-visible` class from the given element if it was not\n * originally added by the author.\n * @param {Element} el\n */\n function removeFocusVisibleClass(el) {\n if (!el.hasAttribute('data-focus-visible-added')) {\n return;\n }\n el.classList.remove('focus-visible');\n el.removeAttribute('data-focus-visible-added');\n }\n\n /**\n * If the most recent user interaction was via the keyboard;\n * and the key press did not include a meta, alt/option, or control key;\n * then the modality is keyboard. Otherwise, the modality is not keyboard.\n * Apply `focus-visible` to any current active element and keep track\n * of our keyboard modality state with `hadKeyboardEvent`.\n * @param {KeyboardEvent} e\n */\n function onKeyDown(e) {\n if (e.metaKey || e.altKey || e.ctrlKey) {\n return;\n }\n\n if (isValidFocusTarget(scope.activeElement)) {\n addFocusVisibleClass(scope.activeElement);\n }\n\n hadKeyboardEvent = true;\n }\n\n /**\n * If at any point a user clicks with a pointing device, ensure that we change\n * the modality away from keyboard.\n * This avoids the situation where a user presses a key on an already focused\n * element, and then clicks on a different element, focusing it with a\n * pointing device, while we still think we're in keyboard modality.\n * @param {Event} e\n */\n function onPointerDown(e) {\n hadKeyboardEvent = false;\n }\n\n /**\n * On `focus`, add the `focus-visible` class to the target if:\n * - the target received focus as a result of keyboard navigation, or\n * - the event target is an element that will likely require interaction\n * via the keyboard (e.g. a text box)\n * @param {Event} e\n */\n function onFocus(e) {\n // Prevent IE from focusing the document or HTML element.\n if (!isValidFocusTarget(e.target)) {\n return;\n }\n\n if (hadKeyboardEvent || focusTriggersKeyboardModality(e.target)) {\n addFocusVisibleClass(e.target);\n }\n }\n\n /**\n * On `blur`, remove the `focus-visible` class from the target.\n * @param {Event} e\n */\n function onBlur(e) {\n if (!isValidFocusTarget(e.target)) {\n return;\n }\n\n if (\n e.target.classList.contains('focus-visible') ||\n e.target.hasAttribute('data-focus-visible-added')\n ) {\n // To detect a tab/window switch, we look for a blur event followed\n // rapidly by a visibility change.\n // If we don't see a visibility change within 100ms, it's probably a\n // regular focus change.\n hadFocusVisibleRecently = true;\n window.clearTimeout(hadFocusVisibleRecentlyTimeout);\n hadFocusVisibleRecentlyTimeout = window.setTimeout(function() {\n hadFocusVisibleRecently = false;\n }, 100);\n removeFocusVisibleClass(e.target);\n }\n }\n\n /**\n * If the user changes tabs, keep track of whether or not the previously\n * focused element had .focus-visible.\n * @param {Event} e\n */\n function onVisibilityChange(e) {\n if (document.visibilityState === 'hidden') {\n // If the tab becomes active again, the browser will handle calling focus\n // on the element (Safari actually calls it twice).\n // If this tab change caused a blur on an element with focus-visible,\n // re-apply the class when the user switches back to the tab.\n if (hadFocusVisibleRecently) {\n hadKeyboardEvent = true;\n }\n addInitialPointerMoveListeners();\n }\n }\n\n /**\n * Add a group of listeners to detect usage of any pointing devices.\n * These listeners will be added when the polyfill first loads, and anytime\n * the window is blurred, so that they are active when the window regains\n * focus.\n */\n function addInitialPointerMoveListeners() {\n document.addEventListener('mousemove', onInitialPointerMove);\n document.addEventListener('mousedown', onInitialPointerMove);\n document.addEventListener('mouseup', onInitialPointerMove);\n document.addEventListener('pointermove', onInitialPointerMove);\n document.addEventListener('pointerdown', onInitialPointerMove);\n document.addEventListener('pointerup', onInitialPointerMove);\n document.addEventListener('touchmove', onInitialPointerMove);\n document.addEventListener('touchstart', onInitialPointerMove);\n document.addEventListener('touchend', onInitialPointerMove);\n }\n\n function removeInitialPointerMoveListeners() {\n document.removeEventListener('mousemove', onInitialPointerMove);\n document.removeEventListener('mousedown', onInitialPointerMove);\n document.removeEventListener('mouseup', onInitialPointerMove);\n document.removeEventListener('pointermove', onInitialPointerMove);\n document.removeEventListener('pointerdown', onInitialPointerMove);\n document.removeEventListener('pointerup', onInitialPointerMove);\n document.removeEventListener('touchmove', onInitialPointerMove);\n document.removeEventListener('touchstart', onInitialPointerMove);\n document.removeEventListener('touchend', onInitialPointerMove);\n }\n\n /**\n * When the polfyill first loads, assume the user is in keyboard modality.\n * If any event is received from a pointing device (e.g. mouse, pointer,\n * touch), turn off keyboard modality.\n * This accounts for situations where focus enters the page from the URL bar.\n * @param {Event} e\n */\n function onInitialPointerMove(e) {\n // Work around a Safari quirk that fires a mousemove on whenever the\n // window blurs, even if you're tabbing out of the page. \u00AF\\_(\u30C4)_/\u00AF\n if (e.target.nodeName && e.target.nodeName.toLowerCase() === 'html') {\n return;\n }\n\n hadKeyboardEvent = false;\n removeInitialPointerMoveListeners();\n }\n\n // For some kinds of state, we are interested in changes at the global scope\n // only. For example, global pointer input, global key presses and global\n // visibility change should affect the state at every scope:\n document.addEventListener('keydown', onKeyDown, true);\n document.addEventListener('mousedown', onPointerDown, true);\n document.addEventListener('pointerdown', onPointerDown, true);\n document.addEventListener('touchstart', onPointerDown, true);\n document.addEventListener('visibilitychange', onVisibilityChange, true);\n\n addInitialPointerMoveListeners();\n\n // For focus and blur, we specifically care about state changes in the local\n // scope. This is because focus / blur events that originate from within a\n // shadow root are not re-dispatched from the host element if it was already\n // the active element in its own scope:\n scope.addEventListener('focus', onFocus, true);\n scope.addEventListener('blur', onBlur, true);\n\n // We detect that a node is a ShadowRoot by ensuring that it is a\n // DocumentFragment and also has a host property. This check covers native\n // implementation and polyfill implementation transparently. If we only cared\n // about the native implementation, we could just check if the scope was\n // an instance of a ShadowRoot.\n if (scope.nodeType === Node.DOCUMENT_FRAGMENT_NODE && scope.host) {\n // Since a ShadowRoot is a special kind of DocumentFragment, it does not\n // have a root element to add a class to. So, we add this attribute to the\n // host element instead:\n scope.host.setAttribute('data-js-focus-visible', '');\n } else if (scope.nodeType === Node.DOCUMENT_NODE) {\n document.documentElement.classList.add('js-focus-visible');\n document.documentElement.setAttribute('data-js-focus-visible', '');\n }\n }\n\n // It is important to wrap all references to global window and document in\n // these checks to support server-side rendering use cases\n // @see https://github.com/WICG/focus-visible/issues/199\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n // Make the polyfill helper globally available. This can be used as a signal\n // to interested libraries that wish to coordinate with the polyfill for e.g.,\n // applying the polyfill to a shadow root:\n window.applyFocusVisiblePolyfill = applyFocusVisiblePolyfill;\n\n // Notify interested libraries of the polyfill's presence, in case the\n // polyfill was loaded lazily:\n var event;\n\n try {\n event = new CustomEvent('focus-visible-polyfill-ready');\n } catch (error) {\n // IE11 does not support using CustomEvent as a constructor directly:\n event = document.createEvent('CustomEvent');\n event.initCustomEvent('focus-visible-polyfill-ready', false, false, {});\n }\n\n window.dispatchEvent(event);\n }\n\n if (typeof document !== 'undefined') {\n // Apply the polyfill to the global document, so that no JavaScript\n // coordination is required to use the polyfill in the top-level document:\n applyFocusVisiblePolyfill(document);\n }\n\n})));\n", "/*!\n * clipboard.js v2.0.11\n * https://clipboardjs.com/\n *\n * Licensed MIT \u00A9 Zeno Rocha\n */\n(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"ClipboardJS\"] = factory();\n\telse\n\t\troot[\"ClipboardJS\"] = factory();\n})(this, function() {\nreturn /******/ (function() { // webpackBootstrap\n/******/ \tvar __webpack_modules__ = ({\n\n/***/ 686:\n/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n \"default\": function() { return /* binding */ clipboard; }\n});\n\n// EXTERNAL MODULE: ./node_modules/tiny-emitter/index.js\nvar tiny_emitter = __webpack_require__(279);\nvar tiny_emitter_default = /*#__PURE__*/__webpack_require__.n(tiny_emitter);\n// EXTERNAL MODULE: ./node_modules/good-listener/src/listen.js\nvar listen = __webpack_require__(370);\nvar listen_default = /*#__PURE__*/__webpack_require__.n(listen);\n// EXTERNAL MODULE: ./node_modules/select/src/select.js\nvar src_select = __webpack_require__(817);\nvar select_default = /*#__PURE__*/__webpack_require__.n(src_select);\n;// CONCATENATED MODULE: ./src/common/command.js\n/**\n * Executes a given operation type.\n * @param {String} type\n * @return {Boolean}\n */\nfunction command(type) {\n try {\n return document.execCommand(type);\n } catch (err) {\n return false;\n }\n}\n;// CONCATENATED MODULE: ./src/actions/cut.js\n\n\n/**\n * Cut action wrapper.\n * @param {String|HTMLElement} target\n * @return {String}\n */\n\nvar ClipboardActionCut = function ClipboardActionCut(target) {\n var selectedText = select_default()(target);\n command('cut');\n return selectedText;\n};\n\n/* harmony default export */ var actions_cut = (ClipboardActionCut);\n;// CONCATENATED MODULE: ./src/common/create-fake-element.js\n/**\n * Creates a fake textarea element with a value.\n * @param {String} value\n * @return {HTMLElement}\n */\nfunction createFakeElement(value) {\n var isRTL = document.documentElement.getAttribute('dir') === 'rtl';\n var fakeElement = document.createElement('textarea'); // Prevent zooming on iOS\n\n fakeElement.style.fontSize = '12pt'; // Reset box model\n\n fakeElement.style.border = '0';\n fakeElement.style.padding = '0';\n fakeElement.style.margin = '0'; // Move element out of screen horizontally\n\n fakeElement.style.position = 'absolute';\n fakeElement.style[isRTL ? 'right' : 'left'] = '-9999px'; // Move element to the same position vertically\n\n var yPosition = window.pageYOffset || document.documentElement.scrollTop;\n fakeElement.style.top = \"\".concat(yPosition, \"px\");\n fakeElement.setAttribute('readonly', '');\n fakeElement.value = value;\n return fakeElement;\n}\n;// CONCATENATED MODULE: ./src/actions/copy.js\n\n\n\n/**\n * Create fake copy action wrapper using a fake element.\n * @param {String} target\n * @param {Object} options\n * @return {String}\n */\n\nvar fakeCopyAction = function fakeCopyAction(value, options) {\n var fakeElement = createFakeElement(value);\n options.container.appendChild(fakeElement);\n var selectedText = select_default()(fakeElement);\n command('copy');\n fakeElement.remove();\n return selectedText;\n};\n/**\n * Copy action wrapper.\n * @param {String|HTMLElement} target\n * @param {Object} options\n * @return {String}\n */\n\n\nvar ClipboardActionCopy = function ClipboardActionCopy(target) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n container: document.body\n };\n var selectedText = '';\n\n if (typeof target === 'string') {\n selectedText = fakeCopyAction(target, options);\n } else if (target instanceof HTMLInputElement && !['text', 'search', 'url', 'tel', 'password'].includes(target === null || target === void 0 ? void 0 : target.type)) {\n // If input type doesn't support `setSelectionRange`. Simulate it. https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setSelectionRange\n selectedText = fakeCopyAction(target.value, options);\n } else {\n selectedText = select_default()(target);\n command('copy');\n }\n\n return selectedText;\n};\n\n/* harmony default export */ var actions_copy = (ClipboardActionCopy);\n;// CONCATENATED MODULE: ./src/actions/default.js\nfunction _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\n\n\n/**\n * Inner function which performs selection from either `text` or `target`\n * properties and then executes copy or cut operations.\n * @param {Object} options\n */\n\nvar ClipboardActionDefault = function ClipboardActionDefault() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n // Defines base properties passed from constructor.\n var _options$action = options.action,\n action = _options$action === void 0 ? 'copy' : _options$action,\n container = options.container,\n target = options.target,\n text = options.text; // Sets the `action` to be performed which can be either 'copy' or 'cut'.\n\n if (action !== 'copy' && action !== 'cut') {\n throw new Error('Invalid \"action\" value, use either \"copy\" or \"cut\"');\n } // Sets the `target` property using an element that will be have its content copied.\n\n\n if (target !== undefined) {\n if (target && _typeof(target) === 'object' && target.nodeType === 1) {\n if (action === 'copy' && target.hasAttribute('disabled')) {\n throw new Error('Invalid \"target\" attribute. Please use \"readonly\" instead of \"disabled\" attribute');\n }\n\n if (action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) {\n throw new Error('Invalid \"target\" attribute. You can\\'t cut text from elements with \"readonly\" or \"disabled\" attributes');\n }\n } else {\n throw new Error('Invalid \"target\" value, use a valid Element');\n }\n } // Define selection strategy based on `text` property.\n\n\n if (text) {\n return actions_copy(text, {\n container: container\n });\n } // Defines which selection strategy based on `target` property.\n\n\n if (target) {\n return action === 'cut' ? actions_cut(target) : actions_copy(target, {\n container: container\n });\n }\n};\n\n/* harmony default export */ var actions_default = (ClipboardActionDefault);\n;// CONCATENATED MODULE: ./src/clipboard.js\nfunction clipboard_typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { clipboard_typeof = function _typeof(obj) { return typeof obj; }; } else { clipboard_typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return clipboard_typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (clipboard_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _isNativeReflectConstruct() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n\n\n\n\n\n/**\n * Helper function to retrieve attribute value.\n * @param {String} suffix\n * @param {Element} element\n */\n\nfunction getAttributeValue(suffix, element) {\n var attribute = \"data-clipboard-\".concat(suffix);\n\n if (!element.hasAttribute(attribute)) {\n return;\n }\n\n return element.getAttribute(attribute);\n}\n/**\n * Base class which takes one or more elements, adds event listeners to them,\n * and instantiates a new `ClipboardAction` on each click.\n */\n\n\nvar Clipboard = /*#__PURE__*/function (_Emitter) {\n _inherits(Clipboard, _Emitter);\n\n var _super = _createSuper(Clipboard);\n\n /**\n * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n * @param {Object} options\n */\n function Clipboard(trigger, options) {\n var _this;\n\n _classCallCheck(this, Clipboard);\n\n _this = _super.call(this);\n\n _this.resolveOptions(options);\n\n _this.listenClick(trigger);\n\n return _this;\n }\n /**\n * Defines if attributes would be resolved using internal setter functions\n * or custom functions that were passed in the constructor.\n * @param {Object} options\n */\n\n\n _createClass(Clipboard, [{\n key: \"resolveOptions\",\n value: function resolveOptions() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n this.action = typeof options.action === 'function' ? options.action : this.defaultAction;\n this.target = typeof options.target === 'function' ? options.target : this.defaultTarget;\n this.text = typeof options.text === 'function' ? options.text : this.defaultText;\n this.container = clipboard_typeof(options.container) === 'object' ? options.container : document.body;\n }\n /**\n * Adds a click event listener to the passed trigger.\n * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n */\n\n }, {\n key: \"listenClick\",\n value: function listenClick(trigger) {\n var _this2 = this;\n\n this.listener = listen_default()(trigger, 'click', function (e) {\n return _this2.onClick(e);\n });\n }\n /**\n * Defines a new `ClipboardAction` on each click event.\n * @param {Event} e\n */\n\n }, {\n key: \"onClick\",\n value: function onClick(e) {\n var trigger = e.delegateTarget || e.currentTarget;\n var action = this.action(trigger) || 'copy';\n var text = actions_default({\n action: action,\n container: this.container,\n target: this.target(trigger),\n text: this.text(trigger)\n }); // Fires an event based on the copy operation result.\n\n this.emit(text ? 'success' : 'error', {\n action: action,\n text: text,\n trigger: trigger,\n clearSelection: function clearSelection() {\n if (trigger) {\n trigger.focus();\n }\n\n window.getSelection().removeAllRanges();\n }\n });\n }\n /**\n * Default `action` lookup function.\n * @param {Element} trigger\n */\n\n }, {\n key: \"defaultAction\",\n value: function defaultAction(trigger) {\n return getAttributeValue('action', trigger);\n }\n /**\n * Default `target` lookup function.\n * @param {Element} trigger\n */\n\n }, {\n key: \"defaultTarget\",\n value: function defaultTarget(trigger) {\n var selector = getAttributeValue('target', trigger);\n\n if (selector) {\n return document.querySelector(selector);\n }\n }\n /**\n * Allow fire programmatically a copy action\n * @param {String|HTMLElement} target\n * @param {Object} options\n * @returns Text copied.\n */\n\n }, {\n key: \"defaultText\",\n\n /**\n * Default `text` lookup function.\n * @param {Element} trigger\n */\n value: function defaultText(trigger) {\n return getAttributeValue('text', trigger);\n }\n /**\n * Destroy lifecycle.\n */\n\n }, {\n key: \"destroy\",\n value: function destroy() {\n this.listener.destroy();\n }\n }], [{\n key: \"copy\",\n value: function copy(target) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n container: document.body\n };\n return actions_copy(target, options);\n }\n /**\n * Allow fire programmatically a cut action\n * @param {String|HTMLElement} target\n * @returns Text cutted.\n */\n\n }, {\n key: \"cut\",\n value: function cut(target) {\n return actions_cut(target);\n }\n /**\n * Returns the support of the given action, or all actions if no action is\n * given.\n * @param {String} [action]\n */\n\n }, {\n key: \"isSupported\",\n value: function isSupported() {\n var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['copy', 'cut'];\n var actions = typeof action === 'string' ? [action] : action;\n var support = !!document.queryCommandSupported;\n actions.forEach(function (action) {\n support = support && !!document.queryCommandSupported(action);\n });\n return support;\n }\n }]);\n\n return Clipboard;\n}((tiny_emitter_default()));\n\n/* harmony default export */ var clipboard = (Clipboard);\n\n/***/ }),\n\n/***/ 828:\n/***/ (function(module) {\n\nvar DOCUMENT_NODE_TYPE = 9;\n\n/**\n * A polyfill for Element.matches()\n */\nif (typeof Element !== 'undefined' && !Element.prototype.matches) {\n var proto = Element.prototype;\n\n proto.matches = proto.matchesSelector ||\n proto.mozMatchesSelector ||\n proto.msMatchesSelector ||\n proto.oMatchesSelector ||\n proto.webkitMatchesSelector;\n}\n\n/**\n * Finds the closest parent that matches a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @return {Function}\n */\nfunction closest (element, selector) {\n while (element && element.nodeType !== DOCUMENT_NODE_TYPE) {\n if (typeof element.matches === 'function' &&\n element.matches(selector)) {\n return element;\n }\n element = element.parentNode;\n }\n}\n\nmodule.exports = closest;\n\n\n/***/ }),\n\n/***/ 438:\n/***/ (function(module, __unused_webpack_exports, __webpack_require__) {\n\nvar closest = __webpack_require__(828);\n\n/**\n * Delegates event to a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\nfunction _delegate(element, selector, type, callback, useCapture) {\n var listenerFn = listener.apply(this, arguments);\n\n element.addEventListener(type, listenerFn, useCapture);\n\n return {\n destroy: function() {\n element.removeEventListener(type, listenerFn, useCapture);\n }\n }\n}\n\n/**\n * Delegates event to a selector.\n *\n * @param {Element|String|Array} [elements]\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\nfunction delegate(elements, selector, type, callback, useCapture) {\n // Handle the regular Element usage\n if (typeof elements.addEventListener === 'function') {\n return _delegate.apply(null, arguments);\n }\n\n // Handle Element-less usage, it defaults to global delegation\n if (typeof type === 'function') {\n // Use `document` as the first parameter, then apply arguments\n // This is a short way to .unshift `arguments` without running into deoptimizations\n return _delegate.bind(null, document).apply(null, arguments);\n }\n\n // Handle Selector-based usage\n if (typeof elements === 'string') {\n elements = document.querySelectorAll(elements);\n }\n\n // Handle Array-like based usage\n return Array.prototype.map.call(elements, function (element) {\n return _delegate(element, selector, type, callback, useCapture);\n });\n}\n\n/**\n * Finds closest match and invokes callback.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Function}\n */\nfunction listener(element, selector, type, callback) {\n return function(e) {\n e.delegateTarget = closest(e.target, selector);\n\n if (e.delegateTarget) {\n callback.call(element, e);\n }\n }\n}\n\nmodule.exports = delegate;\n\n\n/***/ }),\n\n/***/ 879:\n/***/ (function(__unused_webpack_module, exports) {\n\n/**\n * Check if argument is a HTML element.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.node = function(value) {\n return value !== undefined\n && value instanceof HTMLElement\n && value.nodeType === 1;\n};\n\n/**\n * Check if argument is a list of HTML elements.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.nodeList = function(value) {\n var type = Object.prototype.toString.call(value);\n\n return value !== undefined\n && (type === '[object NodeList]' || type === '[object HTMLCollection]')\n && ('length' in value)\n && (value.length === 0 || exports.node(value[0]));\n};\n\n/**\n * Check if argument is a string.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.string = function(value) {\n return typeof value === 'string'\n || value instanceof String;\n};\n\n/**\n * Check if argument is a function.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.fn = function(value) {\n var type = Object.prototype.toString.call(value);\n\n return type === '[object Function]';\n};\n\n\n/***/ }),\n\n/***/ 370:\n/***/ (function(module, __unused_webpack_exports, __webpack_require__) {\n\nvar is = __webpack_require__(879);\nvar delegate = __webpack_require__(438);\n\n/**\n * Validates all params and calls the right\n * listener function based on its target type.\n *\n * @param {String|HTMLElement|HTMLCollection|NodeList} target\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listen(target, type, callback) {\n if (!target && !type && !callback) {\n throw new Error('Missing required arguments');\n }\n\n if (!is.string(type)) {\n throw new TypeError('Second argument must be a String');\n }\n\n if (!is.fn(callback)) {\n throw new TypeError('Third argument must be a Function');\n }\n\n if (is.node(target)) {\n return listenNode(target, type, callback);\n }\n else if (is.nodeList(target)) {\n return listenNodeList(target, type, callback);\n }\n else if (is.string(target)) {\n return listenSelector(target, type, callback);\n }\n else {\n throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList');\n }\n}\n\n/**\n * Adds an event listener to a HTML element\n * and returns a remove listener function.\n *\n * @param {HTMLElement} node\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenNode(node, type, callback) {\n node.addEventListener(type, callback);\n\n return {\n destroy: function() {\n node.removeEventListener(type, callback);\n }\n }\n}\n\n/**\n * Add an event listener to a list of HTML elements\n * and returns a remove listener function.\n *\n * @param {NodeList|HTMLCollection} nodeList\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenNodeList(nodeList, type, callback) {\n Array.prototype.forEach.call(nodeList, function(node) {\n node.addEventListener(type, callback);\n });\n\n return {\n destroy: function() {\n Array.prototype.forEach.call(nodeList, function(node) {\n node.removeEventListener(type, callback);\n });\n }\n }\n}\n\n/**\n * Add an event listener to a selector\n * and returns a remove listener function.\n *\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenSelector(selector, type, callback) {\n return delegate(document.body, selector, type, callback);\n}\n\nmodule.exports = listen;\n\n\n/***/ }),\n\n/***/ 817:\n/***/ (function(module) {\n\nfunction select(element) {\n var selectedText;\n\n if (element.nodeName === 'SELECT') {\n element.focus();\n\n selectedText = element.value;\n }\n else if (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') {\n var isReadOnly = element.hasAttribute('readonly');\n\n if (!isReadOnly) {\n element.setAttribute('readonly', '');\n }\n\n element.select();\n element.setSelectionRange(0, element.value.length);\n\n if (!isReadOnly) {\n element.removeAttribute('readonly');\n }\n\n selectedText = element.value;\n }\n else {\n if (element.hasAttribute('contenteditable')) {\n element.focus();\n }\n\n var selection = window.getSelection();\n var range = document.createRange();\n\n range.selectNodeContents(element);\n selection.removeAllRanges();\n selection.addRange(range);\n\n selectedText = selection.toString();\n }\n\n return selectedText;\n}\n\nmodule.exports = select;\n\n\n/***/ }),\n\n/***/ 279:\n/***/ (function(module) {\n\nfunction E () {\n // Keep this empty so it's easier to inherit from\n // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)\n}\n\nE.prototype = {\n on: function (name, callback, ctx) {\n var e = this.e || (this.e = {});\n\n (e[name] || (e[name] = [])).push({\n fn: callback,\n ctx: ctx\n });\n\n return this;\n },\n\n once: function (name, callback, ctx) {\n var self = this;\n function listener () {\n self.off(name, listener);\n callback.apply(ctx, arguments);\n };\n\n listener._ = callback\n return this.on(name, listener, ctx);\n },\n\n emit: function (name) {\n var data = [].slice.call(arguments, 1);\n var evtArr = ((this.e || (this.e = {}))[name] || []).slice();\n var i = 0;\n var len = evtArr.length;\n\n for (i; i < len; i++) {\n evtArr[i].fn.apply(evtArr[i].ctx, data);\n }\n\n return this;\n },\n\n off: function (name, callback) {\n var e = this.e || (this.e = {});\n var evts = e[name];\n var liveEvents = [];\n\n if (evts && callback) {\n for (var i = 0, len = evts.length; i < len; i++) {\n if (evts[i].fn !== callback && evts[i].fn._ !== callback)\n liveEvents.push(evts[i]);\n }\n }\n\n // Remove event from queue to prevent memory leak\n // Suggested by https://github.com/lazd\n // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910\n\n (liveEvents.length)\n ? e[name] = liveEvents\n : delete e[name];\n\n return this;\n }\n};\n\nmodule.exports = E;\nmodule.exports.TinyEmitter = E;\n\n\n/***/ })\n\n/******/ \t});\n/************************************************************************/\n/******/ \t// The module cache\n/******/ \tvar __webpack_module_cache__ = {};\n/******/ \t\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(__webpack_module_cache__[moduleId]) {\n/******/ \t\t\treturn __webpack_module_cache__[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = __webpack_module_cache__[moduleId] = {\n/******/ \t\t\t// no module.id needed\n/******/ \t\t\t// no module.loaded needed\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/ \t\n/******/ \t\t// Execute the module function\n/******/ \t\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n/******/ \t\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/ \t\n/************************************************************************/\n/******/ \t/* webpack/runtime/compat get default export */\n/******/ \t!function() {\n/******/ \t\t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t\t__webpack_require__.n = function(module) {\n/******/ \t\t\tvar getter = module && module.__esModule ?\n/******/ \t\t\t\tfunction() { return module['default']; } :\n/******/ \t\t\t\tfunction() { return module; };\n/******/ \t\t\t__webpack_require__.d(getter, { a: getter });\n/******/ \t\t\treturn getter;\n/******/ \t\t};\n/******/ \t}();\n/******/ \t\n/******/ \t/* webpack/runtime/define property getters */\n/******/ \t!function() {\n/******/ \t\t// define getter functions for harmony exports\n/******/ \t\t__webpack_require__.d = function(exports, definition) {\n/******/ \t\t\tfor(var key in definition) {\n/******/ \t\t\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n/******/ \t\t\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n/******/ \t\t\t\t}\n/******/ \t\t\t}\n/******/ \t\t};\n/******/ \t}();\n/******/ \t\n/******/ \t/* webpack/runtime/hasOwnProperty shorthand */\n/******/ \t!function() {\n/******/ \t\t__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }\n/******/ \t}();\n/******/ \t\n/************************************************************************/\n/******/ \t// module exports must be returned from runtime so entry inlining is disabled\n/******/ \t// startup\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(686);\n/******/ })()\n.default;\n});", "/*!\n * escape-html\n * Copyright(c) 2012-2013 TJ Holowaychuk\n * Copyright(c) 2015 Andreas Lubbe\n * Copyright(c) 2015 Tiancheng \"Timothy\" Gu\n * MIT Licensed\n */\n\n'use strict';\n\n/**\n * Module variables.\n * @private\n */\n\nvar matchHtmlRegExp = /[\"'&<>]/;\n\n/**\n * Module exports.\n * @public\n */\n\nmodule.exports = escapeHtml;\n\n/**\n * Escape special characters in the given string of html.\n *\n * @param {string} string The string to escape for inserting into HTML\n * @return {string}\n * @public\n */\n\nfunction escapeHtml(string) {\n var str = '' + string;\n var match = matchHtmlRegExp.exec(str);\n\n if (!match) {\n return str;\n }\n\n var escape;\n var html = '';\n var index = 0;\n var lastIndex = 0;\n\n for (index = match.index; index < str.length; index++) {\n switch (str.charCodeAt(index)) {\n case 34: // \"\n escape = '"';\n break;\n case 38: // &\n escape = '&';\n break;\n case 39: // '\n escape = ''';\n break;\n case 60: // <\n escape = '<';\n break;\n case 62: // >\n escape = '>';\n break;\n default:\n continue;\n }\n\n if (lastIndex !== index) {\n html += str.substring(lastIndex, index);\n }\n\n lastIndex = index + 1;\n html += escape;\n }\n\n return lastIndex !== index\n ? html + str.substring(lastIndex, index)\n : html;\n}\n", "/*\n * Copyright (c) 2016-2024 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport \"focus-visible\"\n\nimport {\n EMPTY,\n NEVER,\n Observable,\n Subject,\n defer,\n delay,\n filter,\n map,\n merge,\n mergeWith,\n shareReplay,\n switchMap\n} from \"rxjs\"\n\nimport { configuration, feature } from \"./_\"\nimport {\n at,\n getActiveElement,\n getOptionalElement,\n requestJSON,\n setLocation,\n setToggle,\n watchDocument,\n watchKeyboard,\n watchLocation,\n watchLocationTarget,\n watchMedia,\n watchPrint,\n watchScript,\n watchViewport\n} from \"./browser\"\nimport {\n getComponentElement,\n getComponentElements,\n mountAnnounce,\n mountBackToTop,\n mountConsent,\n mountContent,\n mountDialog,\n mountHeader,\n mountHeaderTitle,\n mountPalette,\n mountProgress,\n mountSearch,\n mountSearchHiglight,\n mountSidebar,\n mountSource,\n mountTableOfContents,\n mountTabs,\n watchHeader,\n watchMain\n} from \"./components\"\nimport {\n SearchIndex,\n setupClipboardJS,\n setupInstantNavigation,\n setupVersionSelector\n} from \"./integrations\"\nimport {\n patchEllipsis,\n patchIndeterminate,\n patchScrollfix,\n patchScrolllock\n} from \"./patches\"\nimport \"./polyfills\"\n\n/* ----------------------------------------------------------------------------\n * Functions - @todo refactor\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch search index\n *\n * @returns Search index observable\n */\nfunction fetchSearchIndex(): Observable {\n if (location.protocol === \"file:\") {\n return watchScript(\n `${new URL(\"search/search_index.js\", config.base)}`\n )\n .pipe(\n // @ts-ignore - @todo fix typings\n map(() => __index),\n shareReplay(1)\n )\n } else {\n return requestJSON(\n new URL(\"search/search_index.json\", config.base)\n )\n }\n}\n\n/* ----------------------------------------------------------------------------\n * Application\n * ------------------------------------------------------------------------- */\n\n/* Yay, JavaScript is available */\ndocument.documentElement.classList.remove(\"no-js\")\ndocument.documentElement.classList.add(\"js\")\n\n/* Set up navigation observables and subjects */\nconst document$ = watchDocument()\nconst location$ = watchLocation()\nconst target$ = watchLocationTarget(location$)\nconst keyboard$ = watchKeyboard()\n\n/* Set up media observables */\nconst viewport$ = watchViewport()\nconst tablet$ = watchMedia(\"(min-width: 960px)\")\nconst screen$ = watchMedia(\"(min-width: 1220px)\")\nconst print$ = watchPrint()\n\n/* Retrieve search index, if search is enabled */\nconst config = configuration()\nconst index$ = document.forms.namedItem(\"search\")\n ? fetchSearchIndex()\n : NEVER\n\n/* Set up Clipboard.js integration */\nconst alert$ = new Subject()\nsetupClipboardJS({ alert$ })\n\n/* Set up progress indicator */\nconst progress$ = new Subject()\n\n/* Set up instant navigation, if enabled */\nif (feature(\"navigation.instant\"))\n setupInstantNavigation({ location$, viewport$, progress$ })\n .subscribe(document$)\n\n/* Set up version selector */\nif (config.version?.provider === \"mike\")\n setupVersionSelector({ document$ })\n\n/* Always close drawer and search on navigation */\nmerge(location$, target$)\n .pipe(\n delay(125)\n )\n .subscribe(() => {\n setToggle(\"drawer\", false)\n setToggle(\"search\", false)\n })\n\n/* Set up global keyboard handlers */\nkeyboard$\n .pipe(\n filter(({ mode }) => mode === \"global\")\n )\n .subscribe(key => {\n switch (key.type) {\n\n /* Go to previous page */\n case \"p\":\n case \",\":\n const prev = getOptionalElement(\"link[rel=prev]\")\n if (typeof prev !== \"undefined\")\n setLocation(prev)\n break\n\n /* Go to next page */\n case \"n\":\n case \".\":\n const next = getOptionalElement(\"link[rel=next]\")\n if (typeof next !== \"undefined\")\n setLocation(next)\n break\n\n /* Expand navigation, see https://bit.ly/3ZjG5io */\n case \"Enter\":\n const active = getActiveElement()\n if (active instanceof HTMLLabelElement)\n active.click()\n }\n })\n\n/* Set up patches */\npatchEllipsis({ viewport$, document$ })\npatchIndeterminate({ document$, tablet$ })\npatchScrollfix({ document$ })\npatchScrolllock({ viewport$, tablet$ })\n\n/* Set up header and main area observable */\nconst header$ = watchHeader(getComponentElement(\"header\"), { viewport$ })\nconst main$ = document$\n .pipe(\n map(() => getComponentElement(\"main\")),\n switchMap(el => watchMain(el, { viewport$, header$ })),\n shareReplay(1)\n )\n\n/* Set up control component observables */\nconst control$ = merge(\n\n /* Consent */\n ...getComponentElements(\"consent\")\n .map(el => mountConsent(el, { target$ })),\n\n /* Dialog */\n ...getComponentElements(\"dialog\")\n .map(el => mountDialog(el, { alert$ })),\n\n /* Header */\n ...getComponentElements(\"header\")\n .map(el => mountHeader(el, { viewport$, header$, main$ })),\n\n /* Color palette */\n ...getComponentElements(\"palette\")\n .map(el => mountPalette(el)),\n\n /* Progress bar */\n ...getComponentElements(\"progress\")\n .map(el => mountProgress(el, { progress$ })),\n\n /* Search */\n ...getComponentElements(\"search\")\n .map(el => mountSearch(el, { index$, keyboard$ })),\n\n /* Repository information */\n ...getComponentElements(\"source\")\n .map(el => mountSource(el))\n)\n\n/* Set up content component observables */\nconst content$ = defer(() => merge(\n\n /* Announcement bar */\n ...getComponentElements(\"announce\")\n .map(el => mountAnnounce(el)),\n\n /* Content */\n ...getComponentElements(\"content\")\n .map(el => mountContent(el, { viewport$, target$, print$ })),\n\n /* Search highlighting */\n ...getComponentElements(\"content\")\n .map(el => feature(\"search.highlight\")\n ? mountSearchHiglight(el, { index$, location$ })\n : EMPTY\n ),\n\n /* Header title */\n ...getComponentElements(\"header-title\")\n .map(el => mountHeaderTitle(el, { viewport$, header$ })),\n\n /* Sidebar */\n ...getComponentElements(\"sidebar\")\n .map(el => el.getAttribute(\"data-md-type\") === \"navigation\"\n ? at(screen$, () => mountSidebar(el, { viewport$, header$, main$ }))\n : at(tablet$, () => mountSidebar(el, { viewport$, header$, main$ }))\n ),\n\n /* Navigation tabs */\n ...getComponentElements(\"tabs\")\n .map(el => mountTabs(el, { viewport$, header$ })),\n\n /* Table of contents */\n ...getComponentElements(\"toc\")\n .map(el => mountTableOfContents(el, {\n viewport$, header$, main$, target$\n })),\n\n /* Back-to-top button */\n ...getComponentElements(\"top\")\n .map(el => mountBackToTop(el, { viewport$, header$, main$, target$ }))\n))\n\n/* Set up component observables */\nconst component$ = document$\n .pipe(\n switchMap(() => content$),\n mergeWith(control$),\n shareReplay(1)\n )\n\n/* Subscribe to all components */\ncomponent$.subscribe()\n\n/* ----------------------------------------------------------------------------\n * Exports\n * ------------------------------------------------------------------------- */\n\nwindow.document$ = document$ /* Document observable */\nwindow.location$ = location$ /* Location subject */\nwindow.target$ = target$ /* Location target observable */\nwindow.keyboard$ = keyboard$ /* Keyboard observable */\nwindow.viewport$ = viewport$ /* Viewport observable */\nwindow.tablet$ = tablet$ /* Media tablet observable */\nwindow.screen$ = screen$ /* Media screen observable */\nwindow.print$ = print$ /* Media print observable */\nwindow.alert$ = alert$ /* Alert subject */\nwindow.progress$ = progress$ /* Progress indicator subject */\nwindow.component$ = component$ /* Component observable */\n", "/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nexport function __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n", "/**\n * Returns true if the object is a function.\n * @param value The value to check\n */\nexport function isFunction(value: any): value is (...args: any[]) => any {\n return typeof value === 'function';\n}\n", "/**\n * Used to create Error subclasses until the community moves away from ES5.\n *\n * This is because compiling from TypeScript down to ES5 has issues with subclassing Errors\n * as well as other built-in types: https://github.com/Microsoft/TypeScript/issues/12123\n *\n * @param createImpl A factory function to create the actual constructor implementation. The returned\n * function should be a named function that calls `_super` internally.\n */\nexport function createErrorClass(createImpl: (_super: any) => any): T {\n const _super = (instance: any) => {\n Error.call(instance);\n instance.stack = new Error().stack;\n };\n\n const ctorFunc = createImpl(_super);\n ctorFunc.prototype = Object.create(Error.prototype);\n ctorFunc.prototype.constructor = ctorFunc;\n return ctorFunc;\n}\n", "import { createErrorClass } from './createErrorClass';\n\nexport interface UnsubscriptionError extends Error {\n readonly errors: any[];\n}\n\nexport interface UnsubscriptionErrorCtor {\n /**\n * @deprecated Internal implementation detail. Do not construct error instances.\n * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269\n */\n new (errors: any[]): UnsubscriptionError;\n}\n\n/**\n * An error thrown when one or more errors have occurred during the\n * `unsubscribe` of a {@link Subscription}.\n */\nexport const UnsubscriptionError: UnsubscriptionErrorCtor = createErrorClass(\n (_super) =>\n function UnsubscriptionErrorImpl(this: any, errors: (Error | string)[]) {\n _super(this);\n this.message = errors\n ? `${errors.length} errors occurred during unsubscription:\n${errors.map((err, i) => `${i + 1}) ${err.toString()}`).join('\\n ')}`\n : '';\n this.name = 'UnsubscriptionError';\n this.errors = errors;\n }\n);\n", "/**\n * Removes an item from an array, mutating it.\n * @param arr The array to remove the item from\n * @param item The item to remove\n */\nexport function arrRemove(arr: T[] | undefined | null, item: T) {\n if (arr) {\n const index = arr.indexOf(item);\n 0 <= index && arr.splice(index, 1);\n }\n}\n", "import { isFunction } from './util/isFunction';\nimport { UnsubscriptionError } from './util/UnsubscriptionError';\nimport { SubscriptionLike, TeardownLogic, Unsubscribable } from './types';\nimport { arrRemove } from './util/arrRemove';\n\n/**\n * Represents a disposable resource, such as the execution of an Observable. A\n * Subscription has one important method, `unsubscribe`, that takes no argument\n * and just disposes the resource held by the subscription.\n *\n * Additionally, subscriptions may be grouped together through the `add()`\n * method, which will attach a child Subscription to the current Subscription.\n * When a Subscription is unsubscribed, all its children (and its grandchildren)\n * will be unsubscribed as well.\n *\n * @class Subscription\n */\nexport class Subscription implements SubscriptionLike {\n /** @nocollapse */\n public static EMPTY = (() => {\n const empty = new Subscription();\n empty.closed = true;\n return empty;\n })();\n\n /**\n * A flag to indicate whether this Subscription has already been unsubscribed.\n */\n public closed = false;\n\n private _parentage: Subscription[] | Subscription | null = null;\n\n /**\n * The list of registered finalizers to execute upon unsubscription. Adding and removing from this\n * list occurs in the {@link #add} and {@link #remove} methods.\n */\n private _finalizers: Exclude[] | null = null;\n\n /**\n * @param initialTeardown A function executed first as part of the finalization\n * process that is kicked off when {@link #unsubscribe} is called.\n */\n constructor(private initialTeardown?: () => void) {}\n\n /**\n * Disposes the resources held by the subscription. May, for instance, cancel\n * an ongoing Observable execution or cancel any other type of work that\n * started when the Subscription was created.\n * @return {void}\n */\n unsubscribe(): void {\n let errors: any[] | undefined;\n\n if (!this.closed) {\n this.closed = true;\n\n // Remove this from it's parents.\n const { _parentage } = this;\n if (_parentage) {\n this._parentage = null;\n if (Array.isArray(_parentage)) {\n for (const parent of _parentage) {\n parent.remove(this);\n }\n } else {\n _parentage.remove(this);\n }\n }\n\n const { initialTeardown: initialFinalizer } = this;\n if (isFunction(initialFinalizer)) {\n try {\n initialFinalizer();\n } catch (e) {\n errors = e instanceof UnsubscriptionError ? e.errors : [e];\n }\n }\n\n const { _finalizers } = this;\n if (_finalizers) {\n this._finalizers = null;\n for (const finalizer of _finalizers) {\n try {\n execFinalizer(finalizer);\n } catch (err) {\n errors = errors ?? [];\n if (err instanceof UnsubscriptionError) {\n errors = [...errors, ...err.errors];\n } else {\n errors.push(err);\n }\n }\n }\n }\n\n if (errors) {\n throw new UnsubscriptionError(errors);\n }\n }\n }\n\n /**\n * Adds a finalizer to this subscription, so that finalization will be unsubscribed/called\n * when this subscription is unsubscribed. If this subscription is already {@link #closed},\n * because it has already been unsubscribed, then whatever finalizer is passed to it\n * will automatically be executed (unless the finalizer itself is also a closed subscription).\n *\n * Closed Subscriptions cannot be added as finalizers to any subscription. Adding a closed\n * subscription to a any subscription will result in no operation. (A noop).\n *\n * Adding a subscription to itself, or adding `null` or `undefined` will not perform any\n * operation at all. (A noop).\n *\n * `Subscription` instances that are added to this instance will automatically remove themselves\n * if they are unsubscribed. Functions and {@link Unsubscribable} objects that you wish to remove\n * will need to be removed manually with {@link #remove}\n *\n * @param teardown The finalization logic to add to this subscription.\n */\n add(teardown: TeardownLogic): void {\n // Only add the finalizer if it's not undefined\n // and don't add a subscription to itself.\n if (teardown && teardown !== this) {\n if (this.closed) {\n // If this subscription is already closed,\n // execute whatever finalizer is handed to it automatically.\n execFinalizer(teardown);\n } else {\n if (teardown instanceof Subscription) {\n // We don't add closed subscriptions, and we don't add the same subscription\n // twice. Subscription unsubscribe is idempotent.\n if (teardown.closed || teardown._hasParent(this)) {\n return;\n }\n teardown._addParent(this);\n }\n (this._finalizers = this._finalizers ?? []).push(teardown);\n }\n }\n }\n\n /**\n * Checks to see if a this subscription already has a particular parent.\n * This will signal that this subscription has already been added to the parent in question.\n * @param parent the parent to check for\n */\n private _hasParent(parent: Subscription) {\n const { _parentage } = this;\n return _parentage === parent || (Array.isArray(_parentage) && _parentage.includes(parent));\n }\n\n /**\n * Adds a parent to this subscription so it can be removed from the parent if it\n * unsubscribes on it's own.\n *\n * NOTE: THIS ASSUMES THAT {@link _hasParent} HAS ALREADY BEEN CHECKED.\n * @param parent The parent subscription to add\n */\n private _addParent(parent: Subscription) {\n const { _parentage } = this;\n this._parentage = Array.isArray(_parentage) ? (_parentage.push(parent), _parentage) : _parentage ? [_parentage, parent] : parent;\n }\n\n /**\n * Called on a child when it is removed via {@link #remove}.\n * @param parent The parent to remove\n */\n private _removeParent(parent: Subscription) {\n const { _parentage } = this;\n if (_parentage === parent) {\n this._parentage = null;\n } else if (Array.isArray(_parentage)) {\n arrRemove(_parentage, parent);\n }\n }\n\n /**\n * Removes a finalizer from this subscription that was previously added with the {@link #add} method.\n *\n * Note that `Subscription` instances, when unsubscribed, will automatically remove themselves\n * from every other `Subscription` they have been added to. This means that using the `remove` method\n * is not a common thing and should be used thoughtfully.\n *\n * If you add the same finalizer instance of a function or an unsubscribable object to a `Subscription` instance\n * more than once, you will need to call `remove` the same number of times to remove all instances.\n *\n * All finalizer instances are removed to free up memory upon unsubscription.\n *\n * @param teardown The finalizer to remove from this subscription\n */\n remove(teardown: Exclude): void {\n const { _finalizers } = this;\n _finalizers && arrRemove(_finalizers, teardown);\n\n if (teardown instanceof Subscription) {\n teardown._removeParent(this);\n }\n }\n}\n\nexport const EMPTY_SUBSCRIPTION = Subscription.EMPTY;\n\nexport function isSubscription(value: any): value is Subscription {\n return (\n value instanceof Subscription ||\n (value && 'closed' in value && isFunction(value.remove) && isFunction(value.add) && isFunction(value.unsubscribe))\n );\n}\n\nfunction execFinalizer(finalizer: Unsubscribable | (() => void)) {\n if (isFunction(finalizer)) {\n finalizer();\n } else {\n finalizer.unsubscribe();\n }\n}\n", "import { Subscriber } from './Subscriber';\nimport { ObservableNotification } from './types';\n\n/**\n * The {@link GlobalConfig} object for RxJS. It is used to configure things\n * like how to react on unhandled errors.\n */\nexport const config: GlobalConfig = {\n onUnhandledError: null,\n onStoppedNotification: null,\n Promise: undefined,\n useDeprecatedSynchronousErrorHandling: false,\n useDeprecatedNextContext: false,\n};\n\n/**\n * The global configuration object for RxJS, used to configure things\n * like how to react on unhandled errors. Accessible via {@link config}\n * object.\n */\nexport interface GlobalConfig {\n /**\n * A registration point for unhandled errors from RxJS. These are errors that\n * cannot were not handled by consuming code in the usual subscription path. For\n * example, if you have this configured, and you subscribe to an observable without\n * providing an error handler, errors from that subscription will end up here. This\n * will _always_ be called asynchronously on another job in the runtime. This is because\n * we do not want errors thrown in this user-configured handler to interfere with the\n * behavior of the library.\n */\n onUnhandledError: ((err: any) => void) | null;\n\n /**\n * A registration point for notifications that cannot be sent to subscribers because they\n * have completed, errored or have been explicitly unsubscribed. By default, next, complete\n * and error notifications sent to stopped subscribers are noops. However, sometimes callers\n * might want a different behavior. For example, with sources that attempt to report errors\n * to stopped subscribers, a caller can configure RxJS to throw an unhandled error instead.\n * This will _always_ be called asynchronously on another job in the runtime. This is because\n * we do not want errors thrown in this user-configured handler to interfere with the\n * behavior of the library.\n */\n onStoppedNotification: ((notification: ObservableNotification, subscriber: Subscriber) => void) | null;\n\n /**\n * The promise constructor used by default for {@link Observable#toPromise toPromise} and {@link Observable#forEach forEach}\n * methods.\n *\n * @deprecated As of version 8, RxJS will no longer support this sort of injection of a\n * Promise constructor. If you need a Promise implementation other than native promises,\n * please polyfill/patch Promise as you see appropriate. Will be removed in v8.\n */\n Promise?: PromiseConstructorLike;\n\n /**\n * If true, turns on synchronous error rethrowing, which is a deprecated behavior\n * in v6 and higher. This behavior enables bad patterns like wrapping a subscribe\n * call in a try/catch block. It also enables producer interference, a nasty bug\n * where a multicast can be broken for all observers by a downstream consumer with\n * an unhandled error. DO NOT USE THIS FLAG UNLESS IT'S NEEDED TO BUY TIME\n * FOR MIGRATION REASONS.\n *\n * @deprecated As of version 8, RxJS will no longer support synchronous throwing\n * of unhandled errors. All errors will be thrown on a separate call stack to prevent bad\n * behaviors described above. Will be removed in v8.\n */\n useDeprecatedSynchronousErrorHandling: boolean;\n\n /**\n * If true, enables an as-of-yet undocumented feature from v5: The ability to access\n * `unsubscribe()` via `this` context in `next` functions created in observers passed\n * to `subscribe`.\n *\n * This is being removed because the performance was severely problematic, and it could also cause\n * issues when types other than POJOs are passed to subscribe as subscribers, as they will likely have\n * their `this` context overwritten.\n *\n * @deprecated As of version 8, RxJS will no longer support altering the\n * context of next functions provided as part of an observer to Subscribe. Instead,\n * you will have access to a subscription or a signal or token that will allow you to do things like\n * unsubscribe and test closed status. Will be removed in v8.\n */\n useDeprecatedNextContext: boolean;\n}\n", "import type { TimerHandle } from './timerHandle';\ntype SetTimeoutFunction = (handler: () => void, timeout?: number, ...args: any[]) => TimerHandle;\ntype ClearTimeoutFunction = (handle: TimerHandle) => void;\n\ninterface TimeoutProvider {\n setTimeout: SetTimeoutFunction;\n clearTimeout: ClearTimeoutFunction;\n delegate:\n | {\n setTimeout: SetTimeoutFunction;\n clearTimeout: ClearTimeoutFunction;\n }\n | undefined;\n}\n\nexport const timeoutProvider: TimeoutProvider = {\n // When accessing the delegate, use the variable rather than `this` so that\n // the functions can be called without being bound to the provider.\n setTimeout(handler: () => void, timeout?: number, ...args) {\n const { delegate } = timeoutProvider;\n if (delegate?.setTimeout) {\n return delegate.setTimeout(handler, timeout, ...args);\n }\n return setTimeout(handler, timeout, ...args);\n },\n clearTimeout(handle) {\n const { delegate } = timeoutProvider;\n return (delegate?.clearTimeout || clearTimeout)(handle as any);\n },\n delegate: undefined,\n};\n", "import { config } from '../config';\nimport { timeoutProvider } from '../scheduler/timeoutProvider';\n\n/**\n * Handles an error on another job either with the user-configured {@link onUnhandledError},\n * or by throwing it on that new job so it can be picked up by `window.onerror`, `process.on('error')`, etc.\n *\n * This should be called whenever there is an error that is out-of-band with the subscription\n * or when an error hits a terminal boundary of the subscription and no error handler was provided.\n *\n * @param err the error to report\n */\nexport function reportUnhandledError(err: any) {\n timeoutProvider.setTimeout(() => {\n const { onUnhandledError } = config;\n if (onUnhandledError) {\n // Execute the user-configured error handler.\n onUnhandledError(err);\n } else {\n // Throw so it is picked up by the runtime's uncaught error mechanism.\n throw err;\n }\n });\n}\n", "/* tslint:disable:no-empty */\nexport function noop() { }\n", "import { CompleteNotification, NextNotification, ErrorNotification } from './types';\n\n/**\n * A completion object optimized for memory use and created to be the\n * same \"shape\" as other notifications in v8.\n * @internal\n */\nexport const COMPLETE_NOTIFICATION = (() => createNotification('C', undefined, undefined) as CompleteNotification)();\n\n/**\n * Internal use only. Creates an optimized error notification that is the same \"shape\"\n * as other notifications.\n * @internal\n */\nexport function errorNotification(error: any): ErrorNotification {\n return createNotification('E', undefined, error) as any;\n}\n\n/**\n * Internal use only. Creates an optimized next notification that is the same \"shape\"\n * as other notifications.\n * @internal\n */\nexport function nextNotification(value: T) {\n return createNotification('N', value, undefined) as NextNotification;\n}\n\n/**\n * Ensures that all notifications created internally have the same \"shape\" in v8.\n *\n * TODO: This is only exported to support a crazy legacy test in `groupBy`.\n * @internal\n */\nexport function createNotification(kind: 'N' | 'E' | 'C', value: any, error: any) {\n return {\n kind,\n value,\n error,\n };\n}\n", "import { config } from '../config';\n\nlet context: { errorThrown: boolean; error: any } | null = null;\n\n/**\n * Handles dealing with errors for super-gross mode. Creates a context, in which\n * any synchronously thrown errors will be passed to {@link captureError}. Which\n * will record the error such that it will be rethrown after the call back is complete.\n * TODO: Remove in v8\n * @param cb An immediately executed function.\n */\nexport function errorContext(cb: () => void) {\n if (config.useDeprecatedSynchronousErrorHandling) {\n const isRoot = !context;\n if (isRoot) {\n context = { errorThrown: false, error: null };\n }\n cb();\n if (isRoot) {\n const { errorThrown, error } = context!;\n context = null;\n if (errorThrown) {\n throw error;\n }\n }\n } else {\n // This is the general non-deprecated path for everyone that\n // isn't crazy enough to use super-gross mode (useDeprecatedSynchronousErrorHandling)\n cb();\n }\n}\n\n/**\n * Captures errors only in super-gross mode.\n * @param err the error to capture\n */\nexport function captureError(err: any) {\n if (config.useDeprecatedSynchronousErrorHandling && context) {\n context.errorThrown = true;\n context.error = err;\n }\n}\n", "import { isFunction } from './util/isFunction';\nimport { Observer, ObservableNotification } from './types';\nimport { isSubscription, Subscription } from './Subscription';\nimport { config } from './config';\nimport { reportUnhandledError } from './util/reportUnhandledError';\nimport { noop } from './util/noop';\nimport { nextNotification, errorNotification, COMPLETE_NOTIFICATION } from './NotificationFactories';\nimport { timeoutProvider } from './scheduler/timeoutProvider';\nimport { captureError } from './util/errorContext';\n\n/**\n * Implements the {@link Observer} interface and extends the\n * {@link Subscription} class. While the {@link Observer} is the public API for\n * consuming the values of an {@link Observable}, all Observers get converted to\n * a Subscriber, in order to provide Subscription-like capabilities such as\n * `unsubscribe`. Subscriber is a common type in RxJS, and crucial for\n * implementing operators, but it is rarely used as a public API.\n *\n * @class Subscriber\n */\nexport class Subscriber extends Subscription implements Observer {\n /**\n * A static factory for a Subscriber, given a (potentially partial) definition\n * of an Observer.\n * @param next The `next` callback of an Observer.\n * @param error The `error` callback of an\n * Observer.\n * @param complete The `complete` callback of an\n * Observer.\n * @return A Subscriber wrapping the (partially defined)\n * Observer represented by the given arguments.\n * @nocollapse\n * @deprecated Do not use. Will be removed in v8. There is no replacement for this\n * method, and there is no reason to be creating instances of `Subscriber` directly.\n * If you have a specific use case, please file an issue.\n */\n static create(next?: (x?: T) => void, error?: (e?: any) => void, complete?: () => void): Subscriber {\n return new SafeSubscriber(next, error, complete);\n }\n\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n protected isStopped: boolean = false;\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n protected destination: Subscriber | Observer; // this `any` is the escape hatch to erase extra type param (e.g. R)\n\n /**\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n * There is no reason to directly create an instance of Subscriber. This type is exported for typings reasons.\n */\n constructor(destination?: Subscriber | Observer) {\n super();\n if (destination) {\n this.destination = destination;\n // Automatically chain subscriptions together here.\n // if destination is a Subscription, then it is a Subscriber.\n if (isSubscription(destination)) {\n destination.add(this);\n }\n } else {\n this.destination = EMPTY_OBSERVER;\n }\n }\n\n /**\n * The {@link Observer} callback to receive notifications of type `next` from\n * the Observable, with a value. The Observable may call this method 0 or more\n * times.\n * @param {T} [value] The `next` value.\n * @return {void}\n */\n next(value?: T): void {\n if (this.isStopped) {\n handleStoppedNotification(nextNotification(value), this);\n } else {\n this._next(value!);\n }\n }\n\n /**\n * The {@link Observer} callback to receive notifications of type `error` from\n * the Observable, with an attached `Error`. Notifies the Observer that\n * the Observable has experienced an error condition.\n * @param {any} [err] The `error` exception.\n * @return {void}\n */\n error(err?: any): void {\n if (this.isStopped) {\n handleStoppedNotification(errorNotification(err), this);\n } else {\n this.isStopped = true;\n this._error(err);\n }\n }\n\n /**\n * The {@link Observer} callback to receive a valueless notification of type\n * `complete` from the Observable. Notifies the Observer that the Observable\n * has finished sending push-based notifications.\n * @return {void}\n */\n complete(): void {\n if (this.isStopped) {\n handleStoppedNotification(COMPLETE_NOTIFICATION, this);\n } else {\n this.isStopped = true;\n this._complete();\n }\n }\n\n unsubscribe(): void {\n if (!this.closed) {\n this.isStopped = true;\n super.unsubscribe();\n this.destination = null!;\n }\n }\n\n protected _next(value: T): void {\n this.destination.next(value);\n }\n\n protected _error(err: any): void {\n try {\n this.destination.error(err);\n } finally {\n this.unsubscribe();\n }\n }\n\n protected _complete(): void {\n try {\n this.destination.complete();\n } finally {\n this.unsubscribe();\n }\n }\n}\n\n/**\n * This bind is captured here because we want to be able to have\n * compatibility with monoid libraries that tend to use a method named\n * `bind`. In particular, a library called Monio requires this.\n */\nconst _bind = Function.prototype.bind;\n\nfunction bind any>(fn: Fn, thisArg: any): Fn {\n return _bind.call(fn, thisArg);\n}\n\n/**\n * Internal optimization only, DO NOT EXPOSE.\n * @internal\n */\nclass ConsumerObserver implements Observer {\n constructor(private partialObserver: Partial>) {}\n\n next(value: T): void {\n const { partialObserver } = this;\n if (partialObserver.next) {\n try {\n partialObserver.next(value);\n } catch (error) {\n handleUnhandledError(error);\n }\n }\n }\n\n error(err: any): void {\n const { partialObserver } = this;\n if (partialObserver.error) {\n try {\n partialObserver.error(err);\n } catch (error) {\n handleUnhandledError(error);\n }\n } else {\n handleUnhandledError(err);\n }\n }\n\n complete(): void {\n const { partialObserver } = this;\n if (partialObserver.complete) {\n try {\n partialObserver.complete();\n } catch (error) {\n handleUnhandledError(error);\n }\n }\n }\n}\n\nexport class SafeSubscriber extends Subscriber {\n constructor(\n observerOrNext?: Partial> | ((value: T) => void) | null,\n error?: ((e?: any) => void) | null,\n complete?: (() => void) | null\n ) {\n super();\n\n let partialObserver: Partial>;\n if (isFunction(observerOrNext) || !observerOrNext) {\n // The first argument is a function, not an observer. The next\n // two arguments *could* be observers, or they could be empty.\n partialObserver = {\n next: (observerOrNext ?? undefined) as (((value: T) => void) | undefined),\n error: error ?? undefined,\n complete: complete ?? undefined,\n };\n } else {\n // The first argument is a partial observer.\n let context: any;\n if (this && config.useDeprecatedNextContext) {\n // This is a deprecated path that made `this.unsubscribe()` available in\n // next handler functions passed to subscribe. This only exists behind a flag\n // now, as it is *very* slow.\n context = Object.create(observerOrNext);\n context.unsubscribe = () => this.unsubscribe();\n partialObserver = {\n next: observerOrNext.next && bind(observerOrNext.next, context),\n error: observerOrNext.error && bind(observerOrNext.error, context),\n complete: observerOrNext.complete && bind(observerOrNext.complete, context),\n };\n } else {\n // The \"normal\" path. Just use the partial observer directly.\n partialObserver = observerOrNext;\n }\n }\n\n // Wrap the partial observer to ensure it's a full observer, and\n // make sure proper error handling is accounted for.\n this.destination = new ConsumerObserver(partialObserver);\n }\n}\n\nfunction handleUnhandledError(error: any) {\n if (config.useDeprecatedSynchronousErrorHandling) {\n captureError(error);\n } else {\n // Ideal path, we report this as an unhandled error,\n // which is thrown on a new call stack.\n reportUnhandledError(error);\n }\n}\n\n/**\n * An error handler used when no error handler was supplied\n * to the SafeSubscriber -- meaning no error handler was supplied\n * do the `subscribe` call on our observable.\n * @param err The error to handle\n */\nfunction defaultErrorHandler(err: any) {\n throw err;\n}\n\n/**\n * A handler for notifications that cannot be sent to a stopped subscriber.\n * @param notification The notification being sent\n * @param subscriber The stopped subscriber\n */\nfunction handleStoppedNotification(notification: ObservableNotification, subscriber: Subscriber) {\n const { onStoppedNotification } = config;\n onStoppedNotification && timeoutProvider.setTimeout(() => onStoppedNotification(notification, subscriber));\n}\n\n/**\n * The observer used as a stub for subscriptions where the user did not\n * pass any arguments to `subscribe`. Comes with the default error handling\n * behavior.\n */\nexport const EMPTY_OBSERVER: Readonly> & { closed: true } = {\n closed: true,\n next: noop,\n error: defaultErrorHandler,\n complete: noop,\n};\n", "/**\n * Symbol.observable or a string \"@@observable\". Used for interop\n *\n * @deprecated We will no longer be exporting this symbol in upcoming versions of RxJS.\n * Instead polyfill and use Symbol.observable directly *or* use https://www.npmjs.com/package/symbol-observable\n */\nexport const observable: string | symbol = (() => (typeof Symbol === 'function' && Symbol.observable) || '@@observable')();\n", "/**\n * This function takes one parameter and just returns it. Simply put,\n * this is like `(x: T): T => x`.\n *\n * ## Examples\n *\n * This is useful in some cases when using things like `mergeMap`\n *\n * ```ts\n * import { interval, take, map, range, mergeMap, identity } from 'rxjs';\n *\n * const source$ = interval(1000).pipe(take(5));\n *\n * const result$ = source$.pipe(\n * map(i => range(i)),\n * mergeMap(identity) // same as mergeMap(x => x)\n * );\n *\n * result$.subscribe({\n * next: console.log\n * });\n * ```\n *\n * Or when you want to selectively apply an operator\n *\n * ```ts\n * import { interval, take, identity } from 'rxjs';\n *\n * const shouldLimit = () => Math.random() < 0.5;\n *\n * const source$ = interval(1000);\n *\n * const result$ = source$.pipe(shouldLimit() ? take(5) : identity);\n *\n * result$.subscribe({\n * next: console.log\n * });\n * ```\n *\n * @param x Any value that is returned by this function\n * @returns The value passed as the first parameter to this function\n */\nexport function identity(x: T): T {\n return x;\n}\n", "import { identity } from './identity';\nimport { UnaryFunction } from '../types';\n\nexport function pipe(): typeof identity;\nexport function pipe(fn1: UnaryFunction): UnaryFunction;\nexport function pipe(fn1: UnaryFunction, fn2: UnaryFunction): UnaryFunction;\nexport function pipe(fn1: UnaryFunction, fn2: UnaryFunction, fn3: UnaryFunction): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction,\n fn8: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction,\n fn8: UnaryFunction,\n fn9: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction,\n fn8: UnaryFunction,\n fn9: UnaryFunction,\n ...fns: UnaryFunction[]\n): UnaryFunction;\n\n/**\n * pipe() can be called on one or more functions, each of which can take one argument (\"UnaryFunction\")\n * and uses it to return a value.\n * It returns a function that takes one argument, passes it to the first UnaryFunction, and then\n * passes the result to the next one, passes that result to the next one, and so on. \n */\nexport function pipe(...fns: Array>): UnaryFunction {\n return pipeFromArray(fns);\n}\n\n/** @internal */\nexport function pipeFromArray(fns: Array>): UnaryFunction {\n if (fns.length === 0) {\n return identity as UnaryFunction;\n }\n\n if (fns.length === 1) {\n return fns[0];\n }\n\n return function piped(input: T): R {\n return fns.reduce((prev: any, fn: UnaryFunction) => fn(prev), input as any);\n };\n}\n", "import { Operator } from './Operator';\nimport { SafeSubscriber, Subscriber } from './Subscriber';\nimport { isSubscription, Subscription } from './Subscription';\nimport { TeardownLogic, OperatorFunction, Subscribable, Observer } from './types';\nimport { observable as Symbol_observable } from './symbol/observable';\nimport { pipeFromArray } from './util/pipe';\nimport { config } from './config';\nimport { isFunction } from './util/isFunction';\nimport { errorContext } from './util/errorContext';\n\n/**\n * A representation of any set of values over any amount of time. This is the most basic building block\n * of RxJS.\n *\n * @class Observable\n */\nexport class Observable implements Subscribable {\n /**\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n */\n source: Observable | undefined;\n\n /**\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n */\n operator: Operator | undefined;\n\n /**\n * @constructor\n * @param {Function} subscribe the function that is called when the Observable is\n * initially subscribed to. This function is given a Subscriber, to which new values\n * can be `next`ed, or an `error` method can be called to raise an error, or\n * `complete` can be called to notify of a successful completion.\n */\n constructor(subscribe?: (this: Observable, subscriber: Subscriber) => TeardownLogic) {\n if (subscribe) {\n this._subscribe = subscribe;\n }\n }\n\n // HACK: Since TypeScript inherits static properties too, we have to\n // fight against TypeScript here so Subject can have a different static create signature\n /**\n * Creates a new Observable by calling the Observable constructor\n * @owner Observable\n * @method create\n * @param {Function} subscribe? the subscriber function to be passed to the Observable constructor\n * @return {Observable} a new observable\n * @nocollapse\n * @deprecated Use `new Observable()` instead. Will be removed in v8.\n */\n static create: (...args: any[]) => any = (subscribe?: (subscriber: Subscriber) => TeardownLogic) => {\n return new Observable(subscribe);\n };\n\n /**\n * Creates a new Observable, with this Observable instance as the source, and the passed\n * operator defined as the new observable's operator.\n * @method lift\n * @param operator the operator defining the operation to take on the observable\n * @return a new observable with the Operator applied\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n * If you have implemented an operator using `lift`, it is recommended that you create an\n * operator by simply returning `new Observable()` directly. See \"Creating new operators from\n * scratch\" section here: https://rxjs.dev/guide/operators\n */\n lift(operator?: Operator): Observable {\n const observable = new Observable();\n observable.source = this;\n observable.operator = operator;\n return observable;\n }\n\n subscribe(observerOrNext?: Partial> | ((value: T) => void)): Subscription;\n /** @deprecated Instead of passing separate callback arguments, use an observer argument. Signatures taking separate callback arguments will be removed in v8. Details: https://rxjs.dev/deprecations/subscribe-arguments */\n subscribe(next?: ((value: T) => void) | null, error?: ((error: any) => void) | null, complete?: (() => void) | null): Subscription;\n /**\n * Invokes an execution of an Observable and registers Observer handlers for notifications it will emit.\n *\n * Use it when you have all these Observables, but still nothing is happening.\n *\n * `subscribe` is not a regular operator, but a method that calls Observable's internal `subscribe` function. It\n * might be for example a function that you passed to Observable's constructor, but most of the time it is\n * a library implementation, which defines what will be emitted by an Observable, and when it be will emitted. This means\n * that calling `subscribe` is actually the moment when Observable starts its work, not when it is created, as it is often\n * the thought.\n *\n * Apart from starting the execution of an Observable, this method allows you to listen for values\n * that an Observable emits, as well as for when it completes or errors. You can achieve this in two\n * of the following ways.\n *\n * The first way is creating an object that implements {@link Observer} interface. It should have methods\n * defined by that interface, but note that it should be just a regular JavaScript object, which you can create\n * yourself in any way you want (ES6 class, classic function constructor, object literal etc.). In particular, do\n * not attempt to use any RxJS implementation details to create Observers - you don't need them. Remember also\n * that your object does not have to implement all methods. If you find yourself creating a method that doesn't\n * do anything, you can simply omit it. Note however, if the `error` method is not provided and an error happens,\n * it will be thrown asynchronously. Errors thrown asynchronously cannot be caught using `try`/`catch`. Instead,\n * use the {@link onUnhandledError} configuration option or use a runtime handler (like `window.onerror` or\n * `process.on('error)`) to be notified of unhandled errors. Because of this, it's recommended that you provide\n * an `error` method to avoid missing thrown errors.\n *\n * The second way is to give up on Observer object altogether and simply provide callback functions in place of its methods.\n * This means you can provide three functions as arguments to `subscribe`, where the first function is equivalent\n * of a `next` method, the second of an `error` method and the third of a `complete` method. Just as in case of an Observer,\n * if you do not need to listen for something, you can omit a function by passing `undefined` or `null`,\n * since `subscribe` recognizes these functions by where they were placed in function call. When it comes\n * to the `error` function, as with an Observer, if not provided, errors emitted by an Observable will be thrown asynchronously.\n *\n * You can, however, subscribe with no parameters at all. This may be the case where you're not interested in terminal events\n * and you also handled emissions internally by using operators (e.g. using `tap`).\n *\n * Whichever style of calling `subscribe` you use, in both cases it returns a Subscription object.\n * This object allows you to call `unsubscribe` on it, which in turn will stop the work that an Observable does and will clean\n * up all resources that an Observable used. Note that cancelling a subscription will not call `complete` callback\n * provided to `subscribe` function, which is reserved for a regular completion signal that comes from an Observable.\n *\n * Remember that callbacks provided to `subscribe` are not guaranteed to be called asynchronously.\n * It is an Observable itself that decides when these functions will be called. For example {@link of}\n * by default emits all its values synchronously. Always check documentation for how given Observable\n * will behave when subscribed and if its default behavior can be modified with a `scheduler`.\n *\n * #### Examples\n *\n * Subscribe with an {@link guide/observer Observer}\n *\n * ```ts\n * import { of } from 'rxjs';\n *\n * const sumObserver = {\n * sum: 0,\n * next(value) {\n * console.log('Adding: ' + value);\n * this.sum = this.sum + value;\n * },\n * error() {\n * // We actually could just remove this method,\n * // since we do not really care about errors right now.\n * },\n * complete() {\n * console.log('Sum equals: ' + this.sum);\n * }\n * };\n *\n * of(1, 2, 3) // Synchronously emits 1, 2, 3 and then completes.\n * .subscribe(sumObserver);\n *\n * // Logs:\n * // 'Adding: 1'\n * // 'Adding: 2'\n * // 'Adding: 3'\n * // 'Sum equals: 6'\n * ```\n *\n * Subscribe with functions ({@link deprecations/subscribe-arguments deprecated})\n *\n * ```ts\n * import { of } from 'rxjs'\n *\n * let sum = 0;\n *\n * of(1, 2, 3).subscribe(\n * value => {\n * console.log('Adding: ' + value);\n * sum = sum + value;\n * },\n * undefined,\n * () => console.log('Sum equals: ' + sum)\n * );\n *\n * // Logs:\n * // 'Adding: 1'\n * // 'Adding: 2'\n * // 'Adding: 3'\n * // 'Sum equals: 6'\n * ```\n *\n * Cancel a subscription\n *\n * ```ts\n * import { interval } from 'rxjs';\n *\n * const subscription = interval(1000).subscribe({\n * next(num) {\n * console.log(num)\n * },\n * complete() {\n * // Will not be called, even when cancelling subscription.\n * console.log('completed!');\n * }\n * });\n *\n * setTimeout(() => {\n * subscription.unsubscribe();\n * console.log('unsubscribed!');\n * }, 2500);\n *\n * // Logs:\n * // 0 after 1s\n * // 1 after 2s\n * // 'unsubscribed!' after 2.5s\n * ```\n *\n * @param {Observer|Function} observerOrNext (optional) Either an observer with methods to be called,\n * or the first of three possible handlers, which is the handler for each value emitted from the subscribed\n * Observable.\n * @param {Function} error (optional) A handler for a terminal event resulting from an error. If no error handler is provided,\n * the error will be thrown asynchronously as unhandled.\n * @param {Function} complete (optional) A handler for a terminal event resulting from successful completion.\n * @return {Subscription} a subscription reference to the registered handlers\n * @method subscribe\n */\n subscribe(\n observerOrNext?: Partial> | ((value: T) => void) | null,\n error?: ((error: any) => void) | null,\n complete?: (() => void) | null\n ): Subscription {\n const subscriber = isSubscriber(observerOrNext) ? observerOrNext : new SafeSubscriber(observerOrNext, error, complete);\n\n errorContext(() => {\n const { operator, source } = this;\n subscriber.add(\n operator\n ? // We're dealing with a subscription in the\n // operator chain to one of our lifted operators.\n operator.call(subscriber, source)\n : source\n ? // If `source` has a value, but `operator` does not, something that\n // had intimate knowledge of our API, like our `Subject`, must have\n // set it. We're going to just call `_subscribe` directly.\n this._subscribe(subscriber)\n : // In all other cases, we're likely wrapping a user-provided initializer\n // function, so we need to catch errors and handle them appropriately.\n this._trySubscribe(subscriber)\n );\n });\n\n return subscriber;\n }\n\n /** @internal */\n protected _trySubscribe(sink: Subscriber): TeardownLogic {\n try {\n return this._subscribe(sink);\n } catch (err) {\n // We don't need to return anything in this case,\n // because it's just going to try to `add()` to a subscription\n // above.\n sink.error(err);\n }\n }\n\n /**\n * Used as a NON-CANCELLABLE means of subscribing to an observable, for use with\n * APIs that expect promises, like `async/await`. You cannot unsubscribe from this.\n *\n * **WARNING**: Only use this with observables you *know* will complete. If the source\n * observable does not complete, you will end up with a promise that is hung up, and\n * potentially all of the state of an async function hanging out in memory. To avoid\n * this situation, look into adding something like {@link timeout}, {@link take},\n * {@link takeWhile}, or {@link takeUntil} amongst others.\n *\n * #### Example\n *\n * ```ts\n * import { interval, take } from 'rxjs';\n *\n * const source$ = interval(1000).pipe(take(4));\n *\n * async function getTotal() {\n * let total = 0;\n *\n * await source$.forEach(value => {\n * total += value;\n * console.log('observable -> ' + value);\n * });\n *\n * return total;\n * }\n *\n * getTotal().then(\n * total => console.log('Total: ' + total)\n * );\n *\n * // Expected:\n * // 'observable -> 0'\n * // 'observable -> 1'\n * // 'observable -> 2'\n * // 'observable -> 3'\n * // 'Total: 6'\n * ```\n *\n * @param next a handler for each value emitted by the observable\n * @return a promise that either resolves on observable completion or\n * rejects with the handled error\n */\n forEach(next: (value: T) => void): Promise;\n\n /**\n * @param next a handler for each value emitted by the observable\n * @param promiseCtor a constructor function used to instantiate the Promise\n * @return a promise that either resolves on observable completion or\n * rejects with the handled error\n * @deprecated Passing a Promise constructor will no longer be available\n * in upcoming versions of RxJS. This is because it adds weight to the library, for very\n * little benefit. If you need this functionality, it is recommended that you either\n * polyfill Promise, or you create an adapter to convert the returned native promise\n * to whatever promise implementation you wanted. Will be removed in v8.\n */\n forEach(next: (value: T) => void, promiseCtor: PromiseConstructorLike): Promise;\n\n forEach(next: (value: T) => void, promiseCtor?: PromiseConstructorLike): Promise {\n promiseCtor = getPromiseCtor(promiseCtor);\n\n return new promiseCtor((resolve, reject) => {\n const subscriber = new SafeSubscriber({\n next: (value) => {\n try {\n next(value);\n } catch (err) {\n reject(err);\n subscriber.unsubscribe();\n }\n },\n error: reject,\n complete: resolve,\n });\n this.subscribe(subscriber);\n }) as Promise;\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): TeardownLogic {\n return this.source?.subscribe(subscriber);\n }\n\n /**\n * An interop point defined by the es7-observable spec https://github.com/zenparsing/es-observable\n * @method Symbol.observable\n * @return {Observable} this instance of the observable\n */\n [Symbol_observable]() {\n return this;\n }\n\n /* tslint:disable:max-line-length */\n pipe(): Observable;\n pipe(op1: OperatorFunction): Observable;\n pipe(op1: OperatorFunction, op2: OperatorFunction): Observable;\n pipe(op1: OperatorFunction, op2: OperatorFunction, op3: OperatorFunction): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction,\n op8: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction,\n op8: OperatorFunction,\n op9: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction,\n op8: OperatorFunction,\n op9: OperatorFunction,\n ...operations: OperatorFunction[]\n ): Observable;\n /* tslint:enable:max-line-length */\n\n /**\n * Used to stitch together functional operators into a chain.\n * @method pipe\n * @return {Observable} the Observable result of all of the operators having\n * been called in the order they were passed in.\n *\n * ## Example\n *\n * ```ts\n * import { interval, filter, map, scan } from 'rxjs';\n *\n * interval(1000)\n * .pipe(\n * filter(x => x % 2 === 0),\n * map(x => x + x),\n * scan((acc, x) => acc + x)\n * )\n * .subscribe(x => console.log(x));\n * ```\n */\n pipe(...operations: OperatorFunction[]): Observable {\n return pipeFromArray(operations)(this);\n }\n\n /* tslint:disable:max-line-length */\n /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n toPromise(): Promise;\n /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n toPromise(PromiseCtor: typeof Promise): Promise;\n /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n toPromise(PromiseCtor: PromiseConstructorLike): Promise;\n /* tslint:enable:max-line-length */\n\n /**\n * Subscribe to this Observable and get a Promise resolving on\n * `complete` with the last emission (if any).\n *\n * **WARNING**: Only use this with observables you *know* will complete. If the source\n * observable does not complete, you will end up with a promise that is hung up, and\n * potentially all of the state of an async function hanging out in memory. To avoid\n * this situation, look into adding something like {@link timeout}, {@link take},\n * {@link takeWhile}, or {@link takeUntil} amongst others.\n *\n * @method toPromise\n * @param [promiseCtor] a constructor function used to instantiate\n * the Promise\n * @return A Promise that resolves with the last value emit, or\n * rejects on an error. If there were no emissions, Promise\n * resolves with undefined.\n * @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise\n */\n toPromise(promiseCtor?: PromiseConstructorLike): Promise {\n promiseCtor = getPromiseCtor(promiseCtor);\n\n return new promiseCtor((resolve, reject) => {\n let value: T | undefined;\n this.subscribe(\n (x: T) => (value = x),\n (err: any) => reject(err),\n () => resolve(value)\n );\n }) as Promise;\n }\n}\n\n/**\n * Decides between a passed promise constructor from consuming code,\n * A default configured promise constructor, and the native promise\n * constructor and returns it. If nothing can be found, it will throw\n * an error.\n * @param promiseCtor The optional promise constructor to passed by consuming code\n */\nfunction getPromiseCtor(promiseCtor: PromiseConstructorLike | undefined) {\n return promiseCtor ?? config.Promise ?? Promise;\n}\n\nfunction isObserver(value: any): value is Observer {\n return value && isFunction(value.next) && isFunction(value.error) && isFunction(value.complete);\n}\n\nfunction isSubscriber(value: any): value is Subscriber {\n return (value && value instanceof Subscriber) || (isObserver(value) && isSubscription(value));\n}\n", "import { Observable } from '../Observable';\nimport { Subscriber } from '../Subscriber';\nimport { OperatorFunction } from '../types';\nimport { isFunction } from './isFunction';\n\n/**\n * Used to determine if an object is an Observable with a lift function.\n */\nexport function hasLift(source: any): source is { lift: InstanceType['lift'] } {\n return isFunction(source?.lift);\n}\n\n/**\n * Creates an `OperatorFunction`. Used to define operators throughout the library in a concise way.\n * @param init The logic to connect the liftedSource to the subscriber at the moment of subscription.\n */\nexport function operate(\n init: (liftedSource: Observable, subscriber: Subscriber) => (() => void) | void\n): OperatorFunction {\n return (source: Observable) => {\n if (hasLift(source)) {\n return source.lift(function (this: Subscriber, liftedSource: Observable) {\n try {\n return init(liftedSource, this);\n } catch (err) {\n this.error(err);\n }\n });\n }\n throw new TypeError('Unable to lift unknown Observable type');\n };\n}\n", "import { Subscriber } from '../Subscriber';\n\n/**\n * Creates an instance of an `OperatorSubscriber`.\n * @param destination The downstream subscriber.\n * @param onNext Handles next values, only called if this subscriber is not stopped or closed. Any\n * error that occurs in this function is caught and sent to the `error` method of this subscriber.\n * @param onError Handles errors from the subscription, any errors that occur in this handler are caught\n * and send to the `destination` error handler.\n * @param onComplete Handles completion notification from the subscription. Any errors that occur in\n * this handler are sent to the `destination` error handler.\n * @param onFinalize Additional teardown logic here. This will only be called on teardown if the\n * subscriber itself is not already closed. This is called after all other teardown logic is executed.\n */\nexport function createOperatorSubscriber(\n destination: Subscriber,\n onNext?: (value: T) => void,\n onComplete?: () => void,\n onError?: (err: any) => void,\n onFinalize?: () => void\n): Subscriber {\n return new OperatorSubscriber(destination, onNext, onComplete, onError, onFinalize);\n}\n\n/**\n * A generic helper for allowing operators to be created with a Subscriber and\n * use closures to capture necessary state from the operator function itself.\n */\nexport class OperatorSubscriber extends Subscriber {\n /**\n * Creates an instance of an `OperatorSubscriber`.\n * @param destination The downstream subscriber.\n * @param onNext Handles next values, only called if this subscriber is not stopped or closed. Any\n * error that occurs in this function is caught and sent to the `error` method of this subscriber.\n * @param onError Handles errors from the subscription, any errors that occur in this handler are caught\n * and send to the `destination` error handler.\n * @param onComplete Handles completion notification from the subscription. Any errors that occur in\n * this handler are sent to the `destination` error handler.\n * @param onFinalize Additional finalization logic here. This will only be called on finalization if the\n * subscriber itself is not already closed. This is called after all other finalization logic is executed.\n * @param shouldUnsubscribe An optional check to see if an unsubscribe call should truly unsubscribe.\n * NOTE: This currently **ONLY** exists to support the strange behavior of {@link groupBy}, where unsubscription\n * to the resulting observable does not actually disconnect from the source if there are active subscriptions\n * to any grouped observable. (DO NOT EXPOSE OR USE EXTERNALLY!!!)\n */\n constructor(\n destination: Subscriber,\n onNext?: (value: T) => void,\n onComplete?: () => void,\n onError?: (err: any) => void,\n private onFinalize?: () => void,\n private shouldUnsubscribe?: () => boolean\n ) {\n // It's important - for performance reasons - that all of this class's\n // members are initialized and that they are always initialized in the same\n // order. This will ensure that all OperatorSubscriber instances have the\n // same hidden class in V8. This, in turn, will help keep the number of\n // hidden classes involved in property accesses within the base class as\n // low as possible. If the number of hidden classes involved exceeds four,\n // the property accesses will become megamorphic and performance penalties\n // will be incurred - i.e. inline caches won't be used.\n //\n // The reasons for ensuring all instances have the same hidden class are\n // further discussed in this blog post from Benedikt Meurer:\n // https://benediktmeurer.de/2018/03/23/impact-of-polymorphism-on-component-based-frameworks-like-react/\n super(destination);\n this._next = onNext\n ? function (this: OperatorSubscriber, value: T) {\n try {\n onNext(value);\n } catch (err) {\n destination.error(err);\n }\n }\n : super._next;\n this._error = onError\n ? function (this: OperatorSubscriber, err: any) {\n try {\n onError(err);\n } catch (err) {\n // Send any errors that occur down stream.\n destination.error(err);\n } finally {\n // Ensure finalization.\n this.unsubscribe();\n }\n }\n : super._error;\n this._complete = onComplete\n ? function (this: OperatorSubscriber) {\n try {\n onComplete();\n } catch (err) {\n // Send any errors that occur down stream.\n destination.error(err);\n } finally {\n // Ensure finalization.\n this.unsubscribe();\n }\n }\n : super._complete;\n }\n\n unsubscribe() {\n if (!this.shouldUnsubscribe || this.shouldUnsubscribe()) {\n const { closed } = this;\n super.unsubscribe();\n // Execute additional teardown if we have any and we didn't already do so.\n !closed && this.onFinalize?.();\n }\n }\n}\n", "import { Subscription } from '../Subscription';\n\ninterface AnimationFrameProvider {\n schedule(callback: FrameRequestCallback): Subscription;\n requestAnimationFrame: typeof requestAnimationFrame;\n cancelAnimationFrame: typeof cancelAnimationFrame;\n delegate:\n | {\n requestAnimationFrame: typeof requestAnimationFrame;\n cancelAnimationFrame: typeof cancelAnimationFrame;\n }\n | undefined;\n}\n\nexport const animationFrameProvider: AnimationFrameProvider = {\n // When accessing the delegate, use the variable rather than `this` so that\n // the functions can be called without being bound to the provider.\n schedule(callback) {\n let request = requestAnimationFrame;\n let cancel: typeof cancelAnimationFrame | undefined = cancelAnimationFrame;\n const { delegate } = animationFrameProvider;\n if (delegate) {\n request = delegate.requestAnimationFrame;\n cancel = delegate.cancelAnimationFrame;\n }\n const handle = request((timestamp) => {\n // Clear the cancel function. The request has been fulfilled, so\n // attempting to cancel the request upon unsubscription would be\n // pointless.\n cancel = undefined;\n callback(timestamp);\n });\n return new Subscription(() => cancel?.(handle));\n },\n requestAnimationFrame(...args) {\n const { delegate } = animationFrameProvider;\n return (delegate?.requestAnimationFrame || requestAnimationFrame)(...args);\n },\n cancelAnimationFrame(...args) {\n const { delegate } = animationFrameProvider;\n return (delegate?.cancelAnimationFrame || cancelAnimationFrame)(...args);\n },\n delegate: undefined,\n};\n", "import { createErrorClass } from './createErrorClass';\n\nexport interface ObjectUnsubscribedError extends Error {}\n\nexport interface ObjectUnsubscribedErrorCtor {\n /**\n * @deprecated Internal implementation detail. Do not construct error instances.\n * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269\n */\n new (): ObjectUnsubscribedError;\n}\n\n/**\n * An error thrown when an action is invalid because the object has been\n * unsubscribed.\n *\n * @see {@link Subject}\n * @see {@link BehaviorSubject}\n *\n * @class ObjectUnsubscribedError\n */\nexport const ObjectUnsubscribedError: ObjectUnsubscribedErrorCtor = createErrorClass(\n (_super) =>\n function ObjectUnsubscribedErrorImpl(this: any) {\n _super(this);\n this.name = 'ObjectUnsubscribedError';\n this.message = 'object unsubscribed';\n }\n);\n", "import { Operator } from './Operator';\nimport { Observable } from './Observable';\nimport { Subscriber } from './Subscriber';\nimport { Subscription, EMPTY_SUBSCRIPTION } from './Subscription';\nimport { Observer, SubscriptionLike, TeardownLogic } from './types';\nimport { ObjectUnsubscribedError } from './util/ObjectUnsubscribedError';\nimport { arrRemove } from './util/arrRemove';\nimport { errorContext } from './util/errorContext';\n\n/**\n * A Subject is a special type of Observable that allows values to be\n * multicasted to many Observers. Subjects are like EventEmitters.\n *\n * Every Subject is an Observable and an Observer. You can subscribe to a\n * Subject, and you can call next to feed values as well as error and complete.\n */\nexport class Subject extends Observable implements SubscriptionLike {\n closed = false;\n\n private currentObservers: Observer[] | null = null;\n\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n observers: Observer[] = [];\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n isStopped = false;\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n hasError = false;\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n thrownError: any = null;\n\n /**\n * Creates a \"subject\" by basically gluing an observer to an observable.\n *\n * @nocollapse\n * @deprecated Recommended you do not use. Will be removed at some point in the future. Plans for replacement still under discussion.\n */\n static create: (...args: any[]) => any = (destination: Observer, source: Observable): AnonymousSubject => {\n return new AnonymousSubject(destination, source);\n };\n\n constructor() {\n // NOTE: This must be here to obscure Observable's constructor.\n super();\n }\n\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n lift(operator: Operator): Observable {\n const subject = new AnonymousSubject(this, this);\n subject.operator = operator as any;\n return subject as any;\n }\n\n /** @internal */\n protected _throwIfClosed() {\n if (this.closed) {\n throw new ObjectUnsubscribedError();\n }\n }\n\n next(value: T) {\n errorContext(() => {\n this._throwIfClosed();\n if (!this.isStopped) {\n if (!this.currentObservers) {\n this.currentObservers = Array.from(this.observers);\n }\n for (const observer of this.currentObservers) {\n observer.next(value);\n }\n }\n });\n }\n\n error(err: any) {\n errorContext(() => {\n this._throwIfClosed();\n if (!this.isStopped) {\n this.hasError = this.isStopped = true;\n this.thrownError = err;\n const { observers } = this;\n while (observers.length) {\n observers.shift()!.error(err);\n }\n }\n });\n }\n\n complete() {\n errorContext(() => {\n this._throwIfClosed();\n if (!this.isStopped) {\n this.isStopped = true;\n const { observers } = this;\n while (observers.length) {\n observers.shift()!.complete();\n }\n }\n });\n }\n\n unsubscribe() {\n this.isStopped = this.closed = true;\n this.observers = this.currentObservers = null!;\n }\n\n get observed() {\n return this.observers?.length > 0;\n }\n\n /** @internal */\n protected _trySubscribe(subscriber: Subscriber): TeardownLogic {\n this._throwIfClosed();\n return super._trySubscribe(subscriber);\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n this._throwIfClosed();\n this._checkFinalizedStatuses(subscriber);\n return this._innerSubscribe(subscriber);\n }\n\n /** @internal */\n protected _innerSubscribe(subscriber: Subscriber) {\n const { hasError, isStopped, observers } = this;\n if (hasError || isStopped) {\n return EMPTY_SUBSCRIPTION;\n }\n this.currentObservers = null;\n observers.push(subscriber);\n return new Subscription(() => {\n this.currentObservers = null;\n arrRemove(observers, subscriber);\n });\n }\n\n /** @internal */\n protected _checkFinalizedStatuses(subscriber: Subscriber) {\n const { hasError, thrownError, isStopped } = this;\n if (hasError) {\n subscriber.error(thrownError);\n } else if (isStopped) {\n subscriber.complete();\n }\n }\n\n /**\n * Creates a new Observable with this Subject as the source. You can do this\n * to create custom Observer-side logic of the Subject and conceal it from\n * code that uses the Observable.\n * @return {Observable} Observable that the Subject casts to\n */\n asObservable(): Observable {\n const observable: any = new Observable();\n observable.source = this;\n return observable;\n }\n}\n\n/**\n * @class AnonymousSubject\n */\nexport class AnonymousSubject extends Subject {\n constructor(\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n public destination?: Observer,\n source?: Observable\n ) {\n super();\n this.source = source;\n }\n\n next(value: T) {\n this.destination?.next?.(value);\n }\n\n error(err: any) {\n this.destination?.error?.(err);\n }\n\n complete() {\n this.destination?.complete?.();\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n return this.source?.subscribe(subscriber) ?? EMPTY_SUBSCRIPTION;\n }\n}\n", "import { Subject } from './Subject';\nimport { Subscriber } from './Subscriber';\nimport { Subscription } from './Subscription';\n\n/**\n * A variant of Subject that requires an initial value and emits its current\n * value whenever it is subscribed to.\n *\n * @class BehaviorSubject\n */\nexport class BehaviorSubject extends Subject {\n constructor(private _value: T) {\n super();\n }\n\n get value(): T {\n return this.getValue();\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n const subscription = super._subscribe(subscriber);\n !subscription.closed && subscriber.next(this._value);\n return subscription;\n }\n\n getValue(): T {\n const { hasError, thrownError, _value } = this;\n if (hasError) {\n throw thrownError;\n }\n this._throwIfClosed();\n return _value;\n }\n\n next(value: T): void {\n super.next((this._value = value));\n }\n}\n", "import { TimestampProvider } from '../types';\n\ninterface DateTimestampProvider extends TimestampProvider {\n delegate: TimestampProvider | undefined;\n}\n\nexport const dateTimestampProvider: DateTimestampProvider = {\n now() {\n // Use the variable rather than `this` so that the function can be called\n // without being bound to the provider.\n return (dateTimestampProvider.delegate || Date).now();\n },\n delegate: undefined,\n};\n", "import { Subject } from './Subject';\nimport { TimestampProvider } from './types';\nimport { Subscriber } from './Subscriber';\nimport { Subscription } from './Subscription';\nimport { dateTimestampProvider } from './scheduler/dateTimestampProvider';\n\n/**\n * A variant of {@link Subject} that \"replays\" old values to new subscribers by emitting them when they first subscribe.\n *\n * `ReplaySubject` has an internal buffer that will store a specified number of values that it has observed. Like `Subject`,\n * `ReplaySubject` \"observes\" values by having them passed to its `next` method. When it observes a value, it will store that\n * value for a time determined by the configuration of the `ReplaySubject`, as passed to its constructor.\n *\n * When a new subscriber subscribes to the `ReplaySubject` instance, it will synchronously emit all values in its buffer in\n * a First-In-First-Out (FIFO) manner. The `ReplaySubject` will also complete, if it has observed completion; and it will\n * error if it has observed an error.\n *\n * There are two main configuration items to be concerned with:\n *\n * 1. `bufferSize` - This will determine how many items are stored in the buffer, defaults to infinite.\n * 2. `windowTime` - The amount of time to hold a value in the buffer before removing it from the buffer.\n *\n * Both configurations may exist simultaneously. So if you would like to buffer a maximum of 3 values, as long as the values\n * are less than 2 seconds old, you could do so with a `new ReplaySubject(3, 2000)`.\n *\n * ### Differences with BehaviorSubject\n *\n * `BehaviorSubject` is similar to `new ReplaySubject(1)`, with a couple of exceptions:\n *\n * 1. `BehaviorSubject` comes \"primed\" with a single value upon construction.\n * 2. `ReplaySubject` will replay values, even after observing an error, where `BehaviorSubject` will not.\n *\n * @see {@link Subject}\n * @see {@link BehaviorSubject}\n * @see {@link shareReplay}\n */\nexport class ReplaySubject extends Subject {\n private _buffer: (T | number)[] = [];\n private _infiniteTimeWindow = true;\n\n /**\n * @param bufferSize The size of the buffer to replay on subscription\n * @param windowTime The amount of time the buffered items will stay buffered\n * @param timestampProvider An object with a `now()` method that provides the current timestamp. This is used to\n * calculate the amount of time something has been buffered.\n */\n constructor(\n private _bufferSize = Infinity,\n private _windowTime = Infinity,\n private _timestampProvider: TimestampProvider = dateTimestampProvider\n ) {\n super();\n this._infiniteTimeWindow = _windowTime === Infinity;\n this._bufferSize = Math.max(1, _bufferSize);\n this._windowTime = Math.max(1, _windowTime);\n }\n\n next(value: T): void {\n const { isStopped, _buffer, _infiniteTimeWindow, _timestampProvider, _windowTime } = this;\n if (!isStopped) {\n _buffer.push(value);\n !_infiniteTimeWindow && _buffer.push(_timestampProvider.now() + _windowTime);\n }\n this._trimBuffer();\n super.next(value);\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n this._throwIfClosed();\n this._trimBuffer();\n\n const subscription = this._innerSubscribe(subscriber);\n\n const { _infiniteTimeWindow, _buffer } = this;\n // We use a copy here, so reentrant code does not mutate our array while we're\n // emitting it to a new subscriber.\n const copy = _buffer.slice();\n for (let i = 0; i < copy.length && !subscriber.closed; i += _infiniteTimeWindow ? 1 : 2) {\n subscriber.next(copy[i] as T);\n }\n\n this._checkFinalizedStatuses(subscriber);\n\n return subscription;\n }\n\n private _trimBuffer() {\n const { _bufferSize, _timestampProvider, _buffer, _infiniteTimeWindow } = this;\n // If we don't have an infinite buffer size, and we're over the length,\n // use splice to truncate the old buffer values off. Note that we have to\n // double the size for instances where we're not using an infinite time window\n // because we're storing the values and the timestamps in the same array.\n const adjustedBufferSize = (_infiniteTimeWindow ? 1 : 2) * _bufferSize;\n _bufferSize < Infinity && adjustedBufferSize < _buffer.length && _buffer.splice(0, _buffer.length - adjustedBufferSize);\n\n // Now, if we're not in an infinite time window, remove all values where the time is\n // older than what is allowed.\n if (!_infiniteTimeWindow) {\n const now = _timestampProvider.now();\n let last = 0;\n // Search the array for the first timestamp that isn't expired and\n // truncate the buffer up to that point.\n for (let i = 1; i < _buffer.length && (_buffer[i] as number) <= now; i += 2) {\n last = i;\n }\n last && _buffer.splice(0, last + 1);\n }\n }\n}\n", "import { Scheduler } from '../Scheduler';\nimport { Subscription } from '../Subscription';\nimport { SchedulerAction } from '../types';\n\n/**\n * A unit of work to be executed in a `scheduler`. An action is typically\n * created from within a {@link SchedulerLike} and an RxJS user does not need to concern\n * themselves about creating and manipulating an Action.\n *\n * ```ts\n * class Action extends Subscription {\n * new (scheduler: Scheduler, work: (state?: T) => void);\n * schedule(state?: T, delay: number = 0): Subscription;\n * }\n * ```\n *\n * @class Action\n */\nexport class Action extends Subscription {\n constructor(scheduler: Scheduler, work: (this: SchedulerAction, state?: T) => void) {\n super();\n }\n /**\n * Schedules this action on its parent {@link SchedulerLike} for execution. May be passed\n * some context object, `state`. May happen at some point in the future,\n * according to the `delay` parameter, if specified.\n * @param {T} [state] Some contextual data that the `work` function uses when\n * called by the Scheduler.\n * @param {number} [delay] Time to wait before executing the work, where the\n * time unit is implicit and defined by the Scheduler.\n * @return {void}\n */\n public schedule(state?: T, delay: number = 0): Subscription {\n return this;\n }\n}\n", "import type { TimerHandle } from './timerHandle';\ntype SetIntervalFunction = (handler: () => void, timeout?: number, ...args: any[]) => TimerHandle;\ntype ClearIntervalFunction = (handle: TimerHandle) => void;\n\ninterface IntervalProvider {\n setInterval: SetIntervalFunction;\n clearInterval: ClearIntervalFunction;\n delegate:\n | {\n setInterval: SetIntervalFunction;\n clearInterval: ClearIntervalFunction;\n }\n | undefined;\n}\n\nexport const intervalProvider: IntervalProvider = {\n // When accessing the delegate, use the variable rather than `this` so that\n // the functions can be called without being bound to the provider.\n setInterval(handler: () => void, timeout?: number, ...args) {\n const { delegate } = intervalProvider;\n if (delegate?.setInterval) {\n return delegate.setInterval(handler, timeout, ...args);\n }\n return setInterval(handler, timeout, ...args);\n },\n clearInterval(handle) {\n const { delegate } = intervalProvider;\n return (delegate?.clearInterval || clearInterval)(handle as any);\n },\n delegate: undefined,\n};\n", "import { Action } from './Action';\nimport { SchedulerAction } from '../types';\nimport { Subscription } from '../Subscription';\nimport { AsyncScheduler } from './AsyncScheduler';\nimport { intervalProvider } from './intervalProvider';\nimport { arrRemove } from '../util/arrRemove';\nimport { TimerHandle } from './timerHandle';\n\nexport class AsyncAction extends Action {\n public id: TimerHandle | undefined;\n public state?: T;\n // @ts-ignore: Property has no initializer and is not definitely assigned\n public delay: number;\n protected pending: boolean = false;\n\n constructor(protected scheduler: AsyncScheduler, protected work: (this: SchedulerAction, state?: T) => void) {\n super(scheduler, work);\n }\n\n public schedule(state?: T, delay: number = 0): Subscription {\n if (this.closed) {\n return this;\n }\n\n // Always replace the current state with the new state.\n this.state = state;\n\n const id = this.id;\n const scheduler = this.scheduler;\n\n //\n // Important implementation note:\n //\n // Actions only execute once by default, unless rescheduled from within the\n // scheduled callback. This allows us to implement single and repeat\n // actions via the same code path, without adding API surface area, as well\n // as mimic traditional recursion but across asynchronous boundaries.\n //\n // However, JS runtimes and timers distinguish between intervals achieved by\n // serial `setTimeout` calls vs. a single `setInterval` call. An interval of\n // serial `setTimeout` calls can be individually delayed, which delays\n // scheduling the next `setTimeout`, and so on. `setInterval` attempts to\n // guarantee the interval callback will be invoked more precisely to the\n // interval period, regardless of load.\n //\n // Therefore, we use `setInterval` to schedule single and repeat actions.\n // If the action reschedules itself with the same delay, the interval is not\n // canceled. If the action doesn't reschedule, or reschedules with a\n // different delay, the interval will be canceled after scheduled callback\n // execution.\n //\n if (id != null) {\n this.id = this.recycleAsyncId(scheduler, id, delay);\n }\n\n // Set the pending flag indicating that this action has been scheduled, or\n // has recursively rescheduled itself.\n this.pending = true;\n\n this.delay = delay;\n // If this action has already an async Id, don't request a new one.\n this.id = this.id ?? this.requestAsyncId(scheduler, this.id, delay);\n\n return this;\n }\n\n protected requestAsyncId(scheduler: AsyncScheduler, _id?: TimerHandle, delay: number = 0): TimerHandle {\n return intervalProvider.setInterval(scheduler.flush.bind(scheduler, this), delay);\n }\n\n protected recycleAsyncId(_scheduler: AsyncScheduler, id?: TimerHandle, delay: number | null = 0): TimerHandle | undefined {\n // If this action is rescheduled with the same delay time, don't clear the interval id.\n if (delay != null && this.delay === delay && this.pending === false) {\n return id;\n }\n // Otherwise, if the action's delay time is different from the current delay,\n // or the action has been rescheduled before it's executed, clear the interval id\n if (id != null) {\n intervalProvider.clearInterval(id);\n }\n\n return undefined;\n }\n\n /**\n * Immediately executes this action and the `work` it contains.\n * @return {any}\n */\n public execute(state: T, delay: number): any {\n if (this.closed) {\n return new Error('executing a cancelled action');\n }\n\n this.pending = false;\n const error = this._execute(state, delay);\n if (error) {\n return error;\n } else if (this.pending === false && this.id != null) {\n // Dequeue if the action didn't reschedule itself. Don't call\n // unsubscribe(), because the action could reschedule later.\n // For example:\n // ```\n // scheduler.schedule(function doWork(counter) {\n // /* ... I'm a busy worker bee ... */\n // var originalAction = this;\n // /* wait 100ms before rescheduling the action */\n // setTimeout(function () {\n // originalAction.schedule(counter + 1);\n // }, 100);\n // }, 1000);\n // ```\n this.id = this.recycleAsyncId(this.scheduler, this.id, null);\n }\n }\n\n protected _execute(state: T, _delay: number): any {\n let errored: boolean = false;\n let errorValue: any;\n try {\n this.work(state);\n } catch (e) {\n errored = true;\n // HACK: Since code elsewhere is relying on the \"truthiness\" of the\n // return here, we can't have it return \"\" or 0 or false.\n // TODO: Clean this up when we refactor schedulers mid-version-8 or so.\n errorValue = e ? e : new Error('Scheduled action threw falsy error');\n }\n if (errored) {\n this.unsubscribe();\n return errorValue;\n }\n }\n\n unsubscribe() {\n if (!this.closed) {\n const { id, scheduler } = this;\n const { actions } = scheduler;\n\n this.work = this.state = this.scheduler = null!;\n this.pending = false;\n\n arrRemove(actions, this);\n if (id != null) {\n this.id = this.recycleAsyncId(scheduler, id, null);\n }\n\n this.delay = null!;\n super.unsubscribe();\n }\n }\n}\n", "import { Action } from './scheduler/Action';\nimport { Subscription } from './Subscription';\nimport { SchedulerLike, SchedulerAction } from './types';\nimport { dateTimestampProvider } from './scheduler/dateTimestampProvider';\n\n/**\n * An execution context and a data structure to order tasks and schedule their\n * execution. Provides a notion of (potentially virtual) time, through the\n * `now()` getter method.\n *\n * Each unit of work in a Scheduler is called an `Action`.\n *\n * ```ts\n * class Scheduler {\n * now(): number;\n * schedule(work, delay?, state?): Subscription;\n * }\n * ```\n *\n * @class Scheduler\n * @deprecated Scheduler is an internal implementation detail of RxJS, and\n * should not be used directly. Rather, create your own class and implement\n * {@link SchedulerLike}. Will be made internal in v8.\n */\nexport class Scheduler implements SchedulerLike {\n public static now: () => number = dateTimestampProvider.now;\n\n constructor(private schedulerActionCtor: typeof Action, now: () => number = Scheduler.now) {\n this.now = now;\n }\n\n /**\n * A getter method that returns a number representing the current time\n * (at the time this function was called) according to the scheduler's own\n * internal clock.\n * @return {number} A number that represents the current time. May or may not\n * have a relation to wall-clock time. May or may not refer to a time unit\n * (e.g. milliseconds).\n */\n public now: () => number;\n\n /**\n * Schedules a function, `work`, for execution. May happen at some point in\n * the future, according to the `delay` parameter, if specified. May be passed\n * some context object, `state`, which will be passed to the `work` function.\n *\n * The given arguments will be processed an stored as an Action object in a\n * queue of actions.\n *\n * @param {function(state: ?T): ?Subscription} work A function representing a\n * task, or some unit of work to be executed by the Scheduler.\n * @param {number} [delay] Time to wait before executing the work, where the\n * time unit is implicit and defined by the Scheduler itself.\n * @param {T} [state] Some contextual data that the `work` function uses when\n * called by the Scheduler.\n * @return {Subscription} A subscription in order to be able to unsubscribe\n * the scheduled work.\n */\n public schedule(work: (this: SchedulerAction, state?: T) => void, delay: number = 0, state?: T): Subscription {\n return new this.schedulerActionCtor(this, work).schedule(state, delay);\n }\n}\n", "import { Scheduler } from '../Scheduler';\nimport { Action } from './Action';\nimport { AsyncAction } from './AsyncAction';\nimport { TimerHandle } from './timerHandle';\n\nexport class AsyncScheduler extends Scheduler {\n public actions: Array> = [];\n /**\n * A flag to indicate whether the Scheduler is currently executing a batch of\n * queued actions.\n * @type {boolean}\n * @internal\n */\n public _active: boolean = false;\n /**\n * An internal ID used to track the latest asynchronous task such as those\n * coming from `setTimeout`, `setInterval`, `requestAnimationFrame`, and\n * others.\n * @type {any}\n * @internal\n */\n public _scheduled: TimerHandle | undefined;\n\n constructor(SchedulerAction: typeof Action, now: () => number = Scheduler.now) {\n super(SchedulerAction, now);\n }\n\n public flush(action: AsyncAction): void {\n const { actions } = this;\n\n if (this._active) {\n actions.push(action);\n return;\n }\n\n let error: any;\n this._active = true;\n\n do {\n if ((error = action.execute(action.state, action.delay))) {\n break;\n }\n } while ((action = actions.shift()!)); // exhaust the scheduler queue\n\n this._active = false;\n\n if (error) {\n while ((action = actions.shift()!)) {\n action.unsubscribe();\n }\n throw error;\n }\n }\n}\n", "import { AsyncAction } from './AsyncAction';\nimport { AsyncScheduler } from './AsyncScheduler';\n\n/**\n *\n * Async Scheduler\n *\n * Schedule task as if you used setTimeout(task, duration)\n *\n * `async` scheduler schedules tasks asynchronously, by putting them on the JavaScript\n * event loop queue. It is best used to delay tasks in time or to schedule tasks repeating\n * in intervals.\n *\n * If you just want to \"defer\" task, that is to perform it right after currently\n * executing synchronous code ends (commonly achieved by `setTimeout(deferredTask, 0)`),\n * better choice will be the {@link asapScheduler} scheduler.\n *\n * ## Examples\n * Use async scheduler to delay task\n * ```ts\n * import { asyncScheduler } from 'rxjs';\n *\n * const task = () => console.log('it works!');\n *\n * asyncScheduler.schedule(task, 2000);\n *\n * // After 2 seconds logs:\n * // \"it works!\"\n * ```\n *\n * Use async scheduler to repeat task in intervals\n * ```ts\n * import { asyncScheduler } from 'rxjs';\n *\n * function task(state) {\n * console.log(state);\n * this.schedule(state + 1, 1000); // `this` references currently executing Action,\n * // which we reschedule with new state and delay\n * }\n *\n * asyncScheduler.schedule(task, 3000, 0);\n *\n * // Logs:\n * // 0 after 3s\n * // 1 after 4s\n * // 2 after 5s\n * // 3 after 6s\n * ```\n */\n\nexport const asyncScheduler = new AsyncScheduler(AsyncAction);\n\n/**\n * @deprecated Renamed to {@link asyncScheduler}. Will be removed in v8.\n */\nexport const async = asyncScheduler;\n", "import { AsyncAction } from './AsyncAction';\nimport { Subscription } from '../Subscription';\nimport { QueueScheduler } from './QueueScheduler';\nimport { SchedulerAction } from '../types';\nimport { TimerHandle } from './timerHandle';\n\nexport class QueueAction extends AsyncAction {\n constructor(protected scheduler: QueueScheduler, protected work: (this: SchedulerAction, state?: T) => void) {\n super(scheduler, work);\n }\n\n public schedule(state?: T, delay: number = 0): Subscription {\n if (delay > 0) {\n return super.schedule(state, delay);\n }\n this.delay = delay;\n this.state = state;\n this.scheduler.flush(this);\n return this;\n }\n\n public execute(state: T, delay: number): any {\n return delay > 0 || this.closed ? super.execute(state, delay) : this._execute(state, delay);\n }\n\n protected requestAsyncId(scheduler: QueueScheduler, id?: TimerHandle, delay: number = 0): TimerHandle {\n // If delay exists and is greater than 0, or if the delay is null (the\n // action wasn't rescheduled) but was originally scheduled as an async\n // action, then recycle as an async action.\n\n if ((delay != null && delay > 0) || (delay == null && this.delay > 0)) {\n return super.requestAsyncId(scheduler, id, delay);\n }\n\n // Otherwise flush the scheduler starting with this action.\n scheduler.flush(this);\n\n // HACK: In the past, this was returning `void`. However, `void` isn't a valid\n // `TimerHandle`, and generally the return value here isn't really used. So the\n // compromise is to return `0` which is both \"falsy\" and a valid `TimerHandle`,\n // as opposed to refactoring every other instanceo of `requestAsyncId`.\n return 0;\n }\n}\n", "import { AsyncScheduler } from './AsyncScheduler';\n\nexport class QueueScheduler extends AsyncScheduler {\n}\n", "import { QueueAction } from './QueueAction';\nimport { QueueScheduler } from './QueueScheduler';\n\n/**\n *\n * Queue Scheduler\n *\n * Put every next task on a queue, instead of executing it immediately\n *\n * `queue` scheduler, when used with delay, behaves the same as {@link asyncScheduler} scheduler.\n *\n * When used without delay, it schedules given task synchronously - executes it right when\n * it is scheduled. However when called recursively, that is when inside the scheduled task,\n * another task is scheduled with queue scheduler, instead of executing immediately as well,\n * that task will be put on a queue and wait for current one to finish.\n *\n * This means that when you execute task with `queue` scheduler, you are sure it will end\n * before any other task scheduled with that scheduler will start.\n *\n * ## Examples\n * Schedule recursively first, then do something\n * ```ts\n * import { queueScheduler } from 'rxjs';\n *\n * queueScheduler.schedule(() => {\n * queueScheduler.schedule(() => console.log('second')); // will not happen now, but will be put on a queue\n *\n * console.log('first');\n * });\n *\n * // Logs:\n * // \"first\"\n * // \"second\"\n * ```\n *\n * Reschedule itself recursively\n * ```ts\n * import { queueScheduler } from 'rxjs';\n *\n * queueScheduler.schedule(function(state) {\n * if (state !== 0) {\n * console.log('before', state);\n * this.schedule(state - 1); // `this` references currently executing Action,\n * // which we reschedule with new state\n * console.log('after', state);\n * }\n * }, 0, 3);\n *\n * // In scheduler that runs recursively, you would expect:\n * // \"before\", 3\n * // \"before\", 2\n * // \"before\", 1\n * // \"after\", 1\n * // \"after\", 2\n * // \"after\", 3\n *\n * // But with queue it logs:\n * // \"before\", 3\n * // \"after\", 3\n * // \"before\", 2\n * // \"after\", 2\n * // \"before\", 1\n * // \"after\", 1\n * ```\n */\n\nexport const queueScheduler = new QueueScheduler(QueueAction);\n\n/**\n * @deprecated Renamed to {@link queueScheduler}. Will be removed in v8.\n */\nexport const queue = queueScheduler;\n", "import { AsyncAction } from './AsyncAction';\nimport { AnimationFrameScheduler } from './AnimationFrameScheduler';\nimport { SchedulerAction } from '../types';\nimport { animationFrameProvider } from './animationFrameProvider';\nimport { TimerHandle } from './timerHandle';\n\nexport class AnimationFrameAction extends AsyncAction {\n constructor(protected scheduler: AnimationFrameScheduler, protected work: (this: SchedulerAction, state?: T) => void) {\n super(scheduler, work);\n }\n\n protected requestAsyncId(scheduler: AnimationFrameScheduler, id?: TimerHandle, delay: number = 0): TimerHandle {\n // If delay is greater than 0, request as an async action.\n if (delay !== null && delay > 0) {\n return super.requestAsyncId(scheduler, id, delay);\n }\n // Push the action to the end of the scheduler queue.\n scheduler.actions.push(this);\n // If an animation frame has already been requested, don't request another\n // one. If an animation frame hasn't been requested yet, request one. Return\n // the current animation frame request id.\n return scheduler._scheduled || (scheduler._scheduled = animationFrameProvider.requestAnimationFrame(() => scheduler.flush(undefined)));\n }\n\n protected recycleAsyncId(scheduler: AnimationFrameScheduler, id?: TimerHandle, delay: number = 0): TimerHandle | undefined {\n // If delay exists and is greater than 0, or if the delay is null (the\n // action wasn't rescheduled) but was originally scheduled as an async\n // action, then recycle as an async action.\n if (delay != null ? delay > 0 : this.delay > 0) {\n return super.recycleAsyncId(scheduler, id, delay);\n }\n // If the scheduler queue has no remaining actions with the same async id,\n // cancel the requested animation frame and set the scheduled flag to\n // undefined so the next AnimationFrameAction will request its own.\n const { actions } = scheduler;\n if (id != null && actions[actions.length - 1]?.id !== id) {\n animationFrameProvider.cancelAnimationFrame(id as number);\n scheduler._scheduled = undefined;\n }\n // Return undefined so the action knows to request a new async id if it's rescheduled.\n return undefined;\n }\n}\n", "import { AsyncAction } from './AsyncAction';\nimport { AsyncScheduler } from './AsyncScheduler';\n\nexport class AnimationFrameScheduler extends AsyncScheduler {\n public flush(action?: AsyncAction): void {\n this._active = true;\n // The async id that effects a call to flush is stored in _scheduled.\n // Before executing an action, it's necessary to check the action's async\n // id to determine whether it's supposed to be executed in the current\n // flush.\n // Previous implementations of this method used a count to determine this,\n // but that was unsound, as actions that are unsubscribed - i.e. cancelled -\n // are removed from the actions array and that can shift actions that are\n // scheduled to be executed in a subsequent flush into positions at which\n // they are executed within the current flush.\n const flushId = this._scheduled;\n this._scheduled = undefined;\n\n const { actions } = this;\n let error: any;\n action = action || actions.shift()!;\n\n do {\n if ((error = action.execute(action.state, action.delay))) {\n break;\n }\n } while ((action = actions[0]) && action.id === flushId && actions.shift());\n\n this._active = false;\n\n if (error) {\n while ((action = actions[0]) && action.id === flushId && actions.shift()) {\n action.unsubscribe();\n }\n throw error;\n }\n }\n}\n", "import { AnimationFrameAction } from './AnimationFrameAction';\nimport { AnimationFrameScheduler } from './AnimationFrameScheduler';\n\n/**\n *\n * Animation Frame Scheduler\n *\n * Perform task when `window.requestAnimationFrame` would fire\n *\n * When `animationFrame` scheduler is used with delay, it will fall back to {@link asyncScheduler} scheduler\n * behaviour.\n *\n * Without delay, `animationFrame` scheduler can be used to create smooth browser animations.\n * It makes sure scheduled task will happen just before next browser content repaint,\n * thus performing animations as efficiently as possible.\n *\n * ## Example\n * Schedule div height animation\n * ```ts\n * // html:
\n * import { animationFrameScheduler } from 'rxjs';\n *\n * const div = document.querySelector('div');\n *\n * animationFrameScheduler.schedule(function(height) {\n * div.style.height = height + \"px\";\n *\n * this.schedule(height + 1); // `this` references currently executing Action,\n * // which we reschedule with new state\n * }, 0, 0);\n *\n * // You will see a div element growing in height\n * ```\n */\n\nexport const animationFrameScheduler = new AnimationFrameScheduler(AnimationFrameAction);\n\n/**\n * @deprecated Renamed to {@link animationFrameScheduler}. Will be removed in v8.\n */\nexport const animationFrame = animationFrameScheduler;\n", "import { Observable } from '../Observable';\nimport { SchedulerLike } from '../types';\n\n/**\n * A simple Observable that emits no items to the Observer and immediately\n * emits a complete notification.\n *\n * Just emits 'complete', and nothing else.\n *\n * ![](empty.png)\n *\n * A simple Observable that only emits the complete notification. It can be used\n * for composing with other Observables, such as in a {@link mergeMap}.\n *\n * ## Examples\n *\n * Log complete notification\n *\n * ```ts\n * import { EMPTY } from 'rxjs';\n *\n * EMPTY.subscribe({\n * next: () => console.log('Next'),\n * complete: () => console.log('Complete!')\n * });\n *\n * // Outputs\n * // Complete!\n * ```\n *\n * Emit the number 7, then complete\n *\n * ```ts\n * import { EMPTY, startWith } from 'rxjs';\n *\n * const result = EMPTY.pipe(startWith(7));\n * result.subscribe(x => console.log(x));\n *\n * // Outputs\n * // 7\n * ```\n *\n * Map and flatten only odd numbers to the sequence `'a'`, `'b'`, `'c'`\n *\n * ```ts\n * import { interval, mergeMap, of, EMPTY } from 'rxjs';\n *\n * const interval$ = interval(1000);\n * const result = interval$.pipe(\n * mergeMap(x => x % 2 === 1 ? of('a', 'b', 'c') : EMPTY),\n * );\n * result.subscribe(x => console.log(x));\n *\n * // Results in the following to the console:\n * // x is equal to the count on the interval, e.g. (0, 1, 2, 3, ...)\n * // x will occur every 1000ms\n * // if x % 2 is equal to 1, print a, b, c (each on its own)\n * // if x % 2 is not equal to 1, nothing will be output\n * ```\n *\n * @see {@link Observable}\n * @see {@link NEVER}\n * @see {@link of}\n * @see {@link throwError}\n */\nexport const EMPTY = new Observable((subscriber) => subscriber.complete());\n\n/**\n * @param scheduler A {@link SchedulerLike} to use for scheduling\n * the emission of the complete notification.\n * @deprecated Replaced with the {@link EMPTY} constant or {@link scheduled} (e.g. `scheduled([], scheduler)`). Will be removed in v8.\n */\nexport function empty(scheduler?: SchedulerLike) {\n return scheduler ? emptyScheduled(scheduler) : EMPTY;\n}\n\nfunction emptyScheduled(scheduler: SchedulerLike) {\n return new Observable((subscriber) => scheduler.schedule(() => subscriber.complete()));\n}\n", "import { SchedulerLike } from '../types';\nimport { isFunction } from './isFunction';\n\nexport function isScheduler(value: any): value is SchedulerLike {\n return value && isFunction(value.schedule);\n}\n", "import { SchedulerLike } from '../types';\nimport { isFunction } from './isFunction';\nimport { isScheduler } from './isScheduler';\n\nfunction last(arr: T[]): T | undefined {\n return arr[arr.length - 1];\n}\n\nexport function popResultSelector(args: any[]): ((...args: unknown[]) => unknown) | undefined {\n return isFunction(last(args)) ? args.pop() : undefined;\n}\n\nexport function popScheduler(args: any[]): SchedulerLike | undefined {\n return isScheduler(last(args)) ? args.pop() : undefined;\n}\n\nexport function popNumber(args: any[], defaultValue: number): number {\n return typeof last(args) === 'number' ? args.pop()! : defaultValue;\n}\n", "export const isArrayLike = ((x: any): x is ArrayLike => x && typeof x.length === 'number' && typeof x !== 'function');", "import { isFunction } from \"./isFunction\";\n\n/**\n * Tests to see if the object is \"thennable\".\n * @param value the object to test\n */\nexport function isPromise(value: any): value is PromiseLike {\n return isFunction(value?.then);\n}\n", "import { InteropObservable } from '../types';\nimport { observable as Symbol_observable } from '../symbol/observable';\nimport { isFunction } from './isFunction';\n\n/** Identifies an input as being Observable (but not necessary an Rx Observable) */\nexport function isInteropObservable(input: any): input is InteropObservable {\n return isFunction(input[Symbol_observable]);\n}\n", "import { isFunction } from './isFunction';\n\nexport function isAsyncIterable(obj: any): obj is AsyncIterable {\n return Symbol.asyncIterator && isFunction(obj?.[Symbol.asyncIterator]);\n}\n", "/**\n * Creates the TypeError to throw if an invalid object is passed to `from` or `scheduled`.\n * @param input The object that was passed.\n */\nexport function createInvalidObservableTypeError(input: any) {\n // TODO: We should create error codes that can be looked up, so this can be less verbose.\n return new TypeError(\n `You provided ${\n input !== null && typeof input === 'object' ? 'an invalid object' : `'${input}'`\n } where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.`\n );\n}\n", "export function getSymbolIterator(): symbol {\n if (typeof Symbol !== 'function' || !Symbol.iterator) {\n return '@@iterator' as any;\n }\n\n return Symbol.iterator;\n}\n\nexport const iterator = getSymbolIterator();\n", "import { iterator as Symbol_iterator } from '../symbol/iterator';\nimport { isFunction } from './isFunction';\n\n/** Identifies an input as being an Iterable */\nexport function isIterable(input: any): input is Iterable {\n return isFunction(input?.[Symbol_iterator]);\n}\n", "import { ReadableStreamLike } from '../types';\nimport { isFunction } from './isFunction';\n\nexport async function* readableStreamLikeToAsyncGenerator(readableStream: ReadableStreamLike): AsyncGenerator {\n const reader = readableStream.getReader();\n try {\n while (true) {\n const { value, done } = await reader.read();\n if (done) {\n return;\n }\n yield value!;\n }\n } finally {\n reader.releaseLock();\n }\n}\n\nexport function isReadableStreamLike(obj: any): obj is ReadableStreamLike {\n // We don't want to use instanceof checks because they would return\n // false for instances from another Realm, like an + +

Requirements

+
    +
  • OpenGL 3.2
  • +
+

Further reading

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/voxedit/Screenshots/index.html b/voxedit/Screenshots/index.html new file mode 100644 index 0000000000..3a1bfab2c0 --- /dev/null +++ b/voxedit/Screenshots/index.html @@ -0,0 +1,1141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + Screenshots - vengi - voxel tools + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

Screenshots

+

image

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/voxedit/Usage/index.html b/voxedit/Usage/index.html new file mode 100644 index 0000000000..513bf10551 --- /dev/null +++ b/voxedit/Usage/index.html @@ -0,0 +1,1593 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + Usage - vengi - voxel tools + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+ +
+ + + +
+
+ + + + + + + +

Usage

+

Scene and edit mode

+

The scene mode is for animating and moving objects in the world - while the edit mode is for modifying voxels in there volumes.

+

You can toggle between those modes by pressing the TAB key in the default binding mode. See controls.

+

Reference position

+

The current reference position is rendered as a blue dot in the scene (in edit mode) and is used to e.g. define the position of where to put procedurally generated content like the trees. It is also used to define the position of where to paste your clipboard at. But also some modifier are using the reference position.

+

The reference position can be set by pressing enter while hovering a particular voxel - or by using the command setreferenceposition - see controls.

+

Brushes

+

voxedit-brushes

+

Shape brush

+

You can use several shapes to create voxels via spanning a bounding box in the viewport volume by pressing and holding the left mouse button.

+

Script brush

+

Execute scripts with this brush.

+

Plane brush

+

This allows you to extrude a whole plane.

+

Stamp brush

+

Load stamps in form of other voxel assets via drag and drop or right click in the asset panel

+

Line brush

+

Generate a line from the reference position to the current cursor position

+

Path brush

+

Generate a path from the reference position to the current cursor position by walking over existing voxels

+

Modifiers

+

The available brushes support several modifiers.

+

Place

+

Place new voxels in your volume.

+

Erase

+

Erase voxels from your volume. There is a shortcut when you are in the other modes to delete voxels: Press the right mouse button (at least in the default binding).

+

Override

+

Override existing voxels with a new color - but also place new voxels.

+

Paint

+

Other than override this modifier only changes the color of existing voxels.

+

Path

+

This modifier puts voxels onto a path using the reference position as start and the position you clicked at as end. This needs solid voxels to work on. This doesn't work in empty volumes.

+

Line

+

A line will just draw a line from the reference position to the position you clicked at. See the bindings window (Edit / Bindings) for the binding to place the reference position in the scene (the ).

+

Color picker

+

You can either use it from the modifiers panel or by default with the key p to pick the color from the current selected voxel.

+

Select

+

Span an selection box to operate in. Either for copy/pasting or to limit a certain action (like the script execution). Don't forget to unselect (Select -> Select none) before being able to operate on the whole volume again.

+

Asset

+

voxedit-asset

+

This is an online and local asset browser for supported formats from gitlab, github, custom urls and apis

+

Camera

+

voxedit-camera

+

Allow you to create camera nodes and modify the current camera values

+

Console

+

voxedit-console

+

See the console logs. Also see the configuration docs for changing the log level

+

LSystem

+

voxedit-lsystem

+

Generate l-system voxel data

+

Memento

+

voxedit-memento

+

Visualizes the undo/redo states

+

Node Inspector

+

voxedit-nodeinspector-edit

+

The node inspector in edit mode can change the size and the position of the voxel volume. Usually you don't want to modify the position of the volume in edit mode, but in scene mode. See below.

+

voxedit-nodeinspector-scene

+

The node inspector in scene mode allows one to change the transforms of the scene graph node. You can rotate, scale and move the node in the world to arrange your objects in your scene.

+

Palette

+

voxedit-palette

+

The palette panel visualized the colors for a node. The colors can get re-ordered and changed, as well as drag-and-dropped to change the slots. See the dedicated palette docs for more details.

+

You can re-order the palette colors by Hue, Saturation, Brightness or CIELab rules.

+

Direct LoSpec palette import is possible and next to LoSpec you can import or export a lot other palette formats, too.

+

Renderer

+

voxedit-rendersettings

+

VoxEdit has built-in support for the yocto pathtracer - see material docs for details.

+

You can configure the pathtracer options here.

+

Scene View

+

voxedit-scene

+

Here you can see all the nodes and their hierarchy in the scene. You can change the parents by using drag and drop and use a actions from the context menu for each nodes.

+

You can hide or show nodes from the viewport or lock them to execute some actions on all locked nodes at the same time.

+

It's also possible to use the play button to loop through all nodes in your scene. Make sure to check out the Model animation speed in the options menu to change the animation speed.

+

Next to these options you can create new nodes - e.g. model or group nodes here.

+

Scripts

+

voxedit-scripts

+

Here you can execute the lua scripts in the editor to modify your scene or the current active volume (depends on the script).

+

The arguments given in the script are visualized here. This allows you to extend the script panel with your own fields to execute the scripts.

+

Animations

+

voxedit-animation

+

Here you can change or create or delete animations from a scene.

+

voxedit-timeline

+

The timeline visualized the key frames for each node for each animation.

+

Tools

+

voxedit-tools-scene

+

The scene and the edit mode have different tools for you. You can resize, crop, flip or rotate voxels in edit mode or duplicate, center pivot, align or delete nodes in scene mode.

+

Tree

+

voxedit-trees

+

Here you can generate a lot of different tree types - all with their own set of configuration options.

+

Viewport

+

voxedit-viewport

+

The viewport can get changed to scene and edit mode. You can switch the cameras from orthogonal to projection, you can record videos of your scene or let the camera automatically rotate.

+ + + + + + + + + + + + + +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + \ No newline at end of file