migrate to CSS Modules

This commit is contained in:
Brian Beck 2026-03-01 09:40:17 -08:00
parent c5b43f2e55
commit d9be5c1eba
51 changed files with 1684 additions and 1630 deletions

71
app/page.module.css Normal file
View file

@ -0,0 +1,71 @@
.CanvasContainer {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 0;
}
.LoadingIndicator {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: flex;
flex-direction: column;
align-items: center;
gap: 16px;
pointer-events: none;
z-index: 1;
opacity: 0.8;
}
.LoadingIndicator[data-complete="true"] {
animation: loadingComplete 0.3s ease-out forwards;
}
.Spinner {
width: 48px;
height: 48px;
border: 4px solid rgba(255, 255, 255, 0.2);
border-top-color: white;
border-radius: 50%;
animation: spin 1s linear infinite;
}
.Progress {
width: 200px;
height: 4px;
background: rgba(255, 255, 255, 0.2);
border-radius: 2px;
overflow: hidden;
}
.ProgressBar {
height: 100%;
background: white;
border-radius: 2px;
transition: width 0.1s ease-out;
}
.ProgressText {
font-size: 14px;
color: rgba(255, 255, 255, 0.7);
font-variant-numeric: tabular-nums;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
@keyframes loadingComplete {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}

View file

@ -49,6 +49,7 @@ import {
findMissionByDemoName, findMissionByDemoName,
} from "@/src/manifest"; } from "@/src/manifest";
import { createParser, parseAsBoolean, useQueryState } from "nuqs"; import { createParser, parseAsBoolean, useQueryState } from "nuqs";
import styles from "./page.module.css";
const MapInfoDialog = lazy(() => const MapInfoDialog = lazy(() =>
import("@/src/components/MapInfoDialog").then((mod) => ({ import("@/src/components/MapInfoDialog").then((mod) => ({
@ -231,17 +232,21 @@ function MapInspector() {
onClearFogEnabledOverride={clearFogEnabledOverride} onClearFogEnabledOverride={clearFogEnabledOverride}
> >
<KeyboardControls map={KEYBOARD_CONTROLS}> <KeyboardControls map={KEYBOARD_CONTROLS}>
<div id="canvasContainer"> <div id="canvasContainer" className={styles.CanvasContainer}>
{showLoadingIndicator && ( {showLoadingIndicator && (
<div id="loadingIndicator" data-complete={!isLoading}> <div
<div className="LoadingSpinner" /> id="loadingIndicator"
<div className="LoadingProgress"> className={styles.LoadingIndicator}
data-complete={!isLoading}
>
<div className={styles.Spinner} />
<div className={styles.Progress}>
<div <div
className="LoadingProgress-bar" className={styles.ProgressBar}
style={{ width: `${loadingProgress * 100}%` }} style={{ width: `${loadingProgress * 100}%` }}
/> />
</div> </div>
<div className="LoadingProgress-text"> <div className={styles.ProgressText}>
{Math.round(loadingProgress * 100)}% {Math.round(loadingProgress * 100)}%
</div> </div>
</div> </div>
@ -304,7 +309,10 @@ function MapInspector() {
/> />
</Suspense> </Suspense>
)} )}
<DemoMissionSync changeMission={changeMission} currentMission={currentMission} /> <DemoMissionSync
changeMission={changeMission}
currentMission={currentMission}
/>
<DemoControls /> <DemoControls />
<DemoWindowAPI /> <DemoWindowAPI />
</KeyboardControls> </KeyboardControls>

View file

@ -44,741 +44,6 @@ main {
height: 100dvh; height: 100dvh;
} }
#canvasContainer {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 0;
}
#controls {
position: fixed;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.5);
color: #fff;
padding: 8px 12px 8px 8px;
border-radius: 0 0 4px 0;
font-size: 13px;
z-index: 2;
}
input[type="range"] { input[type="range"] {
max-width: 80px; max-width: 80px;
} }
.CheckboxField,
.LabelledButton {
display: flex;
align-items: center;
gap: 6px;
}
.Field {
display: flex;
align-items: center;
gap: 6px;
}
#controls,
.Controls-dropdown,
.Controls-group {
display: flex;
align-items: center;
justify-content: center;
gap: 20px;
}
@media (max-width: 1279px) {
.Controls-dropdown[data-open="false"] {
display: none;
}
.Controls-dropdown {
position: absolute;
top: calc(100% + 2px);
left: 2px;
right: 2px;
display: flex;
overflow: auto;
max-height: calc(100dvh - 56px);
flex-direction: column;
align-items: center;
gap: 12px;
background: rgba(0, 0, 0, 0.8);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 4px;
padding: 12px;
box-shadow: 0 0 12px rgba(0, 0, 0, 0.4);
}
.Controls-group {
flex-wrap: wrap;
gap: 12px 20px;
}
}
@media (max-width: 639px) {
#controls {
right: 0;
border-radius: 0;
}
#controls > .MissionSelect-inputWrapper {
flex: 1 1 0;
min-width: 0;
}
#controls > .MissionSelect-inputWrapper .MissionSelect-input {
width: 100%;
}
.Controls-toggle {
flex: 0 0 auto;
}
}
.IconButton {
position: relative;
display: flex;
align-items: center;
justify-content: center;
width: 28px;
height: 28px;
margin: 0 0 0 -12px;
font-size: 15px;
padding: 0;
border-top: 1px solid rgba(255, 255, 255, 0.3);
border-left: 1px solid rgba(255, 255, 255, 0.3);
border-right: 1px solid rgba(200, 200, 200, 0.3);
border-bottom: 1px solid rgba(200, 200, 200, 0.3);
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
border-radius: 4px;
background: rgba(3, 82, 147, 0.6);
color: #fff;
cursor: pointer;
transform: translate(0, 0);
transition:
background 0.2s,
border-color 0.2s;
}
.ButtonLabel {
font-size: 12px;
}
.IconButton svg {
pointer-events: none;
}
@media (hover: hover) {
.IconButton:hover {
background: rgba(0, 98, 179, 0.8);
border-color: rgba(255, 255, 255, 0.4);
}
}
.IconButton:active,
.IconButton[aria-expanded="true"] {
background: rgba(0, 98, 179, 0.7);
border-color: rgba(255, 255, 255, 0.3);
transform: translate(0, 1px);
}
.IconButton[data-active="true"] {
background: rgba(0, 117, 213, 0.9);
border-color: rgba(255, 255, 255, 0.4);
}
.Controls-toggle {
margin: 0;
}
@media (max-width: 1279px) {
.LabelledButton {
width: auto;
padding: 0 10px;
}
}
@media (min-width: 1280px) {
.Controls-toggle {
display: none;
}
.LabelledButton .ButtonLabel {
display: none;
}
.MapInfoButton {
display: none;
}
}
.CopyCoordinatesButton[data-copied="true"] {
background: rgba(0, 117, 213, 0.9);
border-color: rgba(255, 255, 255, 0.4);
}
.CopyCoordinatesButton .ClipboardCheck {
display: none;
opacity: 1;
}
.CopyCoordinatesButton[data-copied="true"] .ClipboardCheck {
display: block;
animation: showClipboardCheck 220ms linear infinite;
}
.CopyCoordinatesButton[data-copied="true"] .MapPin {
display: none;
}
.StaticShapeLabel {
background: rgba(0, 0, 0, 0.5);
color: #fff;
font-size: 11px;
white-space: nowrap;
padding: 1px 3px;
border-radius: 1px;
text-align: center;
}
.PlayerNameplate {
pointer-events: none;
display: inline-flex;
flex-direction: column;
align-items: center;
white-space: nowrap;
}
.PlayerTop {
padding-bottom: 20px;
}
.PlayerBottom {
padding-top: 20px;
}
.PlayerNameplate-iffArrow {
width: 12px;
height: 12px;
image-rendering: pixelated;
filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.7));
}
.PlayerNameplate-name {
color: #fff;
font-size: 11px;
text-shadow:
0 1px 3px rgba(0, 0, 0, 0.9),
0 0 1px rgba(0, 0, 0, 0.7);
}
.PlayerNameplate-healthBar {
width: 60px;
height: 4px;
background: rgba(0, 0, 0, 0.5);
border: 1px solid rgba(255, 255, 255, 0.2);
margin: 2px auto 0;
overflow: hidden;
}
.PlayerNameplate-healthFill {
height: 100%;
background: #2ecc40;
}
.StatsPanel {
left: auto !important;
top: auto !important;
right: 0;
bottom: 0;
}
.AxisLabel {
font-size: 12px;
pointer-events: none;
}
.AxisLabel[data-axis="x"] {
color: rgb(255, 153, 0);
}
.AxisLabel[data-axis="y"] {
color: rgb(153, 255, 0);
}
.AxisLabel[data-axis="z"] {
color: rgb(0, 153, 255);
}
/* MissionSelect combobox styles */
.MissionSelect-inputWrapper {
position: relative;
display: flex;
align-items: center;
}
.MissionSelect-shortcut {
position: absolute;
right: 7px;
font-family: system-ui, sans-serif;
font-size: 11px;
padding: 1px 4px;
border-radius: 3px;
background: rgba(255, 255, 255, 0.15);
color: rgba(255, 255, 255, 0.6);
pointer-events: none;
}
.MissionSelect-input[aria-expanded="true"] ~ .MissionSelect-shortcut {
display: none;
}
.MissionSelect-input {
width: 280px;
padding: 6px 36px 6px 8px;
font-size: 14px;
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 3px;
background: rgba(0, 0, 0, 0.6);
color: #fff;
outline: none;
user-select: text;
}
.MissionSelect-input[aria-expanded="true"] {
padding-right: 8px;
}
.MissionSelect-input:focus {
border-color: rgba(255, 255, 255, 0.6);
}
.MissionSelect-input::placeholder {
color: transparent;
}
.MissionSelect-selectedValue {
position: absolute;
left: 8px;
right: 36px;
display: flex;
align-items: center;
gap: 6px;
pointer-events: none;
overflow: hidden;
}
.MissionSelect-input[aria-expanded="true"] ~ .MissionSelect-selectedValue {
display: none;
}
.MissionSelect-selectedName {
color: #fff;
font-weight: 600;
font-size: 14px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
flex-shrink: 1;
min-width: 0;
}
.MissionSelect-selectedValue > .MissionSelect-itemType {
flex-shrink: 0;
}
.MissionSelect-popover {
z-index: 100;
min-width: 320px;
max-height: var(--popover-available-height, 90vh);
overflow-y: auto;
overscroll-behavior: contain;
background: rgba(20, 20, 20, 0.95);
border: 1px solid rgba(255, 255, 255, 0.5);
border-radius: 3px;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.6);
}
.MissionSelect-list {
padding: 4px 0;
}
.MissionSelect-list:has(> .MissionSelect-group:first-child) {
padding-top: 0;
}
.MissionSelect-group {
padding-bottom: 4px;
}
.MissionSelect-groupLabel {
position: sticky;
top: 0;
padding: 6px 8px 6px 12px;
font-size: 13px;
font-weight: 600;
color: rgb(198, 202, 202);
background: rgba(58, 69, 72, 0.95);
border-bottom: 1px solid rgba(255, 255, 255, 0.3);
z-index: 1;
}
.MissionSelect-group:not(:last-child) {
border-bottom: 1px solid rgba(255, 255, 255, 0.3);
}
.MissionSelect-item {
display: flex;
flex-direction: column;
gap: 1px;
margin: 4px 4px 0;
padding: 6px 8px;
border-radius: 4px;
cursor: pointer;
outline: none;
scroll-margin-top: 32px;
}
.MissionSelect-list > .MissionSelect-item:first-child {
margin-top: 0;
}
.MissionSelect-item[data-active-item] {
background: rgba(255, 255, 255, 0.15);
}
.MissionSelect-item[aria-selected="true"] {
background: rgba(100, 150, 255, 0.3);
}
.MissionSelect-itemHeader {
display: flex;
align-items: center;
gap: 6px;
}
.MissionSelect-itemName {
font-size: 14px;
font-weight: 600;
color: #fff;
}
.MissionSelect-itemTypes {
display: flex;
gap: 3px;
}
.MissionSelect-itemType {
font-size: 10px;
font-weight: 600;
padding: 2px 5px;
border-radius: 3px;
background: rgba(255, 157, 0, 0.4);
color: #fff;
}
.MissionSelect-itemType:hover {
background: rgba(255, 157, 0, 0.7);
}
.MissionSelect-itemMissionName {
font-size: 12px;
color: rgba(255, 255, 255, 0.5);
}
.MissionSelect-noResults {
padding: 12px 8px;
font-size: 13px;
color: rgba(255, 255, 255, 0.5);
text-align: center;
}
.LoadingSpinner {
width: 48px;
height: 48px;
border: 4px solid rgba(255, 255, 255, 0.2);
border-top-color: white;
border-radius: 50%;
animation: LoadingSpinner-spin 1s linear infinite;
}
@keyframes LoadingSpinner-spin {
to {
transform: rotate(360deg);
}
}
#loadingIndicator {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: flex;
flex-direction: column;
align-items: center;
gap: 16px;
pointer-events: none;
z-index: 1;
opacity: 0.8;
}
#loadingIndicator[data-complete="true"] {
animation: loadingComplete 0.3s ease-out forwards;
}
@keyframes loadingComplete {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
.LoadingProgress {
width: 200px;
height: 4px;
background: rgba(255, 255, 255, 0.2);
border-radius: 2px;
overflow: hidden;
}
.LoadingProgress-bar {
height: 100%;
background: white;
border-radius: 2px;
transition: width 0.1s ease-out;
}
.LoadingProgress-text {
font-size: 14px;
color: rgba(255, 255, 255, 0.7);
font-variant-numeric: tabular-nums;
}
@keyframes showClipboardCheck {
0% {
opacity: 1;
}
100% {
opacity: 0.2;
}
}
.KeyboardOverlay {
position: fixed;
bottom: 16px;
left: 50%;
transform: translateX(-50%);
display: flex;
align-items: flex-end;
gap: 10px;
pointer-events: none;
z-index: 1;
}
.KeyboardOverlay-column {
display: flex;
gap: 4px;
flex-direction: column;
justify-content: center;
}
.KeyboardOverlay-row {
display: flex;
gap: 4px;
justify-content: stretch;
}
.KeyboardOverlay-spacer {
width: 32px;
}
.KeyboardOverlay-key {
min-width: 32px;
height: 32px;
display: flex;
flex: 1 0 0;
align-items: center;
justify-content: center;
padding: 0 8px;
border-radius: 4px;
background: rgba(0, 0, 0, 0.4);
border: 1px solid rgba(255, 255, 255, 0.2);
color: rgba(255, 255, 255, 0.5);
font-size: 11px;
font-weight: 600;
white-space: nowrap;
}
.KeyboardOverlay-key[data-pressed="true"] {
background: rgba(52, 187, 171, 0.6);
border-color: rgba(35, 253, 220, 0.5);
color: #fff;
}
.KeyboardOverlay-arrow {
margin-right: 3px;
}
.TouchJoystick {
position: fixed;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
width: 140px;
height: 140px;
z-index: 1;
}
.TouchJoystick--left {
left: 20px;
transform: none;
}
.TouchJoystick--right {
left: auto;
right: 20px;
transform: none;
}
.TouchJoystick .back {
background: rgba(3, 79, 76, 0.6) !important;
border: 1px solid rgba(0, 219, 223, 0.5) !important;
box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.7) !important;
}
.TouchJoystick .front {
background: radial-gradient(
circle at 50% 50%,
rgba(23, 247, 198, 0.9) 0%,
rgba(9, 184, 170, 0.95) 100%
) !important;
border: 2px solid rgba(255, 255, 255, 0.4) !important;
box-shadow:
0 2px 4px rgba(0, 0, 0, 0.5),
0 1px 1px rgba(0, 0, 0, 0.3),
inset 0 1px 0 rgba(255, 255, 255, 0.15),
inset 0 -1px 2px rgba(0, 0, 0, 0.3) !important;
}
.DemoControls {
position: fixed;
bottom: 0;
left: 0;
right: 0;
display: flex;
align-items: center;
gap: 10px;
padding: 8px 12px;
background: rgba(0, 0, 0, 0.7);
color: #fff;
font-size: 13px;
z-index: 2;
}
.DemoControls-playPause {
width: 32px;
height: 32px;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
padding: 0;
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 4px;
background: rgba(3, 82, 147, 0.6);
color: #fff;
font-size: 14px;
cursor: pointer;
}
@media (hover: hover) {
.DemoControls-playPause:hover {
background: rgba(0, 98, 179, 0.8);
}
}
.DemoControls-time {
flex-shrink: 0;
font-variant-numeric: tabular-nums;
white-space: nowrap;
}
.DemoControls-seek[type="range"] {
flex: 1 1 0;
min-width: 0;
max-width: none;
}
.DemoControls-speed {
flex-shrink: 0;
padding: 2px 4px;
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 3px;
background: rgba(0, 0, 0, 0.6);
color: #fff;
font-size: 12px;
}
.DemoDiagnosticsPanel {
display: flex;
flex-direction: column;
gap: 3px;
margin-left: 8px;
padding: 4px 8px;
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 4px;
background: rgba(0, 0, 0, 0.55);
min-width: 320px;
}
.DemoDiagnosticsPanel[data-context-lost="true"] {
border-color: rgba(255, 90, 90, 0.8);
background: rgba(70, 0, 0, 0.45);
}
.DemoDiagnosticsPanel-status {
font-size: 11px;
font-weight: 700;
letter-spacing: 0.02em;
}
.DemoDiagnosticsPanel-metrics {
display: flex;
flex-wrap: wrap;
gap: 4px 10px;
font-size: 11px;
opacity: 0.92;
}
.DemoDiagnosticsPanel-footer {
display: flex;
flex-wrap: wrap;
gap: 4px 8px;
align-items: center;
font-size: 11px;
}
.DemoDiagnosticsPanel-footer button {
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 3px;
background: rgba(3, 82, 147, 0.6);
color: #fff;
padding: 1px 6px;
font-size: 11px;
cursor: pointer;
}
.DemoDiagnosticsPanel-footer button:hover {
background: rgba(0, 98, 179, 0.8);
}
.DemoIcon {
font-size: 19px;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,10 +1,10 @@
1:"$Sreact.fragment" 1:"$Sreact.fragment"
2:I[47257,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"ClientPageRoot"] 2:I[47257,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"ClientPageRoot"]
3:I[31713,["/t2-mapper/_next/static/chunks/e6da73430a674f20.js","/t2-mapper/_next/static/chunks/88e3d9a60c48713e.js","/t2-mapper/_next/static/chunks/93b588fa7f31935c.js","/t2-mapper/_next/static/chunks/22ebafda1e5f0224.js","/t2-mapper/_next/static/chunks/39f1afbfab5559a9.js","/t2-mapper/_next/static/chunks/ad5913f83864409c.js","/t2-mapper/_next/static/chunks/bb0aa1c978feffed.js"],"default"] 3:I[31713,["/t2-mapper/_next/static/chunks/e6da73430a674f20.js","/t2-mapper/_next/static/chunks/c339a594c158eab3.js","/t2-mapper/_next/static/chunks/93b588fa7f31935c.js","/t2-mapper/_next/static/chunks/22ebafda1e5f0224.js","/t2-mapper/_next/static/chunks/39f1afbfab5559a9.js","/t2-mapper/_next/static/chunks/f12455938f261f57.js","/t2-mapper/_next/static/chunks/bb0aa1c978feffed.js"],"default"]
6:I[97367,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"OutletBoundary"] 6:I[97367,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"OutletBoundary"]
7:"$Sreact.suspense" 7:"$Sreact.suspense"
:HL["/t2-mapper/_next/static/chunks/afff663ba7029ccf.css","style"] :HL["/t2-mapper/_next/static/chunks/f6c55b3b7050a508.css","style"]
0:{"buildId":"A7b21KJnATF7QS7o5ziIf","rsc":["$","$1","c",{"children":[["$","$L2",null,{"Component":"$3","serverProvidedParams":{"searchParams":{},"params":{},"promises":["$@4","$@5"]}}],[["$","link","0",{"rel":"stylesheet","href":"/t2-mapper/_next/static/chunks/afff663ba7029ccf.css","precedence":"next"}],["$","script","script-0",{"src":"/t2-mapper/_next/static/chunks/88e3d9a60c48713e.js","async":true}],["$","script","script-1",{"src":"/t2-mapper/_next/static/chunks/93b588fa7f31935c.js","async":true}],["$","script","script-2",{"src":"/t2-mapper/_next/static/chunks/22ebafda1e5f0224.js","async":true}],["$","script","script-3",{"src":"/t2-mapper/_next/static/chunks/39f1afbfab5559a9.js","async":true}],["$","script","script-4",{"src":"/t2-mapper/_next/static/chunks/ad5913f83864409c.js","async":true}],["$","script","script-5",{"src":"/t2-mapper/_next/static/chunks/bb0aa1c978feffed.js","async":true}]],["$","$L6",null,{"children":["$","$7",null,{"name":"Next.MetadataOutlet","children":"$@8"}]}]]}],"loading":null,"isPartial":false} 0:{"buildId":"YSDmiCN1S-sDYVxEL27I6","rsc":["$","$1","c",{"children":[["$","$L2",null,{"Component":"$3","serverProvidedParams":{"searchParams":{},"params":{},"promises":["$@4","$@5"]}}],[["$","link","0",{"rel":"stylesheet","href":"/t2-mapper/_next/static/chunks/f6c55b3b7050a508.css","precedence":"next"}],["$","script","script-0",{"src":"/t2-mapper/_next/static/chunks/c339a594c158eab3.js","async":true}],["$","script","script-1",{"src":"/t2-mapper/_next/static/chunks/93b588fa7f31935c.js","async":true}],["$","script","script-2",{"src":"/t2-mapper/_next/static/chunks/22ebafda1e5f0224.js","async":true}],["$","script","script-3",{"src":"/t2-mapper/_next/static/chunks/39f1afbfab5559a9.js","async":true}],["$","script","script-4",{"src":"/t2-mapper/_next/static/chunks/f12455938f261f57.js","async":true}],["$","script","script-5",{"src":"/t2-mapper/_next/static/chunks/bb0aa1c978feffed.js","async":true}]],["$","$L6",null,{"children":["$","$7",null,{"name":"Next.MetadataOutlet","children":"$@8"}]}]]}],"loading":null,"isPartial":false}
4:{} 4:{}
5:"$0:rsc:props:children:0:props:serverProvidedParams:params" 5:"$0:rsc:props:children:0:props:serverProvidedParams:params"
8:null 8:null

View file

@ -3,15 +3,15 @@
3:I[39756,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"default"] 3:I[39756,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"default"]
4:I[37457,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"default"] 4:I[37457,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"default"]
5:I[47257,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"ClientPageRoot"] 5:I[47257,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"ClientPageRoot"]
6:I[31713,["/t2-mapper/_next/static/chunks/e6da73430a674f20.js","/t2-mapper/_next/static/chunks/88e3d9a60c48713e.js","/t2-mapper/_next/static/chunks/93b588fa7f31935c.js","/t2-mapper/_next/static/chunks/22ebafda1e5f0224.js","/t2-mapper/_next/static/chunks/39f1afbfab5559a9.js","/t2-mapper/_next/static/chunks/ad5913f83864409c.js","/t2-mapper/_next/static/chunks/bb0aa1c978feffed.js"],"default"] 6:I[31713,["/t2-mapper/_next/static/chunks/e6da73430a674f20.js","/t2-mapper/_next/static/chunks/c339a594c158eab3.js","/t2-mapper/_next/static/chunks/93b588fa7f31935c.js","/t2-mapper/_next/static/chunks/22ebafda1e5f0224.js","/t2-mapper/_next/static/chunks/39f1afbfab5559a9.js","/t2-mapper/_next/static/chunks/f12455938f261f57.js","/t2-mapper/_next/static/chunks/bb0aa1c978feffed.js"],"default"]
9:I[97367,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"OutletBoundary"] 9:I[97367,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"OutletBoundary"]
a:"$Sreact.suspense" a:"$Sreact.suspense"
c:I[97367,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"ViewportBoundary"] c:I[97367,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"ViewportBoundary"]
e:I[97367,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"MetadataBoundary"] e:I[97367,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"MetadataBoundary"]
10:I[68027,[],"default"] 10:I[68027,[],"default"]
:HL["/t2-mapper/_next/static/chunks/17606cb20096103a.css","style"] :HL["/t2-mapper/_next/static/chunks/e620039d1c837dab.css","style"]
:HL["/t2-mapper/_next/static/chunks/afff663ba7029ccf.css","style"] :HL["/t2-mapper/_next/static/chunks/f6c55b3b7050a508.css","style"]
0:{"P":null,"b":"A7b21KJnATF7QS7o5ziIf","c":["",""],"q":"","i":false,"f":[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],[["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/t2-mapper/_next/static/chunks/17606cb20096103a.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/t2-mapper/_next/static/chunks/e6da73430a674f20.js","async":true,"nonce":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L2",null,{"defaultOptions":{"clearOnDefault":false},"children":["$","$L3",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L4",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}]}]}]]}],{"children":[["$","$1","c",{"children":[["$","$L5",null,{"Component":"$6","serverProvidedParams":{"searchParams":{},"params":{},"promises":["$@7","$@8"]}}],[["$","link","0",{"rel":"stylesheet","href":"/t2-mapper/_next/static/chunks/afff663ba7029ccf.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/t2-mapper/_next/static/chunks/88e3d9a60c48713e.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/t2-mapper/_next/static/chunks/93b588fa7f31935c.js","async":true,"nonce":"$undefined"}],["$","script","script-2",{"src":"/t2-mapper/_next/static/chunks/22ebafda1e5f0224.js","async":true,"nonce":"$undefined"}],["$","script","script-3",{"src":"/t2-mapper/_next/static/chunks/39f1afbfab5559a9.js","async":true,"nonce":"$undefined"}],["$","script","script-4",{"src":"/t2-mapper/_next/static/chunks/ad5913f83864409c.js","async":true,"nonce":"$undefined"}],["$","script","script-5",{"src":"/t2-mapper/_next/static/chunks/bb0aa1c978feffed.js","async":true,"nonce":"$undefined"}]],["$","$L9",null,{"children":["$","$a",null,{"name":"Next.MetadataOutlet","children":"$@b"}]}]]}],{},null,false,false]},null,false,false],["$","$1","h",{"children":[null,["$","$Lc",null,{"children":"$Ld"}],["$","div",null,{"hidden":true,"children":["$","$Le",null,{"children":["$","$a",null,{"name":"Next.Metadata","children":"$Lf"}]}]}],null]}],false]],"m":"$undefined","G":["$10",[]],"S":true} 0:{"P":null,"b":"YSDmiCN1S-sDYVxEL27I6","c":["",""],"q":"","i":false,"f":[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],[["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/t2-mapper/_next/static/chunks/e620039d1c837dab.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/t2-mapper/_next/static/chunks/e6da73430a674f20.js","async":true,"nonce":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L2",null,{"defaultOptions":{"clearOnDefault":false},"children":["$","$L3",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L4",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}]}]}]]}],{"children":[["$","$1","c",{"children":[["$","$L5",null,{"Component":"$6","serverProvidedParams":{"searchParams":{},"params":{},"promises":["$@7","$@8"]}}],[["$","link","0",{"rel":"stylesheet","href":"/t2-mapper/_next/static/chunks/f6c55b3b7050a508.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/t2-mapper/_next/static/chunks/c339a594c158eab3.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/t2-mapper/_next/static/chunks/93b588fa7f31935c.js","async":true,"nonce":"$undefined"}],["$","script","script-2",{"src":"/t2-mapper/_next/static/chunks/22ebafda1e5f0224.js","async":true,"nonce":"$undefined"}],["$","script","script-3",{"src":"/t2-mapper/_next/static/chunks/39f1afbfab5559a9.js","async":true,"nonce":"$undefined"}],["$","script","script-4",{"src":"/t2-mapper/_next/static/chunks/f12455938f261f57.js","async":true,"nonce":"$undefined"}],["$","script","script-5",{"src":"/t2-mapper/_next/static/chunks/bb0aa1c978feffed.js","async":true,"nonce":"$undefined"}]],["$","$L9",null,{"children":["$","$a",null,{"name":"Next.MetadataOutlet","children":"$@b"}]}]]}],{},null,false,false]},null,false,false],["$","$1","h",{"children":[null,["$","$Lc",null,{"children":"$Ld"}],["$","div",null,{"hidden":true,"children":["$","$Le",null,{"children":["$","$a",null,{"name":"Next.Metadata","children":"$Lf"}]}]}],null]}],false]],"m":"$undefined","G":["$10",[]],"S":true}
7:{} 7:{}
8:"$0:f:0:1:1:children:0:props:children:0:props:serverProvidedParams:params" 8:"$0:f:0:1:1:children:0:props:children:0:props:serverProvidedParams:params"
d:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"}]] d:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"}]]

View file

@ -3,4 +3,4 @@
3:I[97367,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"MetadataBoundary"] 3:I[97367,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"MetadataBoundary"]
4:"$Sreact.suspense" 4:"$Sreact.suspense"
5:I[27201,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"IconMark"] 5:I[27201,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"IconMark"]
0:{"buildId":"A7b21KJnATF7QS7o5ziIf","rsc":["$","$1","h",{"children":[null,["$","$L2",null,{"children":[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"}]]}],["$","div",null,{"hidden":true,"children":["$","$L3",null,{"children":["$","$4",null,{"name":"Next.Metadata","children":[["$","title","0",{"children":"MapGenius  Explore maps for Tribes 2"}],["$","meta","1",{"name":"description","content":"Tribes 2 forever."}],["$","link","2",{"rel":"icon","href":"/t2-mapper/icon.png?icon.2911bba1.png","sizes":"108x128","type":"image/png"}],["$","$L5","3",{}]]}]}]}],null]}],"loading":null,"isPartial":false} 0:{"buildId":"YSDmiCN1S-sDYVxEL27I6","rsc":["$","$1","h",{"children":[null,["$","$L2",null,{"children":[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"}]]}],["$","div",null,{"hidden":true,"children":["$","$L3",null,{"children":["$","$4",null,{"name":"Next.Metadata","children":[["$","title","0",{"children":"MapGenius  Explore maps for Tribes 2"}],["$","meta","1",{"name":"description","content":"Tribes 2 forever."}],["$","link","2",{"rel":"icon","href":"/t2-mapper/icon.png?icon.2911bba1.png","sizes":"108x128","type":"image/png"}],["$","$L5","3",{}]]}]}]}],null]}],"loading":null,"isPartial":false}

View file

@ -2,5 +2,5 @@
2:I[12985,["/t2-mapper/_next/static/chunks/e6da73430a674f20.js"],"NuqsAdapter"] 2:I[12985,["/t2-mapper/_next/static/chunks/e6da73430a674f20.js"],"NuqsAdapter"]
3:I[39756,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"default"] 3:I[39756,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"default"]
4:I[37457,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"default"] 4:I[37457,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"default"]
:HL["/t2-mapper/_next/static/chunks/17606cb20096103a.css","style"] :HL["/t2-mapper/_next/static/chunks/e620039d1c837dab.css","style"]
0:{"buildId":"A7b21KJnATF7QS7o5ziIf","rsc":["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/t2-mapper/_next/static/chunks/17606cb20096103a.css","precedence":"next"}],["$","script","script-0",{"src":"/t2-mapper/_next/static/chunks/e6da73430a674f20.js","async":true}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L2",null,{"defaultOptions":{"clearOnDefault":false},"children":["$","$L3",null,{"parallelRouterKey":"children","template":["$","$L4",null,{}],"notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]]}]}]}]}]]}],"loading":null,"isPartial":false} 0:{"buildId":"YSDmiCN1S-sDYVxEL27I6","rsc":["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/t2-mapper/_next/static/chunks/e620039d1c837dab.css","precedence":"next"}],["$","script","script-0",{"src":"/t2-mapper/_next/static/chunks/e6da73430a674f20.js","async":true}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L2",null,{"defaultOptions":{"clearOnDefault":false},"children":["$","$L3",null,{"parallelRouterKey":"children","template":["$","$L4",null,{}],"notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]]}]}]}]}]]}],"loading":null,"isPartial":false}

View file

@ -1,3 +1,3 @@
:HL["/t2-mapper/_next/static/chunks/17606cb20096103a.css","style"] :HL["/t2-mapper/_next/static/chunks/e620039d1c837dab.css","style"]
:HL["/t2-mapper/_next/static/chunks/afff663ba7029ccf.css","style"] :HL["/t2-mapper/_next/static/chunks/f6c55b3b7050a508.css","style"]
0:{"buildId":"A7b21KJnATF7QS7o5ziIf","tree":{"name":"","paramType":null,"paramKey":"","hasRuntimePrefetch":false,"slots":{"children":{"name":"__PAGE__","paramType":null,"paramKey":"__PAGE__","hasRuntimePrefetch":false,"slots":null,"isRootLayout":false}},"isRootLayout":true},"staleTime":300} 0:{"buildId":"YSDmiCN1S-sDYVxEL27I6","tree":{"name":"","paramType":null,"paramKey":"","hasRuntimePrefetch":false,"slots":{"children":{"name":"__PAGE__","paramType":null,"paramKey":"__PAGE__","hasRuntimePrefetch":false,"slots":null,"isRootLayout":false}},"isRootLayout":true},"staleTime":300}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1 +0,0 @@
.PlayerHUD-module__-E1Scq__PlayerHUD{z-index:1;pointer-events:none;padding-bottom:48px;position:absolute;inset:0}.PlayerHUD-module__-E1Scq__ChatWindow{position:absolute;top:60px;left:4px}.PlayerHUD-module__-E1Scq__Bar{background:#00000080;border:1px solid #fff3;width:160px;height:14px;position:absolute;overflow:hidden}.PlayerHUD-module__-E1Scq__HealthBar{top:60px;right:32px;}.PlayerHUD-module__-E1Scq__EnergyBar{top:80px;right:32px;}.PlayerHUD-module__-E1Scq__BarFill{height:100%;transition:width .15s ease-out;position:absolute;top:0;left:0}.PlayerHUD-module__-E1Scq__HealthBar .PlayerHUD-module__-E1Scq__BarFill{background:#2ecc40}.PlayerHUD-module__-E1Scq__EnergyBar .PlayerHUD-module__-E1Scq__BarFill{background:#0af}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
html{box-sizing:border-box;background:#000;margin:0;padding:0;overflow:hidden}*,:before,:after{box-sizing:inherit}body{-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}html{font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Open Sans,Helvetica Neue,sans-serif;font-size:100%}body{margin:0;padding:0;overflow:hidden}main{width:100dvw;height:100dvh}input[type=range]{max-width:80px}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,12 @@
.FloatingLabel-module__8y09Ka__Label{color:#fff;white-space:nowrap;text-align:center;background:#00000080;border-radius:1px;padding:1px 3px;font-size:11px}
.KeyboardOverlay-module__HsRBsa__Root{pointer-events:none;z-index:1;align-items:flex-end;gap:10px;display:flex;position:fixed;bottom:16px;left:50%;transform:translate(-50%)}.KeyboardOverlay-module__HsRBsa__Column{flex-direction:column;justify-content:center;gap:4px;display:flex}.KeyboardOverlay-module__HsRBsa__Row{justify-content:stretch;gap:4px;display:flex}.KeyboardOverlay-module__HsRBsa__Spacer{width:32px}.KeyboardOverlay-module__HsRBsa__Key{color:#ffffff80;white-space:nowrap;background:#0006;border:1px solid #fff3;border-radius:4px;flex:1 0 0;justify-content:center;align-items:center;min-width:32px;height:32px;padding:0 8px;font-size:11px;font-weight:600;display:flex}.KeyboardOverlay-module__HsRBsa__Key[data-pressed=true]{color:#fff;background:#34bbab99;border-color:#23fddc80}.KeyboardOverlay-module__HsRBsa__Arrow{margin-right:3px}
.TouchControls-module__AkxfgW__Joystick{z-index:1;width:140px;height:140px;position:fixed;bottom:20px;left:50%;transform:translate(-50%)}.TouchControls-module__AkxfgW__Left{left:20px;transform:none;}.TouchControls-module__AkxfgW__Right{left:auto;right:20px;transform:none;}
.MissionSelect-module__N_AIjG__InputWrapper{align-items:center;display:flex;position:relative}.MissionSelect-module__N_AIjG__Shortcut{color:#fff9;pointer-events:none;background:#ffffff26;border-radius:3px;padding:1px 4px;font-family:system-ui,sans-serif;font-size:11px;position:absolute;right:7px}.MissionSelect-module__N_AIjG__Input[aria-expanded=true]~.MissionSelect-module__N_AIjG__Shortcut{display:none}.MissionSelect-module__N_AIjG__Input{color:#fff;-webkit-user-select:text;user-select:text;background:#0009;border:1px solid #ffffff4d;border-radius:3px;outline:none;width:280px;padding:6px 36px 6px 8px;font-size:14px}.MissionSelect-module__N_AIjG__Input[aria-expanded=true]{padding-right:8px}.MissionSelect-module__N_AIjG__Input:focus{border-color:#fff9}.MissionSelect-module__N_AIjG__Input::placeholder{color:#0000}.MissionSelect-module__N_AIjG__SelectedValue{pointer-events:none;align-items:center;gap:6px;display:flex;position:absolute;left:8px;right:36px;overflow:hidden}.MissionSelect-module__N_AIjG__Input[aria-expanded=true]~.MissionSelect-module__N_AIjG__SelectedValue{display:none}.MissionSelect-module__N_AIjG__SelectedName{color:#fff;white-space:nowrap;text-overflow:ellipsis;flex-shrink:1;min-width:0;font-size:14px;font-weight:600;overflow:hidden}.MissionSelect-module__N_AIjG__SelectedValue>.MissionSelect-module__N_AIjG__ItemType{flex-shrink:0}.MissionSelect-module__N_AIjG__Popover{z-index:100;min-width:320px;max-height:var(--popover-available-height,90vh);overscroll-behavior:contain;background:#141414f2;border:1px solid #ffffff80;border-radius:3px;overflow-y:auto;box-shadow:0 8px 24px #0009}.MissionSelect-module__N_AIjG__List{padding:4px 0}.MissionSelect-module__N_AIjG__List:has(>.MissionSelect-module__N_AIjG__Group:first-child){padding-top:0}.MissionSelect-module__N_AIjG__Group{padding-bottom:4px}.MissionSelect-module__N_AIjG__GroupLabel{color:#c6caca;z-index:1;background:#3a4548f2;border-bottom:1px solid #ffffff4d;padding:6px 8px 6px 12px;font-size:13px;font-weight:600;position:sticky;top:0}.MissionSelect-module__N_AIjG__Group:not(:last-child){border-bottom:1px solid #ffffff4d}.MissionSelect-module__N_AIjG__Item{cursor:pointer;border-radius:4px;outline:none;flex-direction:column;gap:1px;margin:4px 4px 0;padding:6px 8px;scroll-margin-top:32px;display:flex}.MissionSelect-module__N_AIjG__List>.MissionSelect-module__N_AIjG__Item:first-child{margin-top:0}.MissionSelect-module__N_AIjG__Item[data-active-item]{background:#ffffff26}.MissionSelect-module__N_AIjG__Item[aria-selected=true]{background:#6496ff4d}.MissionSelect-module__N_AIjG__ItemHeader{align-items:center;gap:6px;display:flex}.MissionSelect-module__N_AIjG__ItemName{color:#fff;font-size:14px;font-weight:600}.MissionSelect-module__N_AIjG__ItemTypes{gap:3px;display:flex}.MissionSelect-module__N_AIjG__ItemType{color:#fff;background:#ff9d0066;border-radius:3px;padding:2px 5px;font-size:10px;font-weight:600}.MissionSelect-module__N_AIjG__ItemType:hover{background:#ff9d00b3}.MissionSelect-module__N_AIjG__ItemMissionName{color:#ffffff80;font-size:12px}.MissionSelect-module__N_AIjG__NoResults{color:#ffffff80;text-align:center;padding:12px 8px;font-size:13px}
.InspectorControls-module__gNRB6W__Controls{color:#fff;z-index:2;background:#00000080;border-radius:0 0 4px;justify-content:center;align-items:center;gap:20px;padding:8px 12px 8px 8px;font-size:13px;display:flex;position:fixed;top:0;left:0}.InspectorControls-module__gNRB6W__Dropdown,.InspectorControls-module__gNRB6W__Group{justify-content:center;align-items:center;gap:20px;display:flex}.InspectorControls-module__gNRB6W__CheckboxField,.InspectorControls-module__gNRB6W__LabelledButton,.InspectorControls-module__gNRB6W__Field{align-items:center;gap:6px;display:flex}.InspectorControls-module__gNRB6W__IconButton{color:#fff;cursor:pointer;background:#03529399;border:1px solid #c8c8c84d;border-color:#ffffff4d #c8c8c84d #c8c8c84d #ffffff4d;border-radius:4px;justify-content:center;align-items:center;width:28px;height:28px;margin:0 0 0 -12px;padding:0;font-size:15px;transition:background .2s,border-color .2s;display:flex;position:relative;transform:translate(0);box-shadow:0 1px 2px #0006}.InspectorControls-module__gNRB6W__IconButton svg{pointer-events:none}@media (hover:hover){.InspectorControls-module__gNRB6W__IconButton:hover{background:#0062b3cc;border-color:#fff6}}.InspectorControls-module__gNRB6W__IconButton:active,.InspectorControls-module__gNRB6W__IconButton[aria-expanded=true]{background:#0062b3b3;border-color:#ffffff4d;transform:translateY(1px)}.InspectorControls-module__gNRB6W__IconButton[data-active=true]{background:#0075d5e6;border-color:#fff6}.InspectorControls-module__gNRB6W__ButtonLabel{font-size:12px}.InspectorControls-module__gNRB6W__Toggle{margin:0;}.InspectorControls-module__gNRB6W__MapInfoButton{}@media (max-width:1279px){.InspectorControls-module__gNRB6W__Dropdown[data-open=false]{display:none}.InspectorControls-module__gNRB6W__Dropdown{background:#000c;border:1px solid #fff3;border-radius:4px;flex-direction:column;align-items:center;gap:12px;max-height:calc(100dvh - 56px);padding:12px;display:flex;position:absolute;top:calc(100% + 2px);left:2px;right:2px;overflow:auto;box-shadow:0 0 12px #0006}.InspectorControls-module__gNRB6W__Group{flex-wrap:wrap;gap:12px 20px}.InspectorControls-module__gNRB6W__LabelledButton{width:auto;padding:0 10px}}@media (max-width:639px){.InspectorControls-module__gNRB6W__Controls{border-radius:0;right:0}.InspectorControls-module__gNRB6W__MissionSelectWrapper{flex:1 1 0;min-width:0}.InspectorControls-module__gNRB6W__MissionSelectWrapper input{width:100%}.InspectorControls-module__gNRB6W__Toggle{flex:none}}@media (min-width:1280px){.InspectorControls-module__gNRB6W__Toggle,.InspectorControls-module__gNRB6W__LabelledButton .InspectorControls-module__gNRB6W__ButtonLabel,.InspectorControls-module__gNRB6W__MapInfoButton{display:none}}
.CopyCoordinatesButton-module__BxovtG__Root{}.CopyCoordinatesButton-module__BxovtG__Root[data-copied=true]{background:#0075d5e6;border-color:#fff6}.CopyCoordinatesButton-module__BxovtG__ClipboardCheck{opacity:1;display:none}.CopyCoordinatesButton-module__BxovtG__Root[data-copied=true] .CopyCoordinatesButton-module__BxovtG__ClipboardCheck{animation:.22s linear infinite CopyCoordinatesButton-module__BxovtG__showClipboardCheck;display:block}.CopyCoordinatesButton-module__BxovtG__Root[data-copied=true] .CopyCoordinatesButton-module__BxovtG__MapPin{display:none}.CopyCoordinatesButton-module__BxovtG__ButtonLabel{}@keyframes CopyCoordinatesButton-module__BxovtG__showClipboardCheck{0%{opacity:1}to{opacity:.2}}
.LoadDemoButton-module__kGZaoW__Root{}.LoadDemoButton-module__kGZaoW__ButtonLabel{}.LoadDemoButton-module__kGZaoW__DemoIcon{font-size:19px}
.DebugElements-module__Cmeo9W__StatsPanel{bottom:0;right:0;top:auto!important;left:auto!important}.DebugElements-module__Cmeo9W__AxisLabel{pointer-events:none;font-size:12px}.DebugElements-module__Cmeo9W__AxisLabel[data-axis=x]{color:#f90}.DebugElements-module__Cmeo9W__AxisLabel[data-axis=y]{color:#9f0}.DebugElements-module__Cmeo9W__AxisLabel[data-axis=z]{color:#09f}
.PlayerNameplate-module__zYDm0a__Root{pointer-events:none;white-space:nowrap;flex-direction:column;align-items:center;display:inline-flex}.PlayerNameplate-module__zYDm0a__Top{padding-bottom:20px;}.PlayerNameplate-module__zYDm0a__Bottom{padding-top:20px;}.PlayerNameplate-module__zYDm0a__IffArrow{width:12px;height:12px;image-rendering:pixelated;filter:drop-shadow(0 1px 2px #000000b3)}.PlayerNameplate-module__zYDm0a__Name{color:#fff;text-shadow:0 1px 3px #000000e6,0 0 1px #000000b3;font-size:11px}.PlayerNameplate-module__zYDm0a__HealthBar{background:#00000080;border:1px solid #fff3;width:60px;height:4px;margin:2px auto 0;overflow:hidden}.PlayerNameplate-module__zYDm0a__HealthFill{background:#2ecc40;height:100%}
.DemoControls-module__PjV4fq__Root{color:#fff;z-index:2;background:#000000b3;align-items:center;gap:10px;padding:8px 12px;font-size:13px;display:flex;position:fixed;bottom:0;left:0;right:0}.DemoControls-module__PjV4fq__PlayPause{color:#fff;cursor:pointer;background:#03529399;border:1px solid #ffffff4d;border-radius:4px;flex-shrink:0;justify-content:center;align-items:center;width:32px;height:32px;padding:0;font-size:14px;display:flex}@media (hover:hover){.DemoControls-module__PjV4fq__PlayPause:hover{background:#0062b3cc}}.DemoControls-module__PjV4fq__Time{font-variant-numeric:tabular-nums;white-space:nowrap;flex-shrink:0}.DemoControls-module__PjV4fq__Seek[type=range]{flex:1 1 0;min-width:0;max-width:none}.DemoControls-module__PjV4fq__Speed{color:#fff;background:#0009;border:1px solid #ffffff4d;border-radius:3px;flex-shrink:0;padding:2px 4px;font-size:12px}.DemoControls-module__PjV4fq__DiagnosticsPanel{background:#0000008c;border:1px solid #fff3;border-radius:4px;flex-direction:column;gap:3px;min-width:320px;margin-left:8px;padding:4px 8px;display:flex}.DemoControls-module__PjV4fq__DiagnosticsPanel[data-context-lost=true]{background:#46000073;border-color:#ff5a5acc}.DemoControls-module__PjV4fq__DiagnosticsStatus{letter-spacing:.02em;font-size:11px;font-weight:700}.DemoControls-module__PjV4fq__DiagnosticsMetrics{opacity:.92;flex-wrap:wrap;gap:4px 10px;font-size:11px;display:flex}.DemoControls-module__PjV4fq__DiagnosticsFooter{flex-wrap:wrap;align-items:center;gap:4px 8px;font-size:11px;display:flex}.DemoControls-module__PjV4fq__DiagnosticsFooter button{color:#fff;cursor:pointer;background:#03529399;border:1px solid #ffffff4d;border-radius:3px;padding:1px 6px;font-size:11px}.DemoControls-module__PjV4fq__DiagnosticsFooter button:hover{background:#0062b3cc}
.PlayerHUD-module__-E1Scq__PlayerHUD{z-index:1;pointer-events:none;padding-bottom:48px;position:absolute;inset:0}.PlayerHUD-module__-E1Scq__ChatWindow{position:absolute;top:60px;left:4px}.PlayerHUD-module__-E1Scq__Bar{background:#00000080;border:1px solid #fff3;width:160px;height:14px;position:absolute;overflow:hidden}.PlayerHUD-module__-E1Scq__HealthBar{top:60px;right:32px;}.PlayerHUD-module__-E1Scq__EnergyBar{top:80px;right:32px;}.PlayerHUD-module__-E1Scq__BarFill{height:100%;transition:width .15s ease-out;position:absolute;top:0;left:0}.PlayerHUD-module__-E1Scq__HealthBar .PlayerHUD-module__-E1Scq__BarFill{background:#2ecc40}.PlayerHUD-module__-E1Scq__EnergyBar .PlayerHUD-module__-E1Scq__BarFill{background:#0af}
.page-module__E0kJGG__CanvasContainer{z-index:0;position:absolute;inset:0}.page-module__E0kJGG__LoadingIndicator{pointer-events:none;z-index:1;opacity:.8;flex-direction:column;align-items:center;gap:16px;display:flex;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.page-module__E0kJGG__LoadingIndicator[data-complete=true]{animation:.3s ease-out forwards page-module__E0kJGG__loadingComplete}.page-module__E0kJGG__Spinner{border:4px solid #fff3;border-top-color:#fff;border-radius:50%;width:48px;height:48px;animation:1s linear infinite page-module__E0kJGG__spin}.page-module__E0kJGG__Progress{background:#fff3;border-radius:2px;width:200px;height:4px;overflow:hidden}.page-module__E0kJGG__ProgressBar{background:#fff;border-radius:2px;height:100%;transition:width .1s ease-out}.page-module__E0kJGG__ProgressText{color:#ffffffb3;font-variant-numeric:tabular-nums;font-size:14px}@keyframes page-module__E0kJGG__spin{to{transform:rotate(360deg)}}@keyframes page-module__E0kJGG__loadingComplete{0%{opacity:1}to{opacity:0}}

View file

@ -7,8 +7,8 @@
8:I[97367,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"ViewportBoundary"] 8:I[97367,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"ViewportBoundary"]
a:I[97367,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"MetadataBoundary"] a:I[97367,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"MetadataBoundary"]
c:I[68027,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"default"] c:I[68027,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"default"]
:HL["/t2-mapper/_next/static/chunks/17606cb20096103a.css","style"] :HL["/t2-mapper/_next/static/chunks/e620039d1c837dab.css","style"]
0:{"P":null,"b":"A7b21KJnATF7QS7o5ziIf","c":["","_not-found",""],"q":"","i":false,"f":[[["",{"children":["/_not-found",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],[["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/t2-mapper/_next/static/chunks/17606cb20096103a.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/t2-mapper/_next/static/chunks/e6da73430a674f20.js","async":true,"nonce":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L2",null,{"defaultOptions":{"clearOnDefault":false},"children":["$","$L3",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L4",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}]}]}]]}],{"children":[["$","$1","c",{"children":[null,["$","$L3",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L4",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:notFound:0:1:props:style","children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:1:props:style","children":404}],["$","div",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:style","children":["$","h2",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:children:props:style","children":"This page could not be found."}]}]]}]}]],null,["$","$L5",null,{"children":["$","$6",null,{"name":"Next.MetadataOutlet","children":"$@7"}]}]]}],{},null,false,false]},null,false,false]},null,false,false],["$","$1","h",{"children":[["$","meta",null,{"name":"robots","content":"noindex"}],["$","$L8",null,{"children":"$L9"}],["$","div",null,{"hidden":true,"children":["$","$La",null,{"children":["$","$6",null,{"name":"Next.Metadata","children":"$Lb"}]}]}],null]}],false]],"m":"$undefined","G":["$c","$undefined"],"S":true} 0:{"P":null,"b":"YSDmiCN1S-sDYVxEL27I6","c":["","_not-found",""],"q":"","i":false,"f":[[["",{"children":["/_not-found",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],[["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/t2-mapper/_next/static/chunks/e620039d1c837dab.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/t2-mapper/_next/static/chunks/e6da73430a674f20.js","async":true,"nonce":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L2",null,{"defaultOptions":{"clearOnDefault":false},"children":["$","$L3",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L4",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}]}]}]]}],{"children":[["$","$1","c",{"children":[null,["$","$L3",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L4",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:notFound:0:1:props:style","children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:1:props:style","children":404}],["$","div",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:style","children":["$","h2",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:children:props:style","children":"This page could not be found."}]}]]}]}]],null,["$","$L5",null,{"children":["$","$6",null,{"name":"Next.MetadataOutlet","children":"$@7"}]}]]}],{},null,false,false]},null,false,false]},null,false,false],["$","$1","h",{"children":[["$","meta",null,{"name":"robots","content":"noindex"}],["$","$L8",null,{"children":"$L9"}],["$","div",null,{"hidden":true,"children":["$","$La",null,{"children":["$","$6",null,{"name":"Next.Metadata","children":"$Lb"}]}]}],null]}],false]],"m":"$undefined","G":["$c","$undefined"],"S":true}
9:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"}]] 9:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"}]]
d:I[27201,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"IconMark"] d:I[27201,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"IconMark"]
7:null 7:null

View file

@ -3,4 +3,4 @@
3:I[97367,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"MetadataBoundary"] 3:I[97367,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"MetadataBoundary"]
4:"$Sreact.suspense" 4:"$Sreact.suspense"
5:I[27201,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"IconMark"] 5:I[27201,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"IconMark"]
0:{"buildId":"A7b21KJnATF7QS7o5ziIf","rsc":["$","$1","h",{"children":[["$","meta",null,{"name":"robots","content":"noindex"}],["$","$L2",null,{"children":[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"}]]}],["$","div",null,{"hidden":true,"children":["$","$L3",null,{"children":["$","$4",null,{"name":"Next.Metadata","children":[["$","title","0",{"children":"MapGenius  Explore maps for Tribes 2"}],["$","meta","1",{"name":"description","content":"Tribes 2 forever."}],["$","link","2",{"rel":"icon","href":"/t2-mapper/icon.png?icon.2911bba1.png","sizes":"108x128","type":"image/png"}],["$","$L5","3",{}]]}]}]}],null]}],"loading":null,"isPartial":false} 0:{"buildId":"YSDmiCN1S-sDYVxEL27I6","rsc":["$","$1","h",{"children":[["$","meta",null,{"name":"robots","content":"noindex"}],["$","$L2",null,{"children":[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"}]]}],["$","div",null,{"hidden":true,"children":["$","$L3",null,{"children":["$","$4",null,{"name":"Next.Metadata","children":[["$","title","0",{"children":"MapGenius  Explore maps for Tribes 2"}],["$","meta","1",{"name":"description","content":"Tribes 2 forever."}],["$","link","2",{"rel":"icon","href":"/t2-mapper/icon.png?icon.2911bba1.png","sizes":"108x128","type":"image/png"}],["$","$L5","3",{}]]}]}]}],null]}],"loading":null,"isPartial":false}

View file

@ -2,5 +2,5 @@
2:I[12985,["/t2-mapper/_next/static/chunks/e6da73430a674f20.js"],"NuqsAdapter"] 2:I[12985,["/t2-mapper/_next/static/chunks/e6da73430a674f20.js"],"NuqsAdapter"]
3:I[39756,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"default"] 3:I[39756,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"default"]
4:I[37457,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"default"] 4:I[37457,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"default"]
:HL["/t2-mapper/_next/static/chunks/17606cb20096103a.css","style"] :HL["/t2-mapper/_next/static/chunks/e620039d1c837dab.css","style"]
0:{"buildId":"A7b21KJnATF7QS7o5ziIf","rsc":["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/t2-mapper/_next/static/chunks/17606cb20096103a.css","precedence":"next"}],["$","script","script-0",{"src":"/t2-mapper/_next/static/chunks/e6da73430a674f20.js","async":true}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L2",null,{"defaultOptions":{"clearOnDefault":false},"children":["$","$L3",null,{"parallelRouterKey":"children","template":["$","$L4",null,{}],"notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]]}]}]}]}]]}],"loading":null,"isPartial":false} 0:{"buildId":"YSDmiCN1S-sDYVxEL27I6","rsc":["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/t2-mapper/_next/static/chunks/e620039d1c837dab.css","precedence":"next"}],["$","script","script-0",{"src":"/t2-mapper/_next/static/chunks/e6da73430a674f20.js","async":true}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L2",null,{"defaultOptions":{"clearOnDefault":false},"children":["$","$L3",null,{"parallelRouterKey":"children","template":["$","$L4",null,{}],"notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]]}]}]}]}]]}],"loading":null,"isPartial":false}

View file

@ -1,5 +1,5 @@
1:"$Sreact.fragment" 1:"$Sreact.fragment"
2:I[97367,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"OutletBoundary"] 2:I[97367,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"OutletBoundary"]
3:"$Sreact.suspense" 3:"$Sreact.suspense"
0:{"buildId":"A7b21KJnATF7QS7o5ziIf","rsc":["$","$1","c",{"children":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],null,["$","$L2",null,{"children":["$","$3",null,{"name":"Next.MetadataOutlet","children":"$@4"}]}]]}],"loading":null,"isPartial":false} 0:{"buildId":"YSDmiCN1S-sDYVxEL27I6","rsc":["$","$1","c",{"children":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],null,["$","$L2",null,{"children":["$","$3",null,{"name":"Next.MetadataOutlet","children":"$@4"}]}]]}],"loading":null,"isPartial":false}
4:null 4:null

View file

@ -1,4 +1,4 @@
1:"$Sreact.fragment" 1:"$Sreact.fragment"
2:I[39756,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"default"] 2:I[39756,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"default"]
3:I[37457,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"default"] 3:I[37457,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"default"]
0:{"buildId":"A7b21KJnATF7QS7o5ziIf","rsc":["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","template":["$","$L3",null,{}]}]]}],"loading":null,"isPartial":false} 0:{"buildId":"YSDmiCN1S-sDYVxEL27I6","rsc":["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","template":["$","$L3",null,{}]}]]}],"loading":null,"isPartial":false}

View file

@ -1,2 +1,2 @@
:HL["/t2-mapper/_next/static/chunks/17606cb20096103a.css","style"] :HL["/t2-mapper/_next/static/chunks/e620039d1c837dab.css","style"]
0:{"buildId":"A7b21KJnATF7QS7o5ziIf","tree":{"name":"","paramType":null,"paramKey":"","hasRuntimePrefetch":false,"slots":{"children":{"name":"/_not-found","paramType":null,"paramKey":"/_not-found","hasRuntimePrefetch":false,"slots":{"children":{"name":"__PAGE__","paramType":null,"paramKey":"__PAGE__","hasRuntimePrefetch":false,"slots":null,"isRootLayout":false}},"isRootLayout":false}},"isRootLayout":true},"staleTime":300} 0:{"buildId":"YSDmiCN1S-sDYVxEL27I6","tree":{"name":"","paramType":null,"paramKey":"","hasRuntimePrefetch":false,"slots":{"children":{"name":"/_not-found","paramType":null,"paramKey":"/_not-found","hasRuntimePrefetch":false,"slots":{"children":{"name":"__PAGE__","paramType":null,"paramKey":"__PAGE__","hasRuntimePrefetch":false,"slots":null,"isRootLayout":false}},"isRootLayout":false}},"isRootLayout":true},"staleTime":300}

File diff suppressed because one or more lines are too long

View file

@ -7,8 +7,8 @@
8:I[97367,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"ViewportBoundary"] 8:I[97367,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"ViewportBoundary"]
a:I[97367,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"MetadataBoundary"] a:I[97367,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"MetadataBoundary"]
c:I[68027,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"default"] c:I[68027,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"default"]
:HL["/t2-mapper/_next/static/chunks/17606cb20096103a.css","style"] :HL["/t2-mapper/_next/static/chunks/e620039d1c837dab.css","style"]
0:{"P":null,"b":"A7b21KJnATF7QS7o5ziIf","c":["","_not-found",""],"q":"","i":false,"f":[[["",{"children":["/_not-found",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],[["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/t2-mapper/_next/static/chunks/17606cb20096103a.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/t2-mapper/_next/static/chunks/e6da73430a674f20.js","async":true,"nonce":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L2",null,{"defaultOptions":{"clearOnDefault":false},"children":["$","$L3",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L4",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}]}]}]]}],{"children":[["$","$1","c",{"children":[null,["$","$L3",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L4",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:notFound:0:1:props:style","children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:1:props:style","children":404}],["$","div",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:style","children":["$","h2",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:children:props:style","children":"This page could not be found."}]}]]}]}]],null,["$","$L5",null,{"children":["$","$6",null,{"name":"Next.MetadataOutlet","children":"$@7"}]}]]}],{},null,false,false]},null,false,false]},null,false,false],["$","$1","h",{"children":[["$","meta",null,{"name":"robots","content":"noindex"}],["$","$L8",null,{"children":"$L9"}],["$","div",null,{"hidden":true,"children":["$","$La",null,{"children":["$","$6",null,{"name":"Next.Metadata","children":"$Lb"}]}]}],null]}],false]],"m":"$undefined","G":["$c","$undefined"],"S":true} 0:{"P":null,"b":"YSDmiCN1S-sDYVxEL27I6","c":["","_not-found",""],"q":"","i":false,"f":[[["",{"children":["/_not-found",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],[["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/t2-mapper/_next/static/chunks/e620039d1c837dab.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/t2-mapper/_next/static/chunks/e6da73430a674f20.js","async":true,"nonce":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L2",null,{"defaultOptions":{"clearOnDefault":false},"children":["$","$L3",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L4",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}]}]}]]}],{"children":[["$","$1","c",{"children":[null,["$","$L3",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L4",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:notFound:0:1:props:style","children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:1:props:style","children":404}],["$","div",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:style","children":["$","h2",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:notFound:0:1:props:children:props:children:2:props:children:props:style","children":"This page could not be found."}]}]]}]}]],null,["$","$L5",null,{"children":["$","$6",null,{"name":"Next.MetadataOutlet","children":"$@7"}]}]]}],{},null,false,false]},null,false,false]},null,false,false],["$","$1","h",{"children":[["$","meta",null,{"name":"robots","content":"noindex"}],["$","$L8",null,{"children":"$L9"}],["$","div",null,{"hidden":true,"children":["$","$La",null,{"children":["$","$6",null,{"name":"Next.Metadata","children":"$Lb"}]}]}],null]}],false]],"m":"$undefined","G":["$c","$undefined"],"S":true}
9:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"}]] 9:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"}]]
d:I[27201,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"IconMark"] d:I[27201,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"IconMark"]
7:null 7:null

File diff suppressed because one or more lines are too long

View file

@ -3,15 +3,15 @@
3:I[39756,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"default"] 3:I[39756,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"default"]
4:I[37457,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"default"] 4:I[37457,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"default"]
5:I[47257,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"ClientPageRoot"] 5:I[47257,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"ClientPageRoot"]
6:I[31713,["/t2-mapper/_next/static/chunks/e6da73430a674f20.js","/t2-mapper/_next/static/chunks/88e3d9a60c48713e.js","/t2-mapper/_next/static/chunks/93b588fa7f31935c.js","/t2-mapper/_next/static/chunks/22ebafda1e5f0224.js","/t2-mapper/_next/static/chunks/39f1afbfab5559a9.js","/t2-mapper/_next/static/chunks/ad5913f83864409c.js","/t2-mapper/_next/static/chunks/bb0aa1c978feffed.js"],"default"] 6:I[31713,["/t2-mapper/_next/static/chunks/e6da73430a674f20.js","/t2-mapper/_next/static/chunks/c339a594c158eab3.js","/t2-mapper/_next/static/chunks/93b588fa7f31935c.js","/t2-mapper/_next/static/chunks/22ebafda1e5f0224.js","/t2-mapper/_next/static/chunks/39f1afbfab5559a9.js","/t2-mapper/_next/static/chunks/f12455938f261f57.js","/t2-mapper/_next/static/chunks/bb0aa1c978feffed.js"],"default"]
9:I[97367,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"OutletBoundary"] 9:I[97367,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"OutletBoundary"]
a:"$Sreact.suspense" a:"$Sreact.suspense"
c:I[97367,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"ViewportBoundary"] c:I[97367,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"ViewportBoundary"]
e:I[97367,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"MetadataBoundary"] e:I[97367,["/t2-mapper/_next/static/chunks/4fd93823156e59e8.js"],"MetadataBoundary"]
10:I[68027,[],"default"] 10:I[68027,[],"default"]
:HL["/t2-mapper/_next/static/chunks/17606cb20096103a.css","style"] :HL["/t2-mapper/_next/static/chunks/e620039d1c837dab.css","style"]
:HL["/t2-mapper/_next/static/chunks/afff663ba7029ccf.css","style"] :HL["/t2-mapper/_next/static/chunks/f6c55b3b7050a508.css","style"]
0:{"P":null,"b":"A7b21KJnATF7QS7o5ziIf","c":["",""],"q":"","i":false,"f":[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],[["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/t2-mapper/_next/static/chunks/17606cb20096103a.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/t2-mapper/_next/static/chunks/e6da73430a674f20.js","async":true,"nonce":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L2",null,{"defaultOptions":{"clearOnDefault":false},"children":["$","$L3",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L4",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}]}]}]]}],{"children":[["$","$1","c",{"children":[["$","$L5",null,{"Component":"$6","serverProvidedParams":{"searchParams":{},"params":{},"promises":["$@7","$@8"]}}],[["$","link","0",{"rel":"stylesheet","href":"/t2-mapper/_next/static/chunks/afff663ba7029ccf.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/t2-mapper/_next/static/chunks/88e3d9a60c48713e.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/t2-mapper/_next/static/chunks/93b588fa7f31935c.js","async":true,"nonce":"$undefined"}],["$","script","script-2",{"src":"/t2-mapper/_next/static/chunks/22ebafda1e5f0224.js","async":true,"nonce":"$undefined"}],["$","script","script-3",{"src":"/t2-mapper/_next/static/chunks/39f1afbfab5559a9.js","async":true,"nonce":"$undefined"}],["$","script","script-4",{"src":"/t2-mapper/_next/static/chunks/ad5913f83864409c.js","async":true,"nonce":"$undefined"}],["$","script","script-5",{"src":"/t2-mapper/_next/static/chunks/bb0aa1c978feffed.js","async":true,"nonce":"$undefined"}]],["$","$L9",null,{"children":["$","$a",null,{"name":"Next.MetadataOutlet","children":"$@b"}]}]]}],{},null,false,false]},null,false,false],["$","$1","h",{"children":[null,["$","$Lc",null,{"children":"$Ld"}],["$","div",null,{"hidden":true,"children":["$","$Le",null,{"children":["$","$a",null,{"name":"Next.Metadata","children":"$Lf"}]}]}],null]}],false]],"m":"$undefined","G":["$10",[]],"S":true} 0:{"P":null,"b":"YSDmiCN1S-sDYVxEL27I6","c":["",""],"q":"","i":false,"f":[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],[["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/t2-mapper/_next/static/chunks/e620039d1c837dab.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/t2-mapper/_next/static/chunks/e6da73430a674f20.js","async":true,"nonce":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L2",null,{"defaultOptions":{"clearOnDefault":false},"children":["$","$L3",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L4",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}]}]}]]}],{"children":[["$","$1","c",{"children":[["$","$L5",null,{"Component":"$6","serverProvidedParams":{"searchParams":{},"params":{},"promises":["$@7","$@8"]}}],[["$","link","0",{"rel":"stylesheet","href":"/t2-mapper/_next/static/chunks/f6c55b3b7050a508.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/t2-mapper/_next/static/chunks/c339a594c158eab3.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/t2-mapper/_next/static/chunks/93b588fa7f31935c.js","async":true,"nonce":"$undefined"}],["$","script","script-2",{"src":"/t2-mapper/_next/static/chunks/22ebafda1e5f0224.js","async":true,"nonce":"$undefined"}],["$","script","script-3",{"src":"/t2-mapper/_next/static/chunks/39f1afbfab5559a9.js","async":true,"nonce":"$undefined"}],["$","script","script-4",{"src":"/t2-mapper/_next/static/chunks/f12455938f261f57.js","async":true,"nonce":"$undefined"}],["$","script","script-5",{"src":"/t2-mapper/_next/static/chunks/bb0aa1c978feffed.js","async":true,"nonce":"$undefined"}]],["$","$L9",null,{"children":["$","$a",null,{"name":"Next.MetadataOutlet","children":"$@b"}]}]]}],{},null,false,false]},null,false,false],["$","$1","h",{"children":[null,["$","$Lc",null,{"children":"$Ld"}],["$","div",null,{"hidden":true,"children":["$","$Le",null,{"children":["$","$a",null,{"name":"Next.Metadata","children":"$Lf"}]}]}],null]}],false]],"m":"$undefined","G":["$10",[]],"S":true}
7:{} 7:{}
8:"$0:f:0:1:1:children:0:props:children:0:props:serverProvidedParams:params" 8:"$0:f:0:1:1:children:0:props:children:0:props:serverProvidedParams:params"
d:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"}]] d:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"}]]

View file

@ -0,0 +1,36 @@
.Root {
composes: IconButton from "./InspectorControls.module.css";
composes: LabelledButton from "./InspectorControls.module.css";
}
.Root[data-copied="true"] {
background: rgba(0, 117, 213, 0.9);
border-color: rgba(255, 255, 255, 0.4);
}
.ClipboardCheck {
display: none;
opacity: 1;
}
.Root[data-copied="true"] .ClipboardCheck {
display: block;
animation: showClipboardCheck 220ms linear infinite;
}
.Root[data-copied="true"] .MapPin {
display: none;
}
.ButtonLabel {
composes: ButtonLabel from "./InspectorControls.module.css";
}
@keyframes showClipboardCheck {
0% {
opacity: 1;
}
100% {
opacity: 0.2;
}
}

View file

@ -3,6 +3,7 @@ import { FaMapPin } from "react-icons/fa";
import { FaClipboardCheck } from "react-icons/fa6"; import { FaClipboardCheck } from "react-icons/fa6";
import { Camera, Quaternion, Vector3 } from "three"; import { Camera, Quaternion, Vector3 } from "three";
import { useSettings } from "./SettingsProvider"; import { useSettings } from "./SettingsProvider";
import styles from "./CopyCoordinatesButton.module.css";
function encodeViewHash({ function encodeViewHash({
position, position,
@ -55,16 +56,16 @@ export function CopyCoordinatesButton({
return ( return (
<button <button
type="button" type="button"
className="IconButton LabelledButton CopyCoordinatesButton" className={styles.Root}
aria-label="Copy coordinates URL" aria-label="Copy coordinates URL"
title="Copy coordinates URL" title="Copy coordinates URL"
onClick={handleCopyLink} onClick={handleCopyLink}
data-copied={showCopied ? "true" : "false"} data-copied={showCopied ? "true" : "false"}
id="copyCoordinatesButton" id="copyCoordinatesButton"
> >
<FaMapPin className="MapPin" /> <FaMapPin className={styles.MapPin} />
<FaClipboardCheck className="ClipboardCheck" /> <FaClipboardCheck className={styles.ClipboardCheck} />
<span className="ButtonLabel"> Copy coordinates URL</span> <span className={styles.ButtonLabel}> Copy coordinates URL</span>
</button> </button>
); );
} }

View file

@ -0,0 +1,23 @@
.StatsPanel {
left: auto !important;
top: auto !important;
right: 0;
bottom: 0;
}
.AxisLabel {
font-size: 12px;
pointer-events: none;
}
.AxisLabel[data-axis="x"] {
color: rgb(255, 153, 0);
}
.AxisLabel[data-axis="y"] {
color: rgb(153, 255, 0);
}
.AxisLabel[data-axis="z"] {
color: rgb(0, 153, 255);
}

View file

@ -2,6 +2,7 @@ import { Stats, Html } from "@react-three/drei";
import { useDebug } from "./SettingsProvider"; import { useDebug } from "./SettingsProvider";
import { useEffect, useRef } from "react"; import { useEffect, useRef } from "react";
import { AxesHelper } from "three"; import { AxesHelper } from "three";
import styles from "./DebugElements.module.css";
export function DebugElements() { export function DebugElements() {
const { debugMode } = useDebug(); const { debugMode } = useDebug();
@ -17,7 +18,7 @@ export function DebugElements() {
return debugMode ? ( return debugMode ? (
<> <>
<Stats className="StatsPanel" /> <Stats className={styles.StatsPanel} />
<axesHelper ref={axesRef} args={[70]} renderOrder={999}> <axesHelper ref={axesRef} args={[70]} renderOrder={999}>
<lineBasicMaterial <lineBasicMaterial
depthTest={false} depthTest={false}
@ -27,17 +28,17 @@ export function DebugElements() {
/> />
</axesHelper> </axesHelper>
<Html position={[80, 0, 0]} center> <Html position={[80, 0, 0]} center>
<span className="AxisLabel" data-axis="y"> <span className={styles.AxisLabel} data-axis="y">
Y Y
</span> </span>
</Html> </Html>
<Html position={[0, 80, 0]} center> <Html position={[0, 80, 0]} center>
<span className="AxisLabel" data-axis="z"> <span className={styles.AxisLabel} data-axis="z">
Z Z
</span> </span>
</Html> </Html>
<Html position={[0, 0, 80]} center> <Html position={[0, 0, 80]} center>
<span className="AxisLabel" data-axis="x"> <span className={styles.AxisLabel} data-axis="x">
X X
</span> </span>
</Html> </Html>

View file

@ -0,0 +1,111 @@
.Root {
position: fixed;
bottom: 0;
left: 0;
right: 0;
display: flex;
align-items: center;
gap: 10px;
padding: 8px 12px;
background: rgba(0, 0, 0, 0.7);
color: #fff;
font-size: 13px;
z-index: 2;
}
.PlayPause {
width: 32px;
height: 32px;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
padding: 0;
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 4px;
background: rgba(3, 82, 147, 0.6);
color: #fff;
font-size: 14px;
cursor: pointer;
}
@media (hover: hover) {
.PlayPause:hover {
background: rgba(0, 98, 179, 0.8);
}
}
.Time {
flex-shrink: 0;
font-variant-numeric: tabular-nums;
white-space: nowrap;
}
.Seek[type="range"] {
flex: 1 1 0;
min-width: 0;
max-width: none;
}
.Speed {
flex-shrink: 0;
padding: 2px 4px;
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 3px;
background: rgba(0, 0, 0, 0.6);
color: #fff;
font-size: 12px;
}
.DiagnosticsPanel {
display: flex;
flex-direction: column;
gap: 3px;
margin-left: 8px;
padding: 4px 8px;
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 4px;
background: rgba(0, 0, 0, 0.55);
min-width: 320px;
}
.DiagnosticsPanel[data-context-lost="true"] {
border-color: rgba(255, 90, 90, 0.8);
background: rgba(70, 0, 0, 0.45);
}
.DiagnosticsStatus {
font-size: 11px;
font-weight: 700;
letter-spacing: 0.02em;
}
.DiagnosticsMetrics {
display: flex;
flex-wrap: wrap;
gap: 4px 10px;
font-size: 11px;
opacity: 0.92;
}
.DiagnosticsFooter {
display: flex;
flex-wrap: wrap;
gap: 4px 8px;
align-items: center;
font-size: 11px;
}
.DiagnosticsFooter button {
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 3px;
background: rgba(3, 82, 147, 0.6);
color: #fff;
padding: 1px 6px;
font-size: 11px;
cursor: pointer;
}
.DiagnosticsFooter button:hover {
background: rgba(0, 98, 179, 0.8);
}

View file

@ -13,6 +13,7 @@ import {
useEngineSelector, useEngineSelector,
useEngineStoreApi, useEngineStoreApi,
} from "../state"; } from "../state";
import styles from "./DemoControls.module.css";
const SPEED_OPTIONS = [0.25, 0.5, 1, 2, 4]; const SPEED_OPTIONS = [0.25, 0.5, 1, 2, 4];
@ -89,23 +90,23 @@ export function DemoControls() {
return ( return (
<div <div
className="DemoControls" className={styles.Root}
onKeyDown={(e) => e.stopPropagation()} onKeyDown={(e) => e.stopPropagation()}
onPointerDown={(e) => e.stopPropagation()} onPointerDown={(e) => e.stopPropagation()}
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
> >
<button <button
className="DemoControls-playPause" className={styles.PlayPause}
onClick={isPlaying ? pause : play} onClick={isPlaying ? pause : play}
aria-label={isPlaying ? "Pause" : "Play"} aria-label={isPlaying ? "Pause" : "Play"}
> >
{isPlaying ? "\u275A\u275A" : "\u25B6"} {isPlaying ? "\u275A\u275A" : "\u25B6"}
</button> </button>
<span className="DemoControls-time"> <span className={styles.Time}>
{`${formatTime(currentTime)} / ${formatTime(duration)}`} {`${formatTime(currentTime)} / ${formatTime(duration)}`}
</span> </span>
<input <input
className="DemoControls-seek" className={styles.Seek}
type="range" type="range"
min={0} min={0}
max={duration} max={duration}
@ -114,7 +115,7 @@ export function DemoControls() {
onChange={handleSeek} onChange={handleSeek}
/> />
<select <select
className="DemoControls-speed" className={styles.Speed}
value={speed} value={speed}
onChange={handleSpeedChange} onChange={handleSpeedChange}
> >
@ -125,13 +126,13 @@ export function DemoControls() {
))} ))}
</select> </select>
<div <div
className="DemoDiagnosticsPanel" className={styles.DiagnosticsPanel}
data-context-lost={webglContextLost ? "true" : undefined} data-context-lost={webglContextLost ? "true" : undefined}
> >
<div className="DemoDiagnosticsPanel-status"> <div className={styles.DiagnosticsStatus}>
{webglContextLost ? "WebGL context: LOST" : "WebGL context: ok"} {webglContextLost ? "WebGL context: LOST" : "WebGL context: ok"}
</div> </div>
<div className="DemoDiagnosticsPanel-metrics"> <div className={styles.DiagnosticsMetrics}>
{latestRendererSample ? ( {latestRendererSample ? (
<> <>
<span> <span>
@ -153,7 +154,7 @@ export function DemoControls() {
<span>No renderer samples yet</span> <span>No renderer samples yet</span>
)} )}
</div> </div>
<div className="DemoDiagnosticsPanel-footer"> <div className={styles.DiagnosticsFooter}>
<span> <span>
samples {rendererSampleCount} events {playbackEventCount} samples {rendererSampleCount} events {playbackEventCount}
</span> </span>

View file

@ -0,0 +1,9 @@
.Label {
background: rgba(0, 0, 0, 0.5);
color: #fff;
font-size: 11px;
white-space: nowrap;
padding: 1px 3px;
border-radius: 1px;
text-align: center;
}

View file

@ -2,6 +2,7 @@ import { memo, ReactNode, useRef, useState } from "react";
import { Object3D, Vector3 } from "three"; import { Object3D, Vector3 } from "three";
import { useFrame } from "@react-three/fiber"; import { useFrame } from "@react-three/fiber";
import { Html } from "@react-three/drei"; import { Html } from "@react-three/drei";
import styles from "./FloatingLabel.module.css";
const DEFAULT_POSITION = [0, 0, 0] as [x: number, y: number, z: number]; const DEFAULT_POSITION = [0, 0, 0] as [x: number, y: number, z: number];
const _worldPos = new Vector3(); const _worldPos = new Vector3();
@ -15,7 +16,9 @@ function isBehindCamera(
): boolean { ): boolean {
const e = camera.matrixWorld.elements; const e = camera.matrixWorld.elements;
// Dot product of (objectPos - cameraPos) with camera forward (-Z column). // Dot product of (objectPos - cameraPos) with camera forward (-Z column).
return (wx - e[12]) * -e[8] + (wy - e[13]) * -e[9] + (wz - e[14]) * -e[10] < 0; return (
(wx - e[12]) * -e[8] + (wy - e[13]) * -e[9] + (wz - e[14]) * -e[10] < 0
);
} }
export const FloatingLabel = memo(function FloatingLabel({ export const FloatingLabel = memo(function FloatingLabel({
@ -39,10 +42,17 @@ export const FloatingLabel = memo(function FloatingLabel({
if (!group) return; if (!group) return;
group.getWorldPosition(_worldPos); group.getWorldPosition(_worldPos);
const behind = isBehindCamera(camera, _worldPos.x, _worldPos.y, _worldPos.z); const behind = isBehindCamera(
camera,
_worldPos.x,
_worldPos.y,
_worldPos.z,
);
if (fadeWithDistance) { if (fadeWithDistance) {
const distance = behind ? Infinity : camera.position.distanceTo(_worldPos); const distance = behind
? Infinity
: camera.position.distanceTo(_worldPos);
const shouldBeVisible = distance < 200; const shouldBeVisible = distance < 200;
if (isVisible !== shouldBeVisible) { if (isVisible !== shouldBeVisible) {
@ -69,7 +79,7 @@ export const FloatingLabel = memo(function FloatingLabel({
<group ref={groupRef}> <group ref={groupRef}>
{isVisible ? ( {isVisible ? (
<Html position={position} center> <Html position={position} center>
<div ref={labelRef} className="StaticShapeLabel" style={{ color }}> <div ref={labelRef} className={styles.Label} style={{ color }}>
{children} {children}
</div> </div>
</Html> </Html>

View file

@ -0,0 +1,175 @@
.Controls {
position: fixed;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.5);
color: #fff;
padding: 8px 12px 8px 8px;
border-radius: 0 0 4px 0;
font-size: 13px;
z-index: 2;
display: flex;
align-items: center;
justify-content: center;
gap: 20px;
}
.Dropdown {
display: flex;
align-items: center;
justify-content: center;
gap: 20px;
}
.Group {
display: flex;
align-items: center;
justify-content: center;
gap: 20px;
}
.CheckboxField,
.LabelledButton {
display: flex;
align-items: center;
gap: 6px;
}
.Field {
display: flex;
align-items: center;
gap: 6px;
}
.IconButton {
position: relative;
display: flex;
align-items: center;
justify-content: center;
width: 28px;
height: 28px;
margin: 0 0 0 -12px;
font-size: 15px;
padding: 0;
border-top: 1px solid rgba(255, 255, 255, 0.3);
border-left: 1px solid rgba(255, 255, 255, 0.3);
border-right: 1px solid rgba(200, 200, 200, 0.3);
border-bottom: 1px solid rgba(200, 200, 200, 0.3);
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
border-radius: 4px;
background: rgba(3, 82, 147, 0.6);
color: #fff;
cursor: pointer;
transform: translate(0, 0);
transition:
background 0.2s,
border-color 0.2s;
}
.IconButton svg {
pointer-events: none;
}
@media (hover: hover) {
.IconButton:hover {
background: rgba(0, 98, 179, 0.8);
border-color: rgba(255, 255, 255, 0.4);
}
}
.IconButton:active,
.IconButton[aria-expanded="true"] {
background: rgba(0, 98, 179, 0.7);
border-color: rgba(255, 255, 255, 0.3);
transform: translate(0, 1px);
}
.IconButton[data-active="true"] {
background: rgba(0, 117, 213, 0.9);
border-color: rgba(255, 255, 255, 0.4);
}
.ButtonLabel {
font-size: 12px;
}
.Toggle {
composes: IconButton;
margin: 0;
}
.MapInfoButton {
composes: IconButton;
composes: LabelledButton;
}
.MissionSelectWrapper {
}
@media (max-width: 1279px) {
.Dropdown[data-open="false"] {
display: none;
}
.Dropdown {
position: absolute;
top: calc(100% + 2px);
left: 2px;
right: 2px;
display: flex;
overflow: auto;
max-height: calc(100dvh - 56px);
flex-direction: column;
align-items: center;
gap: 12px;
background: rgba(0, 0, 0, 0.8);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 4px;
padding: 12px;
box-shadow: 0 0 12px rgba(0, 0, 0, 0.4);
}
.Group {
flex-wrap: wrap;
gap: 12px 20px;
}
.LabelledButton {
width: auto;
padding: 0 10px;
}
}
@media (max-width: 639px) {
.Controls {
right: 0;
border-radius: 0;
}
.MissionSelectWrapper {
flex: 1 1 0;
min-width: 0;
}
.MissionSelectWrapper input {
width: 100%;
}
.Toggle {
flex: 0 0 auto;
}
}
@media (min-width: 1280px) {
.Toggle {
display: none;
}
.LabelledButton .ButtonLabel {
display: none;
}
.MapInfoButton {
display: none;
}
}

View file

@ -11,6 +11,7 @@ import { CopyCoordinatesButton } from "./CopyCoordinatesButton";
import { LoadDemoButton } from "./LoadDemoButton"; import { LoadDemoButton } from "./LoadDemoButton";
import { useDemoRecording } from "./DemoProvider"; import { useDemoRecording } from "./DemoProvider";
import { FiInfo, FiSettings } from "react-icons/fi"; import { FiInfo, FiSettings } from "react-icons/fi";
import styles from "./InspectorControls.module.css";
export function InspectorControls({ export function InspectorControls({
missionName, missionName,
@ -79,20 +80,23 @@ export function InspectorControls({
return ( return (
<div <div
id="controls" id="controls"
className={styles.Controls}
onKeyDown={(e) => e.stopPropagation()} onKeyDown={(e) => e.stopPropagation()}
onPointerDown={(e) => e.stopPropagation()} onPointerDown={(e) => e.stopPropagation()}
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
> >
<MissionSelect <div className={styles.MissionSelectWrapper}>
value={missionName} <MissionSelect
missionType={missionType} value={missionName}
onChange={onChangeMission} missionType={missionType}
disabled={isDemoLoaded} onChange={onChangeMission}
/> disabled={isDemoLoaded}
/>
</div>
<div ref={focusAreaRef}> <div ref={focusAreaRef}>
<button <button
ref={buttonRef} ref={buttonRef}
className="IconButton Controls-toggle" className={styles.Toggle}
onClick={() => { onClick={() => {
setSettingsOpen((isOpen) => !isOpen); setSettingsOpen((isOpen) => !isOpen);
}} }}
@ -103,7 +107,7 @@ export function InspectorControls({
<FiSettings /> <FiSettings />
</button> </button>
<div <div
className="Controls-dropdown" className={styles.Dropdown}
ref={dropdownRef} ref={dropdownRef}
id="settingsPanel" id="settingsPanel"
tabIndex={-1} tabIndex={-1}
@ -111,7 +115,7 @@ export function InspectorControls({
onBlur={handleDropdownBlur} onBlur={handleDropdownBlur}
data-open={settingsOpen} data-open={settingsOpen}
> >
<div className="Controls-group"> <div className={styles.Group}>
<CopyCoordinatesButton <CopyCoordinatesButton
cameraRef={cameraRef} cameraRef={cameraRef}
missionName={missionName} missionName={missionName}
@ -120,16 +124,16 @@ export function InspectorControls({
<LoadDemoButton /> <LoadDemoButton />
<button <button
type="button" type="button"
className="IconButton LabelledButton MapInfoButton" className={styles.MapInfoButton}
aria-label="Show map info" aria-label="Show map info"
onClick={onOpenMapInfo} onClick={onOpenMapInfo}
> >
<FiInfo /> <FiInfo />
<span className="ButtonLabel">Show map info</span> <span className={styles.ButtonLabel}>Show map info</span>
</button> </button>
</div> </div>
<div className="Controls-group"> <div className={styles.Group}>
<div className="CheckboxField"> <div className={styles.CheckboxField}>
<input <input
id="fogInput" id="fogInput"
type="checkbox" type="checkbox"
@ -140,7 +144,7 @@ export function InspectorControls({
/> />
<label htmlFor="fogInput">Fog?</label> <label htmlFor="fogInput">Fog?</label>
</div> </div>
<div className="CheckboxField"> <div className={styles.CheckboxField}>
<input <input
id="audioInput" id="audioInput"
type="checkbox" type="checkbox"
@ -152,8 +156,8 @@ export function InspectorControls({
<label htmlFor="audioInput">Audio?</label> <label htmlFor="audioInput">Audio?</label>
</div> </div>
</div> </div>
<div className="Controls-group"> <div className={styles.Group}>
<div className="CheckboxField"> <div className={styles.CheckboxField}>
<input <input
id="animationInput" id="animationInput"
type="checkbox" type="checkbox"
@ -164,7 +168,7 @@ export function InspectorControls({
/> />
<label htmlFor="animationInput">Animation?</label> <label htmlFor="animationInput">Animation?</label>
</div> </div>
<div className="CheckboxField"> <div className={styles.CheckboxField}>
<input <input
id="debugInput" id="debugInput"
type="checkbox" type="checkbox"
@ -176,8 +180,8 @@ export function InspectorControls({
<label htmlFor="debugInput">Debug?</label> <label htmlFor="debugInput">Debug?</label>
</div> </div>
</div> </div>
<div className="Controls-group"> <div className={styles.Group}>
<div className="Field"> <div className={styles.Field}>
<label htmlFor="fovInput">FOV</label> <label htmlFor="fovInput">FOV</label>
<input <input
id="fovInput" id="fovInput"
@ -191,7 +195,7 @@ export function InspectorControls({
/> />
<output htmlFor="fovInput">{fov}</output> <output htmlFor="fovInput">{fov}</output>
</div> </div>
<div className="Field"> <div className={styles.Field}>
<label htmlFor="speedInput">Speed</label> <label htmlFor="speedInput">Speed</label>
<input <input
id="speedInput" id="speedInput"
@ -208,8 +212,8 @@ export function InspectorControls({
</div> </div>
</div> </div>
{isTouch && ( {isTouch && (
<div className="Controls-group"> <div className={styles.Group}>
<div className="Field"> <div className={styles.Field}>
<label htmlFor="touchModeInput">Joystick:</label>{" "} <label htmlFor="touchModeInput">Joystick:</label>{" "}
<select <select
id="touchModeInput" id="touchModeInput"

View file

@ -0,0 +1,55 @@
.Root {
position: fixed;
bottom: 16px;
left: 50%;
transform: translateX(-50%);
display: flex;
align-items: flex-end;
gap: 10px;
pointer-events: none;
z-index: 1;
}
.Column {
display: flex;
gap: 4px;
flex-direction: column;
justify-content: center;
}
.Row {
display: flex;
gap: 4px;
justify-content: stretch;
}
.Spacer {
width: 32px;
}
.Key {
min-width: 32px;
height: 32px;
display: flex;
flex: 1 0 0;
align-items: center;
justify-content: center;
padding: 0 8px;
border-radius: 4px;
background: rgba(0, 0, 0, 0.4);
border: 1px solid rgba(255, 255, 255, 0.2);
color: rgba(255, 255, 255, 0.5);
font-size: 11px;
font-weight: 600;
white-space: nowrap;
}
.Key[data-pressed="true"] {
background: rgba(52, 187, 171, 0.6);
border-color: rgba(35, 253, 220, 0.5);
color: #fff;
}
.Arrow {
margin-right: 3px;
}

View file

@ -1,6 +1,7 @@
import { useKeyboardControls } from "@react-three/drei"; import { useKeyboardControls } from "@react-three/drei";
import { Controls } from "./ObserverControls"; import { Controls } from "./ObserverControls";
import { useDemoRecording } from "./DemoProvider"; import { useDemoRecording } from "./DemoProvider";
import styles from "./KeyboardOverlay.module.css";
export function KeyboardOverlay() { export function KeyboardOverlay() {
const recording = useDemoRecording(); const recording = useDemoRecording();
@ -18,55 +19,55 @@ export function KeyboardOverlay() {
if (recording) return null; if (recording) return null;
return ( return (
<div className="KeyboardOverlay"> <div className={styles.Root}>
<div className="KeyboardOverlay-column"> <div className={styles.Column}>
<div className="KeyboardOverlay-row"> <div className={styles.Row}>
<div className="KeyboardOverlay-spacer" /> <div className={styles.Spacer} />
<div className="KeyboardOverlay-key" data-pressed={forward}> <div className={styles.Key} data-pressed={forward}>
W W
</div> </div>
<div className="KeyboardOverlay-spacer" /> <div className={styles.Spacer} />
</div> </div>
<div className="KeyboardOverlay-row"> <div className={styles.Row}>
<div className="KeyboardOverlay-key" data-pressed={left}> <div className={styles.Key} data-pressed={left}>
A A
</div> </div>
<div className="KeyboardOverlay-key" data-pressed={backward}> <div className={styles.Key} data-pressed={backward}>
S S
</div> </div>
<div className="KeyboardOverlay-key" data-pressed={right}> <div className={styles.Key} data-pressed={right}>
D D
</div> </div>
</div> </div>
</div> </div>
<div className="KeyboardOverlay-column"> <div className={styles.Column}>
<div className="KeyboardOverlay-row"> <div className={styles.Row}>
<div className="KeyboardOverlay-key" data-pressed={up}> <div className={styles.Key} data-pressed={up}>
<span className="KeyboardOverlay-arrow">&uarr;</span> Space <span className={styles.Arrow}>&uarr;</span> Space
</div> </div>
</div> </div>
<div className="KeyboardOverlay-row"> <div className={styles.Row}>
<div className="KeyboardOverlay-key" data-pressed={down}> <div className={styles.Key} data-pressed={down}>
<span className="KeyboardOverlay-arrow">&darr;</span> Shift <span className={styles.Arrow}>&darr;</span> Shift
</div> </div>
</div> </div>
</div> </div>
<div className="KeyboardOverlay-column"> <div className={styles.Column}>
<div className="KeyboardOverlay-row"> <div className={styles.Row}>
<div className="KeyboardOverlay-spacer" /> <div className={styles.Spacer} />
<div className="KeyboardOverlay-key" data-pressed={lookUp}> <div className={styles.Key} data-pressed={lookUp}>
&uarr; &uarr;
</div> </div>
<div className="KeyboardOverlay-spacer" /> <div className={styles.Spacer} />
</div> </div>
<div className="KeyboardOverlay-row"> <div className={styles.Row}>
<div className="KeyboardOverlay-key" data-pressed={lookLeft}> <div className={styles.Key} data-pressed={lookLeft}>
&larr; &larr;
</div> </div>
<div className="KeyboardOverlay-key" data-pressed={lookDown}> <div className={styles.Key} data-pressed={lookDown}>
&darr; &darr;
</div> </div>
<div className="KeyboardOverlay-key" data-pressed={lookRight}> <div className={styles.Key} data-pressed={lookRight}>
&rarr; &rarr;
</div> </div>
</div> </div>

View file

@ -0,0 +1,12 @@
.Root {
composes: IconButton from "./InspectorControls.module.css";
composes: LabelledButton from "./InspectorControls.module.css";
}
.ButtonLabel {
composes: ButtonLabel from "./InspectorControls.module.css";
}
.DemoIcon {
font-size: 19px;
}

View file

@ -2,6 +2,7 @@ import { useCallback, useRef } from "react";
import { MdOndemandVideo } from "react-icons/md"; import { MdOndemandVideo } from "react-icons/md";
import { useDemoActions, useDemoRecording } from "./DemoProvider"; import { useDemoActions, useDemoRecording } from "./DemoProvider";
import { createDemoStreamingRecording } from "../demo/streaming"; import { createDemoStreamingRecording } from "../demo/streaming";
import styles from "./LoadDemoButton.module.css";
export function LoadDemoButton() { export function LoadDemoButton() {
const recording = useDemoRecording(); const recording = useDemoRecording();
@ -53,14 +54,14 @@ export function LoadDemoButton() {
/> />
<button <button
type="button" type="button"
className="IconButton LabelledButton" className={styles.Root}
aria-label={recording ? "Unload demo" : "Load demo (.rec)"} aria-label={recording ? "Unload demo" : "Load demo (.rec)"}
title={recording ? "Unload demo" : "Load demo (.rec)"} title={recording ? "Unload demo" : "Load demo (.rec)"}
onClick={handleClick} onClick={handleClick}
data-active={recording ? "true" : undefined} data-active={recording ? "true" : undefined}
> >
<MdOndemandVideo className="DemoIcon" /> <MdOndemandVideo className={styles.DemoIcon} />
<span className="ButtonLabel"> <span className={styles.ButtonLabel}>
{recording ? "Unload demo" : "Demo"} {recording ? "Unload demo" : "Demo"}
</span> </span>
</button> </button>

View file

@ -0,0 +1,181 @@
.InputWrapper {
position: relative;
display: flex;
align-items: center;
}
.Shortcut {
position: absolute;
right: 7px;
font-family: system-ui, sans-serif;
font-size: 11px;
padding: 1px 4px;
border-radius: 3px;
background: rgba(255, 255, 255, 0.15);
color: rgba(255, 255, 255, 0.6);
pointer-events: none;
}
.Input[aria-expanded="true"] ~ .Shortcut {
display: none;
}
.Input {
width: 280px;
padding: 6px 36px 6px 8px;
font-size: 14px;
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 3px;
background: rgba(0, 0, 0, 0.6);
color: #fff;
outline: none;
user-select: text;
}
.Input[aria-expanded="true"] {
padding-right: 8px;
}
.Input:focus {
border-color: rgba(255, 255, 255, 0.6);
}
.Input::placeholder {
color: transparent;
}
.SelectedValue {
position: absolute;
left: 8px;
right: 36px;
display: flex;
align-items: center;
gap: 6px;
pointer-events: none;
overflow: hidden;
}
.Input[aria-expanded="true"] ~ .SelectedValue {
display: none;
}
.SelectedName {
color: #fff;
font-weight: 600;
font-size: 14px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
flex-shrink: 1;
min-width: 0;
}
.SelectedValue > .ItemType {
flex-shrink: 0;
}
.Popover {
z-index: 100;
min-width: 320px;
max-height: var(--popover-available-height, 90vh);
overflow-y: auto;
overscroll-behavior: contain;
background: rgba(20, 20, 20, 0.95);
border: 1px solid rgba(255, 255, 255, 0.5);
border-radius: 3px;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.6);
}
.List {
padding: 4px 0;
}
.List:has(> .Group:first-child) {
padding-top: 0;
}
.Group {
padding-bottom: 4px;
}
.GroupLabel {
position: sticky;
top: 0;
padding: 6px 8px 6px 12px;
font-size: 13px;
font-weight: 600;
color: rgb(198, 202, 202);
background: rgba(58, 69, 72, 0.95);
border-bottom: 1px solid rgba(255, 255, 255, 0.3);
z-index: 1;
}
.Group:not(:last-child) {
border-bottom: 1px solid rgba(255, 255, 255, 0.3);
}
.Item {
display: flex;
flex-direction: column;
gap: 1px;
margin: 4px 4px 0;
padding: 6px 8px;
border-radius: 4px;
cursor: pointer;
outline: none;
scroll-margin-top: 32px;
}
.List > .Item:first-child {
margin-top: 0;
}
.Item[data-active-item] {
background: rgba(255, 255, 255, 0.15);
}
.Item[aria-selected="true"] {
background: rgba(100, 150, 255, 0.3);
}
.ItemHeader {
display: flex;
align-items: center;
gap: 6px;
}
.ItemName {
font-size: 14px;
font-weight: 600;
color: #fff;
}
.ItemTypes {
display: flex;
gap: 3px;
}
.ItemType {
font-size: 10px;
font-weight: 600;
padding: 2px 5px;
border-radius: 3px;
background: rgba(255, 157, 0, 0.4);
color: #fff;
}
.ItemType:hover {
background: rgba(255, 157, 0, 0.7);
}
.ItemMissionName {
font-size: 12px;
color: rgba(255, 255, 255, 0.5);
}
.NoResults {
padding: 12px 8px;
font-size: 13px;
color: rgba(255, 255, 255, 0.5);
text-align: center;
}

View file

@ -19,6 +19,7 @@ import {
import { matchSorter } from "match-sorter"; import { matchSorter } from "match-sorter";
import { getMissionInfo, getMissionList, getSourceAndPath } from "../manifest"; import { getMissionInfo, getMissionList, getSourceAndPath } from "../manifest";
import orderBy from "lodash.orderby"; import orderBy from "lodash.orderby";
import styles from "./MissionSelect.module.css";
const excludeMissions = new Set([ const excludeMissions = new Set([
"SkiFree", "SkiFree",
@ -125,16 +126,16 @@ const isMac =
function MissionItemContent({ mission }: { mission: MissionItem }) { function MissionItemContent({ mission }: { mission: MissionItem }) {
return ( return (
<> <>
<span className="MissionSelect-itemHeader"> <span className={styles.ItemHeader}>
<span className="MissionSelect-itemName"> <span className={styles.ItemName}>
{mission.displayName || mission.missionName} {mission.displayName || mission.missionName}
</span> </span>
{mission.missionTypes.length > 0 && ( {mission.missionTypes.length > 0 && (
<span className="MissionSelect-itemTypes"> <span className={styles.ItemTypes}>
{mission.missionTypes.map((type) => ( {mission.missionTypes.map((type) => (
<span <span
key={type} key={type}
className="MissionSelect-itemType" className={styles.ItemType}
data-mission-type={type} data-mission-type={type}
> >
{type} {type}
@ -143,9 +144,7 @@ function MissionItemContent({ mission }: { mission: MissionItem }) {
</span> </span>
)} )}
</span> </span>
<span className="MissionSelect-itemMissionName"> <span className={styles.ItemMissionName}>{mission.missionName}</span>
{mission.missionName}
</span>
</> </>
); );
} }
@ -234,7 +233,7 @@ export function MissionSelect({
<ComboboxItem <ComboboxItem
key={mission.missionName} key={mission.missionName}
value={mission.missionName} value={mission.missionName}
className="MissionSelect-item" className={styles.Item}
focusOnHover focusOnHover
onClick={(event) => { onClick={(event) => {
if (event.target && event.target instanceof HTMLElement) { if (event.target && event.target instanceof HTMLElement) {
@ -265,13 +264,13 @@ export function MissionSelect({
return ( return (
<ComboboxProvider store={combobox}> <ComboboxProvider store={combobox}>
<div className="MissionSelect-inputWrapper"> <div className={styles.InputWrapper}>
<Combobox <Combobox
ref={inputRef} ref={inputRef}
autoSelect autoSelect
disabled={disabled} disabled={disabled}
placeholder={displayValue} placeholder={displayValue}
className="MissionSelect-input" className={styles.Input}
onFocus={() => { onFocus={() => {
try { try {
document.exitPointerLock(); document.exitPointerLock();
@ -284,35 +283,29 @@ export function MissionSelect({
} }
}} }}
/> />
<div className="MissionSelect-selectedValue"> <div className={styles.SelectedValue}>
<span className="MissionSelect-selectedName">{displayValue}</span> <span className={styles.SelectedName}>{displayValue}</span>
{missionType && ( {missionType && (
<span <span className={styles.ItemType} data-mission-type={missionType}>
className="MissionSelect-itemType"
data-mission-type={missionType}
>
{missionType} {missionType}
</span> </span>
)} )}
</div> </div>
<kbd className="MissionSelect-shortcut">{isMac ? "⌘K" : "^K"}</kbd> <kbd className={styles.Shortcut}>{isMac ? "⌘K" : "^K"}</kbd>
</div> </div>
<ComboboxPopover <ComboboxPopover
gutter={4} gutter={4}
fitViewport fitViewport
autoFocusOnHide={false} autoFocusOnHide={false}
className="MissionSelect-popover" className={styles.Popover}
> >
<ComboboxList className="MissionSelect-list"> <ComboboxList className={styles.List}>
{filteredResults.type === "flat" {filteredResults.type === "flat"
? filteredResults.missions.map(renderItem) ? filteredResults.missions.map(renderItem)
: filteredResults.groups.map(([groupName, missions]) => : filteredResults.groups.map(([groupName, missions]) =>
groupName ? ( groupName ? (
<ComboboxGroup <ComboboxGroup key={groupName} className={styles.Group}>
key={groupName} <ComboboxGroupLabel className={styles.GroupLabel}>
className="MissionSelect-group"
>
<ComboboxGroupLabel className="MissionSelect-groupLabel">
{groupName} {groupName}
</ComboboxGroupLabel> </ComboboxGroupLabel>
{missions.map(renderItem)} {missions.map(renderItem)}
@ -324,7 +317,7 @@ export function MissionSelect({
), ),
)} )}
{noResults && ( {noResults && (
<div className="MissionSelect-noResults">No missions found</div> <div className={styles.NoResults}>No missions found</div>
)} )}
</ComboboxList> </ComboboxList>
</ComboboxPopover> </ComboboxPopover>

View file

@ -0,0 +1,46 @@
.Root {
pointer-events: none;
display: inline-flex;
flex-direction: column;
align-items: center;
white-space: nowrap;
}
.Top {
composes: Root;
padding-bottom: 20px;
}
.Bottom {
composes: Root;
padding-top: 20px;
}
.IffArrow {
width: 12px;
height: 12px;
image-rendering: pixelated;
filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.7));
}
.Name {
color: #fff;
font-size: 11px;
text-shadow:
0 1px 3px rgba(0, 0, 0, 0.9),
0 0 1px rgba(0, 0, 0, 0.7);
}
.HealthBar {
width: 60px;
height: 4px;
background: rgba(0, 0, 0, 0.5);
border: 1px solid rgba(255, 255, 255, 0.2);
margin: 2px auto 0;
overflow: hidden;
}
.HealthFill {
height: 100%;
background: #2ecc40;
}

View file

@ -7,6 +7,7 @@ import { getKeyframeAtTime } from "../demo/demoPlaybackUtils";
import { textureToUrl } from "../loaders"; import { textureToUrl } from "../loaders";
import { useStaticShape } from "./GenericShape"; import { useStaticShape } from "./GenericShape";
import type { DemoEntity } from "../demo/types"; import type { DemoEntity } from "../demo/types";
import styles from "./PlayerNameplate.module.css";
/** Max distance at which nameplates are visible. */ /** Max distance at which nameplates are visible. */
const NAMEPLATE_FADE_DISTANCE = 150; const NAMEPLATE_FADE_DISTANCE = 150;
@ -139,24 +140,21 @@ export function PlayerNameplate({
{isVisible && ( {isVisible && (
<> <>
<Html position={[0, iffHeight, 0]} center> <Html position={[0, iffHeight, 0]} center>
<div ref={iffContainerRef} className="PlayerNameplate PlayerTop"> <div ref={iffContainerRef} className={styles.Top}>
<img <img
ref={iffImgRef} ref={iffImgRef}
className="PlayerNameplate-iffArrow" className={styles.IffArrow}
src={iffMarkerUrl} src={iffMarkerUrl}
alt="" alt=""
/> />
</div> </div>
</Html> </Html>
<Html position={[0, NAME_HEIGHT, 0]} center> <Html position={[0, NAME_HEIGHT, 0]} center>
<div <div ref={nameContainerRef} className={styles.Bottom}>
ref={nameContainerRef} <div className={styles.Name}>{displayName}</div>
className="PlayerNameplate PlayerBottom"
>
<div className="PlayerNameplate-name">{displayName}</div>
{hasHealthData && ( {hasHealthData && (
<div className="PlayerNameplate-healthBar"> <div className={styles.HealthBar}>
<div ref={fillRef} className="PlayerNameplate-healthFill" /> <div ref={fillRef} className={styles.HealthFill} />
</div> </div>
)} )}
</div> </div>

View file

@ -0,0 +1,22 @@
.Joystick {
position: fixed;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
width: 140px;
height: 140px;
z-index: 1;
}
.Left {
composes: Joystick;
left: 20px;
transform: none;
}
.Right {
composes: Joystick;
left: auto;
right: 20px;
transform: none;
}

View file

@ -3,6 +3,25 @@ import { Euler, Vector3 } from "three";
import { useFrame, useThree } from "@react-three/fiber"; import { useFrame, useThree } from "@react-three/fiber";
import type nipplejs from "nipplejs"; import type nipplejs from "nipplejs";
import { useControls } from "./SettingsProvider"; import { useControls } from "./SettingsProvider";
import styles from "./TouchControls.module.css";
/** Apply styles to nipplejs-generated `.back` and `.front` elements imperatively. */
function applyNippleStyles(zone: HTMLElement) {
const back = zone.querySelector<HTMLElement>(".back");
if (back) {
back.style.background = "rgba(3, 79, 76, 0.6)";
back.style.border = "1px solid rgba(0, 219, 223, 0.5)";
back.style.boxShadow = "inset 0 0 10px rgba(0, 0, 0, 0.7)";
}
const front = zone.querySelector<HTMLElement>(".front");
if (front) {
front.style.background =
"radial-gradient(circle at 50% 50%, rgba(23, 247, 198, 0.9) 0%, rgba(9, 184, 170, 0.95) 100%)";
front.style.border = "2px solid rgba(255, 255, 255, 0.4)";
front.style.boxShadow =
"0 2px 4px rgba(0, 0, 0, 0.5), 0 1px 1px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.15), inset 0 -1px 2px rgba(0, 0, 0, 0.3)";
}
}
const BASE_SPEED = 80; const BASE_SPEED = 80;
const LOOK_SENSITIVITY = 0.004; const LOOK_SENSITIVITY = 0.004;
@ -50,6 +69,8 @@ export function TouchJoystick({
restOpacity: 0.9, restOpacity: 0.9,
}); });
applyNippleStyles(zone);
manager.on("move", (_event, data) => { manager.on("move", (_event, data) => {
joystickState.current.angle = data.angle.radian; joystickState.current.angle = data.angle.radian;
joystickState.current.force = Math.min(1, data.force); joystickState.current.force = Math.min(1, data.force);
@ -86,6 +107,8 @@ export function TouchJoystick({
restOpacity: 0.9, restOpacity: 0.9,
}); });
applyNippleStyles(zone);
manager.on("move", (_event, data) => { manager.on("move", (_event, data) => {
lookJoystickState.current.angle = data.angle.radian; lookJoystickState.current.angle = data.angle.radian;
lookJoystickState.current.force = Math.min(1, data.force); lookJoystickState.current.force = Math.min(1, data.force);
@ -113,13 +136,13 @@ export function TouchJoystick({
<> <>
<div <div
ref={joystickZone} ref={joystickZone}
className="TouchJoystick TouchJoystick--left" className={styles.Left}
onContextMenu={(e) => e.preventDefault()} onContextMenu={(e) => e.preventDefault()}
onTouchStart={blurActiveElement} onTouchStart={blurActiveElement}
/> />
<div <div
ref={lookJoystickZone} ref={lookJoystickZone}
className="TouchJoystick TouchJoystick--right" className={styles.Right}
onContextMenu={(e) => e.preventDefault()} onContextMenu={(e) => e.preventDefault()}
onTouchStart={blurActiveElement} onTouchStart={blurActiveElement}
/> />
@ -130,7 +153,7 @@ export function TouchJoystick({
return ( return (
<div <div
ref={joystickZone} ref={joystickZone}
className="TouchJoystick" className={styles.Joystick}
onContextMenu={(e) => e.preventDefault()} onContextMenu={(e) => e.preventDefault()}
onTouchStart={blurActiveElement} onTouchStart={blurActiveElement}
/> />
@ -268,9 +291,7 @@ export function TouchCameraMovement({
camera.getWorldDirection(forwardVec.current); camera.getWorldDirection(forwardVec.current);
forwardVec.current.normalize(); forwardVec.current.normalize();
sideVec.current sideVec.current.crossVectors(camera.up, forwardVec.current).normalize();
.crossVectors(camera.up, forwardVec.current)
.normalize();
moveVec.current moveVec.current
.set(0, 0, 0) .set(0, 0, 0)
@ -288,9 +309,7 @@ export function TouchCameraMovement({
const speed = BASE_SPEED * speedMultiplier * 0.5; const speed = BASE_SPEED * speedMultiplier * 0.5;
camera.getWorldDirection(forwardVec.current); camera.getWorldDirection(forwardVec.current);
forwardVec.current.normalize(); forwardVec.current.normalize();
moveVec.current moveVec.current.copy(forwardVec.current).multiplyScalar(speed * delta);
.copy(forwardVec.current)
.multiplyScalar(speed * delta);
camera.position.add(moveVec.current); camera.position.add(moveVec.current);
if (force >= SINGLE_STICK_DEADZONE) { if (force >= SINGLE_STICK_DEADZONE) {