Jacob Schmidt 68218304ab Move store catalog service server-side and rebuild WebUI bundles
- Shift store catalog initialization from client addon to server addon
- Rebuild/minify bank, garage, org, and store WebUI site assets
- Update webui build tooling and npm metadata; ignore node_modules
2026-03-14 20:06:27 -05:00

1 line
16 KiB
JavaScript

!function(){const e=window.ForgeWebUI;(window.GarageApp=window.GarageApp||{}).runtime=e,window.AppRuntime=e}(),function(){const e=window.GarageApp=window.GarageApp||{},a={garageName:"Vehicle Garage",capacityUsed:0,capacityMax:5,nearbyCount:0,spawnBlocked:!1,spawnStatus:"Ready"},t={vehicles:[]},r={vehicles:[]};function s(e,a){var t;Object.keys(e).forEach(a=>delete e[a]),Object.assign(e,(t=a,JSON.parse(JSON.stringify(t))))}e.data={categories:[{id:"all",label:"All"},{id:"car",label:"Cars"},{id:"armor",label:"Armor"},{id:"air",label:"Air"},{id:"naval",label:"Naval"},{id:"other",label:"Other"}],session:Object.assign({},a),garage:Object.assign({},t),nearby:Object.assign({},r),applyHydratePayload(e){s(this.session,Object.assign({},a,e?.session||{})),s(this.garage,Object.assign({},t,e?.garage||{})),s(this.nearby,Object.assign({},r,e?.nearby||{}))}}}(),function(){const e=window.GarageApp=window.GarageApp||{},{createSignal:a}=e.runtime;e.store=new class{constructor(){[this.getSelectedKind,this.setSelectedKind]=a(""),[this.getSelectedId,this.setSelectedId]=a(""),[this.getSearchQuery,this.setSearchQuery]=a(""),[this.getCategoryFilter,this.setCategoryFilter]=a("all"),[this.getPendingAction,this.setPendingAction]=a(""),[this.getNotice,this.setNotice]=a({type:"",text:""})}getSelection(){return{id:this.getSelectedId(),kind:this.getSelectedKind()}}clearSelection(){this.setSelectedKind(""),this.setSelectedId("")}select(e,a){this.setSelectedKind(String(e||"")),this.setSelectedId(String(a||""))}startAction(e){this.setPendingAction(String(e||""))}finishAction(){this.setPendingAction("")}matchesSelection(e){if(!e||"object"!=typeof e)return!1;const a=this.getSelection();return!(!a.kind||!a.id)&&("stored"===a.kind?"stored"===e.entryKind&&String(e.plate||"")===a.id:"nearby"===a.kind&&("nearby"===e.entryKind&&String(e.netId||"")===a.id))}ensureSelection(){const a=Array.isArray(e.data?.garage?.vehicles)?e.data.garage.vehicles:[],t=Array.isArray(e.data?.nearby?.vehicles)?e.data.nearby.vehicles:[];if([...a,...t].some(e=>this.matchesSelection(e)))return;const r=a[0]||null;if(r)return void this.select("stored",r.plate||"");const s=t[0]||null;s?this.select("nearby",s.netId||""):this.clearSelection()}hydrateFromPayload(){this.finishAction(),this.ensureSelection()}}}(),function(){const e=window.GarageApp=window.GarageApp||{},a=e.store,t=window.ForgeWebUI.createBridge({closeEvent:"garage::close",globalName:"ForgeBridge",readyEvent:"garage::ready"});function r(t){e.data.applyHydratePayload(t),a.hydrateFromPayload(t)}t.on("garage::hydrate",r),t.on("garage::sync",r),t.on("garage::retrieve::success",t=>{a.finishAction(),e.actions&&e.actions.showNotice("success",t.message||"Vehicle retrieved from the garage.")}),t.on("garage::retrieve::failure",t=>{a.finishAction(),e.actions&&e.actions.showNotice("error",t.message||"Unable to retrieve vehicle.")}),t.on("garage::store::success",t=>{a.finishAction(),e.actions&&e.actions.showNotice("success",t.message||"Vehicle stored in the garage.")}),t.on("garage::store::failure",t=>{a.finishAction(),e.actions&&e.actions.showNotice("error",t.message||"Unable to store vehicle.")}),e.bridge={notifyReady:function(){return t.ready({loaded:!0})},receive:t.receive,requestClose:function(){return t.close({})},requestRefresh:function(){return t.send("garage::refresh",{})},requestRetrieve:function(e){return t.send("garage::vehicle::retrieve::request",e)},requestStore:function(e){return t.send("garage::vehicle::store::request",e)},sendEvent:t.send}}(),function(){const e=window.GarageApp=window.GarageApp||{},a=e.store;let t=null;function r(){const t=a.getSelection();return"stored"===t.kind?(Array.isArray(e.data?.garage?.vehicles)?e.data.garage.vehicles:[]).find(e=>String(e.plate||"")===t.id)||null:"nearby"===t.kind&&(Array.isArray(e.data?.nearby?.vehicles)?e.data.nearby.vehicles:[]).find(e=>String(e.netId||"")===t.id)||null}function s(e,r){a.setNotice({type:e,text:r}),t&&clearTimeout(t),t=setTimeout(()=>{a.setNotice({type:"",text:""}),t=null},3200)}e.actions={showNotice:s,closeGarage:function(){const a=e.bridge;if(a&&"function"==typeof a.requestClose){if(a.requestClose())return!0}return s("error","Garage bridge is unavailable."),!1},refreshGarage:function(){const a=e.bridge;if(a&&"function"==typeof a.requestRefresh){if(a.requestRefresh())return!0}return s("error","Garage refresh bridge is unavailable."),!1},applySearchQuery:function(e){a.setSearchQuery(String(e||"").trim())},clearSearch:function(){a.setSearchQuery("")},selectCategory:function(e){a.setCategoryFilter(String(e||"all").trim()||"all")},selectEntry:function(e,t){a.select(e,t)},getSelectedEntry:r,requestRetrieveSelected:function(){const t=r();if(!t||"stored"!==t.entryKind)return s("error","Select a stored vehicle to retrieve."),!1;if(e.data?.session?.spawnBlocked)return s("error","The garage spawn area is blocked."),!1;const i=e.bridge;return i&&"function"==typeof i.requestRetrieve?(a.startAction("retrieve"),!!i.requestRetrieve({plate:t.plate||""})||(a.finishAction(),s("error","Garage retrieve bridge is unavailable."),!1)):(s("error","Garage retrieve bridge is unavailable."),!1)},requestStoreSelected:function(){const t=r();if(!t||"nearby"!==t.entryKind)return s("error","Select a nearby vehicle to store."),!1;if(!1===t.isEmpty)return s("error","All crew must exit the vehicle before storing it."),!1;const i=e.bridge;return i&&"function"==typeof i.requestStore?(a.startAction("store"),!!i.requestStore({netId:t.netId||""})||(a.finishAction(),s("error","Garage store bridge is unavailable."),!1)):(s("error","Garage store bridge is unavailable."),!1)}}}(),function(){const e=window.GarageApp=window.GarageApp||{},{h:a}=e.runtime,t=window.SharedUI.componentFns.WindowTitleBar,r=e.store,s=e.actions,{categories:i,garage:n,nearby:c,session:l}=e.data;function o(e){return Math.max(0,Math.min(100,Math.round(100*Number(e||0))))}function g(e){const a=i.find(a=>a.id===String(e||"other").toLowerCase());return a?a.label:"Other"}function d(e){return`${Math.round(Number(e||0))} m`}function u(e){return String(e||"").trim()||"Untracked"}function m(e,a){return(e||[]).filter(e=>("all"===a.categoryFilter||String(e.category||"").toLowerCase()===a.categoryFilter)&&function(e,a){const t=String(e||"").trim().toLowerCase();return!t||a.some(e=>String(e||"").toLowerCase().includes(t))}(a.searchQuery,[e.displayName,e.classname,e.plate,e.netId,e.category]))}function p(e,t,r=""){return a("div",{className:r?`garage-stat-card is-${r}`:"garage-stat-card"},a("span",{className:"garage-stat-label"},e),a("span",{className:"garage-stat-value"},t))}function h(e,t,r){return a("div",{className:"garage-meter"},a("div",{className:"garage-meter-label-row"},a("span",{className:"garage-meter-label"},e),a("span",{className:"garage-meter-value"},`${t}%`)),a("div",{className:"garage-meter-track"},a("span",{className:`garage-meter-fill is-${r}`,style:{width:`${t}%`}})))}function y(e,t,r,i,n){return a("section",{className:"garage-card garage-list-card"},a("div",{className:"garage-card-header"},a("div",null,a("span",{className:"garage-eyebrow"},t),a("h2",{className:"garage-section-title"},e)),a("span",{className:"garage-pill"},`${i.length} ${1===i.length?"Vehicle":"Vehicles"}`)),a("div",{className:"garage-card-body garage-scroll-body","data-preserve-scroll-id":r},i.length>0?i.map(e=>function(e,t){const r="stored"===e.entryKind?String(e.plate||""):String(e.netId||""),i="nearby"===e.entryKind;return a("button",{type:"button",className:(n=e,c=t,n&&c&&String(n.entryKind||"")===String(c.entryKind||"")&&String(n.plate||"")===String(c.plate||"")&&String(n.netId||"")===String(c.netId||"")?"garage-vehicle-item is-selected":"garage-vehicle-item"),onClick:()=>s.selectEntry(e.entryKind,r)},a("div",{className:"garage-vehicle-item-head"},a("div",{className:"garage-vehicle-copy"},a("span",{className:"garage-vehicle-title"},e.displayName||e.classname||"Vehicle"),a("span",{className:"garage-vehicle-meta"},i?`Nearby ${d(e.distance)}`:`Plate ${u(e.plate)}`)),a("span",{className:i&&!1===e.isEmpty?"garage-badge is-warning":"garage-badge"},i?!1===e.isEmpty?"Crewed":"Empty":g(e.category))),a("div",{className:"garage-inline-meters"},h("Health",o(e.health),"health"),h("Fuel",o(e.fuel),"fuel")));var n,c}(e,n)):a("div",{className:"garage-empty-state"},a("h3",{className:"garage-empty-title"},"No matching vehicles"),a("p",{className:"garage-empty-copy"},"Adjust the current search or category filter to view more records."))))}function b(e){const t=(Array.isArray(e)?e:[]).slice().sort((e,a)=>Number(a.value||0)-Number(e.value||0)).slice(0,6).filter(e=>Number(e.value||0)>0);return 0===t.length?a("div",{className:"garage-empty-inline"},"No subsystem damage reported."):a("div",{className:"garage-hitpoint-grid"},t.map(e=>{return a("div",{className:"garage-hitpoint-row"},a("div",{className:"garage-hitpoint-copy"},a("span",{className:"garage-hitpoint-name"},(t=e.name,String(t||"").replace(/^Hit/i,"").replace(/([a-z])([A-Z])/g,"$1 $2").replace(/_/g," ").trim()||"Subsystem")),e.selection?a("span",{className:"garage-hitpoint-selection"},e.selection):null),a("span",{className:"garage-hitpoint-value"},`${Math.round(100*Number(e.value||0))}%`));var t}))}e.components=e.components||{},e.components.App=function(){const e={categoryFilter:r.getCategoryFilter(),notice:r.getNotice(),pendingAction:r.getPendingAction(),searchQuery:r.getSearchQuery(),selectedId:r.getSelectedId(),selectedKind:r.getSelectedKind()},v=function(e){return"stored"===e.selectedKind?(n.vehicles||[]).find(a=>String(a.plate||"")===e.selectedId)||null:"nearby"===e.selectedKind&&(c.vehicles||[]).find(a=>String(a.netId||"")===e.selectedId)||null}(e),N=m(n.vehicles||[],e),f=m(c.vehicles||[],e),S=e.searchQuery?`Search: ${e.searchQuery}`:"Live";return a("div",{className:"garage-shell"},t({kicker:"FORGE Logistics",title:"Vehicle Garage",onClose:()=>s.closeGarage(),closeLabel:"Close garage interface"}),e.notice.text?a("div",{className:"garage-toast-stack"},a("div",{className:"error"===e.notice.type?"garage-toast is-error":"garage-toast is-success"},e.notice.text)):null,a("div",{className:"garage-layout"},a("aside",{className:"garage-sidebar"},a("section",{className:"garage-module"},a("div",{className:"garage-module-header"},a("div",null,a("span",{className:"garage-eyebrow"},"Search"),a("h2",{className:"garage-section-title"},"Vehicle Records")),a("span",{className:"garage-pill"},S)),a("div",{className:"garage-search-form"},a("input",{id:"garage-search-input",type:"text",className:"garage-search-input",placeholder:"Search by name, plate, or category",value:e.searchQuery}),a("div",{className:"garage-search-actions"},a("button",{type:"button",className:"garage-btn garage-btn-primary",onClick:()=>s.applySearchQuery(document.getElementById("garage-search-input")?.value||"")},"Apply Search"),a("button",{type:"button",className:"garage-btn garage-btn-secondary",onClick:()=>s.clearSearch()},"Clear")))),a("section",{className:"garage-module"},a("div",{className:"garage-module-header"},a("div",null,a("span",{className:"garage-eyebrow"},"Filter"),a("h2",{className:"garage-section-title"},"Vehicle Categories"))),a("div",{className:"garage-category-grid"},i.map(t=>a("button",{type:"button",className:e.categoryFilter===t.id?"garage-chip is-active":"garage-chip",onClick:()=>s.selectCategory(t.id)},t.label)))),a("section",{className:"garage-module"},a("div",{className:"garage-module-header"},a("div",null,a("span",{className:"garage-eyebrow"},"Status"),a("h2",{className:"garage-section-title"},"Garage Summary")),a("button",{type:"button",className:"garage-btn garage-btn-secondary",disabled:Boolean(e.pendingAction),onClick:()=>s.refreshGarage()},"Refresh")),a("div",{className:"garage-summary-grid"},p("Stored",`${l.capacityUsed}/${l.capacityMax}`),p("Nearby",l.nearbyCount,"accent"),p("Spawn Lane",l.spawnStatus,l.spawnBlocked?"danger":"")))),a("main",{className:"garage-main"},a("section",{className:"garage-panel"},a("div",{className:"garage-panel-header"},a("div",null,a("span",{className:"garage-eyebrow"},"Operations Bay"),a("h1",{className:"garage-title"},l.garageName||"Vehicle Garage")),a("span",{className:"garage-pill"},`${l.capacityUsed}/${l.capacityMax} Stored`)),a("div",{className:"garage-panel-intro"},a("p",{className:"garage-copy"},"Retrieve stored vehicles into the active spawn lane or store nearby empty vehicles back into persistent ownership records.")),a("div",{className:"garage-dashboard"},y("Stored Vehicles","Persistent Records","garage-stored-list",N,v),y("Nearby Vehicles","Store Window","garage-nearby-list",f,v),function(e,t){if(!e)return a("section",{className:"garage-card garage-detail-card"},a("div",{className:"garage-card-header"},a("div",null,a("span",{className:"garage-eyebrow"},"Selection"),a("h2",{className:"garage-section-title"},"Vehicle Detail"))),a("div",{className:"garage-card-body garage-detail-empty"},a("h3",{className:"garage-empty-title"},"Select a vehicle"),a("p",{className:"garage-empty-copy"},"Choose a stored record to retrieve or a nearby vehicle to store.")));const r="stored"===e.entryKind,i=String(t.pendingAction||""),n="retrieve"===i||"store"===i,c=r&&!l.spawnBlocked&&!n,m=!r&&!1!==e.isEmpty&&!n;return a("section",{className:"garage-card garage-detail-card"},a("div",{className:"garage-card-header"},a("div",null,a("span",{className:"garage-eyebrow"},r?"Stored Record":"Nearby Vehicle"),a("h2",{className:"garage-section-title"},e.displayName||e.classname||"Vehicle")),a("span",{className:"nearby"===e.entryKind&&!1===e.isEmpty?"garage-badge is-warning":"garage-badge"},r?`Plate ${u(e.plate)}`:!1===e.isEmpty?"Crewed":"Ready")),a("div",{className:"garage-card-body garage-detail-body"},a("div",{className:"garage-detail-grid"},a("div",{className:"garage-detail-copy"},a("div",{className:"garage-detail-meta"},p("Category",g(e.category)),p("Status",(y=e)?"stored"===y.entryKind?"Stored":!1===y.isEmpty?"Crewed":"Ready":"-","nearby"===e.entryKind&&!1===e.isEmpty?"danger":""),p(r?"Record":"Distance",r?u(e.plate):d(e.distance),r?"":"accent")),a("div",{className:"garage-meter-stack"},h("Health",o(e.health),"health"),h("Fuel",o(e.fuel),"fuel")),a("div",{className:"garage-action-row"},r?a("button",{type:"button",className:"garage-btn garage-btn-primary",disabled:!c,onClick:()=>s.requestRetrieveSelected()},"retrieve"===i?"Retrieving...":"Retrieve Vehicle"):a("button",{type:"button",className:"garage-btn garage-btn-primary",disabled:!m,onClick:()=>s.requestStoreSelected()},"store"===i?"Storing...":"Store Vehicle"),a("button",{type:"button",className:"garage-btn garage-btn-secondary",disabled:n,onClick:()=>s.refreshGarage()},"Refresh")),a("p",{className:"garage-detail-note"},r?l.spawnBlocked?"The garage spawn lane is currently blocked.":"Retrieve this stored vehicle into the active spawn lane.":!1===e.isEmpty?"Only empty nearby vehicles can be stored.":"Store this nearby vehicle back into persistent garage storage.")),a("div",{className:"garage-detail-subsystems"},a("div",{className:"garage-subsystem-header"},a("span",{className:"garage-eyebrow"},"Subsystems"),a("span",{className:"garage-detail-caption"},"Highest damage first")),b(e.hitPoints)))));var y}(v,e))))),a("footer",{className:"garage-footer-bar"},a("div",{className:"garage-footer"},a("div",{className:"garage-footer-block"},a("span",{className:"garage-footer-title"},"Storage Capacity"),a("span",{className:"garage-footer-copy"},`${l.capacityUsed} of ${l.capacityMax} vehicle slot(s) are currently occupied.`)),a("div",{className:"garage-footer-block"},a("span",{className:"garage-footer-title"},"Retrieval Window"),a("span",{className:"garage-footer-copy"},l.spawnBlocked?"Spawn lane is blocked. Clear the bay before retrieving another vehicle.":"Spawn lane is clear. Stored vehicles can be retrieved immediately.")),a("div",{className:"garage-footer-block"},a("span",{className:"garage-footer-title"},"Store Rules"),a("span",{className:"garage-footer-copy"},"Only nearby empty vehicles can be stored. Nearby count updates from the live world state.")))))}}(),function(){const e=window.ForgeWebUI,a=window.GarageApp;e.createApp({name:"garage",root:"#app",setup({root:t}){e.mount(t,()=>a.components.App(),{preserveScroll:!0}),a.bridge&&a.bridge.notifyReady()}}).start()}();