diff --git a/README.md b/README.md
new file mode 100644
index 0000000..66fa177
--- /dev/null
+++ b/README.md
@@ -0,0 +1,138 @@
+# Studio Lite
+A web viewer for _Roblox[^1]_ place and model files, with a gorgeous interface.
+
+
+
+## This is still in alpha
+Expect bugs and unfinished features
+
+## Acknowledgements
+Studio Lite uses the [rbxBinaryParser](https://github.com/MrSprinkleToes/rbxBinaryParser) library by [MrSprinkleToes](https://github.com/MrSprinkleToes). Additionally, some code, mostly mesh parsing code, is taken from [roblox-in-webbrowser](https://github.com/MrSprinkleToes/roblox-in-webbrowser) and [roblox-web-viewer](https://github.com/MrSprinkleToes/roblox-web-viewer).
+
+These other libraries are also used:
+* [THREE.js](https://threejs.org/) for rendering
+* [7.css](https://khang-nd.github.io/7.css/) for that gorgeous user interface
+* [jsTree](https://www.jstree.com/) for displaying interactive trees
+
+## Included assets
+For demo purposes, Studio Lite includes some downloaded assets in the `asset/` directory and some place files in `examples/`. Please note that these files are copyright of their respective owners.
+
+The _Roblox[^1]_ Studio icons, used in the title bar and Explorer view, and stored under the `content/icons/` directory, are copyright of Roblox Corporation.
+
+Other assets within the `content/` directory, as well as the `favicon.ico` in the root of the source tree, are also copyright of Roblox Corporation.
+
+Studio Lite is not affiliated with, or endorsed by Roblox Corporation.
+
+## Features
+### Read RBXL and RBXM files
+
+
+
+
+These file types can be opened by Studio Lite. Keep in mind that there is no support for files in the XML format (though it is a high priority), so you'll encounter issues especially with older places (which often have RBXL extension but contain XML data).
+
+You can use the Explorer and Properties views to browse the contents of the DataModel. You can click on scripts to view their code. Parts selected in the Explorer are highlighted in the renderer, and you can also zoom to the currently selected part.
+
+### Asset support
+
+
+
+
+
+
+
+Studio Lite can load decals and meshes accurately! In light of _Roblox[^1]_'s API changes, you must manually download assets using AssetDelivery and place them in the `asset/` folder. This is made easy as you get a list of all missing assets along with their type upon loading a Place.
+
+### Perfect for renders
+
+
+You can render the current view to a PNG file at any resolution you want. Do you want [a top-down view of Crossroads in 8K resolution](images/crossroads8k.png)? No problem.
+
+_Also, here's [an 8K render of the Suburban map](images/suburban8k.png), for those interested. Caution, large file, about 2 MB!_
+
+
+
+
+You can also hide the skybox, leaving a transparent background. This is useful for thumbnails. You can open a model file, hide the skybox and render a 420x420 image. This will produce a thumbnail similar to those on the _Roblox[^1]_ website. (see examples above)
+
+## How to use
+Studio Lite makes many network requests, so I've refrained from hosting a live demo in fear of rate limits. It is very easy to run yourself, though, being a fully client-side application.
+
+All you need is a decent computer and an HTTP server. Download these files (you can clone the repo or just download as ZIP) and run a web server in the root directory.
+
+If you have Python installed, it's very easy to run a local server: `python -m http.server`. Then you can access Studio Lite on `localhost:8000`. Otherwise, use your preferred method of starting up a quick server (you can use Node.js or PHP).
+
+If you have any issues or are unsatisfied with your experience, please open an issue!
+
+## How to download assets
+Read the first section to learn how the download process works. Then read the second section, which shows you how to get the AssetIDs you need to download.
+
+### The download process itself
+Due to _Roblox[^1]_ API changes, you must be logged in to access AssetDelivery. Therefore, you must be signed into your _Roblox[^1]_ account on the browser.
+
+While my experimentation has shown that you can download _Roblox[^1]_-owned assets anonymously, authentication is required otherwise.
+
+To download an asset, copy the Asset ID (the long number) and navigate to the URL below, first replacing `[assetid]` with the Asset ID you've copied.
+
+AssetDelivery URL: `https://assetdelivery.roblox.com/v1/asset?id=[assetid]`
+
+This will download a file with a random name. Rename it like you're told in the second section.
+
+### Downloading all assets in a Place
+1. Open a Place containing un-downloaded assets.
+2. Look in the console. If it says that there are missing assets, then go to `File > Missing assets` like it tells you.
+3. Browse the list. For each line, if it is a decal, download the asset and rename it to `[assetid].png`, where `[assetid]` is the AssetID. If it is a mesh, do the same but use `.mesh` extension. Download all of the mesh's textures (if any) with the `.png` extension.
+4. If you're done, reload the page and open your Place again. You shouldn't get the console warning, and `File > Missing assets` should say all assets have loaded successfully.
+
+### Possible errors while downloading
+You may encounter some errors during asset downloads, which will get you a JSON response.
+
+##### Authentication required / User not authorized
+JSON response: `{"errors":[{"code":0,"message":"Authentication required to access Asset."}]}`
+
+Alternatively: `{"errors":[{"code":1,"message":"User is not authorized to access Asset."}]}`
+
+You need to log in to download the asset. If you're logged in on the _Roblox[^1]_ website, but still get this error, the asset could be private or something. Idk.
+
+##### Requested asset is archived
+JSON response: `{"errors":[{"code":0,"message":"Requested asset is archived"}]}`
+
+Exactly what it says on the tin. You're not getting the asset :)
+
+You could put a placeholder image in its place, to silence the Missing assets error...
+
+## Roadmap (WIP)
+- [ ] Fix bugs
+- - [ ] Issues with mesh Scale and Offset (see comments in `StudioLiteRenderer.renderPart`, around where it says `// Give meshes special treatment`)
+- - [ ] Upside down decals (see paintings in suburban house and piano in western lounge)
+- - [ ] Merry-go-round in Suburban playground is broken (base renders sideways)
+- [ ] Support XML format
+- [ ] Support all primitive shapes
+- - [x] Block
+- - [x] Ball
+- - [x] Wedge
+- - [x] Cylinder (for the most part, see bugs)
+- - [ ] Truss
+- [ ] Cool effects
+- - [ ] Show light for parts with [Light](https://create.roblox.com/docs/reference/engine/classes/Light) children
+- - [ ] ParticleEmitter support
+- - [ ] Fire and Smoke
+- - [ ] Glow for parts with Neon material
+- [ ] Completionist questline (impossible)
+- - [ ] Support part materials
+- - [ ] Basic support for rendering Smooth Terrain (really, this is a problem of reading terrain voxels, which might very well be impossible)
+- - [ ] hmm... ~~Edit Mode~~ (lol no... but maybe one day?)
+
+## Licensing
+Studio Lite is **MIT licensed**. However, the following files and directories in the source tree are exempt from licensing:
+* `asset/` (non-free assets)
+* `content/` (non-free assets)
+* `examples/` (non-free assets)
+* `favicon.ico` (non-free asset)
+* `app/rendering/mesh/MeshParser.js` (contains mesh parsing code from `roblox-in-webbrowser`/`roblox-web-viewer`, which are unlicensed. Please see **Acknowledgements**)
+* `app/controls/FlyCamera.js` (contains camera code from `roblox-web-viewer`, which is unlicensed. See **Acknowledgements**)
+
+## How you can help
+Contributions are welcome! You don't need to write any code, I'll be very happy if you told me what you didn't like, or what you'd like added.
+
+[^1]: _Roblox_ is a registered trademark of Roblox Corporation.
\ No newline at end of file
diff --git a/app/app.css b/app/app.css
new file mode 100644
index 0000000..86206c4
--- /dev/null
+++ b/app/app.css
@@ -0,0 +1,241 @@
+body {
+ margin: 0;
+ font-family: sans-serif;
+ --window-background-color: #805ba5;
+}
+
+dialog {
+ background-color: #ffffffff;
+ border: none;
+ padding: 0;
+}
+
+.rightPane {
+ height: calc(100vh - 29px - 29px - 27px + 4px);
+ width: 400px;
+ position: absolute;
+ top: 56px;
+ left: calc(100vw - 400px);
+ background-color: white;
+ overflow: hidden;
+ z-index: 2;
+}
+
+.console {
+ position: absolute;
+ height: calc(200px - 22px);
+ width: calc(100vw - 400px);
+ top: calc(100vh - 206px);
+ background-color: white;
+ overflow: hidden;
+}
+
+.title {
+ height: 20px;
+ padding: 5px;
+ border-bottom: 5px solid black;
+ text-align: center;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ overflow: hidden;
+}
+
+.title-bar-text {
+ width: 100%;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ overflow: hidden;
+}
+
+.tree, .tree2, .properties {
+ --height: calc(50vh - 29px - 14.5px - 17px - 13.5px - 6px + 2px);
+ overflow: scroll;
+ width: 385px;
+}
+
+.tree, .tree2 {
+ height: calc(var(--height) - 23px);
+}
+
+.properties {
+ height: var(--height);
+}
+
+table {
+ min-width: 100%;
+}
+
+th, td {
+ text-align: left;
+}
+
+/* taken from 7.css "highlighted" rule */
+table > tbody > tr:hover {
+ background: var(--item-highlighted-background);
+ border: var(--listview-border) var(--item-highlighted-border);
+ border-radius: var(--border-radius);
+}
+
+.message, .onboarding {
+ position: absolute;
+ width: calc(100vw - 400px);
+ height: calc(100vh - 200px - 29px - 29px);
+ background-color: rgba(221, 221, 221, .5);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ color: white;
+ font-size: 22px;
+ text-shadow: 2px 0 #000, -2px 0 #000, 0 2px #000, 0 -2px #000,
+ 1px 1px #000, -1px -1px #000, 1px -1px #000, -1px 1px #000;
+ cursor: url(../content/Textures/ArrowFarCursor.png), auto;
+}
+
+.onboarding {
+ flex-direction: column;
+}
+
+.onboarding > h1 {
+ width: fit-content;
+ font-size: 44px;
+}
+
+.onboarding > button {
+ font-size: 40px;
+}
+
+.onboarding > :is(button, input, label),
+#stats, #stats > * {
+ cursor: url(../content/Textures/ArrowCursor.png), auto !important;
+}
+
+.editor {
+ position: absolute;
+ width: calc(100vw - 410px);
+ height: calc(100vh - 215px - 29px - 29px);
+ background-color: white;
+ color: black;
+ padding: 5px;
+ font-size: 22px;
+ font-family: monospace;
+ overflow: scroll;
+ z-index: 10001;
+}
+
+.log {
+ height: calc(100% - 35px);
+ width: calc(100% - 12px);
+ overflow: scroll;
+ font-family: monospace;
+ font-size: 18px;
+}
+
+pre {
+ border: none;
+}
+
+body > .title-bar {
+ position: absolute;
+ width: calc(100vw - 14px);
+ z-index: 10002;
+ top: 0;
+ left: 0;
+}
+
+body > ul[role=menubar] {
+ position: absolute;
+ top: 29px;
+ left: 0;
+ width: 100vw;
+ z-index: 10002;
+}
+
+canvas {
+ margin-top: 58px;
+ cursor: url(../content/Textures/ArrowFarCursor.png), auto;
+}
+
+.status-bar {
+ position: absolute;
+ top: calc(100vh - 27px);
+ width: calc(100vw - 2px);
+ margin: 0;
+ z-index: 3;
+}
+
+.flexcenter {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.status-bar-field > *[role=progressbar] {
+ width: 100%;
+}
+
+.marquee.error:before {
+ background: linear-gradient(to right,transparent,var(--progress-color-error),transparent 35%);
+}
+
+/* yellow is not for paused, but for fetching :) */
+.marquee.paused:before {
+ background: linear-gradient(to right,transparent,var(--progress-color-paused),transparent 35%);
+}
+
+.title-bar-icon {
+ padding-left: 20px;
+ background-repeat: no-repeat;
+ background-position: left bottom;
+}
+
+.icon-studio {
+ background-image: url(../content/icons/StudioService.png);
+}
+
+#notepad .window-body {
+ width: 700px;
+ height: 400px;
+}
+
+#notepad textarea {
+ width: 100%;
+ height: calc(100% - 29px);
+ resize: none;
+ font-size: 16px;
+ font-family: monospace;
+}
+
+.title-bar, .status-bar-field {
+ height: 21px;
+}
+
+*[role=menubar] {
+ height: 29px;
+}
+
+.status-bar {
+ height: 25px;
+}
+
+.title-bar, *[role=menubar], *[role=tablist], .tree2, .message, .onboarding, .tree, td:first-child, .status-bar {
+ user-select: none;
+}
+
+.menu[role=tablist] {
+ height: 23px;
+}
+
+.github {
+ color: black;
+ padding-left: 5px !important;
+ padding-right: 5px !important;
+ text-shadow: 0 0 10px #fff,0 0 10px #fff,0 0 10px #fff,0 0 10px #fff,0 0 10px #fff,0 0 10px #fff,0 0 10px #fff,0 0 10px #fff;
+}
+
+.github::before {
+ background: none !important;
+}
+
+.title-bar.active .github, .title-bar.active .github::before {
+ background: var(--control-background) !important;
+}
\ No newline at end of file
diff --git a/app/app.js b/app/app.js
new file mode 100644
index 0000000..e76ae53
--- /dev/null
+++ b/app/app.js
@@ -0,0 +1,697 @@
+import Stats from './thirdparty/three/stats.module.js';
+import {
+ StudioLiteRenderer,
+ partClasses
+} from './rendering/StudioLiteRenderer.js';
+import {
+ sleep,
+ rgbToHex
+} from './etc/Helpers.js';
+
+const titleBar = document.body.querySelector(".title-bar");
+const sstat = document.body.querySelector("#menuitem-stats");
+const saxes = document.body.querySelector("#menuitem-axes");
+const sbx2 = document.body.querySelector("#menuitem-hoverbox");
+const sbox = document.body.querySelector("#menuitem-selectionbox");
+const szoom = document.body.querySelector("#menuitem-zoomto");
+const ssky = document.body.querySelector("#menuitem-skybox");
+const log = document.body.querySelector(".log");
+const msg = document.body.querySelector(".message");
+const editor = document.body.querySelector(".editor");
+const bar = document.body.querySelector(".status-bar-field > *[role=progressbar]");
+const status = document.body.querySelector(".status-bar-field.status");
+const menurender = document.body.querySelector("#menuitem-renderimage");
+menurender.setAttribute("aria-disabled", true);
+let sal = document.body.querySelector(".onboarding");
+let statusLastText = "Ready";
+szoom.setAttribute("aria-disabled", true);
+
+var jsTreeData = [];
+
+const threeIcons = {
+ "AmbientLight": "Lighting",
+ "DirectionalLight": "Lighting",
+ "Mesh": "Part",
+ "BoxHelper": "SelectionBox"
+}
+
+function threeNodeToTreeData(node) {
+ let data = [];
+ for (const child of node) {
+ data.push({
+ node: child,
+ text: child.name.length > 0 ? child.name : child.type,
+ icon: `content/icons/${threeIcons[child.type] ? threeIcons[child.type] : "BaseScript"}.png`,
+ children: threeNodeToTreeData(child.children)
+ });
+ }
+ return data;
+}
+let treeRefresh2 = () => {};
+
+let renderer = new StudioLiteRenderer({
+ get width() {
+ return window.innerWidth - 400;
+ },
+ get height() {
+ return window.innerHeight - 200 - 29 - 34;
+ },
+ sharedFunctions: {
+ print: print,
+ treeRefresh2: () => { treeRefresh2(); }
+ },
+ sharedObjects: {
+ jsTreeData: jsTreeData
+ }
+});
+document.body.appendChild(renderer.domElement);
+
+const stats = Stats();
+document.body.appendChild(stats.dom);
+stats.dom.id = "stats";
+stats.dom.style.display = "none";
+if (sstat.checked) stats.dom.style.display = "block";
+sstat.addEventListener("input", () => {
+ if (sstat.checked) {
+ stats.dom.style.display = "block";
+ } else {
+ stats.dom.style.display = "none";
+ }
+});
+
+let rendering = false;
+var animate = function () {
+ if (rendering) renderer.render();
+ stats.update();
+}
+
+renderer.setAnimationLoop(animate);
+
+function print(s) {
+ const date = new Date();
+ const el = document.createElement("span");
+ const br = document.createElement("br");
+ if (typeof s === "object") s = JSON.stringify(s);
+ el.innerText = `${date.toLocaleTimeString("us")}.${date.getMilliseconds().toString().padStart(3, '0')} - ${s}`;
+ log.appendChild(el);
+ log.appendChild(br);
+ log.scrollTo(0, log.scrollHeight);
+}
+
+window.console.log = (...args) => {
+ let s = "";
+ for (let t of args) {
+ if (typeof t === "object") t = JSON.stringify(t);
+ s += t + " ";
+ }
+ s = s.substring(0, s.length - 1).split("\n");
+ for (const t of s) print(t);
+}
+
+function setTitle(t) {
+ t = `${t} - Studio Lite (alpha-1)`;
+ document.title = t;
+ titleBar.querySelector(".title-bar-text").innerText = t;
+}
+
+let file = "";
+
+let placeName = "Start Page";
+
+function barError() {
+ bar.classList.add("error");
+}
+
+function objToTreeData(obj) {
+ let keys = Object.keys(obj);
+ let data = [];
+ for (let key of keys) {
+ let d = {};
+ d.text = key;
+ if (typeof obj[key] === "object") {
+ d.children = objToTreeData(obj[key]);
+ } else {
+ d.text += ": " + obj[key].toString();
+ d.children = [];
+ }
+ data.push(d);
+ }
+ return data;
+}
+
+async function start() {
+ bar.className = "marquee paused";
+ status.innerText = "Busy";
+ rendering = false;
+ titleBar.classList.add("active");
+ try { document.body.removeChild(document.body.querySelector("#remoteload")); } catch (ignored) {};
+ document.body.removeChild(sal);
+ sal = null;
+ msg.querySelector("span").innerText = "Loading Place. Please wait...";
+ msg.style.display = "flex";
+ const url = new URL(file, window.location.href);
+ try {
+ if (typeof file === "string") {
+ print (`DataModel Loading ${url}`);
+ placeName = url.href.split("/").pop();
+ status.innerText = `Fetching ${placeName}`;
+ let fileData = null;
+ try {
+ fileData = await fetch(url);
+ if (fileData.status !== 200) throw new Error();
+ } catch (ignored) {
+ print('Failed to fetch. Please reload.');
+ barError();
+ throw new Error("Failed to fetch. Please reload.");
+ }
+ window.data = await fileData.arrayBuffer();
+ // we read it successfully, make the bar green from now on!
+ bar.classList.remove("paused");
+ status.innerText = `Loading ${placeName}`;
+ await sleep(200);
+ } else {
+ print (`DataModel Loading ${file.name}`);
+ placeName = file.name;
+ status.innerText = `Fetching ${placeName}`;
+ window.data = await file.arrayBuffer();
+ // we read it successfully, make the bar green from now on!
+ bar.classList.remove("paused");
+ status.innerText = `Loading ${placeName}`;
+ await sleep(200);
+ }
+ } catch (ignored) {
+ print('The file could not be read. Please reload.');
+ barError();
+ throw new Error("The file could not be read. Please reload.");
+ }
+ setTitle(placeName);
+ statusLastText = status.innerText;
+ try {
+ await renderer.loadPlace(window.data);
+ } catch (ignored) {
+ print('The file could not be read. Please reload.');
+ barError();
+ throw new Error("The file could not be read. Please reload.");
+ }
+ delete window.data;
+
+ renderer.toggleAxes(saxes.checked);
+ saxes.addEventListener("input", () => {
+ renderer.toggleAxes(saxes.checked);
+ treeRefresh2();
+ })
+
+ renderer.showSkybox(ssky.checked);
+ ssky.addEventListener("input", () => {
+ renderer.showSkybox(ssky.checked);
+ })
+ renderer.useSelectionBox = sbox.checked;
+ sbox.addEventListener("input", () => {
+ renderer.useSelectionBox = sbox.checked;
+ renderer.removeSelectionBoxesIfNeeded();
+ })
+ renderer.useSelectionBox2 = sbx2.checked;
+ sbx2.addEventListener("input", () => {
+ renderer.useSelectionBox2 = sbx2.checked;
+ renderer.removeSelectionBoxesIfNeeded();
+ })
+
+ $(".tree").jstree({'core' : {
+ 'data' : jsTreeData
+ }});
+
+ let treeRef = $(".tree").jstree(true);
+
+ const zoomTo = () => {
+ try {
+ const instance = treeRef.get_selected(true)[0].original.instance;
+ if (partClasses.indexOf(instance.ClassName) !== -1) {
+ try {
+ renderer.zoomTo(instance.CFrame || instance.CoordinateFrame, false);
+ } catch (ignored) {};
+ }
+ } catch (ignored) {};
+ };
+
+ szoom.setAttribute("aria-disabled", true);
+ szoom.addEventListener("click", zoomTo);
+ document.addEventListener("keydown", e => {
+ switch (e.code) {
+ case "KeyF":
+ zoomTo();
+ break;
+ }
+ });
+
+ const hiddenProperties = ["Children", "Source", "CollisionGroupData", "PhysicsGrid", "SmoothGrid", "MaterialColors"];
+ const dropdownProperties = [
+ "BackSurface", "BackSurfaceInput", "BottomSurfaceInput",
+ "FrontSurface", "FrontSurfaceInput", "LeftSurface",
+ "LeftSurfaceInput", "Material", "RightSurface",
+ "RightSurfaceInput", "TopSurface", "TopSurfaceInput",
+ "Shape", "Classic", "DevCameraOcclusionMode",
+ "DevComputerCameraMovementMode", "DevComputerMovementMode", "DevTouchCameraMovementMode",
+ "DevTouchMovementMode", "EnableDynamicHeads", "GameSettingsAvatar",
+ "GameSettingsR15Collision", "ScreenOrientation", "VirtualCursorMode",
+ "Technology", "VolumetricAudio", "AmbientReverb",
+ "ClientAnimatorThrottling", "InterpolationThrottling", "InterpolationThrottling",
+ "MeshPartHeadsAndAccessories", "ModelStreamingMode", "PhysicsSteppingMethod",
+ "RejectCharacterDeletions", "ReplicateInstanceDestroySetting", "Retargeting",
+ "StreamOutBehavior", "StreamingIntegrityMode", "Face",
+ "RenderFidelity", "CameraType", "FieldOfViewMode",
+ "RunContext", "SelectionBehaviorDown", "SelectionBehaviorLeft",
+ "SelectionBehaviorRight", "SelectionBehaviorUp", "SizingMode",
+ "ZIndexBehavior", "RollOffMode", "AutomaticSize",
+ "BorderMode", "SizeConstraint", "Style",
+ "LevelOfDetail", "HorizontalAlignment", "VerticalAlignment",
+ "TextXAlignment", "TextYAlignment", "ScaleType",
+ "AspectType", "DominantAxis", "BottomSurface",
+ "CollisionType", "DisplayDistanceType", "HealthDisplayType",
+ "NameOcclusion", "RigType"
+ ];
+ const colorProperties = [
+ "Color3", "TintColor", "Ambient", "ColorShift_Top", "ColorShift_Bottom",
+ "FogColor", "OutdoorAmbient", "BackgroundColor3", "BorderColor3", "ImageColor3",
+ "TextColor3", "PlaceholderColor3", "TextStrokeColor3"
+ ];
+
+ function parsePropValue(prop, value) {
+ switch (prop) {
+ default:
+ return value.toString();
+ }
+ }
+
+ $('.tree').on("changed.jstree", async function (e, data) {
+ const original = treeRef.get_node(data.selected[0]).original;
+ let instance = original.instance;
+ (async () => {
+ if (original.id) renderer.updateSelectionBox(renderer.getThreeId(original.id));
+ })();
+ if (instance.CFrame) renderer.setAxesPosition(instance.CFrame.Position.X, instance.CFrame.Position.Y, instance.CFrame.Position.Z);
+ if (partClasses.indexOf(instance.ClassName) !== -1 && (instance.CFrame || instance.CoordinateFrame))
+ szoom.removeAttribute("aria-disabled");
+ else
+ szoom.setAttribute("aria-disabled", true);
+ document.body.querySelector("#propertiesTitle").innerText = `Properties - ${instance.ClassName} "${instance.Name}"`;
+ let keys = Object.keys(instance);
+ let objviewIndex = 0;
+ let treedatatemp = null;
+ propTable.innerHTML = "";
+ propSpinner.style.display = "block";
+ propTable.style.display = "none";
+ if (["Script", "LocalScript", "ModuleScript"].indexOf(instance.ClassName) !== -1) {
+ setTitle(instance.Name);
+ editor.style.display = "block";
+ editor.innerHTML = "";
+ const pre = document.createElement("pre");
+ pre.innerText = instance.Source;
+ editor.appendChild(pre);
+ rendering = false;
+ } else {
+ rendering = true;
+ setTitle(placeName);
+ editor.innerHTML = "";
+ editor.style.display = "none";
+ }
+ for (let key of keys) {
+ if (hiddenProperties.indexOf(key) === -1) {
+ let row = document.createElement("tr");
+ let one = document.createElement("td");
+ let two = document.createElement("td");
+ one.innerText = key;
+ if (typeof instance[key] === "object") {
+ let objview = document.createElement("div");
+ if (colorProperties.indexOf(key) !== -1) {
+ const val = instance[key];
+ let clr = document.createElement("input");
+ clr.type = "color";
+ clr.disabled = true;
+ clr.value = rgbToHex(val.R*255, val.G*255, val.B*255);
+ two.appendChild(clr);
+ }
+ two.appendChild(objview);
+ objview.id = `objview-${objviewIndex}`;
+ treedatatemp = {'core' : {
+ 'data' : objToTreeData(instance[key])
+ }};
+ } else if ([true, false].indexOf(instance[key]) !== -1) {
+ let chk = document.createElement("input");
+ chk.disabled = "true";
+ chk.type = "checkbox";
+ chk.id = "checkbox-" + key;
+ if (instance[key]) chk.checked = true;
+ let txt = document.createElement("label");
+ txt.for = "checkbox-" + key;
+ two.appendChild(chk);
+ two.appendChild(txt);
+ } else if (typeof instance[key] === "number") {
+ let nr = document.createElement("input");
+ nr.type = "number";
+ nr.min = instance[key];
+ nr.max = instance[key];
+ nr.value = instance[key];
+ nr.disabled = true;
+ two.appendChild(nr);
+ } else if (dropdownProperties.indexOf(key) !== -1) {
+ let sel = document.createElement("select");
+ let opt = document.createElement("option");
+ opt.innerText = instance[key];
+ opt.selected = true;
+ sel.disabled = true;
+ sel.appendChild(opt);
+ two.appendChild(sel);
+ } else {
+ two.innerText = parsePropValue(key, instance[key]);
+ }
+ row.appendChild(one);
+ row.appendChild(two);
+ propTable.appendChild(row);
+ if (treedatatemp !== null) {
+ $(`#objview-${objviewIndex}`).jstree(treedatatemp);
+ objviewIndex++;
+ treedatatemp = null;
+ }
+ }
+ }
+ propSpinner.style.display = "none";
+ propTable.style.display = "table-row-group";
+ });
+
+ rendering = true;
+ msg.style.display = "none";
+ statusLastText = "Busy";
+ status.innerText = "Busy";
+
+ async function postQueue() {
+ if (renderer.mAssetManager.hasRbxGameAsset) print("This Place contains rbxgameasset:// paths. Studio Lite cannot resolve them, as they are relative to the published game!");
+ if (renderer.mAssetManager.computeMissingAssetsList()) print("Some assets failed to load! See File > Missing assets for more info.");
+ treeRefresh2();
+ menurender.removeAttribute("aria-disabled");
+ menurender.addEventListener("click", () => {
+ rendering = false;
+ const dlg = document.body.querySelector("#render");
+ const btn = dlg.querySelector("#dorender");
+ const img = dlg.querySelector("img");
+ const width = dlg.querySelector("#renderwidth");
+ const height = dlg.querySelector("#renderheight");
+ width.value = renderer.conf.width;
+ height.value = renderer.conf.height;
+ let doRender = () => {
+ img.src = renderer.renderImage(width.value, height.value);
+ }
+ let close = () => {
+ dlg.removeEventListener("cancel", close);
+ dlg.querySelector(".close").removeEventListener("click", close);
+ dlg.querySelector(".ok").removeEventListener("click", close);
+ btn.removeEventListener("click", doRender);
+ img.src = "";
+ dlg.close();
+ titleBar.classList.add("active");
+ rendering = true;
+ }
+ dlg.addEventListener("cancel", close);
+ titleBar.classList.remove("active");
+ dlg.showModal();
+ dlg.querySelector(".close").addEventListener("click", close);
+ dlg.querySelector(".ok").addEventListener("click", close);
+ btn.addEventListener("click", doRender);
+ });
+ }
+
+ let waitForQueuedOps = setInterval(() => {
+ if (renderer.queueSize === 0) {
+ clearInterval(waitForQueuedOps);
+ waitForQueuedOps = null;
+ bar.className = "animate";
+ statusLastText = "Ready";
+ status.innerText = "Ready";
+ postQueue();
+ }
+ }, 1000);
+}
+
+sal.style.display = "flex";
+
+const menuabout = document.body.querySelector("#menuitem-about");
+document.body.querySelector("#menuitem-reload").addEventListener("click", () => window.location.reload());
+menuabout.addEventListener("click", () => {
+ const dlg = document.body.querySelector("#about");
+ let close = () => {
+ dlg.removeEventListener("cancel", close);
+ dlg.querySelector(".close").removeEventListener("click", close);
+ dlg.querySelector(".ok").removeEventListener("click", close);
+ dlg.querySelector(".view-notice").removeEventListener("click", viewNotice);
+ dlg.close();
+ titleBar.classList.add("active");
+ }
+ dlg.addEventListener("cancel", close);
+ titleBar.classList.remove("active");
+ dlg.showModal();
+ dlg.querySelector(".close").addEventListener("click", close);
+ dlg.querySelector(".ok").addEventListener("click", close);
+ dlg.querySelector(".view-notice").addEventListener("click", viewNotice);
+});
+
+const menuassets = document.body.querySelector("#menuitem-missingassets");
+menuassets.addEventListener("click", () => {
+ openNotepad("missing_assets.txt", renderer.mAssetManager.missingAssets);
+});
+
+function viewNotice() {
+ openNotepad("notice.txt", `Studio Lite is built upon MrSprinkleToes' rbxBinaryParser [https://github.com/MrSprinkleToes/rbxBinaryParser].
+Additionally, some code from roblox-in-webbrowser [https://github.com/MrSprinkleToes/roblox-in-webbrowser] and roblox-web-viewer [https://github.com/MrSprinkleToes/roblox-web-viewer] is used.
+Please see the README for more information.
+
+The THREE.js library [https://threejs.org] is used for rendering the game view.
+The THREE.js add-ons PointerLockControls and Stats are also included within the application.
+
+jsTree [https://www.jstree.com] is used for displaying interactive trees in the Explorer and Properties views.
+
+7.css [https://khang-nd.github.io/7.css] is used for theming the user interface.
+
+Roblox Studio icons and other assets stored within the content/ directory, as well as the favicon.ico, are Copyright © Roblox Corporation.
+The assets saved within the asset/ directory and the example files in examples/ are copyright of their respective owners.
+
+Studio Lite is not affiliated in any way, shape or form with Roblox Corporation.`, true);
+}
+
+function openNotepad(fileName, text, nested = false) {
+ const dlg = document.body.querySelector("#notepad");
+ const title = dlg.querySelector("#dialog-title");
+ const textarea = dlg.querySelector("textarea");
+ title.innerText = `${fileName} - Notepad`;
+ textarea.value = text;
+ let close = () => {
+ dlg.removeEventListener("cancel", close);
+ dlg.querySelector(".close").removeEventListener("click", close);
+ dlg.close();
+ title.innerText = "Notepad";
+ textarea.innerText = "";
+ if (!nested) titleBar.classList.add("active");
+ }
+ dlg.addEventListener("cancel", close);
+ titleBar.classList.remove("active");
+ dlg.showModal();
+ dlg.querySelector(".close").addEventListener("click", close);
+}
+
+const menuchangelog = document.body.querySelector("#menuitem-changelog");
+menuchangelog.addEventListener("click", () => openNotepad("changelog.txt", `Studio Lite Changelog
+
+New in alpha-1:
+- Initial release.`));
+
+const examples = [
+ "examples/Classic-Crossroads.rbxl",
+ "examples/City.rbxl",
+ "examples/Suburban.rbxl",
+ "examples/Western-Lounge.rbxm",
+ "examples/Dilapidated-House.rbxm"
+];
+
+const buttons = sal.querySelectorAll("button");
+buttons[0].addEventListener("click", async () => {
+ let dlg = document.body.querySelector("#remoteload");
+ let txt = dlg.querySelector("input");
+ let btn = dlg.querySelector(".open");
+ let exp = dlg.querySelector("#examples");
+ exp.innerHTML = "";
+ for (const e of examples) {
+ let el = document.createElement("li");
+ el.role = "option";
+ el.innerText = e;
+ el.addEventListener("click", () => {
+ txt.value = el.innerText;
+ txt.dispatchEvent(new Event("input"));
+ });
+ exp.appendChild(el);
+ }
+ let close = () => {
+ dlg.removeEventListener("cancel", close);
+ dlg.querySelector(".close").removeEventListener("click", close);
+ dlg.querySelector(".cancel").removeEventListener("click", close);
+ btn.removeEventListener("click", doLoad);
+ txt.removeEventListener("keyup", keyup);
+ txt.removeEventListener("input", input);
+ titleBar.classList.add("active");
+ dlg.close();
+ }
+ dlg.addEventListener("cancel", close);
+ titleBar.classList.remove("active");
+ dlg.showModal();
+ dlg.querySelector(".close").addEventListener("click", close);
+ dlg.querySelector(".cancel").addEventListener("click", close);
+ let doLoad = () => {
+ doLoad = null;
+ file = txt.value;
+ close(); close = null;
+ try { document.body.removeChild(dlg); } catch (ignored) {};
+ dlg = null; txt = null; btn = null;
+ start();
+ };
+ btn.addEventListener("click", doLoad);
+ let keyup = ({key}) => {
+ if (!btn.disabled && key === "Enter") doLoad();
+ };
+ txt.addEventListener("keyup", keyup);
+ let input = () => {
+ if (txt.value.trim().length > 0) {
+ btn.disabled = false;
+ } else {
+ btn.disabled = true;
+ }
+ };
+ txt.addEventListener("input", input);
+})
+
+const browse = sal.querySelector("input[type=file]");
+browse.addEventListener("input", () => {
+ file = browse.files[0];
+ start();
+})
+
+window.addEventListener("resize", () => {
+ renderer.resize();
+})
+
+const tree = document.body.querySelector(".tree");
+const tree2 = document.body.querySelector(".tree2");
+const datamodeltab = document.body.querySelector("button[aria-controls=datamodel-explorer]");
+const scenetab = document.body.querySelector("button[aria-controls=scene-explorer]");
+tree2.style.display = "none";
+datamodeltab.addEventListener("mousedown", () => {
+ datamodeltab.ariaSelected = true;
+ scenetab.ariaSelected = false;
+ tree2.style.display = "none";
+ tree.style.display = "block";
+});
+let treeRefresh2Pending = false;
+scenetab.addEventListener("mousedown", () => {
+ datamodeltab.ariaSelected = false;
+ scenetab.ariaSelected = true;
+ tree.style.display = "none";
+ rendering = true;
+ setTitle(placeName);
+ editor.innerHTML = "";
+ editor.style.display = "none";
+ tree2.style.display = "block";
+ (async () => {
+ if (treeRefresh2Pending) {
+ treeRefresh2();
+ treeRefresh2Pending = false;
+ }
+ })();
+});
+datamodeltab.disabled = false;
+scenetab.disabled = false;
+
+$(".tree2").jstree({'core' : {
+ 'data': []
+}});
+
+let treeRef2 = $(".tree2").jstree(true);
+let propTable = document.body.querySelector(".properties > table > tbody");
+let propSpinner = document.body.querySelector(".properties > .loader");
+
+treeRefresh2 = () => {
+ // don't render what we can't see!
+ if (tree2.style.display === "none") { treeRefresh2Pending = true; return; }
+ treeRef2.settings.core.data = threeNodeToTreeData([renderer.scene]);
+ treeRef2.refresh();
+}
+
+$('.tree2').on("changed.jstree", async function (e, data) {
+ let node = treeRef2.get_node(data.selected[0]).original;
+ if (node) {} else return;
+ node = node.node.object;
+ document.body.querySelector("#propertiesTitle").innerText = `Properties - ${node.type} "${node.name ? node.name : node.type}"`;
+ let keys = Object.keys(node);
+ let objviewIndex = 0;
+ let treedatatemp = null;
+ propTable.innerHTML = "";
+ propSpinner.style.display = "block";
+ propTable.style.display = "none";
+ for (let key of keys) {
+ if (key !== "children") {
+ let row = document.createElement("tr");
+ let one = document.createElement("td");
+ let two = document.createElement("td");
+ one.innerText = key;
+ if (typeof node[key] === "object") {
+ let objview = document.createElement("div");
+ two.appendChild(objview);
+ objview.id = `objview-${objviewIndex}`;
+ treedatatemp = {'core' : {
+ 'data' : objToTreeData(node[key])
+ }};
+ } else if (key === "color") {
+ let clr = document.createElement("input");
+ clr.type = "color";
+ clr.disabled = true;
+ clr.value = "#" + node[key].toString(16);
+ two.appendChild(clr);
+ let span = document.createElement("span");
+ span.innerHTML = ` ${clr.value}`;
+ two.appendChild(span);
+ } else if ([true, false].indexOf(node[key]) !== -1) {
+ let chk = document.createElement("input");
+ chk.disabled = "true";
+ chk.type = "checkbox";
+ chk.id = "checkbox-" + key;
+ if (node[key]) chk.checked = true;
+ let txt = document.createElement("label");
+ txt.for = "checkbox-" + key;
+ two.appendChild(chk);
+ two.appendChild(txt);
+ } else if (typeof node[key] === "number") {
+ let nr = document.createElement("input");
+ nr.type = "number";
+ nr.min = node[key];
+ nr.max = node[key];
+ nr.value = node[key];
+ nr.disabled = true;
+ two.appendChild(nr);
+ } else {
+ two.innerText = node[key].toString();
+ }
+ row.appendChild(one);
+ row.appendChild(two);
+ propTable.appendChild(row);
+ if (treedatatemp !== null) {
+ $(`#objview-${objviewIndex}`).jstree(treedatatemp);
+ objviewIndex++;
+ treedatatemp = null;
+ }
+ }
+ }
+ propSpinner.style.display = "none";
+ propTable.style.display = "table-row-group";
+});
+
+setTitle("Start Page");
+print("Welcome to Studio Lite (alpha-1)!");
+
+rendering = true;
+
+treeRefresh2();
\ No newline at end of file
diff --git a/app/controls/FlyCamera.js b/app/controls/FlyCamera.js
new file mode 100644
index 0000000..68b0ec2
--- /dev/null
+++ b/app/controls/FlyCamera.js
@@ -0,0 +1,135 @@
+import { PointerLockControls } from "./PointerLockControls.js";
+
+export default class FlyCamera {
+ /**
+ *
+ * @param {*} cam THREE.PerspectiveCamera to control
+ * @param {*} domElement The DOM element to listen for click & key events on
+ */
+ constructor(cam, domElement) {
+ this.cam = cam;
+ this.domElement = domElement;
+ this.movementSpeed = 0;
+ this.horizontalMovementSpeed = 0;
+ this.verticalMovementSpeed = 0;
+ this.flySpeed = 5;
+ // this.lookSpeed = 0.005;
+ this.controls = new PointerLockControls(this.cam, this.domElement);
+
+ /**
+ * Locks mouse on click
+ */
+ domElement.addEventListener('click', () => {
+ this.controls.lock();
+ });
+ /**
+ * Sets movement directions based on key presses
+ */
+ window.addEventListener("keydown", (e) => {
+ if (!this.controls.isLocked) return;
+ switch (e.code) {
+ case "KeyW":
+ this.moveForward = true;
+ break;
+ case "KeyS":
+ this.moveBackward = true;
+ break;
+ case "KeyA":
+ this.moveLeft = true;
+ break;
+ case "KeyD":
+ this.moveRight = true;
+ break;
+ case "KeyE":
+ this.moveUp = true;
+ break;
+ case "KeyQ":
+ this.moveDown = true;
+ break;
+ }
+ });
+ /**
+ * Sets movement directions based on key releases
+ */
+ window.addEventListener("keyup", (e) => {
+ if (!this.controls.isLocked) return;
+ switch (e.code) {
+ case "KeyW":
+ this.moveForward = false;
+ break;
+ case "KeyS":
+ this.moveBackward = false;
+ break;
+ case "KeyA":
+ this.moveLeft = false;
+ break;
+ case "KeyD":
+ this.moveRight = false;
+ break;
+ case "KeyE":
+ this.moveUp = false;
+ break;
+ case "KeyQ":
+ this.moveDown = false;
+ break;
+ }
+ });
+ }
+ /**
+ * Updates this.cam position based on movement directions
+ * @param {number} dt
+ */
+ update(dt) {
+ if (!this.controls.isLocked) return;
+ // console.log(this.moveForward);
+ if (this.moveForward) {
+ // console.log("forward");
+ if (this.movementSpeed < 50) {
+ this.movementSpeed += this.flySpeed;
+ }
+ } else if (this.moveBackward) {
+ if (this.movementSpeed > -50) {
+ this.movementSpeed -= this.flySpeed;
+ }
+ } else {
+ if (this.movementSpeed > 0) {
+ this.movementSpeed -= this.flySpeed;
+ } else if (this.movementSpeed < 0) {
+ this.movementSpeed += this.flySpeed;
+ }
+ }
+ if (this.moveLeft) {
+ if (this.horizontalMovementSpeed > -50) {
+ this.horizontalMovementSpeed -= this.flySpeed;
+ }
+ } else if (this.moveRight) {
+ if (this.horizontalMovementSpeed < 50) {
+ this.horizontalMovementSpeed += this.flySpeed;
+ }
+ } else {
+ if (this.horizontalMovementSpeed > 0) {
+ this.horizontalMovementSpeed -= this.flySpeed;
+ } else if (this.horizontalMovementSpeed < 0) {
+ this.horizontalMovementSpeed += this.flySpeed;
+ }
+ }
+ if (this.moveUp) {
+ if (this.verticalMovementSpeed < 50) {
+ this.verticalMovementSpeed += this.flySpeed;
+ }
+ } else if (this.moveDown) {
+ if (this.verticalMovementSpeed > -50) {
+ this.verticalMovementSpeed -= this.flySpeed;
+ }
+ } else {
+ if (this.verticalMovementSpeed > 0) {
+ this.verticalMovementSpeed -= this.flySpeed;
+ } else if (this.verticalMovementSpeed < 0) {
+ this.verticalMovementSpeed += this.flySpeed;
+ }
+ }
+ this.cam.translateX(this.horizontalMovementSpeed * dt);
+ this.cam.translateY(this.verticalMovementSpeed * dt);
+ this.cam.translateZ(-this.movementSpeed * dt);
+ }
+}
\ No newline at end of file
diff --git a/app/controls/PointerLockControls.js b/app/controls/PointerLockControls.js
new file mode 100644
index 0000000..133da64
--- /dev/null
+++ b/app/controls/PointerLockControls.js
@@ -0,0 +1,272 @@
+import {
+ Controls,
+ Euler,
+ Vector3
+} from '../thirdparty/three/three.core.js';
+
+const _euler = new Euler( 0, 0, 0, 'YXZ' );
+const _vector = new Vector3();
+
+/**
+ * Fires when the user moves the mouse.
+ *
+ * @event PointerLockControls#change
+ * @type {Object}
+ */
+const _changeEvent = { type: 'change' };
+
+/**
+ * Fires when the pointer lock status is "locked" (in other words: the mouse is captured).
+ *
+ * @event PointerLockControls#lock
+ * @type {Object}
+ */
+const _lockEvent = { type: 'lock' };
+
+/**
+ * Fires when the pointer lock status is "unlocked" (in other words: the mouse is not captured anymore).
+ *
+ * @event PointerLockControls#unlock
+ * @type {Object}
+ */
+const _unlockEvent = { type: 'unlock' };
+
+const _MOUSE_SENSITIVITY = 0.002;
+const _PI_2 = Math.PI / 2;
+
+/**
+ * The implementation of this class is based on the [Pointer Lock API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API}.
+ * `PointerLockControls` is a perfect choice for first person 3D games.
+ *
+ * ```js
+ * const controls = new PointerLockControls( camera, document.body );
+ *
+ * // add event listener to show/hide a UI (e.g. the game's menu)
+ * controls.addEventListener( 'lock', function () {
+ *
+ * menu.style.display = 'none';
+ *
+ * } );
+ *
+ * controls.addEventListener( 'unlock', function () {
+ *
+ * menu.style.display = 'block';
+ *
+ * } );
+ * ```
+ *
+ * @augments Controls
+ * @three_import import { PointerLockControls } from 'three/addons/controls/PointerLockControls.js';
+ */
+class PointerLockControls extends Controls {
+
+ /**
+ * Constructs a new controls instance.
+ *
+ * @param {Camera} camera - The camera that is managed by the controls.
+ * @param {?HTMLDOMElement} domElement - The HTML element used for event listeners.
+ */
+ constructor( camera, domElement = null ) {
+
+ super( camera, domElement );
+
+ /**
+ * Whether the controls are locked or not.
+ *
+ * @type {boolean}
+ * @readonly
+ * @default false
+ */
+ this.isLocked = false;
+
+ /**
+ * Camera pitch, lower limit. Range is '[0, Math.PI]' in radians.
+ *
+ * @type {number}
+ * @default 0
+ */
+ this.minPolarAngle = 0;
+
+ /**
+ * Camera pitch, upper limit. Range is '[0, Math.PI]' in radians.
+ *
+ * @type {number}
+ * @default Math.PI
+ */
+ this.maxPolarAngle = Math.PI;
+
+ /**
+ * Multiplier for how much the pointer movement influences the camera rotation.
+ *
+ * @type {number}
+ * @default 1
+ */
+ this.pointerSpeed = 1.0;
+
+ // event listeners
+
+ this._onMouseMove = onMouseMove.bind( this );
+ this._onPointerlockChange = onPointerlockChange.bind( this );
+ this._onPointerlockError = onPointerlockError.bind( this );
+
+ if ( this.domElement !== null ) {
+
+ this.connect( this.domElement );
+
+ }
+
+ }
+
+ connect( element ) {
+
+ super.connect( element );
+
+ this.domElement.ownerDocument.addEventListener( 'mousemove', this._onMouseMove );
+ this.domElement.ownerDocument.addEventListener( 'pointerlockchange', this._onPointerlockChange );
+ this.domElement.ownerDocument.addEventListener( 'pointerlockerror', this._onPointerlockError );
+
+ }
+
+ disconnect() {
+
+ this.domElement.ownerDocument.removeEventListener( 'mousemove', this._onMouseMove );
+ this.domElement.ownerDocument.removeEventListener( 'pointerlockchange', this._onPointerlockChange );
+ this.domElement.ownerDocument.removeEventListener( 'pointerlockerror', this._onPointerlockError );
+
+ }
+
+ dispose() {
+
+ this.disconnect();
+
+ }
+
+ getObject() {
+
+ console.warn( 'THREE.PointerLockControls: getObject() has been deprecated. Use controls.object instead.' ); // @deprecated r169
+
+ return this.object;
+
+ }
+
+ /**
+ * Returns the look direction of the camera.
+ *
+ * @param {Vector3} v - The target vector that is used to store the method's result.
+ * @return {Vector3} The normalized direction vector.
+ */
+ getDirection( v ) {
+
+ return v.set( 0, 0, - 1 ).applyQuaternion( this.object.quaternion );
+
+ }
+
+ /**
+ * Moves the camera forward parallel to the xz-plane. Assumes camera.up is y-up.
+ *
+ * @param {number} distance - The signed distance.
+ */
+ moveForward( distance ) {
+
+ if ( this.enabled === false ) return;
+
+ // move forward parallel to the xz-plane
+ // assumes camera.up is y-up
+
+ const camera = this.object;
+
+ _vector.setFromMatrixColumn( camera.matrix, 0 );
+
+ _vector.crossVectors( camera.up, _vector );
+
+ camera.position.addScaledVector( _vector, distance );
+
+ }
+
+ /**
+ * Moves the camera sidewards parallel to the xz-plane.
+ *
+ * @param {number} distance - The signed distance.
+ */
+ moveRight( distance ) {
+
+ if ( this.enabled === false ) return;
+
+ const camera = this.object;
+
+ _vector.setFromMatrixColumn( camera.matrix, 0 );
+
+ camera.position.addScaledVector( _vector, distance );
+
+ }
+
+ /**
+ * Activates the pointer lock.
+ *
+ * @param {boolean} [unadjustedMovement=false] - Disables OS-level adjustment for mouse acceleration, and accesses raw mouse input instead.
+ * Setting it to true will disable mouse acceleration.
+ */
+ lock( unadjustedMovement = false ) {
+
+ this.domElement.requestPointerLock( {
+ unadjustedMovement
+ } );
+
+ }
+
+ /**
+ * Exits the pointer lock.
+ */
+ unlock() {
+
+ this.domElement.ownerDocument.exitPointerLock();
+
+ }
+
+}
+
+// event listeners
+
+function onMouseMove( event ) {
+
+ if ( this.enabled === false || this.isLocked === false ) return;
+
+ const camera = this.object;
+ _euler.setFromQuaternion( camera.quaternion );
+
+ _euler.y -= event.movementX * _MOUSE_SENSITIVITY * this.pointerSpeed;
+ _euler.x -= event.movementY * _MOUSE_SENSITIVITY * this.pointerSpeed;
+
+ _euler.x = Math.max( _PI_2 - this.maxPolarAngle, Math.min( _PI_2 - this.minPolarAngle, _euler.x ) );
+
+ camera.quaternion.setFromEuler( _euler );
+
+ this.dispatchEvent( _changeEvent );
+
+}
+
+function onPointerlockChange() {
+
+ if ( this.domElement.ownerDocument.pointerLockElement === this.domElement ) {
+
+ this.dispatchEvent( _lockEvent );
+
+ this.isLocked = true;
+
+ } else {
+
+ this.dispatchEvent( _unlockEvent );
+
+ this.isLocked = false;
+
+ }
+
+}
+
+function onPointerlockError() {
+
+ console.error( 'THREE.PointerLockControls: Unable to use Pointer Lock API' );
+
+}
+
+export { PointerLockControls };
diff --git a/app/datamodel/DataModelUtils.js b/app/datamodel/DataModelUtils.js
new file mode 100644
index 0000000..2e23b14
--- /dev/null
+++ b/app/datamodel/DataModelUtils.js
@@ -0,0 +1,5 @@
+export function findByClassName(parent, className) {
+ for (let child of parent) {
+ if (child && child.ClassName === className) return child;
+ }
+}
\ No newline at end of file
diff --git a/app/etc/Helpers.js b/app/etc/Helpers.js
new file mode 100644
index 0000000..9340fe2
--- /dev/null
+++ b/app/etc/Helpers.js
@@ -0,0 +1,12 @@
+export function sleep(ms) { return new Promise((r) => { setTimeout(r, ms); }); }
+
+/* https://stackoverflow.com/a/5624139 */
+function componentToHex(c) {
+ var hex = c.toString(16);
+ return hex.length == 1 ? "0" + hex : hex;
+}
+
+export function rgbToHex(r, g, b) {
+ return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
+}
+/* https://stackoverflow.com/a/5624139 */
\ No newline at end of file
diff --git a/app/http/AssetManager.js b/app/http/AssetManager.js
new file mode 100644
index 0000000..0d665ae
--- /dev/null
+++ b/app/http/AssetManager.js
@@ -0,0 +1,79 @@
+import { tryToFetch_status } from "./TryToFetch.js";
+
+export default class AssetManager {
+ constructor(conf) {
+ this.conf = conf;
+ this.parseCache = {};
+ this.failedAssets = [];
+ this.texturesOfFailedMeshes = {};
+ this.missingAssets = `You haven't opened a Place yet. Open a Place to get insights on missing assets.`;
+ this.hasRbxGameAsset = false;
+ }
+
+ getAssetId(path) {
+ if (path.split("://")[0] === "rbxassetid") return path.split("://").pop().trim();
+ if (path.split("://")[0] === "http") return path.split("=").pop().trim();
+ if (!this.hasRbxGameAsset && path.split("://")[0] === "rbxgameasset") this.hasRbxGameAsset = true;
+ return false;
+ }
+
+ pushFailedMesh(assetId, meshTexture) {
+ if (this.texturesOfFailedMeshes[assetId]) {} else this.texturesOfFailedMeshes[assetId] = [];
+ if (this.texturesOfFailedMeshes[assetId].indexOf(meshTexture) === -1) this.texturesOfFailedMeshes[assetId].push(meshTexture);
+ }
+
+ async parseAssetPath(path, type = "decal", meshTexture = "N/A") {
+ if (meshTexture === false) meshTexture = "N/A";
+ const assetId = this.getAssetId(path);
+ if (type === "mesh" && this.parseCache[path] && this.parseCache[path].length === 0) this.pushFailedMesh(assetId, meshTexture);
+ if (this.parseCache[path]) return this.parseCache[path];
+ //status.innerText = "Loading assets...";
+ let href = "";
+ if (path.split("://")[0] === "rbxasset") href = "content/" + path.split("://").pop();
+ if (assetId) href = "asset/" + assetId.trim() + (type === "decal" ? ".png" : ".mesh");
+ if (this.failedAssets.indexOf(assetId) !== -1) { this.parseCache[path] = ""; return this.parseCache[path]; }
+ if (href.trim().length === 0) {
+ if (path.trim().length === 0)
+ //print("parseAssetPath was called with an empty string!");
+ ;
+ else
+ if (path.split("://")[0] !== "rbxgameasset") this.conf.sharedFunctions.print(`Asset path ${path} could not be resolved! This might be a deficiency in Studio Lite, please open an issue!`);
+ href = "";
+ } else {
+ if (path.trim().length === 0) { this.parseCache[path] = ""; return this.parseCache[path]; }
+ const fetchResult = await tryToFetch_status(href);
+ if (fetchResult === 200) { this.parseCache[path] = href; return href; } else {
+ if (fetchResult === 404 && assetId !== false && this.failedAssets.indexOf(assetId) === -1) {
+ this.failedAssets.push(assetId);
+ }
+ if (type === "mesh" && fetchResult === 404 && assetId !== false && meshTexture !== false) this.pushFailedMesh(assetId, meshTexture);
+ this.parseCache[path] = "";
+ return this.parseCache[path];
+ }
+ }
+ this.parseCache[path] = href;
+ //status.innerText = statusLastText;
+ return href;
+ }
+
+ computeMissingAssetsList() {
+ if (this.failedAssets.length > 0) {
+ this.missingAssets = `Below are listed all the assets in this Place that have failed to load, likely because they aren't saved on the server.
+To fix this, download the missing assets using the AssetDelivery API and place them in the asset/ directory.
+The name must be given as [assetid].[extension], where the extension is:
+.png for image assets
+.mesh for meshes
+
+AssetID listing starts here:`;
+ for (const i in this.failedAssets) {
+ const asset = this.failedAssets[i];
+ const textures = this.texturesOfFailedMeshes[asset];
+ this.missingAssets += `\n${textures ? "Mesh" : "Decal"} ${asset.trim()}${textures ? `, texture ${textures.join(", ")}` : ""}`;
+ }
+ return true;
+ } else {
+ this.missingAssets = "All assets in this Place have loaded successfully.";
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/http/TryToFetch.js b/app/http/TryToFetch.js
new file mode 100644
index 0000000..8e96fc9
--- /dev/null
+++ b/app/http/TryToFetch.js
@@ -0,0 +1,12 @@
+export async function tryToFetch_status(url) {
+ if (url.trim().length === 0) return false;
+ try {
+ let r = await fetch(url, {method: "HEAD"});
+ return r.status;
+ } catch (ignored) { return false; }
+}
+
+export async function tryToFetch(url) {
+ if (await tryToFetch_status(url) === 200) return true;
+ return false;
+}
\ No newline at end of file
diff --git a/app/rendering/StudioLiteRenderer.js b/app/rendering/StudioLiteRenderer.js
new file mode 100644
index 0000000..301b9a1
--- /dev/null
+++ b/app/rendering/StudioLiteRenderer.js
@@ -0,0 +1,495 @@
+import {
+ Scene,
+ PerspectiveCamera,
+ PCFSoftShadowMap,
+ TextureLoader,
+ Clock,
+ Matrix4,
+ DirectionalLight,
+ AmbientLight,
+ Color,
+ SphereGeometry,
+ CylinderGeometry,
+ BufferAttribute,
+ BufferGeometry,
+ Mesh,
+ MeshPhongMaterial,
+ BackSide,
+ MeshBasicMaterial,
+ BoxGeometry,
+ DataTexture,
+ SRGBColorSpace,
+ AxesHelper,
+ BoxHelper,
+ Raycaster,
+ Vector2
+} from '../thirdparty/three/three.core.js';
+import { decode } from "../thirdparty/rbxBinaryParser.js";
+import FlyCamera from '../controls/FlyCamera.js';
+import { WebGLRenderer } from '../thirdparty/three/three.module.js';
+import {
+ findByClassName
+} from '../datamodel/DataModelUtils.js';
+import { parseMesh } from './mesh/MeshParser.js';
+import {
+ tryToFetch
+} from '../http/TryToFetch.js';
+import AssetManager from '../http/AssetManager.js';
+
+const decalSides = ["Right", "Left", "Top", "Bottom", "Back", "Front"];
+export const partClasses = ["Part", "SpawnLocation", "WedgePart", "Seat", "VehicleSeat"];
+
+export class StudioLiteRenderer {
+ constructor(conf) {
+ this.conf = conf;
+ this.queue = {
+ total: 0,
+ completed: 0
+ }
+ this.texturesOfFailedMeshes = {};
+ this.imagePlaceholder = false;
+ this.mAssetManager = new AssetManager({
+ sharedFunctions: {
+ print: this.conf.sharedFunctions.print
+ }
+ });
+ this.scene = new Scene();
+ this.camera = new PerspectiveCamera(75, this.conf.width/this.conf.height, 0.1, 15000);
+ this.renderer = new WebGLRenderer({
+ antialias: true,
+ alpha: true
+ });
+ this.renderer.autoClear = false;
+ this.renderer.setSize(this.conf.width, this.conf.height);
+ this.renderer.shadowMap.enabled = true;
+ this.renderer.shadowMap.style = PCFSoftShadowMap;
+ this.domElement = this.renderer.domElement;
+ this.loader = new TextureLoader();
+ this.loader.crossOrigin = "Anonymous";
+ this.clock = new Clock();
+ let sun = new DirectionalLight(new Color(1, 1, 1), 1);
+ sun.position.set(0, 10, 1);
+ this.scene.add(sun);
+ let light = new AmbientLight(new Color(1, 1, 1), .5);
+ this.scene.add(light);
+ this.controls = new FlyCamera(this.camera, this.domElement);
+ this.setSkybox({
+ SkyboxBk: "rbxasset://sky/null_plainsky512_bk.jpg",
+ SkyboxDn: "rbxasset://sky/null_plainsky512_dn.jpg",
+ SkyboxFt: "rbxasset://sky/null_plainsky512_ft.jpg",
+ SkyboxLf: "rbxasset://sky/null_plainsky512_lf.jpg",
+ SkyboxRt: "rbxasset://sky/null_plainsky512_rt.jpg",
+ SkyboxUp: "rbxasset://sky/null_plainsky512_up.jpg"
+ });
+ this.axesHelper = new AxesHelper(20);
+ this.scene.add(this.axesHelper);
+ this.raycaster = new Raycaster();
+ this.threeids = [];
+ this.pointer = new Vector2();
+ this.useSelectionBox = false;
+ this.useSelectionBox2 = false;
+ this.domElement.addEventListener("mousemove", (event) => {
+ if (!this.useSelectionBox2) return;
+ const rect = event.target.getBoundingClientRect();
+ this.pointer.x = ( (event.clientX - rect.left) / this.conf.width ) * 2 - 1;
+ this.pointer.y = - ( (event.clientY - rect.top) / this.conf.height ) * 2 + 1;
+ });
+ this.noWorkspace = false;
+ }
+
+ render() {
+ if (this.controls) this.controls.update(this.clock.getDelta());
+ this.renderer.render(this.scene, this.camera);
+ if (this.useSelectionBox2) {
+ this.raycaster.setFromCamera(this.pointer, this.camera);
+ const intersects = this.raycaster.intersectObjects(this.scene.children, false);
+ if (intersects.length > 0) {
+ this.updateSelectionBox2(intersects[0].object);
+ }
+ }
+ }
+
+ renderImage(width = this.conf.width, height = this.conf.height) {
+ if (this.selectionBox) this.scene.remove(this.selectionBox);
+ if (this.selectionBox2) this.scene.remove(this.selectionBox2);
+ this.renderer.setSize(width, height);
+ this.camera.aspect = width / height;
+ this.camera.updateProjectionMatrix();
+ this.renderer.render(this.scene, this.camera);
+ const result = this.domElement.toDataURL();
+ this.resize();
+ if (this.selectionBox) this.scene.add(this.selectionBox);
+ if (this.selectionBox2) this.scene.add(this.selectionBox2);
+ return result;
+ }
+
+ setAnimationLoop(cb) {
+ this.renderer.setAnimationLoop(cb);
+ }
+
+ resize() {
+ this.renderer.setSize(this.conf.width, this.conf.height);
+ this.camera.aspect = this.conf.width / this.conf.height;
+ this.camera.updateProjectionMatrix();
+ }
+
+ toggleAxes(axes) {
+ if (axes) {
+ this.scene.add(this.axesHelper);
+ } else {
+ this.scene.remove(this.axesHelper);
+ }
+ }
+
+ setAxesPosition(x, y, z) {
+ this.axesHelper.position.set(x, y, z);
+ }
+
+ zoomTo(cameraFrame, rotate = true) {
+ this.camera.position.set(cameraFrame.Position.X, cameraFrame.Position.Y, cameraFrame.Position.Z);
+ if (rotate) this.camera.setRotationFromMatrix(new Matrix4().fromArray([
+ cameraFrame.Components[3], cameraFrame.Components[6], cameraFrame.Components[9], 0,
+ cameraFrame.Components[4], cameraFrame.Components[7], cameraFrame.Components[10], 0,
+ cameraFrame.Components[5], cameraFrame.Components[8], cameraFrame.Components[11], 0,
+ 0, 0, 0, 1
+ ]));
+ }
+
+ updateSelectionBox(threeid) {
+ if (!this.useSelectionBox) return;
+ if (threeid !== 1) {
+ const mesh = this.scene.getObjectById(threeid);
+ if (this.selectionBox) {
+ this.selectionBox.setFromObject(mesh);
+ } else {
+ this.selectionBox = new BoxHelper(mesh, new Color(1, 1, 1));
+ this.scene.add(this.selectionBox);
+ this.conf.sharedFunctions.treeRefresh2();
+ }
+ }
+ }
+
+ updateSelectionBox2(mesh) {
+ if (!this.useSelectionBox2) return;
+ if (this.selectionBox2) {
+ if (mesh !== this.skybox) this.selectionBox2.setFromObject(mesh);
+ } else {
+ this.selectionBox2 = new BoxHelper(mesh, new Color(1, 1, 1));
+ this.scene.add(this.selectionBox2);
+ this.conf.sharedFunctions.treeRefresh2();
+ }
+ }
+
+ removeSelectionBoxesIfNeeded() {
+ if (!this.useSelectionBox && this.selectionBox) {
+ this.scene.remove(this.selectionBox);
+ this.selectionBox.dispose();
+ this.selectionBox = null;
+ }
+ if (!this.useSelectionBox2 && this.selectionBox2) {
+ this.scene.remove(this.selectionBox2);
+ this.selectionBox2.dispose();
+ this.selectionBox2 = null;
+ }
+ this.conf.sharedFunctions.treeRefresh2();
+ }
+
+ showSkybox(show) {
+ if (show)
+ this.scene.add(this.skybox);
+ else
+ this.scene.remove(this.skybox);
+ }
+
+ getThreeId(id) {
+ return this.threeids[id];
+ }
+
+ async setSkybox(sky) {
+ if (this.skybox) this.scene.remove(this.skybox);
+ this.skybox = null
+ var material = []
+ material[0] = await this.mAssetManager.parseAssetPath(sky.SkyboxFt);
+ material[1] = await this.mAssetManager.parseAssetPath(sky.SkyboxBk);
+ material[2] = await this.mAssetManager.parseAssetPath(sky.SkyboxUp);
+ material[3] = await this.mAssetManager.parseAssetPath(sky.SkyboxDn);
+ material[4] = await this.mAssetManager.parseAssetPath(sky.SkyboxRt);
+ material[5] = await this.mAssetManager.parseAssetPath(sky.SkyboxLf);
+ for (var i = 0; i < material.length; i++) {
+ material[i] = new MeshBasicMaterial({map: this.loadColorTexture(material[i])})
+ material[i].side = BackSide
+ }
+ var geometry = new BoxGeometry(10000, 10000, 10000)
+ this.skybox = new Mesh(geometry, material)
+ this.skybox.position.set(0, 0, 0)
+ this.skybox.name = "Skybox";
+ this.scene.add(this.skybox)
+ console.log("skybox added")
+ this.conf.sharedFunctions.treeRefresh2();
+ }
+
+ queueOperation(cb) {
+ (async () => {
+ this.queue.total++;
+ await cb();
+ this.queue.completed++;
+ })();
+ }
+
+ get queueSize() {
+ return this.queue.total - this.queue.completed;
+ }
+
+ async renderPart(part, forceNoMesh = false, mappedid) {
+ const transparent = part.Transparency > 0;
+ let geometry, material, decals = [];
+ let offset = {x: 0, y: 0, z: 0};
+ let scale = {x: 1, y: 1, z: 1};
+
+ // Look for mesh data
+ const mesh = findByClassName(part.Children, "SpecialMesh");
+ if (typeof mesh !== "object" && part.ClassName === "MeshPart") mesh = part;
+
+ // Decide part color
+ let color = new Color(1, 1, 1);
+ if (part.Color3) {
+ color = new Color(part.Color3.R, part.Color3.G, part.Color3.B);
+ } else if (part.BrickColor) {
+ color = new Color(part.BrickColor.Color.R/255, part.BrickColor.Color.G/255, part.BrickColor.Color.B/255)
+ }
+
+ // Give meshes special treatment
+ const blockMesh = mesh && mesh !== part ? mesh : findByClassName(part.Children, "BlockMesh");
+ if (blockMesh) {
+ scale = {
+ x: blockMesh.Scale.X,
+ y: blockMesh.Scale.Y,
+ z: blockMesh.Scale.Z
+ };
+ // offset stays y-only for now. offset coordinates are somehow relative to rotation? tf??
+ // to see what I mean, uncomment X and Z, then open City.rbxl from the examples.
+ // Look at the stop signs. whaat? I ain't figuring this one out.
+ offset = {
+ x: 0,//blockMesh.Offset.X,
+ y: blockMesh.Offset.Y,
+ z: 0,//blockMesh.Offset.Z
+ };
+ }
+
+ // If ball or cylinder, decide geometry
+ if (part.Shape == "Ball") {
+ geometry = new SphereGeometry(part.Size.X / 2, 10, 10)
+ } else if (part.Shape === "Cylinder" || (mesh && mesh.MeshType === "Head")) {
+ let x, y, z;
+ if (part.Shape === "Cylinder") {
+ x = part.Size.X;
+ y = part.Size.Y;
+ z = part.Size.Z;
+ } else {
+ x = part.Size.Y;
+ y = part.Size.X;
+ z = part.Size.Z;
+ }
+ const cylinderRadius = Math.min(y, z) / 2;
+ geometry = new CylinderGeometry(cylinderRadius, cylinderRadius, x, 16, 16);
+ } else if (!forceNoMesh && mesh && (mesh.MeshType === "FileMesh" || part.ClassName === "MeshPart")) {
+ // Look, a mesh! Let's queue that so it doesn't block place loading.
+ this.queueOperation(async () => {
+ try {
+ var meshData = await this.getMesh(mesh.MeshId, this.mAssetManager.getAssetId(mesh.TextureId));
+ var { positions, normal, uv } = await parseMesh(meshData, mesh.MeshId);
+ const geometry = new BufferGeometry();
+ const positionNumComponents = 3;
+ const normalNumComponents = 3;
+ const uvNumComponents = 3;
+ geometry.setAttribute(
+ "position",
+ new BufferAttribute(
+ new Float32Array(positions),
+ positionNumComponents
+ )
+ );
+ geometry.setAttribute(
+ "normal",
+ new BufferAttribute(new Float32Array(normal), normalNumComponents)
+ );
+ geometry.setAttribute(
+ "uv",
+ new BufferAttribute(new Float32Array(uv), uvNumComponents)
+ );
+ geometry.computeBoundingBox();
+ let box = geometry.boundingBox;
+ let x = box.max.x - box.min.x;
+ let y = box.max.y - box.min.y;
+ let z = box.max.z - box.min.z;
+ geometry.scale(part.Size.X / x, part.Size.Y / y, part.Size.Z / z);
+
+ material = new MeshPhongMaterial( {
+ map: this.loadColorTexture(await this.mAssetManager.parseAssetPath(mesh.TextureId)),
+ transparent: transparent,
+ opacity: part.transparency*-1+1,
+ specular: 0x222222
+ } )
+
+ let cube = new Mesh(geometry, material);
+ cube.receiveShadow = true
+ cube.castShadow = true
+ cube.name = part.Name;
+ cube.position.set(part.CFrame.Position.X, part.CFrame.Position.Y, part.CFrame.Position.Z);
+ cube.setRotationFromMatrix(new Matrix4().fromArray([
+ part.CFrame.Components[3], part.CFrame.Components[6], part.CFrame.Components[9], 0,
+ part.CFrame.Components[4], part.CFrame.Components[7], part.CFrame.Components[10], 0,
+ part.CFrame.Components[5], part.CFrame.Components[8], part.CFrame.Components[11], 0,
+ 0, 0, 0, 1
+ ]));
+ this.scene.add(cube);
+ if (mappedid) this.threeids[mappedid] = cube.id;
+ // That didn't work! Let's load the part meshless instead.
+ } catch (e) {
+ // forceNoMesh = true skips the mesh code, so this part will follow the regular code path.
+ this.renderPart(part, true);
+ }
+ });
+ return;
+ } else {
+ geometry = new BoxGeometry( part.Size.X * scale.x, part.Size.Y * scale.y, part.Size.Z * scale.z )
+ }
+
+ // Render wedgepart
+ if (part.ClassName === "WedgePart") {
+ let pos = geometry.attributes.position;
+ for(let i = 0; i < pos.count; i++){
+ if (pos.getZ(i) < 0 && pos.getY(i) > 0) pos.setY(i, (part.Size.Y / 2) * -1); // change Y-coord by condition
+ }
+ geometry.computeVertexNormals(); // don't forget to re-compute normals
+ }
+
+ // Enumerate decals
+ for (let child of part.Children) {
+ if (child.ClassName === "Decal" || child.ClassName === "Texture") {
+ decals.push(child);
+ }
+ }
+
+ // Stage two. We will queue this if there are decals, to not block.
+ const renderPartStageTwo = async () => {
+ if (decals.length > 0) {
+ // Build a decal material.
+ material = [null, null, null, null, null, null];
+ let index;
+ for (let decal of decals) {
+ index = decalSides.indexOf(decal.Face);
+ if (index !== -1) {
+ material[index] = new MeshPhongMaterial({
+ map: this.loadColorTexture(await this.mAssetManager.parseAssetPath(decal.Texture)),
+ transparent: decal.Transparency > 0,
+ opacity: decal.Transparency*-1+1,
+ specular: 0x222222
+ });
+ }
+ }
+ for (let i in material) {
+ if (material[i] === null) material[i] = new MeshPhongMaterial({
+ color: color,
+ transparent: transparent,
+ opacity: part.Transparency*-1+1,
+ specular: 0x222222
+ });
+ }
+ } else {
+ // No decals? Just one material, then.
+ material = new MeshPhongMaterial( {
+ color: color,
+ transparent: transparent,
+ opacity: part.Transparency*-1+1,
+ specular: 0x222222
+ } )
+ }
+
+ // Create the mesh for our part.
+ var cube = new Mesh( geometry, material )
+ cube.receiveShadow = true
+ cube.castShadow = true
+ cube.name = part.Name;
+ cube.position.set(part.CFrame.Position.X + offset.x, part.CFrame.Position.Y + offset.y, part.CFrame.Position.Z + offset.z);
+ // Degrees aren't enough! We need to set the exact rotation matrix.
+ // If we use just CFrame.Orientation, it will lead to incorrect placements => destroyed buildings.
+ cube.setRotationFromMatrix(new Matrix4().fromArray([
+ part.CFrame.Components[3], part.CFrame.Components[6], part.CFrame.Components[9], 0,
+ part.CFrame.Components[4], part.CFrame.Components[7], part.CFrame.Components[10], 0,
+ part.CFrame.Components[5], part.CFrame.Components[8], part.CFrame.Components[11], 0,
+ 0, 0, 0, 1
+ ]));
+ // This is needed for cylinders to rotate correctly. No idea why.
+ if (part.Shape === "Cylinder") cube.rotation.z += Math.PI / 2;
+ //cube.rotation.set(MathUtils.degToRad(part.CFrame.Orientation.X), MathUtils.degToRad(part.CFrame.Orientation.Y), MathUtils.degToRad(part.CFrame.Orientation.Z));
+ this.scene.add( cube )
+ if (mappedid) this.threeids[mappedid] = cube.id;
+ };
+
+ // If there are no assets to load, render the part synchronously.
+ // If there are assets, move rendering to the background,
+ // so it doesn't block everything else if the user's connection is slow.
+ // (it is just a HEAD request, tho...)
+ if (decals.length > 0) {
+ this.queueOperation(renderPartStageTwo);
+ } else await renderPartStageTwo();
+ }
+
+ async traverse(instance, treeData, render = false) {
+ for (let child of instance.Children) {
+ if (child) {
+ let item = {'text': child.Name, 'icon': `content/icons/${child.ClassName}.png`, 'children': [], 'instance': child, 'id': this.threeids.push(1) - 1};
+ treeData.push(item);
+ if (render && partClasses.indexOf(child.ClassName) !== -1) {
+ await this.renderPart(child, false, item.id);
+ }
+ await this.traverse(child, item.children, render ? true : child.ClassName === "Workspace" || this.noWorkspace);
+ }
+ }
+ }
+
+ loadColorTexture( path ) {
+ if (path.trim().length === 0) return new DataTexture(new Uint8Array(4), 1, 1);
+ this.conf.sharedFunctions.print("Load texture " + new URL(path, window.location.href));
+ const texture = this.loader.load( path );
+ texture.colorSpace = SRGBColorSpace;
+ return texture;
+ }
+
+ async getMesh(mesh, texture) {
+ const path = await this.mAssetManager.parseAssetPath(mesh, "mesh", texture);
+ if (path.trim().length === 0) throw new Error();
+ var d = await fetch(path);
+ var data = await d.arrayBuffer();
+ return data;
+ }
+
+ async loadPlace(ab) {
+ this.data = decode(ab);
+ const workspace = findByClassName(this.data, "Workspace");
+ if (workspace) this.noWorkspace = false; else this.noWorkspace = true;
+ try {
+ const robloxCamera = findByClassName((this.noWorkspace ? findByClassName(this.data, "Model") : workspace).Children, "Camera");
+ const cameraFrame = robloxCamera.CFrame || robloxCamera.CoordinateFrame;
+ this.zoomTo(cameraFrame);
+ } catch (ignored) {
+ this.conf.sharedFunctions.print("Could not determine camera position!");
+ }
+ this.queueOperation(async () => {
+ try {
+ const sky = findByClassName(findByClassName(this.data, "Lighting").Children, "Sky");
+ if (!sky) throw new Error();
+ try {
+ for (const key of ["Bk", "Dn", "Ft", "Lf", "Rt", "Up"]) {
+ if (await tryToFetch(await this.mAssetManager.parseAssetPath(sky["Skybox" + key]))) {} else { throw new Error(); }
+ }
+ await this.setSkybox(sky);
+ } catch (ignored) {
+ this.conf.sharedFunctions.print("Could not load sky!");
+ }
+ } catch (ignored) {};
+ });
+ await this.traverse({"Children": this.data}, this.conf.sharedObjects.jsTreeData);
+ }
+}
\ No newline at end of file
diff --git a/app/rendering/mesh/MeshParser.js b/app/rendering/mesh/MeshParser.js
new file mode 100644
index 0000000..7057b79
--- /dev/null
+++ b/app/rendering/mesh/MeshParser.js
@@ -0,0 +1,153 @@
+function parse1xMesh(MESHDATA, is10) {
+ var vectors = MESHDATA.replace(/]/g, "").split("[");
+ var h = vectors.shift();
+ var positions = [];
+ var normal = [];
+ var uv = [];
+ // 1.00 assets are scaled up by 2x in the file-
+ var offset = is10 ? 0.5 : 1;
+
+ function toVector(vstring, offst) {
+ var a = [];
+ for (var i of vstring.split(",")) {
+ a.push(parseFloat(i) * offst);
+ }
+ return a;
+ }
+ for (var i = 0; i < vectors.length; i += 3) {
+ positions.push(...toVector(vectors[i], offset));
+ normal.push(...toVector(vectors[i + 1], 1));
+ uv.push(...toVector(vectors[i + 2], 1));
+ }
+ console.log(
+ `Parsed version 1 mesh\n\nDetails:\nVectors: ${vectors.length} (/ 3 = ${
+ vectors.length / 3
+ })\n\nHeader:`,
+ h
+ );
+ vectors = null;
+ return {
+ positions,
+ normal,
+ uv
+ };
+}
+
+function parse2x3xMesh(dv) {
+ var headerStart = 13;
+ var MeshHeader = {
+ sizeof_MeshHeader: dv.getUint16(headerStart, true),
+ sizeof_Vertex: dv.getUint8(headerStart + 2, true),
+ sizeof_Face: dv.getUint8(headerStart + 3, true),
+ numVerts: dv.getUint32(headerStart + 4, true),
+ numFaces: dv.getUint32(headerStart + 8, true)
+ };
+ if (MeshHeader.sizeof_MeshHeader > 12) {
+ // v3 header
+ MeshHeader.sizeof_LOD = dv.getUint16(headerStart + 4, true);
+ MeshHeader.numLODs = dv.getUint16(headerStart + 6, true);
+ MeshHeader.numVerts = dv.getUint16(headerStart + 8, true);
+ MeshHeader.numFaces = dv.getUint16(headerStart + 12, true);
+ }
+ console.log("Parsing version 2/3 mesh\n\nDetails:\n" + JSON.stringify(MeshHeader));
+ var i = headerStart + MeshHeader.sizeof_MeshHeader;
+ var verticies = [];
+ var verticiesEnd =
+ headerStart +
+ MeshHeader.sizeof_MeshHeader +
+ MeshHeader.numVerts * MeshHeader.sizeof_Vertex;
+ while (i < verticiesEnd) {
+ var vertex = {
+ px: dv.getFloat32(i, true),
+ py: dv.getFloat32(i + 4, true),
+ pz: dv.getFloat32(i + 8, true),
+ nx: dv.getFloat32(i + 12, true),
+ ny: dv.getFloat32(i + 16, true),
+ nz: dv.getFloat32(i + 20, true),
+ u: dv.getFloat32(i + 24, true),
+ v: dv.getFloat32(i + 28, true),
+ w: dv.getFloat32(i + 32, true),
+ r: 255,
+ g: 255,
+ b: 255,
+ a: 255
+ };
+ if (MeshHeader.sizeof_Vertex >= 40) {
+ vertex.r = dv.getUint8(i + 36, true);
+ vertex.g = dv.getUint8(i + 37, true);
+ vertex.b = dv.getUint8(i + 38, true);
+ vertex.a = dv.getUint8(i + 39, true);
+ }
+ if (MeshHeader.sizeof_MeshHeader > 12) vertex.u = vertex.u;
+ verticies.push(vertex);
+ i += MeshHeader.sizeof_Vertex;
+ }
+
+ var faces = [];
+ var facesEnd = verticiesEnd + MeshHeader.numFaces * MeshHeader.sizeof_Face;
+ while (i < facesEnd) {
+ faces.push({
+ a: dv.getUint32(i, true),
+ b: dv.getUint32(i + 4, true),
+ c: dv.getUint32(i + 8, true)
+ });
+ i += MeshHeader.sizeof_Face;
+ }
+
+ var LODs = [];
+ if (MeshHeader.sizeof_MeshHeader > 12) {
+ var lodsEnd = facesEnd + MeshHeader.numLODs * MeshHeader.sizeof_LOD;
+ while (i < lodsEnd) {
+ LODs.push(dv.getUint32(i, true));
+ i += MeshHeader.sizeof_LOD;
+ }
+ }
+
+ console.log({
+ MeshHeader,
+ verticies,
+ faces,
+ LODs
+ });
+
+ var positions = [];
+ var normal = [];
+ var uv = [];
+
+ for (var faceIdx in faces) {
+ if (LODs.length > 1 && faceIdx > LODs[1]) break;
+ var face = faces[faceIdx];
+ for (var i in face) {
+ var vertex = verticies[face[i]];
+ positions.push(vertex.px, vertex.py, vertex.pz);
+ normal.push(vertex.nx, vertex.ny, vertex.nz);
+ uv.push(vertex.u, 1 - vertex.v, vertex.w);
+ }
+ }
+
+ return {
+ positions,
+ normal,
+ uv
+ };
+}
+
+let meshCache = {};
+export function parseMesh(data, meshId) {
+ if (meshCache[meshId]) return meshCache[meshId];
+ let returnValue;
+ var stringData = new TextDecoder().decode(data);
+ if (stringData.startsWith("version 1.0")) {
+ returnValue = parse1xMesh(stringData, stringData.startsWith("version 1.0"));
+ } else if (
+ stringData.startsWith("version 2.0") ||
+ stringData.startsWith("version 3.0")
+ ) {
+ console.log("Parsing v2/3 mesh, header: ", stringData.substring(0, 12));
+ returnValue = parse2x3xMesh(new DataView(data));
+ } else {
+ console.log("unsupported mesh " + stringData.split("\n")[0]);
+ }
+ meshCache[meshId] = returnValue;
+ return returnValue;
+}
\ No newline at end of file
diff --git a/app/thirdparty/7.css b/app/thirdparty/7.css
new file mode 100644
index 0000000..d0c275e
--- /dev/null
+++ b/app/thirdparty/7.css
@@ -0,0 +1,4 @@
+/*! 7.css v0.18.0 - https://khang-nd.github.io/7.css */:root{--font:9pt "Segoe UI","SegoeUI","Noto Sans",sans-serif;--surface:#f0f0f0;--button-highlight:#fff;--button-face:#f2f2f2;--button-face-hover:#eaf6fd;--button-face-active:#c4e5f6;--button-face-disabled:#f4f4f4;--button-shade-light:#ebebeb;--button-shade-light-default:#c3dcea;--button-shade-light-hovered:#bee6fd;--button-shade-light-active:#98d1ef;--button-shade-dark:#cfcfcf;--button-shadow:inset 0 0 0 1px #fffc;--button-shadow-active:inset 1px 1px 0 #0003,inset -1px 1px 0 #0001;--button-border:1px solid;--button-border-color:#8e8f8f;--button-border-color-default:#5586a3;--button-border-color-hovered:#3c7fb1;--button-border-color-active:#6d91ab;--button-border-color-disabled:#aeb2b5;--button-text-color-disabled:#838383;--button-gradient:linear-gradient(to bottom,var(--button-face) 45%,var(--button-shade-light) 45%,var(--button-shade-dark));--button-gradient-hovered:linear-gradient(to bottom,var(--button-face-hover) 45%,var(--button-shade-light-hovered) 45%,#a7d9f5);--button-gradient-active:linear-gradient(to bottom,#e5f4fc,var(--button-face-active) 30% 50%,var(--button-shade-light-active) 50%,#68b3db);--item-highlighted-border:#aaddfa;--item-highlighted-background:linear-gradient(180deg,#fff9,#e6ecf5cc 90%,#fffc);--element-spacing:8px;--grouped-element-spacing:6px;--border-radius:3px;--border-width:1px}body{color:#222;font-family:Segoe UI,SegoeUI,Noto Sans,sans-serif;font-size:9pt}.surface{background:var(--surface)}h1{font-size:5rem}h2{font-size:2.5rem}h3{font-size:2rem}h4{font-size:1.5rem}u{border-bottom:.5px solid #222;text-decoration:none}code,code *{font-family:monospace}pre{background:#fff;border:1px solid var(--button-border-color);display:block;margin:0;padding:12px 8px}summary:focus-visible{outline:1px dotted #000}:root{--balloon-border-color:#0006;--balloon-tail-top:url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='20' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M.5 1.5v18h18l-18-18Z' fill='%23fff' stroke='%23fff'/%3E%3Cpath d='M1 19.5H.5v-18l18 18H18' stroke='%23939393'/%3E%3C/svg%3E");--balloon-tail-bottom:url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='20' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M.5 1.5v18h18l-18-18Z' fill='%23ddd' stroke='%23ddd'/%3E%3Cpath d='M1 19.5H.5v-18l18 18H18' stroke='%23939393'/%3E%3C/svg%3E");--balloon-tail-size:18px;--balloon-tail-offset:1em}[role=tooltip]{background:linear-gradient(to bottom,#fff,var(--button-shade-light));border:1px solid var(--balloon-border-color);border-radius:var(--border-radius);box-shadow:5px 5px 3px -3px var(--balloon-border-color);padding:1em 1em 1em 2.5em;position:relative}[role=tooltip]:before{background:var(--balloon-tail-top);content:"";height:var(--balloon-tail-size);left:var(--balloon-tail-offset);position:absolute;top:calc(var(--balloon-tail-size)*-1);width:var(--balloon-tail-size)}[role=tooltip][id]{position:absolute}[role=tooltip].is-top:before{background:var(--balloon-tail-bottom);bottom:calc(var(--balloon-tail-size)*-1);top:unset;transform:scale(-1)}[role=tooltip].is-top.is-right:before{transform:scaleY(-1)}[role=tooltip].is-left:before{left:unset;right:var(--balloon-tail-offset)}[role=tooltip].is-left.is-bottom:before{transform:scaleX(-1)}[role=button],button{background:var(--button-gradient);border:var(--button-border);border-color:var(--button-border-color);border-radius:var(--border-radius);box-shadow:var(--button-shadow);box-sizing:border-box;color:#222;font:var(--font);min-height:23px;min-width:75px;padding:0 12px;position:relative;text-align:center;z-index:0}[role=button]:before,button:before{background:var(--button-gradient-hovered);border-radius:var(--border-radius);box-shadow:var(--button-shadow)}[role=button]:after,[role=button]:before,button:after,button:before{content:"";height:100%;left:0;margin:0;opacity:0;padding:0;position:absolute;top:0;transition:opacity .3s;width:100%;z-index:-1}[role=button]:after,button:after{background:var(--button-gradient-active);border-radius:2px;box-shadow:var(--button-shadow-active)}[role=button]:disabled,button:disabled{background:var(--button-face-disabled);border-color:var(--button-border-color-disabled);color:var(--button-text-color-disabled)}[role=button]:not(:disabled):hover,button:not(:disabled):hover{border-color:var(--button-border-color-hovered);transition:border-color .3s}[role=button]:not(:disabled):hover:before,button:not(:disabled):hover:before{opacity:1;transition:opacity .3s}[role=button]:not(:disabled):not(:hover),button:not(:disabled):not(:hover){border-color:var(--button-border-color);transition:border-color 1s linear}[role=button]:not(:disabled):not(:hover):before,button:not(:disabled):not(:hover):before{opacity:0;transition:opacity 1s linear}[role=button]:not(:disabled).active,[role=button]:not(:disabled):active,button:not(:disabled).active,button:not(:disabled):active{border-color:var(--button-border-color-active);transition:border-color .3s}[role=button]:not(:disabled).active:after,[role=button]:not(:disabled):active:after,button:not(:disabled).active:after,button:not(:disabled):active:after{opacity:1;transition:opacity .3s}[role=button].focused,[role=button]:focus-visible,button.focused,button:focus-visible{box-shadow:inset 0 0 0 2px var(--button-shade-light-active);outline:1px dotted #000;outline-offset:-4px}[role=button].default,[role=button].focused,[role=button]:focus,button.default,button.focused,button:focus{-webkit-animation:pulse-anim 1s ease infinite alternate;animation:pulse-anim 1s ease infinite alternate;background-image:var(--button-gradient-hovered);border-color:var(--button-border-color-default)}@-webkit-keyframes pulse-anim{0%{box-shadow:inset 0 0 3px 1px #34deffdd}to{box-shadow:inset 0 0 1px 1px #34deffdd}}@keyframes pulse-anim{0%{box-shadow:inset 0 0 3px 1px #34deffdd}to{box-shadow:inset 0 0 1px 1px #34deffdd}}:root{--checkbox-width:14px;--checkbox-label-spacing:6px;--checkbox-total-width-precalc:0;--checkbox-total-width:calc(var(--checkbox-total-width-precalc));--checkmark-top:0;--checkmark-left:2px}input[type=checkbox]{appearance:none;-webkit-appearance:none;-moz-appearance:none;background:none;border:none;font:var(--font);margin:0;opacity:0}input[type=checkbox]+label{align-items:center;display:inline-flex;font:var(--font);margin-left:var(--checkbox-total-width);position:relative}input[type=checkbox]+label:before{background:#f6f6f6;border:1px solid;border-color:var(--button-border-color);box-shadow:inset 0 0 0 1px #f4f4f4,inset 1px 1px 0 1px #aeaeae,inset -1px -1px 0 1px #ddd,inset 3px 3px 6px #ccc;box-sizing:border-box;content:"";display:inline-block;height:var(--checkbox-width);margin-right:var(--checkbox-label-spacing);transition:.4s;width:var(--checkbox-width)}input[type=checkbox]+label:hover:before{background:#e9f7fe;border-color:var(--button-border-color-hovered);box-shadow:inset 0 0 0 1px #def9fa,inset 1px 1px 0 1px #79c6f9,inset -1px -1px 0 1px #c6e9fc,inset 3px 3px 6px #b1dffd}input[type=checkbox]:focus-visible+label{outline:1px dotted #000}input[type=checkbox]:checked+label:after{color:#4a5f97;content:"\2714";display:block;font-weight:700;left:var(--checkmark-left);position:absolute;top:var(--checkmark-top)}input[type=checkbox]:disabled+label{opacity:.6}:root{--chevron-size:5px}details{margin-top:0}details>summary{cursor:pointer;display:inline;margin-bottom:0;position:relative}details>summary:before{border:var(--chevron-size) solid transparent;border-left-color:#000;border-radius:3px;content:"";position:absolute;right:100%;top:calc(50% - var(--chevron-size))}details>summary::-webkit-details-marker,details>summary::marker{display:none}details[open]>summary:before{top:calc(50% - var(--chevron-size)/2);transform:rotate(45deg)}:root{--combobox-chevron-size:4px}.combobox{display:inline-block;position:relative}.combobox input[type=text]{padding-right:20px;width:100%}.combobox button{background:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTciIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJhIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjEwMCUiIHkyPSIwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3R5bGU9InN0b3AtY29sb3I6IzMzMztzdG9wLW9wYWNpdHk6MSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3R5bGU9InN0b3AtY29sb3I6I2FhYTtzdG9wLW9wYWNpdHk6MSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxwYXRoIGQ9Ik0xMSA2SDR2MWgxdjFoMXYxaDF2MWgxVjloMVY4aDFWN2gxVjZaIiBmaWxsPSJ1cmwoI2EpIi8+PC9zdmc+") 50% no-repeat,var(--button-gradient);min-width:16px;padding:0;position:absolute;right:0}.combobox button,.combobox button:before{border-bottom-left-radius:0;border-top-left-radius:0}.combobox button:before{background:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTciIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJhIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjEwMCUiIHkyPSIwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3R5bGU9InN0b3AtY29sb3I6IzMzMztzdG9wLW9wYWNpdHk6MSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3R5bGU9InN0b3AtY29sb3I6I2FhYTtzdG9wLW9wYWNpdHk6MSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxwYXRoIGQ9Ik0xMSA2SDR2MWgxdjFoMXYxaDF2MWgxVjloMVY4aDFWN2gxVjZaIiBmaWxsPSJ1cmwoI2EpIi8+PC9zdmc+") 50% no-repeat,var(--button-gradient-hovered)}.combobox button:after{background:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTciIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJhIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjEwMCUiIHkyPSIwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3R5bGU9InN0b3AtY29sb3I6IzMzMztzdG9wLW9wYWNpdHk6MSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3R5bGU9InN0b3AtY29sb3I6I2FhYTtzdG9wLW9wYWNpdHk6MSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxwYXRoIGQ9Ik0xMSA2SDR2MWgxdjFoMXYxaDF2MWgxVjloMVY4aDFWN2gxVjZaIiBmaWxsPSJ1cmwoI2EpIi8+PC9zdmc+") 50% no-repeat,var(--button-gradient-active);border-bottom-left-radius:0;border-top-left-radius:0}.combobox button:focus{box-shadow:none;outline:none}select:not([multiple]){-webkit-appearance:none;-moz-appearance:none;appearance:none;background:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTciIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJhIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjEwMCUiIHkyPSIwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3R5bGU9InN0b3AtY29sb3I6IzMzMztzdG9wLW9wYWNpdHk6MSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3R5bGU9InN0b3AtY29sb3I6I2FhYTtzdG9wLW9wYWNpdHk6MSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxwYXRoIGQ9Ik0xMSA2SDR2MWgxdjFoMXYxaDF2MWgxVjloMVY4aDFWN2gxVjZaIiBmaWxsPSJ1cmwoI2EpIi8+PC9zdmc+"),var(--button-gradient);background-position:100%;background-repeat:no-repeat;border:var(--button-border);border-color:var(--button-border-color);border-radius:var(--border-radius);box-shadow:var(--button-shadow);box-sizing:border-box;color:#222;font:var(--font);padding:2px 30px 2px 3px;position:relative}select:not([multiple]):hover{background-image:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTciIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJhIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjEwMCUiIHkyPSIwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3R5bGU9InN0b3AtY29sb3I6IzMzMztzdG9wLW9wYWNpdHk6MSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3R5bGU9InN0b3AtY29sb3I6I2FhYTtzdG9wLW9wYWNpdHk6MSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxwYXRoIGQ9Ik0xMSA2SDR2MWgxdjFoMXYxaDF2MWgxVjloMVY4aDFWN2gxVjZaIiBmaWxsPSJ1cmwoI2EpIi8+PC9zdmc+"),var(--button-gradient-hovered);border-color:var(--button-border-color-hovered)}select:not([multiple]):active{background-image:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTciIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJhIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjEwMCUiIHkyPSIwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3R5bGU9InN0b3AtY29sb3I6IzMzMztzdG9wLW9wYWNpdHk6MSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3R5bGU9InN0b3AtY29sb3I6I2FhYTtzdG9wLW9wYWNpdHk6MSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxwYXRoIGQ9Ik0xMSA2SDR2MWgxdjFoMXYxaDF2MWgxVjloMVY4aDFWN2gxVjZaIiBmaWxsPSJ1cmwoI2EpIi8+PC9zdmc+"),var(--button-gradient-active);border-color:var(--button-border-color-active);box-shadow:var(--button-shadow-active);outline:none}select:not([multiple]):focus{box-shadow:inset 0 0 0 2px var(--button-shade-light-active);outline:1px dotted #000;outline-offset:-4px}fieldset{border:1px solid #cdd7db;border-radius:var(--border-radius);box-shadow:inset 0 0 0 1px #fff;margin:0;padding:calc(var(--border-width)*2 + var(--element-spacing));-webkit-padding-before:var(--element-spacing);padding-block-start:var(--element-spacing)}fieldset legend{font:var(--font)}.field-row{align-items:center;display:flex}.field-row>*+*{margin-left:var(--grouped-element-spacing)}.field-row-stacked{display:flex;flex-direction:column}.field-row-stacked *+*,[class^=field-row]+[class^=field-row]{margin-top:var(--grouped-element-spacing)}[role=listbox],select[multiple]{background:#fff;border:1px solid #c0c1cd;display:block;font:var(--font);overflow-y:scroll}[role=listbox].has-shadow,select[multiple].has-shadow{box-shadow:4px 4px 3px -2px #999}[role=listbox].has-hover li:hover,select[multiple].has-hover li:hover{background-color:#2a90ff;color:#fff}[role=listbox]:focus,select[multiple]:focus{outline:none}[role=listbox] [role=option],[role=listbox] option,select[multiple] [role=option],select[multiple] option{padding:2px}[role=listbox] [role=option]:focus,[role=listbox] [role=option][aria-selected],[role=listbox] option:focus,[role=listbox] option[aria-selected],select[multiple] [role=option]:focus,select[multiple] [role=option][aria-selected],select[multiple] option:focus,select[multiple] option[aria-selected]{background-color:#2a90ff;color:#fff}:root{--listview-chevron-size:5px;--listview-background:#fff;--listview-border:1px solid;--listview-border-color:#eee;--listview-border-color-header:#d7d7d7;--listview-gradient:linear-gradient(180deg,#fff 45%,#fafafa 0,#f0f0f0);--listview-header-border-color-highlight:#a7d8f5;--listview-header-gradient-highlight:linear-gradient(180deg,#f3f9fc 45%,#e4f0f8 0,#d9eaf5);--listview-header-chevron-background:linear-gradient(to bottom right,#667f91 45%,#90c1e2 65%,#cce3f2)}table{background-color:var(--listview-background);border:1px solid #c0c1cd;border-collapse:collapse;font:var(--font);position:relative;table-layout:fixed;text-align:left;white-space:nowrap}table td,table th{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}table.has-shadow{box-shadow:4px 4px 3px -2px #999}table>thead>tr>*{background:var(--listview-gradient);border:var(--listview-border) var(--listview-border-color-header);box-sizing:border-box;cursor:default;font-weight:400;height:22px;padding:0 var(--grouped-element-spacing);position:sticky;top:0}table>thead>tr>.highlighted{background:var(--listview-header-gradient-highlight);border:var(--listview-border) var(--listview-header-border-color-highlight);border-radius:var(--border-radius)}table>thead>tr>.highlighted:not(:last-child){border-right-color:var(--listview-header-border-color-highlight)}table>thead>tr>.highlighted.indicator:before{background:var(--listview-header-chevron-background);-webkit-clip-path:polygon(0 0,50% 100%,100% 0);clip-path:polygon(0 0,50% 100%,100% 0);content:"";height:var(--listview-chevron-size);position:absolute;right:50%;top:0;width:calc(var(--listview-chevron-size)*1.2)}table>thead>tr>.highlighted.indicator.up:before{-webkit-clip-path:polygon(0 100%,50% 0,100% 100%);clip-path:polygon(0 100%,50% 0,100% 100%)}table>tbody>tr{cursor:default}table>tbody>tr.highlighted{background:var(--item-highlighted-background);border:var(--listview-border) var(--item-highlighted-border);border-radius:var(--border-radius)}table>tbody>tr.highlighted>:not(:last-child){border-right:none}table>tbody>tr>*{height:14px;padding:2px var(--element-spacing)}table>tbody>tr>:not(:last-child){border-right:var(--listview-border) var(--listview-border-color)}:root{--menu-padding:2px;--item-offset-left:30px}ul[role]{cursor:default;list-style:none;margin:0;padding:0}ul[role=menubar]{background:linear-gradient(#fff 20%,#f1f4fa 25%,#f1f4fa 43%,#d4dbee 48%,#e6eaf6);display:flex}ul[role=menubar]>[role=menuitem]{padding:6px 10px;position:relative}ul[role=menubar]>[role=menuitem]:focus,ul[role=menubar]>[role=menuitem]:focus-within,ul[role=menubar]>[role=menuitem]:hover{background:#39f;color:#fff;outline:none}ul[role=menubar]>[role=menuitem]:focus-within~[role=menuitem]:focus,ul[role=menubar]>[role=menuitem]:focus-within~[role=menuitem]:focus-within,ul[role=menubar]>[role=menuitem]:focus~[role=menuitem]:focus,ul[role=menubar]>[role=menuitem]:focus~[role=menuitem]:focus-within,ul[role=menubar]>[role=menuitem]:hover~[role=menuitem]:focus,ul[role=menubar]>[role=menuitem]:hover~[role=menuitem]:focus-within{background:transparent;color:inherit}ul[role=menubar]>[role=menuitem]:focus-within:has(~[role=menuitem]:hover),ul[role=menubar]>[role=menuitem]:focus:has(~[role=menuitem]:hover),ul[role=menubar]>[role=menuitem]:hover:has(~[role=menuitem]:hover){background:transparent;color:inherit}ul[role=menu]{background:var(--surface);border:1px solid #0006;box-shadow:4px 4px 3px -2px #00000080;color:initial;min-width:150px;padding:var(--menu-padding);position:relative}ul[role=menu]:before{box-shadow:inset 1px 0 #00000026,inset -1px 0 #fff;content:"";height:calc(100% - 4px);left:var(--item-offset-left);pointer-events:none;position:absolute;width:2px}[role=menuitem] ul[role=menu]{display:none;left:0;position:absolute;top:100%;z-index:99}ul[role=menu] [role=menuitem]>[role=menu]{left:100%;top:-4px}ul[role=menu]>[role=menuitem]>a,ul[role=menu]>[role=menuitem]>button,ul[role=menu]>[role=menuitem]>label,ul[role=menu]>[role=menuitem][aria-haspopup=true]{all:unset;border:1px solid transparent;border-radius:3px;box-sizing:border-box;display:flex;justify-content:space-between;padding:4px 10px 4px 32px;position:relative;white-space:nowrap;width:100%}ul[role=menu]>[role=menuitem]>a:focus-visible,ul[role=menu]>[role=menuitem]>a:hover,ul[role=menu]>[role=menuitem]>button:focus-visible,ul[role=menu]>[role=menuitem]>button:hover,ul[role=menu]>[role=menuitem]>label:focus-visible,ul[role=menu]>[role=menuitem]>label:hover,ul[role=menu]>[role=menuitem][aria-haspopup=true]:focus-visible,ul[role=menu]>[role=menuitem][aria-haspopup=true]:hover{background:var(--item-highlighted-background);border-color:var(--item-highlighted-border)}ul[role=menu]>[role=menuitem]>button:after,ul[role=menu]>[role=menuitem]>button:hover:before{content:none}ul[role=menu]>[role=menuitem][aria-haspopup=true]:after{border:4px solid transparent;border-left-color:currentcolor;content:"";position:absolute;right:2px;top:50%;transform:translateY(-50%)}ul [role=menuitem]{position:relative}ul [role=menuitem]>input[type]{display:none}ul [role=menuitem]>input[type]+label{display:block;position:relative}ul [role=menuitem]>input[type]+label:before{all:unset;background:var(--item-highlighted-background);border-radius:inherit;box-shadow:0 0 0 1px #b3d3f9;box-sizing:border-box;height:22px;left:0;position:absolute;top:0;width:22px}ul [role=menuitem]>input[type]:checked+label:before{content:""}ul [role=menuitem]>input[type][type=radio]:checked+label:after{background:radial-gradient(circle at 75% 25%,#d5d4ea,#333583);border:1px solid #1a1490;box-shadow:none;left:8px;top:50%;transform:translateY(-50%)}ul [role=menuitem]>input[type][type=checkbox]:checked+label:after{color:#0c12a1;font-size:10pt;left:6px;top:50%;transform:translateY(-52%)}ul [role=menuitem]:focus-within>[role=menu],ul [role=menuitem]:focus>[role=menu]{display:block}ul [role=menuitem]:focus-within:has(~[role=menuitem]:hover)>[role=menu],ul [role=menuitem]:focus:has(~[role=menuitem]:hover)>[role=menu]{display:none}ul [role=menuitem][aria-disabled]{opacity:.5;pointer-events:none}ul [role=menuitem].has-divider:after{box-shadow:inset 0 1px #00000026,inset 0 -1px #fff;content:"";display:block;height:2px;margin:3px 0 2px;margin-left:var(--item-offset-left);pointer-events:none}ul [role=menuitem] img{left:2px;pointer-events:none;position:absolute;top:50%;transform:translateY(-50%);z-index:1}ul [role=menuitem] span{margin-left:32px}ul.can-hover [role=menuitem]:hover>[role=menu]{display:block}ul.can-hover [role=menuitem]:hover~[role=menuitem]:focus,ul.can-hover [role=menuitem]:hover~[role=menuitem]:focus-within{background:transparent;color:inherit}ul.can-hover [role=menuitem]:hover~[role=menuitem]:focus-within>[role=menu],ul.can-hover [role=menuitem]:hover~[role=menuitem]:focus>[role=menu]{display:none}:root{--progress-color-normal:#0bd82c;--progress-color-paused:#e6df1b;--progress-color-error:#ef0000}[role=progressbar]{background:radial-gradient(circle at 0 50%,#0000001f 10px,transparent 30px),radial-gradient(circle at 100% 50%,#0000001f 10px,transparent 30px),linear-gradient(180deg,#f3f3f3af,#fcfcfcaf 3px,#dbdbdbaf 6px,#cacacaaf 0,#d5d5d5af),#ddd;border:1px solid var(--button-border-color);border-radius:var(--border-radius);box-shadow:inset 0 0 0 1px #f3f3f388,0 0 0 1px #eaeaea88;height:15px;margin:2px 0;overflow:hidden}[role=progressbar]>div{background-color:var(--progress-color-normal);background-image:linear-gradient(180deg,#f3f3f3af,#fcfcfcaf 3px,#dbdbdbaf 6px,transparent 0),radial-gradient(circle at 0 50%,#0000002f 10px,transparent 30px),radial-gradient(circle at 100% 50%,#0000002f 10px,transparent 30px),linear-gradient(180deg,transparent 65%,#ffffff55),linear-gradient(180deg,transparent 6px,#cacaca33 0,#d5d5d533);box-shadow:inset 0 0 0 1px #ffffff1f;height:100%;overflow:hidden}[role=progressbar].paused>div{background-color:var(--progress-color-paused)}[role=progressbar].error>div{background-color:var(--progress-color-error)}[role=progressbar].animate>div:before,[role=progressbar].marquee:before{-webkit-animation:progressbar 3s linear infinite;animation:progressbar 3s linear infinite;background:linear-gradient(90deg,transparent,#ffffff80,transparent 40%);content:"";display:block;height:100%}[role=progressbar].marquee:before{background:linear-gradient(to right,transparent,var(--progress-color-normal),transparent 35%);opacity:.5}@-webkit-keyframes progressbar{0%{transform:translateX(-40%)}60%{transform:translateX(100%)}to{transform:translateX(100%)}}@keyframes progressbar{0%{transform:translateX(-40%)}60%{transform:translateX(100%)}to{transform:translateX(100%)}}:root{--radio-width:14px;--radio-label-spacing:6px;--radio-total-width-precalc:var(--radio-width) + var(--radio-label-spacing);--radio-total-width:calc(var(--radio-total-width-precalc));--radio-dot-width:8px;--radio-dot-offset:calc(var(--radio-width)/2);--radio-dot-top:calc(var(--radio-dot-offset) - var(--radio-dot-width)/2);--radio-dot-left:calc(var(--radio-total-width)*-1 + var(--radio-width)/2 - var(
+ --radio-dot-width
+ )/2)}input[type=radio]{appearance:none;-webkit-appearance:none;-moz-appearance:none;background:0;border:none;margin:0;opacity:0;position:fixed}input[type=radio]+label{align-items:center;display:inline-flex;font:var(--font);margin-left:var(--radio-total-width);position:relative}input[type=radio]+label:before{background:#f6f6f6;border:1px solid;border-color:var(--button-border-color);border-radius:50%;box-shadow:inset 0 0 0 1.5px #f4f4f4,inset 1px 1px 0 1.5px #aeaeae,inset -1px 0 0 1.5px #ddd,inset 3px 3px 6px #ccc;box-sizing:border-box;content:"";display:inline-block;height:var(--radio-width);left:calc(var(--radio-total-width)*-1);margin-right:var(--radio-label-spacing);position:absolute;top:0;transition:.4s;width:var(--radio-width)}input[type=radio]+label:hover:before{border-color:var(--button-border-color-hovered);box-shadow:inset 0 0 0 1.5px #def9fa,inset 1px 1px 0 1.5px #79c6f9,inset -1px -1px 0 1.5px #c6e9fc,inset 3px 3px 6px #b1dffd}input[type=radio]:checked+label:after{background:#7cd3eb;border:1.5px solid #27506d;border-radius:50%;box-shadow:inset -1px -1px 0 .5px #16638f,inset -1px -1px 0 1px #1985c0;box-sizing:border-box;content:"";display:block;height:var(--radio-dot-width);left:var(--radio-dot-left);position:absolute;top:var(--radio-dot-top);width:var(--radio-dot-width)}input[type=radio]:focus-visible+label{outline:1px dotted #000}input[type=radio]:disabled+label{opacity:.6}:root{--scrollbar-y:linear-gradient(to right,#e5e5e5,var(--surface) 20%);--scrollbar-x:linear-gradient(to bottom,#e5e5e5,var(--surface) 20%)}.has-scrollbar::-webkit-scrollbar{width:16px}.has-scrollbar::-webkit-scrollbar:horizontal{height:17px}.has-scrollbar::-webkit-scrollbar-corner{background:var(--button-face)}.has-scrollbar::-webkit-scrollbar-track:vertical{background:var(--scrollbar-y)}.has-scrollbar::-webkit-scrollbar-track:horizontal{background:var(--scrollbar-x)}.has-scrollbar::-webkit-scrollbar-thumb{background-color:var(--button-face);border:var(--button-border);border-color:var(--button-border-color);border-radius:var(--border-radius);box-shadow:var(--button-shadow)}.has-scrollbar::-webkit-scrollbar-thumb:vertical{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAKCAIAAADpZ+PpAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAADrSURBVChTTc5LboJQGAXguyoCu4ERCzAGlRk7UOwGWIDh0s4M4kxb06RSq/jAB6AxJkJ4lTDrue3AnvyzP+fLId+/yfM8juP7PQmCCOf7B3e+ZD+O40RRVFW12VQUpd3r9U3T2m4OpKoqWZYNwzBZLEqfh0N7NnvfrPcEWlEUWZb9mWF4Ph6D0ylcLbfM5HkeJrhGA2hb15/QXnv+w7RYXsDatjOdvnmrHSnLEizMNE2v11sUXQBCnn98kbquBUGQJAlmq9WB2e3qg4HJdqKkaRql1HGc0WgMcDJ5dd0F24kediZJ8t/ELT69H+8py0CYSIO5AAAAAElFTkSuQmCC") no-repeat 50%,linear-gradient(to right,var(--button-face) 45%,var(--button-shade-light) 45%,var(--button-shade-dark))}.has-scrollbar::-webkit-scrollbar-thumb:horizontal{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAJCAYAAAALpr0TAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAADcSURBVChTNZBLqoUwEEQrURQUxZGCvy24ACfiityJi7tv8GauQoPxk5tquA2RQ9vVVYk6z9NZaxFFEe77htYazjk8z4MwDIVZ+rourOuKaZrwvi+WZcE8z1BKCbPPCjk4DAO2bRP1OI7wLiL6Mbd7J408z1GWpQwWRYGqqiQG+03TgMu0MacfUN4qANmn8UOv9MjW3sKaSm7iIdOSlziOQ3LScd93aPonSYK6riVLlmVo21aYfVqzND9pmqLrOlGT+76XbcxLZkb19/l3fEP+oF0cx8KMEASBsDEGX2/CgZCHkg+8AAAAAElFTkSuQmCC") no-repeat 50%,linear-gradient(to bottom,var(--button-face) 45%,var(--button-shade-light) 45%,var(--button-shade-dark))}.has-scrollbar::-webkit-scrollbar-thumb:hover:vertical{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAKCAIAAADpZ+PpAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAADrSURBVChTTc5LboJQGAXguyoCu4ERCzAGlRk7UOwGWIDh0s4M4kxb06RSq/jAB6AxJkJ4lTDrue3AnvyzP+fLId+/yfM8juP7PQmCCOf7B3e+ZD+O40RRVFW12VQUpd3r9U3T2m4OpKoqWZYNwzBZLEqfh0N7NnvfrPcEWlEUWZb9mWF4Ph6D0ylcLbfM5HkeJrhGA2hb15/QXnv+w7RYXsDatjOdvnmrHSnLEizMNE2v11sUXQBCnn98kbquBUGQJAlmq9WB2e3qg4HJdqKkaRql1HGc0WgMcDJ5dd0F24kediZJ8t/ELT69H+8py0CYSIO5AAAAAElFTkSuQmCC") no-repeat 50%,linear-gradient(to right,var(--button-face-hover) 45%,var(--button-shade-light-hovered) 45%);border-color:var(--button-border-color-hovered)}.has-scrollbar::-webkit-scrollbar-thumb:hover:horizontal{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAJCAYAAAALpr0TAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAADcSURBVChTNZBLqoUwEEQrURQUxZGCvy24ACfiityJi7tv8GauQoPxk5tquA2RQ9vVVYk6z9NZaxFFEe77htYazjk8z4MwDIVZ+rourOuKaZrwvi+WZcE8z1BKCbPPCjk4DAO2bRP1OI7wLiL6Mbd7J408z1GWpQwWRYGqqiQG+03TgMu0MacfUN4qANmn8UOv9MjW3sKaSm7iIdOSlziOQ3LScd93aPonSYK6riVLlmVo21aYfVqzND9pmqLrOlGT+76XbcxLZkb19/l3fEP+oF0cx8KMEASBsDEGX2/CgZCHkg+8AAAAAElFTkSuQmCC") no-repeat 50%,linear-gradient(to bottom,var(--button-face-hover) 45%,var(--button-shade-light-hovered) 45%);border-color:var(--button-border-color-hovered)}.has-scrollbar::-webkit-scrollbar-thumb:active:vertical{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAKCAIAAADpZ+PpAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAADrSURBVChTTc5LboJQGAXguyoCu4ERCzAGlRk7UOwGWIDh0s4M4kxb06RSq/jAB6AxJkJ4lTDrue3AnvyzP+fLId+/yfM8juP7PQmCCOf7B3e+ZD+O40RRVFW12VQUpd3r9U3T2m4OpKoqWZYNwzBZLEqfh0N7NnvfrPcEWlEUWZb9mWF4Ph6D0ylcLbfM5HkeJrhGA2hb15/QXnv+w7RYXsDatjOdvnmrHSnLEizMNE2v11sUXQBCnn98kbquBUGQJAlmq9WB2e3qg4HJdqKkaRql1HGc0WgMcDJ5dd0F24kediZJ8t/ELT69H+8py0CYSIO5AAAAAElFTkSuQmCC") no-repeat 50%,linear-gradient(to right,var(--button-face-active) 45%,var(--button-shade-light-active) 45%);border-color:var(--button-border-color-active)}.has-scrollbar::-webkit-scrollbar-thumb:active:horizontal{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAJCAYAAAALpr0TAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAADcSURBVChTNZBLqoUwEEQrURQUxZGCvy24ACfiityJi7tv8GauQoPxk5tquA2RQ9vVVYk6z9NZaxFFEe77htYazjk8z4MwDIVZ+rourOuKaZrwvi+WZcE8z1BKCbPPCjk4DAO2bRP1OI7wLiL6Mbd7J408z1GWpQwWRYGqqiQG+03TgMu0MacfUN4qANmn8UOv9MjW3sKaSm7iIdOSlziOQ3LScd93aPonSYK6riVLlmVo21aYfVqzND9pmqLrOlGT+76XbcxLZkb19/l3fEP+oF0cx8KMEASBsDEGX2/CgZCHkg+8AAAAAElFTkSuQmCC") no-repeat 50%,linear-gradient(to bottom,var(--button-face-active) 45%,var(--button-shade-light-active) 45%);border-color:var(--button-border-color-active)}.has-scrollbar::-webkit-scrollbar-button:horizontal:end:decrement,.has-scrollbar::-webkit-scrollbar-button:horizontal:start:increment,.has-scrollbar::-webkit-scrollbar-button:vertical:end:decrement,.has-scrollbar::-webkit-scrollbar-button:vertical:start:increment{display:none}.has-scrollbar::-webkit-scrollbar-button{border:var(--button-border) transparent}.has-scrollbar::-webkit-scrollbar-button:vertical{height:17px}.has-scrollbar::-webkit-scrollbar-button:vertical:start{background:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTciIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJhIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjEwMCUiIHkyPSIwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3R5bGU9InN0b3AtY29sb3I6IzMzMztzdG9wLW9wYWNpdHk6MSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3R5bGU9InN0b3AtY29sb3I6I2FhYTtzdG9wLW9wYWNpdHk6MSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxwYXRoIGQ9Ik04IDZIN3YxSDZ2MUg1djFINHYxaDdWOWgtMVY4SDlWN0g4VjZaIiBmaWxsPSJ1cmwoI2EpIi8+PC9zdmc+"),var(--scrollbar-y)}.has-scrollbar::-webkit-scrollbar-button:vertical:end{background:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTciIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJhIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjEwMCUiIHkyPSIwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3R5bGU9InN0b3AtY29sb3I6IzMzMztzdG9wLW9wYWNpdHk6MSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3R5bGU9InN0b3AtY29sb3I6I2FhYTtzdG9wLW9wYWNpdHk6MSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxwYXRoIGQ9Ik0xMSA2SDR2MWgxdjFoMXYxaDF2MWgxVjloMVY4aDFWN2gxVjZaIiBmaWxsPSJ1cmwoI2EpIi8+PC9zdmc+"),var(--scrollbar-y)}.has-scrollbar::-webkit-scrollbar-button:horizontal{width:16px}.has-scrollbar::-webkit-scrollbar-button:horizontal:start{background:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTciIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJhIiB4MT0iMCUiIHkxPSIxMDAlIiB4Mj0iMCUiIHkyPSIwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3R5bGU9InN0b3AtY29sb3I6IzMzMztzdG9wLW9wYWNpdHk6MSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3R5bGU9InN0b3AtY29sb3I6I2FhYTtzdG9wLW9wYWNpdHk6MSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxwYXRoIGQ9Ik05IDRIOHYxSDd2MUg2djFINXYxaDF2MWgxdjFoMXYxaDFWNFoiIGZpbGw9InVybCgjYSkiLz48L3N2Zz4="),var(--scrollbar-x)}.has-scrollbar::-webkit-scrollbar-button:horizontal:end{background:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTciIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJhIiB4MT0iMCUiIHkxPSIxMDAlIiB4Mj0iMCUiIHkyPSIwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3R5bGU9InN0b3AtY29sb3I6IzMzMztzdG9wLW9wYWNpdHk6MSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3R5bGU9InN0b3AtY29sb3I6I2FhYTtzdG9wLW9wYWNpdHk6MSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxwYXRoIGQ9Ik03IDRINnY3aDF2LTFoMVY5aDFWOGgxVjdIOVY2SDhWNUg3VjRaIiBmaWxsPSJ1cmwoI2EpIi8+PC9zdmc+"),var(--scrollbar-x)}.has-scrollbar::-webkit-scrollbar-button:hover{background-color:var(--button-face);border-color:var(--button-border-color);border-radius:var(--border-radius);box-shadow:var(--button-shadow)}.has-scrollbar::-webkit-scrollbar-button:hover:vertical{height:17px}.has-scrollbar::-webkit-scrollbar-button:hover:vertical:start{background:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTciIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJhIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjEwMCUiIHkyPSIwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3R5bGU9InN0b3AtY29sb3I6IzMzMztzdG9wLW9wYWNpdHk6MSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3R5bGU9InN0b3AtY29sb3I6I2FhYTtzdG9wLW9wYWNpdHk6MSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxwYXRoIGQ9Ik04IDZIN3YxSDZ2MUg1djFINHYxaDdWOWgtMVY4SDlWN0g4VjZaIiBmaWxsPSJ1cmwoI2EpIi8+PC9zdmc+"),linear-gradient(to right,var(--button-face-hover) 45%,var(--button-shade-light-hovered) 45%);border-color:var(--button-border-color-hovered)}.has-scrollbar::-webkit-scrollbar-button:hover:vertical:end{background:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTciIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJhIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjEwMCUiIHkyPSIwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3R5bGU9InN0b3AtY29sb3I6IzMzMztzdG9wLW9wYWNpdHk6MSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3R5bGU9InN0b3AtY29sb3I6I2FhYTtzdG9wLW9wYWNpdHk6MSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxwYXRoIGQ9Ik0xMSA2SDR2MWgxdjFoMXYxaDF2MWgxVjloMVY4aDFWN2gxVjZaIiBmaWxsPSJ1cmwoI2EpIi8+PC9zdmc+"),linear-gradient(to right,var(--button-face-hover) 45%,var(--button-shade-light-hovered) 45%);border-color:var(--button-border-color-hovered)}.has-scrollbar::-webkit-scrollbar-button:hover:horizontal{width:16px}.has-scrollbar::-webkit-scrollbar-button:hover:horizontal:start{background:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTciIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJhIiB4MT0iMCUiIHkxPSIxMDAlIiB4Mj0iMCUiIHkyPSIwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3R5bGU9InN0b3AtY29sb3I6IzMzMztzdG9wLW9wYWNpdHk6MSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3R5bGU9InN0b3AtY29sb3I6I2FhYTtzdG9wLW9wYWNpdHk6MSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxwYXRoIGQ9Ik05IDRIOHYxSDd2MUg2djFINXYxaDF2MWgxdjFoMXYxaDFWNFoiIGZpbGw9InVybCgjYSkiLz48L3N2Zz4="),linear-gradient(to bottom,var(--button-face-hover) 45%,var(--button-shade-light-hovered) 45%);border-color:var(--button-border-color-hovered)}.has-scrollbar::-webkit-scrollbar-button:hover:horizontal:end{background:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTciIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJhIiB4MT0iMCUiIHkxPSIxMDAlIiB4Mj0iMCUiIHkyPSIwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3R5bGU9InN0b3AtY29sb3I6IzMzMztzdG9wLW9wYWNpdHk6MSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3R5bGU9InN0b3AtY29sb3I6I2FhYTtzdG9wLW9wYWNpdHk6MSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxwYXRoIGQ9Ik03IDRINnY3aDF2LTFoMVY5aDFWOGgxVjdIOVY2SDhWNUg3VjRaIiBmaWxsPSJ1cmwoI2EpIi8+PC9zdmc+"),linear-gradient(to bottom,var(--button-face-hover) 45%,var(--button-shade-light-hovered) 45%);border-color:var(--button-border-color-hovered)}.has-scrollbar::-webkit-scrollbar-button:active{background-color:var(--button-face);border-color:var(--button-border-color);border-radius:var(--border-radius);box-shadow:var(--button-shadow)}.has-scrollbar::-webkit-scrollbar-button:active:vertical{height:17px}.has-scrollbar::-webkit-scrollbar-button:active:vertical:start{background:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTciIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJhIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjEwMCUiIHkyPSIwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3R5bGU9InN0b3AtY29sb3I6IzMzMztzdG9wLW9wYWNpdHk6MSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3R5bGU9InN0b3AtY29sb3I6I2FhYTtzdG9wLW9wYWNpdHk6MSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxwYXRoIGQ9Ik04IDZIN3YxSDZ2MUg1djFINHYxaDdWOWgtMVY4SDlWN0g4VjZaIiBmaWxsPSJ1cmwoI2EpIi8+PC9zdmc+"),linear-gradient(to right,var(--button-face-active) 45%,var(--button-shade-light-active) 45%);border-color:var(--button-border-color-active)}.has-scrollbar::-webkit-scrollbar-button:active:vertical:end{background:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTciIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJhIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjEwMCUiIHkyPSIwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3R5bGU9InN0b3AtY29sb3I6IzMzMztzdG9wLW9wYWNpdHk6MSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3R5bGU9InN0b3AtY29sb3I6I2FhYTtzdG9wLW9wYWNpdHk6MSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxwYXRoIGQ9Ik0xMSA2SDR2MWgxdjFoMXYxaDF2MWgxVjloMVY4aDFWN2gxVjZaIiBmaWxsPSJ1cmwoI2EpIi8+PC9zdmc+"),linear-gradient(to right,var(--button-face-active) 45%,var(--button-shade-light-active) 45%);border-color:var(--button-border-color-active)}.has-scrollbar::-webkit-scrollbar-button:active:horizontal{width:16px}.has-scrollbar::-webkit-scrollbar-button:active:horizontal:start{background:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTciIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJhIiB4MT0iMCUiIHkxPSIxMDAlIiB4Mj0iMCUiIHkyPSIwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3R5bGU9InN0b3AtY29sb3I6IzMzMztzdG9wLW9wYWNpdHk6MSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3R5bGU9InN0b3AtY29sb3I6I2FhYTtzdG9wLW9wYWNpdHk6MSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxwYXRoIGQ9Ik05IDRIOHYxSDd2MUg2djFINXYxaDF2MWgxdjFoMXYxaDFWNFoiIGZpbGw9InVybCgjYSkiLz48L3N2Zz4="),linear-gradient(to bottom,var(--button-face-active) 45%,var(--button-shade-light-active) 45%);border-color:var(--button-border-color-active)}.has-scrollbar::-webkit-scrollbar-button:active:horizontal:end{background:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTciIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJhIiB4MT0iMCUiIHkxPSIxMDAlIiB4Mj0iMCUiIHkyPSIwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3R5bGU9InN0b3AtY29sb3I6IzMzMztzdG9wLW9wYWNpdHk6MSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3R5bGU9InN0b3AtY29sb3I6I2FhYTtzdG9wLW9wYWNpdHk6MSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxwYXRoIGQ9Ik03IDRINnY3aDF2LTFoMVY5aDFWOGgxVjdIOVY2SDhWNUg3VjRaIiBmaWxsPSJ1cmwoI2EpIi8+PC9zdmc+"),linear-gradient(to bottom,var(--button-face-active) 45%,var(--button-shade-light-active) 45%);border-color:var(--button-border-color-active)}:root{--search-icon:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiI+PHBhdGggc3Ryb2tlPSIjMjA3MGI5IiBkPSJNMTAuNSAxQzguMDIgMSA2IDMuMDIgNiA1LjVhNC40NSA0LjQ1IDAgMCAwIDEgMi43OTNMMi4wMjMgMTMuMjdsLjcwNC43MUw3LjcwNyA5Yy43Ny42MTcgMS43MzQgMSAyLjc5MyAxIDIuNDggMCA0LjUtMi4wMiA0LjUtNC41UzEyLjk4IDEgMTAuNSAxWm0wIDFDMTIuNDM4IDIgMTQgMy41NjMgMTQgNS41IDE0IDcuNDM4IDEyLjQzNyA5IDEwLjUgOUEzLjQ5NCAzLjQ5NCAwIDAgMSA3IDUuNUM3IDMuNTYyIDguNTYzIDIgMTAuNSAyWiIvPjwvc3ZnPg==");--search-button:var(--search-icon) no-repeat center}[type=search]{background-color:var(--button-highlight);border:1px solid transparent;border-radius:2px;box-shadow:inset 1px 1px 0 var(--button-border-color),inset -1px -1px 0 #ccc;box-sizing:border-box;font:var(--font);height:24px;min-width:187px;padding:3px 6px}[type=search]:-moz-placeholder-shown{background-image:var(--search-icon);background-position:calc(100% - 8px);background-repeat:no-repeat;background-size:14px}[type=search]:placeholder-shown{background-image:var(--search-icon);background-position:calc(100% - 8px);background-repeat:no-repeat;background-size:14px}[type=search]:focus{outline:none}[type=search]::-moz-placeholder{font-style:italic}[type=search]::placeholder{font-style:italic}.searchbox [type=search]{padding-right:26px}.searchbox [type=search]+[aria-label=search]{background:var(--search-button),var(--button-gradient);background-size:14px;border-radius:0;min-height:22px;min-width:26px;padding:0;position:absolute;right:1px;top:1px}.searchbox [type=search]+[aria-label=search]:before{background:var(--search-button),var(--button-gradient-hovered);background-size:14px;border-radius:0}.searchbox [type=search]+[aria-label=search]:after{background:var(--search-button),var(--button-gradient-active);background-size:14px;border-radius:0}.searchbox [type=search]+[aria-label=search]:focus-visible{outline:1px dotted #000;outline-offset:-4px}.searchbox{display:inline-block;position:relative}:root{--thumb-w:10px;--thumb-h:18px;--thumb-icon:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAASCAYAAABit09LAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAC7SURBVHgBlZLBCYQwEEVj9CDYgRfbswF7sRAbsArPdhBICDmEzPoDE9CdXeKH0eHP48fINOrSPM+k/mhd16YDtCyLmqZJhM7zxIs6PAF570WQAzJIRLkksd89DUl939eB1Ym3b0wpiQBmIYSXiTFGZYwRgWEY6o8uIPQLZGlu2rYtP54L3g3c912N45gHSEahh4dZERZj2zZyztFxHLnQw/vaLIattbmeULkMdg6XxLFaa3WB7MlCirTIHxVUkxicbwSEAAAAAElFTkSuQmCC");--thumb-icon-box:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAASCAYAAABit09LAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAABrSURBVHgB7dLNCcAgDAXgWASjm9TJ3Egns8N4SGv6c2gbyQA+kED40IPPwJGUEsEgpRRjO8o5i6i11gfZe7HVCojIJ4QA6D3vnXM8F1DmBUkL1TdOOIRGC2X7hcIvPu1ZY/wFV83OhzTF3QGRrxiDB3GCSQAAAABJRU5ErkJggg==");--thumb-icon-active:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAASCAYAAABit09LAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACsSURBVHgB3ZKxCoMwEIYvJWOn0r10LHTuVDp1KIU+RN+gT9FZ6AP0LYqDY+nQWXAScXMQdRYh+ouRqEF0cPGHHJfcl7sbfkaFroYlqEefx5lxQK/blu6rjRZ6R34RLcFxAWSkmRZEbUkeLWigZgVymZhuoid264lGjwMvTkhmtYsqvKEGMQQY43jYNwoy//7t0j31b8DPXyBOcVYe5Kr9mDpKdoY6ndoCrDNyDnRZRNbxQWFyAAAAAElFTkSuQmCC");--thumb-icon-box-active:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAASCAYAAABit09LAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAABmSURBVHgB7dKxCYAwEAXQfyEKYhrBThdwCwsLyRKukFGcRiyyh0tY2kcT0fJIn/zijg+v/IQnerUOTDYzkfToWkbOQcM6+ZX5OMNvVIVeFehqEbopXyIQmQzTgf969qFlIfkTM9wbGH4SS8YdBX4AAAAASUVORK5CYII=")}input[type=range]{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:transparent;padding:10px 1px;width:100%}input[type=range]:focus-visible{outline:1px dotted #000}input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;background:var(--thumb-icon);height:var(--thumb-h);transform:translateY(-7px);width:var(--thumb-w)}input[type=range]::-webkit-slider-thumb:active{background:var(--thumb-icon-active)}input[type=range]::-moz-range-thumb{background:var(--thumb-icon);border:0;border-radius:0;height:var(--thumb-h);width:var(--thumb-w)}input[type=range]::-moz-range-thumb:active{background:var(--thumb-icon-active)}input[type=range]::-webkit-slider-runnable-track{background:var(--surface);box-shadow:inset 1px 1px 1px #999,inset -1px 0 #999,0 1px #fff;box-sizing:border-box;height:3px;width:100%}input[type=range]::-moz-range-track{background:var(--surface);box-shadow:inset 1px 1px 1px #999,inset -1px 0 #999,0 1px #fff;box-sizing:border-box;height:3px;width:100%}input[type=range].has-box-indicator::-webkit-slider-thumb{background:var(--thumb-icon-box)}input[type=range].has-box-indicator::-webkit-slider-thumb:active{background:var(--thumb-icon-box-active)}input[type=range].has-box-indicator::-moz-range-thumb{background:var(--thumb-icon-box)}input[type=range].has-box-indicator::-moz-range-thumb:active{background:var(--thumb-icon-box-active)}.is-vertical{display:inline-block;height:150px;transform:translateY(50%);width:4px}.is-vertical>input[type=range]{height:4px;margin:0 calc(var(--grouped-element-spacing) + var(--range-spacing)) 0 var(--range-spacing);transform:rotate(270deg) translateX(calc(-50% + var(--element-spacing)));transform-origin:left;width:150px}.is-vertical>input[type=range]::-webkit-slider-thumb{transform:translateY(-8px) scaleX(-1)}.is-vertical>input[type=range]::-moz-range-thumb{transform:translateY(2px) scaleX(-1)}.is-vertical>input[type=range].has-box-indicator::-webkit-slider-thumb{transform:translateY(-9px) scaleX(-1)}.is-vertical>input[type=range].has-box-indicator::-moz-range-thumb{transform:translateY(0) scaleX(-1)}.loader,.spinner{background:url("data:image/png;base64,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") 50%;color:transparent;display:inline-block;height:20px;width:20px}.loader.animate,.spinner.animate{background-image:url("data:image/gif;base64,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")}:root{--tab-border:1px solid #888;--tab-border-color:#888;--tab-bg:#fff}menu[role=tablist]{display:flex;list-style-type:none;margin:0 0 -2px;padding-left:3px;position:relative;text-indent:0}menu[role=tablist] button{border-radius:0;color:#222;display:block;min-width:unset;padding:2px 6px;text-decoration:none;z-index:1}menu[role=tablist] button[aria-selected=true]{background:var(--tab-bg);border-bottom:0;box-shadow:none;margin:-2px 0 1px -3px;padding-bottom:4px;position:relative;z-index:8}menu[role=tablist] button[aria-selected=true]:after,menu[role=tablist] button[aria-selected=true]:before{content:none}menu[role=tablist] button[aria-selected=true]:hover{border-color:var(--tab-border-color)}menu[role=tablist] button[aria-selected=true].active,menu[role=tablist] button[aria-selected=true]:active,menu[role=tablist] button[aria-selected=true]:focus{-webkit-animation:none;animation:none;border-color:var(--tab-border-color)}menu[role=tablist] button[aria-selected=true]:focus-visible{outline:1px dotted #222;outline-offset:-4px}menu[role=tablist] button:before{border-radius:0}menu[role=tablist] button:after{content:none}menu[role=tablist] button:disabled{opacity:.6}menu[role=tablist].justified button{flex-grow:1;text-align:center}[role=tabpanel]{background:var(--tab-bg);border:var(--tab-border);clear:both;margin-bottom:9px;padding:14px;position:relative;z-index:2}input[type=email],input[type=number],input[type=password],input[type=text],input[type=url]{height:23px}input[type=email],input[type=number],input[type=password],input[type=text],input[type=url],textarea{background-color:var(--button-highlight);border:1px solid #ccc;border-radius:2px;border-top:1px solid var(--button-border-color);box-sizing:border-box;font:var(--font);padding:3px 4px 5px}input[type=email]:focus,input[type=number]:focus,input[type=password]:focus,input[type=text]:focus,input[type=url]:focus,textarea:focus{border-color:var(--button-shade-light-hovered);border-top-color:var(--button-shade-light-active);outline:none}:root{--treeview-square-size:8px;--treeview-spacing:20px}ul.tree-view{display:block;font:var(--font);margin:0;padding:6px 6px 6px var(--treeview-spacing)}ul.tree-view li{list-style-type:none;margin-top:4px;position:relative}ul.tree-view a{color:#000;text-decoration:none}ul.tree-view ul{margin-top:4px;padding-left:var(--treeview-spacing)}ul.tree-view.has-container{background:#fff;border:1px solid var(--button-border-color)}ul.tree-view.has-collapse-button details>summary::-webkit-details-marker,ul.tree-view.has-collapse-button details>summary::marker{display:none}ul.tree-view.has-collapse-button details>summary:before{background:linear-gradient(to bottom,var(--button-face) 45%,var(--button-shade-light));border:1px solid #919191;border-radius:1px;color:#4b63a7;content:"\002b";font-size:8pt;font-weight:700;height:var(--treeview-square-size);left:calc(var(--treeview-square-size)*2*-1);line-height:calc(var(--treeview-square-size) - 50% + var(--treeview-square-size)/2);margin:0;right:unset;text-align:center;top:calc(50% - var(--treeview-square-size)/2);width:var(--treeview-square-size)}ul.tree-view.has-collapse-button details[open]>summary:before{content:"\2013";transform:none}ul.tree-view.has-connector ul{position:relative}ul.tree-view.has-connector ul:before{border-left:1px dotted #000;content:"";height:calc(100% - var(--treeview-square-size));left:var(--treeview-square-size);position:absolute;top:0}ul.tree-view.has-connector ul li:before{border-bottom:1px dotted #000;content:"";position:absolute;right:calc(100% + var(--treeview-square-size)/4);top:var(--treeview-square-size);width:calc(var(--treeview-spacing)/2)}:root{--link-color:#06c;--link-color-hovered:#39f;--primary-color:#039;--secondary-color:#000}a{color:var(--link-color);text-decoration:none}a:focus-visible{outline:1px dotted var(--link-color)}a:focus,a:hover{color:var(--link-color-hovered);text-decoration:underline}.instruction{color:var(--secondary-color);font:var(--font);font-weight:400;margin:0 0 20px}.instruction-primary{color:var(--primary-color);font-size:12pt}.header{font:var(--font);font-weight:400}.header-document{color:var(--secondary-color);font-family:Calibri,Noto Sans,sans-serif;font-size:17pt}.header-group{color:var(--primary-color);font-size:11pt}:root{--window-spacing:6px;--window-border:1px solid;--window-border-radius:6px;--window-border-color:#000000b3;--window-background-color:#4580c4;--window-background-glass-stripes:linear-gradient(135deg,#fff5 70px,transparent 100px),linear-gradient(225deg,#fff5 70px,transparent 100px),linear-gradient(54deg,#0002 0 4%,#6661 6% 6%,#0002 8% 10%,#0002 15% 16%,#aaa1 17% 18%,#0002 23% 24%,#bbb2 25% 26%,#0002 31% 33%,#0002 34% 34.5%,#bbb2 36% 40%,#0002 41% 41.5%,#bbb2 44% 45%,#bbb2 46% 47%,#0002 48% 49%,#0002 50% 50.5%,#0002 56% 56.5%,#bbb2 57% 63%,#0002 67% 69%,#bbb2 69.5% 70%,#0002 73.5% 74%,#bbb2 74.5% 79%,#0002 80% 84%,#aaa2 85% 86%,#0002 87%,#bbb1 90%) left center/100vw 100vh no-repeat fixed;--window-background:linear-gradient(to right,#ffffff66,#0000001a,#ffffff33),var(--window-background-color);--control-border-color:#0000004d;--control-border-radius:5px;--control-inset-shadow:inset 0 0 0 1px #fffa;--control-background:linear-gradient(#ffffff80,#ffffff4d 45%,#0000001a 50%,#0000001a 75%,#ffffff80);--control-background-hovered:radial-gradient(circle at bottom,#2aceda,transparent 65%),linear-gradient(#b6d9ee 50%,#1a6ca1 0);--control-background-active:radial-gradient(circle at bottom,#0bfdfa,transparent 65%),linear-gradient(#86a7bc 50%,#092747 0);--control-background-close:radial-gradient(circle at -60% 50%,#0007 5% 10%,#0000 50%),radial-gradient(circle at 160% 50%,#0007 5% 10%,#0000 50%),linear-gradient(#e0a197e5,#cf796a 25% 50%,#d54f36 50%);--control-background-close-hovered:radial-gradient(circle at 50% 170%,#f4e676 10% 20%,#0000 60%),radial-gradient(circle at -60% 50%,#000a 5% 10%,#0000 50%),radial-gradient(circle at 160% 50%,#000a 5% 10%,#0000 50%),linear-gradient(#fb9d8b,#ee6d56 25% 50%,#d42809 50%);--control-background-close-active:radial-gradient(circle at 50% 170%,#dcc03f 10% 20%,#0000 60%),radial-gradient(circle at -60% 50%,#000 5% 10%,#0000 50%),radial-gradient(circle at 160% 50%,#000 5% 10%,#0000 50%),linear-gradient(#d1a894,#b67562 25% 50%,#7d0d01 50%)}.window{border:var(--window-border) var(--window-border-color);box-shadow:2px 2px 10px 1px var(--window-border-color),inset 0 0 0 1px #fffa;font:var(--font);position:relative;z-index:0}.window,.window:before{border-radius:var(--window-border-radius)}.window:before{background:linear-gradient(transparent 20%,#ffffffb3 40%,transparent 41%),var(--window-background);background-color:var(--window-background-color);box-shadow:inset 0 0 0 1px #fffd;content:"";height:100%;left:0;position:absolute;top:0;width:100%;z-index:-1}.window-body{background:var(--surface);border:var(--window-border) var(--window-border-color);box-shadow:0 0 0 1px #fff9;margin:var(--window-spacing);margin-top:0}.window-body.has-space{padding:var(--window-spacing)}.window-body pre{margin:calc(var(--window-spacing)*-1)}.window footer,.window-footer{background:var(--surface);border:var(--window-border) var(--window-border-color);border-top:0;box-shadow:0 .5px 1px .5px #fff;margin:var(--window-spacing);margin-top:calc(var(--window-spacing)*-1 - 1px);padding:10px;position:relative}.window footer:before,.window-footer:before{box-shadow:inset 0 1px #0000004d,inset 0 -1px #fff;content:"";height:2px;left:0;position:absolute;top:0;width:100%}.window.is-bright .window-body{background:#fff}.window.is-bright .window-footer,.window.is-bright footer{background:#eee;box-shadow:inset 0 1px 3px #ddd,0 1px 0 #fff9,1px 1px 0 #fff9,-1px 1px 0 #fff9}.window.is-bright .window-footer:before,.window.is-bright footer:before{content:none}.window.glass:before{opacity:.6}.window.glass:after{-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);border:none;border-radius:var(--window-border-radius);content:"";height:100%;left:0;position:absolute;top:0;width:100%;z-index:-10}.window.glass>.title-bar{background:var(--window-background-glass-stripes)}.window>.title-bar{border:0;box-shadow:inset 0 1px 0 #fffd,inset 1px 0 0 #fffd,inset -1px 0 0 #fffd}.window fieldset{margin-bottom:9px}.window[role=dialog]{left:50%;opacity:0;position:fixed;top:50%;transform:translate(-50%,-50%);transition-duration:.2s;transition-property:visibility,opacity;visibility:hidden;z-index:999}.window[role=dialog]:target{opacity:1;visibility:visible}.title-bar{align-items:center;background:var(--window-background);background-color:var(--window-background-color);border:var(--window-border) var(--window-border-color);border-radius:var(--window-border-radius) var(--window-border-radius) 0 0;box-shadow:inset 0 0 0 1px #fff9;display:flex;font:var(--font);justify-content:space-between;padding:var(--window-spacing);padding-top:0}.title-bar-text{color:#000;letter-spacing:0;line-height:15px;padding-top:var(--window-spacing);text-shadow:0 0 10px #fff,0 0 10px #fff,0 0 10px #fff,0 0 10px #fff,0 0 10px #fff,0 0 10px #fff,0 0 10px #fff,0 0 10px #fff}.title-bar-controls{background:#fff3;border:var(--window-border) var(--control-border-color);border-radius:0 0 var(--control-border-radius) var(--control-border-radius);border-top:0;box-shadow:0 1px 0 #fffa,1px 0 0 #fffa,-1px 0 0 #fffa;display:flex}.title-bar-controls button{background:none;border:0;border-radius:0;border-right:var(--window-border) var(--control-border-color);box-shadow:none;box-sizing:border-box;min-height:19px;min-width:29px;padding:0;position:relative}.title-bar-controls button:after{content:none}.title-bar-controls button:active,.title-bar-controls button:hover{background:none}.title-bar-controls button:disabled:before{opacity:.4}.title-bar-controls button:before{border-radius:0;bottom:0;box-shadow:inset 0 0 0 1px #fff5;content:"";left:0;opacity:1;position:absolute;right:0;top:0}.title-bar-controls button:not(:hover):before{opacity:1;transition:none}.title-bar-controls button.is-minimize:before,.title-bar-controls button[aria-label=Minimize]:before{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAFCAYAAABxeg0vAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAA7SURBVHgBlY+xDQAgDMNaiQ9B8AHcxAlI/NYtKwj6QOohUzxYc+1HAqQ3e03qXNpwwcyE5QsAaEGjDRf8ZAza6Bz6VQAAAABJRU5ErkJggg==") no-repeat center 10px}.title-bar-controls button.is-maximize:before,.title-bar-controls button[aria-label=Maximize]:before{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAYAAACALL/6AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAABsSURBVHgBlZHBCYAwDEVT6YaKbqArOILgBLqBosP1VkhAaQ6S1lKad+ihPy8kxLT9+IACG57r2KqKu2GCBpTYtEMOOQELzrnv4z53I4vDjjJnwXsPJWTOAiJGHVNB5pGwLjPk+AlEBLUY7eFebCosBHOR7vYAAAAASUVORK5CYII=") no-repeat 50%}.title-bar-controls button.is-help:before,.title-bar-controls button[aria-label=Help]:before{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAMBAMAAACtsOGuAAAAG1BMVEUAAABTVmb////39/fa2trm5ubj4+Pq6urg4OByvnYHAAAAAXRSTlMAQObYZgAAADtJREFUCNdjYBQUFGAQVFISZBBSUlJkEDYUNmQQFBAvZGBgDA1kYBBLE2RgkGgUYGAQBDIYRBwhBJgLAKBIBQ2X+PZ0AAAAAElFTkSuQmCC") no-repeat 50%}.title-bar-controls button.is-restore:before,.title-bar-controls button[aria-label=Restore]:before{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACVSURBVHgBlVDLCoMwENwU/7ClvRYK7b2lCIJHEQQ/QEHwqujfBXJIQMnihg34iHPJ7GNm2AhYcL2/JwhAxIuhq3aXb48PiFBna2YFERVHzoQLnAQmSCmxeL5+3rBtSsdpBwVKKTcY+1rY197G+8RRoLVejed94igwxrgB/zXeJ+4Jijz2Erjg+8/WE7ZAt6EgSUsIxQwaJEWv7G6SSgAAAABJRU5ErkJggg==") no-repeat 50%}.title-bar-controls button.is-close,.title-bar-controls button[aria-label=Close]{min-width:48px}.title-bar-controls button.is-close:before,.title-bar-controls button[aria-label=Close]:before{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAKCAYAAABi8KSDAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACUSURBVHgBlZFNCoQwDIVbmRvOMHOAAd0K/uDGlYKiCG4VPICi9yu0oCSQoFUXFtKEl6+voZXvr7sKay1TL690FOexY+Hz87i2decOuDKQsNGVe8AGYTRJIh0Y+orBvxszCPllOymlxN06jNE26Qnwg4zdHQLrMhFaawwAqAadDPE1ijwUxhiMKCmxCZk06OMYTz5lAx3xWDeXkLNAAAAAAElFTkSuQmCC") no-repeat 50%}.title-bar-controls button:first-child,.title-bar-controls button:first-child:before{border-bottom-left-radius:var(--control-border-radius)}.title-bar-controls button:last-child,.title-bar-controls button:last-child:before{border:0;border-bottom-right-radius:var(--control-border-radius)}.title-bar-controls button:focus{-webkit-animation:none;animation:none;outline:none}.title-bar.active .title-bar-controls,.window.active .title-bar .title-bar-controls{border-color:var(--window-border-color)}.title-bar.active .title-bar-controls button,.window.active .title-bar .title-bar-controls button{border-color:var(--window-border-color);box-shadow:var(--control-inset-shadow)}.title-bar.active .title-bar-controls button:after,.window.active .title-bar .title-bar-controls button:after{content:none}.title-bar.active .title-bar-controls button.is-minimize,.title-bar.active .title-bar-controls button[aria-label=Minimize],.window.active .title-bar .title-bar-controls button.is-minimize,.window.active .title-bar .title-bar-controls button[aria-label=Minimize]{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAFCAYAAABxeg0vAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAA7SURBVHgBlY+xDQAgDMNaiQ9B8AHcxAlI/NYtKwj6QOohUzxYc+1HAqQ3e03qXNpwwcyE5QsAaEGjDRf8ZAza6Bz6VQAAAABJRU5ErkJggg==") no-repeat center 10px,var(--control-background)}.title-bar.active .title-bar-controls button.is-minimize:before,.title-bar.active .title-bar-controls button[aria-label=Minimize]:before,.window.active .title-bar .title-bar-controls button.is-minimize:before,.window.active .title-bar .title-bar-controls button[aria-label=Minimize]:before{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAFCAYAAABxeg0vAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAA7SURBVHgBlY+xDQAgDMNaiQ9B8AHcxAlI/NYtKwj6QOohUzxYc+1HAqQ3e03qXNpwwcyE5QsAaEGjDRf8ZAza6Bz6VQAAAABJRU5ErkJggg==") no-repeat center 10px,var(--control-background-hovered);border-bottom-left-radius:var(--control-border-radius);box-shadow:0 0 7px 3px #5dc4f0,var(--control-inset-shadow);content:"";opacity:0;transition:opacity .3s linear}.title-bar.active .title-bar-controls button.is-minimize:focus-visible:before,.title-bar.active .title-bar-controls button.is-minimize:hover:before,.title-bar.active .title-bar-controls button[aria-label=Minimize]:focus-visible:before,.title-bar.active .title-bar-controls button[aria-label=Minimize]:hover:before,.window.active .title-bar .title-bar-controls button.is-minimize:focus-visible:before,.window.active .title-bar .title-bar-controls button.is-minimize:hover:before,.window.active .title-bar .title-bar-controls button[aria-label=Minimize]:focus-visible:before,.window.active .title-bar .title-bar-controls button[aria-label=Minimize]:hover:before{opacity:1;transition:opacity .1s linear}.title-bar.active .title-bar-controls button.is-minimize:active:before,.title-bar.active .title-bar-controls button[aria-label=Minimize]:active:before,.window.active .title-bar .title-bar-controls button.is-minimize:active:before,.window.active .title-bar .title-bar-controls button[aria-label=Minimize]:active:before{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAFCAYAAABxeg0vAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAA7SURBVHgBlY+xDQAgDMNaiQ9B8AHcxAlI/NYtKwj6QOohUzxYc+1HAqQ3e03qXNpwwcyE5QsAaEGjDRf8ZAza6Bz6VQAAAABJRU5ErkJggg==") no-repeat center 10px,var(--control-background-active)}.title-bar.active .title-bar-controls button.is-maximize,.title-bar.active .title-bar-controls button[aria-label=Maximize],.window.active .title-bar .title-bar-controls button.is-maximize,.window.active .title-bar .title-bar-controls button[aria-label=Maximize]{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAYAAACALL/6AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAABsSURBVHgBlZHBCYAwDEVT6YaKbqArOILgBLqBosP1VkhAaQ6S1lKad+ihPy8kxLT9+IACG57r2KqKu2GCBpTYtEMOOQELzrnv4z53I4vDjjJnwXsPJWTOAiJGHVNB5pGwLjPk+AlEBLUY7eFebCosBHOR7vYAAAAASUVORK5CYII=") no-repeat 50%,var(--control-background)}.title-bar.active .title-bar-controls button.is-maximize:before,.title-bar.active .title-bar-controls button[aria-label=Maximize]:before,.window.active .title-bar .title-bar-controls button.is-maximize:before,.window.active .title-bar .title-bar-controls button[aria-label=Maximize]:before{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAYAAACALL/6AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAABsSURBVHgBlZHBCYAwDEVT6YaKbqArOILgBLqBosP1VkhAaQ6S1lKad+ihPy8kxLT9+IACG57r2KqKu2GCBpTYtEMOOQELzrnv4z53I4vDjjJnwXsPJWTOAiJGHVNB5pGwLjPk+AlEBLUY7eFebCosBHOR7vYAAAAASUVORK5CYII=") no-repeat 50%,var(--control-background-hovered);box-shadow:0 0 7px 3px #5dc4f0,var(--control-inset-shadow);content:"";opacity:0;transition:opacity .3s linear}.title-bar.active .title-bar-controls button.is-maximize:focus-visible:before,.title-bar.active .title-bar-controls button.is-maximize:hover:before,.title-bar.active .title-bar-controls button[aria-label=Maximize]:focus-visible:before,.title-bar.active .title-bar-controls button[aria-label=Maximize]:hover:before,.window.active .title-bar .title-bar-controls button.is-maximize:focus-visible:before,.window.active .title-bar .title-bar-controls button.is-maximize:hover:before,.window.active .title-bar .title-bar-controls button[aria-label=Maximize]:focus-visible:before,.window.active .title-bar .title-bar-controls button[aria-label=Maximize]:hover:before{opacity:1;transition:opacity .1s linear}.title-bar.active .title-bar-controls button.is-maximize:active:before,.title-bar.active .title-bar-controls button[aria-label=Maximize]:active:before,.window.active .title-bar .title-bar-controls button.is-maximize:active:before,.window.active .title-bar .title-bar-controls button[aria-label=Maximize]:active:before{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAYAAACALL/6AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAABsSURBVHgBlZHBCYAwDEVT6YaKbqArOILgBLqBosP1VkhAaQ6S1lKad+ihPy8kxLT9+IACG57r2KqKu2GCBpTYtEMOOQELzrnv4z53I4vDjjJnwXsPJWTOAiJGHVNB5pGwLjPk+AlEBLUY7eFebCosBHOR7vYAAAAASUVORK5CYII=") no-repeat 50%,var(--control-background-active)}.title-bar.active .title-bar-controls button.is-help,.title-bar.active .title-bar-controls button[aria-label=Help],.window.active .title-bar .title-bar-controls button.is-help,.window.active .title-bar .title-bar-controls button[aria-label=Help]{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAMBAMAAACtsOGuAAAAG1BMVEUAAABTVmb////39/fa2trm5ubj4+Pq6urg4OByvnYHAAAAAXRSTlMAQObYZgAAADtJREFUCNdjYBQUFGAQVFISZBBSUlJkEDYUNmQQFBAvZGBgDA1kYBBLE2RgkGgUYGAQBDIYRBwhBJgLAKBIBQ2X+PZ0AAAAAElFTkSuQmCC") no-repeat 50%,var(--control-background)}.title-bar.active .title-bar-controls button.is-help:before,.title-bar.active .title-bar-controls button[aria-label=Help]:before,.window.active .title-bar .title-bar-controls button.is-help:before,.window.active .title-bar .title-bar-controls button[aria-label=Help]:before{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAMBAMAAACtsOGuAAAAG1BMVEUAAABTVmb////39/fa2trm5ubj4+Pq6urg4OByvnYHAAAAAXRSTlMAQObYZgAAADtJREFUCNdjYBQUFGAQVFISZBBSUlJkEDYUNmQQFBAvZGBgDA1kYBBLE2RgkGgUYGAQBDIYRBwhBJgLAKBIBQ2X+PZ0AAAAAElFTkSuQmCC") no-repeat 50%,var(--control-background-hovered);box-shadow:0 0 7px 3px #5dc4f0,var(--control-inset-shadow);content:"";opacity:0;transition:opacity .3s linear}.title-bar.active .title-bar-controls button.is-help:focus-visible:before,.title-bar.active .title-bar-controls button.is-help:hover:before,.title-bar.active .title-bar-controls button[aria-label=Help]:focus-visible:before,.title-bar.active .title-bar-controls button[aria-label=Help]:hover:before,.window.active .title-bar .title-bar-controls button.is-help:focus-visible:before,.window.active .title-bar .title-bar-controls button.is-help:hover:before,.window.active .title-bar .title-bar-controls button[aria-label=Help]:focus-visible:before,.window.active .title-bar .title-bar-controls button[aria-label=Help]:hover:before{opacity:1;transition:opacity .1s linear}.title-bar.active .title-bar-controls button.is-help:active:before,.title-bar.active .title-bar-controls button[aria-label=Help]:active:before,.window.active .title-bar .title-bar-controls button.is-help:active:before,.window.active .title-bar .title-bar-controls button[aria-label=Help]:active:before{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAMBAMAAACtsOGuAAAAG1BMVEUAAABTVmb////39/fa2trm5ubj4+Pq6urg4OByvnYHAAAAAXRSTlMAQObYZgAAADtJREFUCNdjYBQUFGAQVFISZBBSUlJkEDYUNmQQFBAvZGBgDA1kYBBLE2RgkGgUYGAQBDIYRBwhBJgLAKBIBQ2X+PZ0AAAAAElFTkSuQmCC") no-repeat 50%,var(--control-background-active)}.title-bar.active .title-bar-controls button.is-restore,.title-bar.active .title-bar-controls button[aria-label=Restore],.window.active .title-bar .title-bar-controls button.is-restore,.window.active .title-bar .title-bar-controls button[aria-label=Restore]{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACVSURBVHgBlVDLCoMwENwU/7ClvRYK7b2lCIJHEQQ/QEHwqujfBXJIQMnihg34iHPJ7GNm2AhYcL2/JwhAxIuhq3aXb48PiFBna2YFERVHzoQLnAQmSCmxeL5+3rBtSsdpBwVKKTcY+1rY197G+8RRoLVejed94igwxrgB/zXeJ+4Jijz2Erjg+8/WE7ZAt6EgSUsIxQwaJEWv7G6SSgAAAABJRU5ErkJggg==") no-repeat 50%,var(--control-background)}.title-bar.active .title-bar-controls button.is-restore:before,.title-bar.active .title-bar-controls button[aria-label=Restore]:before,.window.active .title-bar .title-bar-controls button.is-restore:before,.window.active .title-bar .title-bar-controls button[aria-label=Restore]:before{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACVSURBVHgBlVDLCoMwENwU/7ClvRYK7b2lCIJHEQQ/QEHwqujfBXJIQMnihg34iHPJ7GNm2AhYcL2/JwhAxIuhq3aXb48PiFBna2YFERVHzoQLnAQmSCmxeL5+3rBtSsdpBwVKKTcY+1rY197G+8RRoLVejed94igwxrgB/zXeJ+4Jijz2Erjg+8/WE7ZAt6EgSUsIxQwaJEWv7G6SSgAAAABJRU5ErkJggg==") no-repeat 50%,var(--control-background-hovered);box-shadow:0 0 7px 3px #5dc4f0,var(--control-inset-shadow);content:"";opacity:0;transition:opacity .3s linear}.title-bar.active .title-bar-controls button.is-restore:focus-visible:before,.title-bar.active .title-bar-controls button.is-restore:hover:before,.title-bar.active .title-bar-controls button[aria-label=Restore]:focus-visible:before,.title-bar.active .title-bar-controls button[aria-label=Restore]:hover:before,.window.active .title-bar .title-bar-controls button.is-restore:focus-visible:before,.window.active .title-bar .title-bar-controls button.is-restore:hover:before,.window.active .title-bar .title-bar-controls button[aria-label=Restore]:focus-visible:before,.window.active .title-bar .title-bar-controls button[aria-label=Restore]:hover:before{opacity:1;transition:opacity .1s linear}.title-bar.active .title-bar-controls button.is-restore:active:before,.title-bar.active .title-bar-controls button[aria-label=Restore]:active:before,.window.active .title-bar .title-bar-controls button.is-restore:active:before,.window.active .title-bar .title-bar-controls button[aria-label=Restore]:active:before{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACVSURBVHgBlVDLCoMwENwU/7ClvRYK7b2lCIJHEQQ/QEHwqujfBXJIQMnihg34iHPJ7GNm2AhYcL2/JwhAxIuhq3aXb48PiFBna2YFERVHzoQLnAQmSCmxeL5+3rBtSsdpBwVKKTcY+1rY197G+8RRoLVejed94igwxrgB/zXeJ+4Jijz2Erjg+8/WE7ZAt6EgSUsIxQwaJEWv7G6SSgAAAABJRU5ErkJggg==") no-repeat 50%,var(--control-background-active)}.title-bar.active .title-bar-controls button.is-close,.title-bar.active .title-bar-controls button[aria-label=Close],.window.active .title-bar .title-bar-controls button.is-close,.window.active .title-bar .title-bar-controls button[aria-label=Close]{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAKCAYAAABi8KSDAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACUSURBVHgBlZFNCoQwDIVbmRvOMHOAAd0K/uDGlYKiCG4VPICi9yu0oCSQoFUXFtKEl6+voZXvr7sKay1TL690FOexY+Hz87i2decOuDKQsNGVe8AGYTRJIh0Y+orBvxszCPllOymlxN06jNE26Qnwg4zdHQLrMhFaawwAqAadDPE1ijwUxhiMKCmxCZk06OMYTz5lAx3xWDeXkLNAAAAAAElFTkSuQmCC") no-repeat 50%,var(--control-background),var(--control-background-close);box-shadow:var(--control-inset-shadow)}.title-bar.active .title-bar-controls button.is-close:before,.title-bar.active .title-bar-controls button[aria-label=Close]:before,.window.active .title-bar .title-bar-controls button.is-close:before,.window.active .title-bar .title-bar-controls button[aria-label=Close]:before{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAKCAYAAABi8KSDAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACUSURBVHgBlZFNCoQwDIVbmRvOMHOAAd0K/uDGlYKiCG4VPICi9yu0oCSQoFUXFtKEl6+voZXvr7sKay1TL690FOexY+Hz87i2decOuDKQsNGVe8AGYTRJIh0Y+orBvxszCPllOymlxN06jNE26Qnwg4zdHQLrMhFaawwAqAadDPE1ijwUxhiMKCmxCZk06OMYTz5lAx3xWDeXkLNAAAAAAElFTkSuQmCC") no-repeat 50%,var(--control-background),var(--control-background-close-hovered);border-bottom-right-radius:var(--control-border-radius);box-shadow:0 0 7px 3px #e68e75,var(--control-inset-shadow);content:"";opacity:0;transition:opacity .3s linear}.title-bar.active .title-bar-controls button.is-close:focus-visible:before,.title-bar.active .title-bar-controls button.is-close:hover:before,.title-bar.active .title-bar-controls button[aria-label=Close]:focus-visible:before,.title-bar.active .title-bar-controls button[aria-label=Close]:hover:before,.window.active .title-bar .title-bar-controls button.is-close:focus-visible:before,.window.active .title-bar .title-bar-controls button.is-close:hover:before,.window.active .title-bar .title-bar-controls button[aria-label=Close]:focus-visible:before,.window.active .title-bar .title-bar-controls button[aria-label=Close]:hover:before{opacity:1;transition:opacity .1s linear}.title-bar.active .title-bar-controls button.is-close:active:before,.title-bar.active .title-bar-controls button[aria-label=Close]:active:before,.window.active .title-bar .title-bar-controls button.is-close:active:before,.window.active .title-bar .title-bar-controls button[aria-label=Close]:active:before{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAKCAYAAABi8KSDAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACUSURBVHgBlZFNCoQwDIVbmRvOMHOAAd0K/uDGlYKiCG4VPICi9yu0oCSQoFUXFtKEl6+voZXvr7sKay1TL690FOexY+Hz87i2decOuDKQsNGVe8AGYTRJIh0Y+orBvxszCPllOymlxN06jNE26Qnwg4zdHQLrMhFaawwAqAadDPE1ijwUxhiMKCmxCZk06OMYTz5lAx3xWDeXkLNAAAAAAElFTkSuQmCC") no-repeat 50%,var(--control-background),var(--control-background-close-active)}.title-bar.active .title-bar-controls button:disabled.is-maximize,.title-bar.active .title-bar-controls button:disabled[aria-label=Maximize],.window.active .title-bar .title-bar-controls button:disabled.is-maximize,.window.active .title-bar .title-bar-controls button:disabled[aria-label=Maximize]{background:var(--control-background)}.title-bar.active .title-bar-controls button:disabled.is-maximize:before,.title-bar.active .title-bar-controls button:disabled[aria-label=Maximize]:before,.window.active .title-bar .title-bar-controls button:disabled.is-maximize:before,.window.active .title-bar .title-bar-controls button:disabled[aria-label=Maximize]:before{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAYAAACALL/6AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAABsSURBVHgBlZHBCYAwDEVT6YaKbqArOILgBLqBosP1VkhAaQ6S1lKad+ihPy8kxLT9+IACG57r2KqKu2GCBpTYtEMOOQELzrnv4z53I4vDjjJnwXsPJWTOAiJGHVNB5pGwLjPk+AlEBLUY7eFebCosBHOR7vYAAAAASUVORK5CYII=") no-repeat 50%;content:"";opacity:.4}.status-bar{background:var(--surface);border:var(--window-border) var(--window-border-color);border-top:0;box-shadow:0 1px 0 #fff9,1px 0 0 #fff9,-1px 0 0 #fff9;display:flex;margin:var(--window-spacing);margin-top:calc(var(--window-spacing)*-1)}.status-bar-field{border-right:var(--window-border) #cfcfcf;flex-grow:1;margin:0;padding:2px 3px}.status-bar-field:last-child{border-right:0}
+/*# sourceMappingURL=7.css.map */
\ No newline at end of file
diff --git a/app/thirdparty/jstree/32px.png b/app/thirdparty/jstree/32px.png
new file mode 100644
index 0000000..a1c565e
Binary files /dev/null and b/app/thirdparty/jstree/32px.png differ
diff --git a/app/thirdparty/jstree/jquery.min.js b/app/thirdparty/jstree/jquery.min.js
new file mode 100644
index 0000000..a5195a3
--- /dev/null
+++ b/app/thirdparty/jstree/jquery.min.js
@@ -0,0 +1,5 @@
+/*! jQuery v1.12.1 | (c) jQuery Foundation | jquery.org/license */
+!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m="1.12.1",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return e.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:e.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a){return n.each(this,a)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(e.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:g,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){var b=a&&a.toString();return!n.isArray(a)&&b-parseFloat(b)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!k.call(a,"constructor")&&!k.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(!l.ownFirst)for(b in a)return k.call(a,b);for(b in a);return void 0===b||k.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?i[j.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(s(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):g.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(h)return h.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,g=0,h=[];if(s(a))for(d=a.length;d>g;g++)e=b(a[g],g,c),null!=e&&h.push(e);else for(g in a)e=b(a[g],g,c),null!=e&&h.push(e);return f.apply([],h)},guid:1,proxy:function(a,b){var c,d,f;return"string"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=e.call(arguments,2),d=function(){return a.apply(b||this,c.concat(e.call(arguments)))},d.guid=a.guid=a.guid||n.guid++,d):void 0},now:function(){return+new Date},support:l}),"function"==typeof Symbol&&(n.fn[Symbol.iterator]=c[Symbol.iterator]),n.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){i["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=!!a&&"length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ga(),z=ga(),A=ga(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+M+"))|)"+L+"*\\]",O=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+N+")*)|.*)\\)|)",P=new RegExp(L+"+","g"),Q=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),R=new RegExp("^"+L+"*,"+L+"*"),S=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),T=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),U=new RegExp(O),V=new RegExp("^"+M+"$"),W={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M+"|[*])"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Z=/^[^{]+\{\s*\[native \w/,$=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,_=/[+~]/,aa=/'|\\/g,ba=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),ca=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},da=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(ea){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fa(a,b,d,e){var f,h,j,k,l,o,r,s,w=b&&b.ownerDocument,x=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==x&&9!==x&&11!==x)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==x&&(o=$.exec(a)))if(f=o[1]){if(9===x){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(w&&(j=w.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(o[2])return H.apply(d,b.getElementsByTagName(a)),d;if((f=o[3])&&c.getElementsByClassName&&b.getElementsByClassName)return H.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==x)w=b,s=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(aa,"\\$&"):b.setAttribute("id",k=u),r=g(a),h=r.length,l=V.test(k)?"#"+k:"[id='"+k+"']";while(h--)r[h]=l+" "+qa(r[h]);s=r.join(","),w=_.test(a)&&oa(b.parentNode)||b}if(s)try{return H.apply(d,w.querySelectorAll(s)),d}catch(y){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(Q,"$1"),b,d,e)}function ga(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ha(a){return a[u]=!0,a}function ia(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ja(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function ka(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function la(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function na(a){return ha(function(b){return b=+b,ha(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function oa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=fa.support={},f=fa.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fa.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ia(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ia(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Z.test(n.getElementsByClassName),c.getById=ia(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return"undefined"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Z.test(n.querySelectorAll))&&(ia(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ia(function(a){var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Z.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ia(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",O)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Z.test(o.compareDocumentPosition),t=b||Z.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return ka(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?ka(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},fa.matches=function(a,b){return fa(a,null,null,b)},fa.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(T,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fa(b,n,null,[a]).length>0},fa.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fa.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fa.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fa.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fa.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fa.selectors={cacheLength:50,createPseudo:ha,match:W,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ba,ca),a[3]=(a[3]||a[4]||a[5]||"").replace(ba,ca),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fa.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fa.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return W.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&U.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ba,ca).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fa.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(P," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fa.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ha(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ha(function(a){var b=[],c=[],d=h(a.replace(Q,"$1"));return d[u]?ha(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ha(function(a){return function(b){return fa(a,b).length>0}}),contains:ha(function(a){return a=a.replace(ba,ca),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ha(function(a){return V.test(a||"")||fa.error("unsupported lang: "+a),a=a.replace(ba,ca).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Y.test(a.nodeName)},input:function(a){return X.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:na(function(){return[0]}),last:na(function(a,b){return[b-1]}),eq:na(function(a,b,c){return[0>c?c+b:c]}),even:na(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:na(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:na(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:na(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function ra(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j,k=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(j=b[u]||(b[u]={}),i=j[b.uniqueID]||(j[b.uniqueID]={}),(h=i[d])&&h[0]===w&&h[1]===f)return k[2]=h[2];if(i[d]=k,k[2]=a(b,c,g))return!0}}}function sa(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ta(a,b,c){for(var d=0,e=b.length;e>d;d++)fa(a,b[d],c);return c}function ua(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function va(a,b,c,d,e,f){return d&&!d[u]&&(d=va(d)),e&&!e[u]&&(e=va(e,f)),ha(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ta(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ua(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ua(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ua(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function wa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ra(function(a){return a===b},h,!0),l=ra(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[ra(sa(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return va(i>1&&sa(m),i>1&&qa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(Q,"$1"),c,e>i&&wa(a.slice(i,e)),f>e&&wa(a=a.slice(e)),f>e&&qa(a))}m.push(c)}return sa(m)}function xa(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=F.call(i));u=ua(u)}H.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&fa.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ha(f):f}return h=fa.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xa(e,d)),f.selector=a}return f},i=fa.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ba,ca),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=W.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ba,ca),_.test(j[0].type)&&oa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qa(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||_.test(a)&&oa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ia(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ia(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ja("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ia(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ja("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ia(function(a){return null==a.getAttribute("disabled")})||ja(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fa}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.uniqueSort=n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},v=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},w=n.expr.match.needsContext,x=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,y=/^.[^:#\[\.,]*$/;function z(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(y.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>-1!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(z(this,a||[],!1))},not:function(a){return this.pushStack(z(this,a||[],!0))},is:function(a){return!!z(this,"string"==typeof a&&w.test(a)?n(a):a||[],!1).length}});var A,B=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=n.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||A,"string"==typeof a){if(e="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:B.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),x.test(e[1])&&n.isPlainObject(b))for(e in b)n.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}if(f=d.getElementById(e[2]),f&&f.parentNode){if(f.id!==e[2])return A.find(a);this.length=1,this[0]=f}return this.context=d,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof c.ready?c.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};C.prototype=n.fn,A=n(d);var D=/^(?:parents|prev(?:Until|All))/,E={children:!0,contents:!0,next:!0,prev:!0};n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=w.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.uniqueSort(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function F(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return u(a,"parentNode")},parentsUntil:function(a,b,c){return u(a,"parentNode",c)},next:function(a){return F(a,"nextSibling")},prev:function(a){return F(a,"previousSibling")},nextAll:function(a){return u(a,"nextSibling")},prevAll:function(a){return u(a,"previousSibling")},nextUntil:function(a,b,c){return u(a,"nextSibling",c)},prevUntil:function(a,b,c){return u(a,"previousSibling",c)},siblings:function(a){return v((a.parentNode||{}).firstChild,a)},children:function(a){return v(a.firstChild)},contents:function(a){return n.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(E[a]||(e=n.uniqueSort(e)),D.test(a)&&(e=e.reverse())),this.pushStack(e)}});var G=/\S+/g;function H(a){var b={};return n.each(a.match(G)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?H(a):n.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?n.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=!0,c||j.disable(),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().progress(c.notify).done(c.resolve).fail(c.reject):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=e.call(arguments),d=c.length,f=1!==d||a&&n.isFunction(a.promise)?d:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?e.call(arguments):d,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(d>1)for(i=new Array(d),j=new Array(d),k=new Array(d);d>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().progress(h(b,j,i)).done(h(b,k,c)).fail(g.reject):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(d,[n]),n.fn.triggerHandler&&(n(d).triggerHandler("ready"),n(d).off("ready"))))}});function J(){d.addEventListener?(d.removeEventListener("DOMContentLoaded",K),a.removeEventListener("load",K)):(d.detachEvent("onreadystatechange",K),a.detachEvent("onload",K))}function K(){(d.addEventListener||"load"===a.event.type||"complete"===d.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll)a.setTimeout(n.ready);else if(d.addEventListener)d.addEventListener("DOMContentLoaded",K),a.addEventListener("load",K);else{d.attachEvent("onreadystatechange",K),a.attachEvent("onload",K);var c=!1;try{c=null==a.frameElement&&d.documentElement}catch(e){}c&&c.doScroll&&!function f(){if(!n.isReady){try{c.doScroll("left")}catch(b){return a.setTimeout(f,50)}J(),n.ready()}}()}return I.promise(b)},n.ready.promise();var L;for(L in n(l))break;l.ownFirst="0"===L,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c,e;c=d.getElementsByTagName("body")[0],c&&c.style&&(b=d.createElement("div"),e=d.createElement("div"),e.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(e).appendChild(b),"undefined"!=typeof b.style.zoom&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",l.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(e))}),function(){var a=d.createElement("div");l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}a=null}();var M=function(a){var b=n.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b},N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(O,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0;
+}return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function R(a,b,d,e){if(M(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f}}function S(a,b,c){if(M(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=void 0)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},Z=/^(?:checkbox|radio)$/i,$=/<([\w:-]+)/,_=/^$|\/(?:java|ecma)script/i,aa=/^\s+/,ba="abbr|article|aside|audio|bdi|canvas|data|datalist|details|dialog|figcaption|figure|footer|header|hgroup|main|mark|meter|nav|output|picture|progress|section|summary|template|time|video";function ca(a){var b=ba.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}!function(){var a=d.createElement("div"),b=d.createDocumentFragment(),c=d.createElement("input");a.innerHTML=" a",l.leadingWhitespace=3===a.firstChild.nodeType,l.tbody=!a.getElementsByTagName("tbody").length,l.htmlSerialize=!!a.getElementsByTagName("link").length,l.html5Clone="<:nav>"!==d.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,b.appendChild(c),l.appendChecked=c.checked,a.innerHTML="",l.noCloneChecked=!!a.cloneNode(!0).lastChild.defaultValue,b.appendChild(a),c=d.createElement("input"),c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),a.appendChild(c),l.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!!a.addEventListener,a[n.expando]=1,l.attributes=!a.getAttribute(n.expando)}();var da={option:[1,""],legend:[1,""],area:[1,""],param:[1,""],thead:[1,""],tr:[2,""],col:[2,""],td:[3,""],_default:l.htmlSerialize?[0,"",""]:[1,"X","
"]};da.optgroup=da.option,da.tbody=da.tfoot=da.colgroup=da.caption=da.thead,da.th=da.td;function ea(a,b){var c,d,e=0,f="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,ea(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function fa(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,"globalEval",!b||n._data(b[d],"globalEval"))}var ga=/<|?\w+;/,ha=/r;r++)if(g=a[r],g||0===g)if("object"===n.type(g))n.merge(q,g.nodeType?[g]:g);else if(ga.test(g)){i=i||p.appendChild(b.createElement("div")),j=($.exec(g)||["",""])[1].toLowerCase(),m=da[j]||da._default,i.innerHTML=m[1]+n.htmlPrefilter(g)+m[2],f=m[0];while(f--)i=i.lastChild;if(!l.leadingWhitespace&&aa.test(g)&&q.push(b.createTextNode(aa.exec(g)[0])),!l.tbody){g="table"!==j||ha.test(g)?""!==m[1]||ha.test(g)?0:i:i.firstChild,f=g&&g.childNodes.length;while(f--)n.nodeName(k=g.childNodes[f],"tbody")&&!k.childNodes.length&&g.removeChild(k)}n.merge(q,i.childNodes),i.textContent="";while(i.firstChild)i.removeChild(i.firstChild);i=p.lastChild}else q.push(b.createTextNode(g));i&&p.removeChild(i),l.appendChecked||n.grep(ea(q,"input"),ia),r=0;while(g=q[r++])if(d&&n.inArray(g,d)>-1)e&&e.push(g);else if(h=n.contains(g.ownerDocument,g),i=ea(p.appendChild(g),"script"),h&&fa(i),c){f=0;while(g=i[f++])_.test(g.type||"")&&c.push(g)}return i=null,p}!function(){var b,c,e=d.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b]=c in a)||(e.setAttribute(c,"t"),l[b]=e.attributes[c].expando===!1);e=null}();var ka=/^(?:input|select|textarea)$/i,la=/^key/,ma=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,na=/^(?:focusinfocus|focusoutblur)$/,oa=/^([^.]*)(?:\.(.+)|)/;function pa(){return!0}function qa(){return!1}function ra(){try{return d.activeElement}catch(a){}}function sa(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)sa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=qa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return n().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=n.guid++)),a.each(function(){n.event.add(this,b,e,d,c)})}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return"undefined"==typeof n||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(G)||[""],h=b.length;while(h--)f=oa.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(G)||[""],j=b.length;while(j--)if(h=oa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},trigger:function(b,c,e,f){var g,h,i,j,l,m,o,p=[e||d],q=k.call(b,"type")?b.type:b,r=k.call(b,"namespace")?b.namespace.split("."):[];if(i=m=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!na.test(q+n.event.triggered)&&(q.indexOf(".")>-1&&(r=q.split("."),q=r.shift(),r.sort()),h=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=r.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:n.makeArray(c,[b]),l=n.event.special[q]||{},f||!l.trigger||l.trigger.apply(e,c)!==!1)){if(!f&&!l.noBubble&&!n.isWindow(e)){for(j=l.delegateType||q,na.test(j+q)||(i=i.parentNode);i;i=i.parentNode)p.push(i),m=i;m===(e.ownerDocument||d)&&p.push(m.defaultView||m.parentWindow||a)}o=0;while((i=p[o++])&&!b.isPropagationStopped())b.type=o>1?j:l.bindType||q,g=(n._data(i,"events")||{})[b.type]&&n._data(i,"handle"),g&&g.apply(i,c),g=h&&i[h],g&&g.apply&&M(i)&&(b.result=g.apply(i,c),b.result===!1&&b.preventDefault());if(b.type=q,!f&&!b.isDefaultPrevented()&&(!l._default||l._default.apply(p.pop(),c)===!1)&&M(e)&&h&&e[q]&&!n.isWindow(e)){m=e[h],m&&(e[h]=null),n.event.triggered=q;try{e[q]()}catch(s){}n.event.triggered=void 0,m&&(e[h]=m)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,d,f,g,h=[],i=e.call(arguments),j=(n._data(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.rnamespace||a.rnamespace.test(g.namespace))&&(a.handleObj=g,a.data=g.data,d=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==d&&(a.result=d)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&("click"!==a.type||isNaN(a.button)||a.button<1))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>-1:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]","i"),va=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,wa=/