diff --git a/client/demo.js b/client/demo.js index 2a8ba5c7..691846b2 100644 --- a/client/demo.js +++ b/client/demo.js @@ -92,7 +92,7 @@ class DemoDataGenerator { } - /* + */ let idx = 1; DEMO_UNIT_DATA[idx] = JSON.parse(JSON.stringify(baseData)); DEMO_UNIT_DATA[idx].name = "S_75M_Volhov"; @@ -153,7 +153,7 @@ class DemoDataGenerator { DEMO_UNIT_DATA[idx].position.lat += idx / 100; DEMO_UNIT_DATA[idx].category = "Aircraft"; DEMO_UNIT_DATA[idx].isLeader = true; - */ + this.startTime = Date.now(); } diff --git a/client/package-lock.json b/client/package-lock.json index 44be542b..0b82ed23 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -19,7 +19,8 @@ "leaflet-gesture-handling": "^1.2.2", "morgan": "~1.9.1", "save": "^2.9.0", - "srtm-elevation": "^2.1.2" + "srtm-elevation": "^2.1.2", + "uuid": "^9.0.1" }, "devDependencies": { "@babel/preset-env": "^7.21.4", @@ -8820,6 +8821,18 @@ "node": ">= 0.4.0" } }, + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", diff --git a/client/package.json b/client/package.json index e7727c1f..1b2ff03a 100644 --- a/client/package.json +++ b/client/package.json @@ -25,7 +25,8 @@ "leaflet-gesture-handling": "^1.2.2", "morgan": "~1.9.1", "save": "^2.9.0", - "srtm-elevation": "^2.1.2" + "srtm-elevation": "^2.1.2", + "uuid": "^9.0.1" }, "devDependencies": { "@babel/preset-env": "^7.21.4", diff --git a/client/public/stylesheets/markers/airbase.css b/client/public/stylesheets/markers/airbase.css index a9640cf3..f734bf34 100644 --- a/client/public/stylesheets/markers/airbase.css +++ b/client/public/stylesheets/markers/airbase.css @@ -4,6 +4,8 @@ display: flex; justify-content: center; position: relative; + width: 100%; + height: 100%; } .airbase-icon[data-coalition="red"] svg * { diff --git a/client/public/stylesheets/markers/bullseye.css b/client/public/stylesheets/markers/bullseye.css index 81663b09..e75f0441 100644 --- a/client/public/stylesheets/markers/bullseye.css +++ b/client/public/stylesheets/markers/bullseye.css @@ -4,6 +4,8 @@ display: flex; justify-content: center; position: relative; + width: 100%; + height: 100%; } .bullseye-icon[data-coalition="red"] svg * { diff --git a/client/public/stylesheets/markers/units.css b/client/public/stylesheets/markers/units.css index 19574ec2..e2cba54d 100644 --- a/client/public/stylesheets/markers/units.css +++ b/client/public/stylesheets/markers/units.css @@ -50,6 +50,11 @@ width: var(--unit-width); } +.unit-icon svg { + height: 100%; + width: 100%; +} + [data-is-selected] .unit-icon::before { background-color: var(--unit-spotlight-fill); border-radius: 50%; diff --git a/client/public/stylesheets/other/contextmenus.css b/client/public/stylesheets/other/contextmenus.css index 98936a8b..b133be08 100644 --- a/client/public/stylesheets/other/contextmenus.css +++ b/client/public/stylesheets/other/contextmenus.css @@ -61,9 +61,13 @@ .contextmenu-advanced-options-toggle:after, .contextmenu-metadata-toggle:after { - content: url(/resources/theme/images/icons/chevron-down.svg); + content: ""; margin-left: auto; margin-top: auto; + background-image: url(/resources/theme/images/icons/chevron-down.svg); + background-size: 100% 100%; + width: 15px; + height: 15px; } .contextmenu-advanced-options-toggle.is-open:after, @@ -407,84 +411,124 @@ /* Buttons */ #center-map::before { - content: url("/resources/theme/images/icons/arrows-to-eye-solid.svg"); + background-image: url("/resources/theme/images/icons/arrows-to-eye-solid.svg"); + content: ""; + background-size: 20px 20px; } #refuel::before { - content: url("/resources/theme/images/icons/fuel.svg"); + background-image: url("/resources/theme/images/icons/fuel.svg"); + content: ""; + background-size: 20px 20px; } #attack::before { - content: url("/resources/theme/images/icons/sword.svg"); + background-image: url("/resources/theme/images/icons/sword.svg"); + content: ""; + background-size: 20px 20px; } #bomb::before { - content: url("/resources/theme/images/icons/crosshairs-solid.svg"); + background-image: url("/resources/theme/images/icons/crosshairs-solid.svg"); + content: ""; + background-size: 20px 20px; } #carpet-bomb::before { - content: url("/resources/theme/images/icons/explosion-solid.svg"); + background-image: url("/resources/theme/images/icons/explosion-solid.svg"); + content: ""; + background-size: 20px 20px; } #fire-at-area::before { - content: url("/resources/theme/images/icons/crosshairs-solid.svg"); + background-image: url("/resources/theme/images/icons/crosshairs-solid.svg"); + content: ""; + background-size: 20px 20px; } #simulate-fire-fight::before { - content: url("/resources/theme/images/icons/crosshairs-solid.svg"); + background-image: url("/resources/theme/images/icons/crosshairs-solid.svg"); + content: ""; + background-size: 20px 20px; } #follow::before { - content: url("/resources/theme/images/icons/follow.svg"); + background-image: url("/resources/theme/images/icons/follow.svg"); + content: ""; + background-size: 20px 20px; } #scenic-aaa::before { - content: url("/resources/theme/images/icons/scenic.svg"); + background-image: url("/resources/theme/images/icons/scenic.svg"); + content: ""; + background-size: 20px 20px; } #miss-aaa::before { - content: url("/resources/theme/images/icons/miss.svg"); + background-image: url("/resources/theme/images/icons/miss.svg"); + content: ""; + background-size: 20px 20px; } #group-ground::before { - content: url("/resources/theme/images/icons/group-ground.svg"); + background-image: url("/resources/theme/images/icons/group-ground.svg"); + content: ""; + background-size: 20px 20px; } #group-navy::before { - content: url("/resources/theme/images/icons/group-navy.svg"); + background-image: url("/resources/theme/images/icons/group-navy.svg"); + content: ""; + background-size: 20px 20px; } #land-at-point::before { - content: url("/resources/theme/images/icons/land-at-point.svg"); + background-image: url("/resources/theme/images/icons/land-at-point.svg"); + content: ""; + background-size: 20px 20px; } #trail::before { - content: url("/resources/theme/images/icons/trail.svg"); + background-image: url("/resources/theme/images/icons/trail.svg"); + content: ""; + background-size: 20px 20px; } #echelon-lh::before { - content: url("/resources/theme/images/icons/echelon-lh.svg"); + background-image: url("/resources/theme/images/icons/echelon-lh.svg"); + content: ""; + background-size: 20px 20px; } #echelon-rh::before { - content: url("/resources/theme/images/icons/echelon-rh.svg"); + background-image: url("/resources/theme/images/icons/echelon-rh.svg"); + content: ""; + background-size: 20px 20px; } #line-abreast-rh::before, #line-abreast-lh::before { - content: url("/resources/theme/images/icons/line-abreast.svg"); + background-image: url("/resources/theme/images/icons/line-abreast.svg"); + content: ""; + background-size: 20px 20px; } #front::before { - content: url("/resources/theme/images/icons/front.svg"); + background-image: url("/resources/theme/images/icons/front.svg"); + content: ""; + background-size: 20px 20px; } #diamond::before { - content: url("/resources/theme/images/icons/diamond.svg"); + background-image: url("/resources/theme/images/icons/diamond.svg"); + content: ""; + background-size: 20px 20px; } #custom::before { - content: url("/resources/theme/images/icons/custom.svg"); + background-image: url("/resources/theme/images/icons/custom.svg"); + content: ""; + background-size: 20px 20px; } #custom-formation-dialog { diff --git a/client/public/stylesheets/panels/logpanel.css b/client/public/stylesheets/panels/logpanel.css index 1c5cd002..00adcaff 100644 --- a/client/public/stylesheets/panels/logpanel.css +++ b/client/public/stylesheets/panels/logpanel.css @@ -27,7 +27,6 @@ display: block; } - #log-panel-header-right { align-items: center; column-gap: 16px; @@ -35,6 +34,11 @@ flex-flow: row nowrap; } +#log-panel-header-right svg { + width: 15px; + height: 15px; +} + #server-status-panel abbr { text-decoration: none; } diff --git a/client/public/stylesheets/panels/unitcontrol.css b/client/public/stylesheets/panels/unitcontrol.css index 11801c24..b7039a92 100644 --- a/client/public/stylesheets/panels/unitcontrol.css +++ b/client/public/stylesheets/panels/unitcontrol.css @@ -6,60 +6,69 @@ body.feature-forceShowUnitControlPanel #unit-control-panel { #roe-buttons-container button, #reaction-to-threat-buttons-container button, #emissions-countermeasures-buttons-container button, -#shots-scatter-buttons-container button -#shots-intensity-buttons-container button { - align-items: center; - background-color: transparent; - border: 1px solid var(--accent-light-blue); - display: flex; - height: 30px; - justify-content: center; - width: 30px; +#shots-scatter-buttons-container button #shots-intensity-buttons-container button { + align-items: center; + background-color: transparent; + border: 1px solid var(--accent-light-blue); + display: flex; + height: 30px; + justify-content: center; + width: 30px; } #reaction-to-threat-buttons-container button:not(:first-child) svg { - width: 150%; - margin: -5px; + width: 150%; + margin: -5px; +} + +#unit-control-panel .ol-option-button button { + width: 30px; + height: 30px; +} + +#unit-control-panel .ol-option-button svg { + width: 100%; + height: 100%; } #unit-control-panel .ol-option-button button.selected { - background-color: white; - border-color: white; + background-color: white; + border-color: white; } #unit-control-panel .ol-option-button button.selected svg * { - fill: var(--background-steel); - stroke: var(--background-steel); + fill: var(--background-steel); + stroke: var(--background-steel); } #rapid-controls { - display: flex; - flex-direction: column; - row-gap: 5px; - height: fit-content; - width: fit-content; + display: flex; + flex-direction: column; + row-gap: 5px; + height: fit-content; + width: fit-content; } #rapid-controls button { - padding: 4px; + padding: 4px; } #rapid-controls button.pulse { - animation: pulse 1.5s linear infinite; + animation: pulse 1.5s linear infinite; } #rapid-controls svg { - height: 20px; - width: 20px; - fill: white; - stroke: white; + height: 20px; + width: 20px; + fill: white; + stroke: white; } #rapid-controls button:before { - display: inline-block; - filter: invert(100%); - height: 20px; - width: 20px; + display: inline-block; + filter: invert(100%); + height: 20px; + width: 20px; } #unit-control-panel { @@ -109,7 +118,7 @@ body.feature-forceShowUnitControlPanel #unit-control-panel { width: fit-content; } - #unit-control-panel:not(:hover)>*:nth-child(2), + #unit-control-panel:not(:hover)>*:nth-child(2), #unit-control-panel:not(:hover)>*:nth-child(3) { display: none; } @@ -196,7 +205,7 @@ body.feature-forceShowUnitControlPanel #unit-control-panel { } #advanced-settings-dialog>.ol-dialog-content>div input[type="number"] { - width: 60px; + width: 60px; } #advanced-settings-dialog hr { @@ -266,7 +275,6 @@ body.feature-forceShowUnitControlPanel #unit-control-panel { width: 40px; } - .ol-slider-value { color: var(--accent-light-blue); cursor: pointer; @@ -276,13 +284,15 @@ body.feature-forceShowUnitControlPanel #unit-control-panel { .switch-control { align-items: center; + align-content: center; display: flex; width: 100%; justify-content: space-between; } .switch-control h4 { - margin: 0px; + margin: 0px !important; + padding: 0px; display: flex; align-items: center; } @@ -303,30 +313,30 @@ body.feature-forceShowUnitControlPanel #unit-control-panel { position: relative; } -#advanced-settings-div > button { +#advanced-settings-div>button { background-color: var(--background-grey); - box-shadow: 0px 2px 5px #000A; - font-size:13px; + box-shadow: 0px 2px 5px #000A; + font-size: 13px; height: 40px; - padding:0 20px; + padding: 0 20px; } #delete-options { - font-size:13px; + font-size: 13px; } -#delete-options.ol-select > .ol-select-value:after { +#delete-options.ol-select>.ol-select-value:after { content: ""; } -#delete-options.ol-select > .ol-select-value svg { +#delete-options.ol-select>.ol-select-value svg { background-color: transparent; position: absolute; - right:2px; - translate:0 1px; + right: 2px; + translate: 0 1px; } -#delete-options.ol-select > .ol-select-value svg * { +#delete-options.ol-select>.ol-select-value svg * { fill: var(--primary-red); } @@ -334,21 +344,21 @@ body.feature-forceShowUnitControlPanel #unit-control-panel { background-color: var(--background-steel); } -#delete-options.ol-select > .ol-select-value:hover, -#delete-options .ol-select-options > div:not(.hr):hover, -#delete-options .ol-select-options > div:not(.hr):hover button, -#delete-options .ol-select-options > div hr { +#delete-options.ol-select>.ol-select-value:hover, +#delete-options .ol-select-options>div:not(.hr):hover, +#delete-options .ol-select-options>div:not(.hr):hover button, +#delete-options .ol-select-options>div hr { background-color: var(--background-grey); } -#delete-options .ol-select-options > div:first-of-type { - margin-top:12px; - padding-top:0; +#delete-options .ol-select-options>div:first-of-type { + margin-top: 12px; + padding-top: 0; } -#delete-options .ol-select-options > div:last-of-type { - margin-bottom:12px; - padding-bottom:0; +#delete-options .ol-select-options>div:last-of-type { + margin-bottom: 12px; + padding-bottom: 0; } #delete-options button { @@ -389,4 +399,4 @@ body.feature-forceShowUnitControlPanel #unit-control-panel { #advanced-settings-dialog:not([data-show-radio]) #radio-options, #advanced-settings-dialog:not([data-show-air-unit-checkboxes]) .air-unit-checkbox { display: none; -} +} \ No newline at end of file diff --git a/client/public/stylesheets/panels/unitinfo.css b/client/public/stylesheets/panels/unitinfo.css index 3535b5b5..4a4d92f6 100644 --- a/client/public/stylesheets/panels/unitinfo.css +++ b/client/public/stylesheets/panels/unitinfo.css @@ -146,12 +146,12 @@ } #fuel-percentage::before { - content: url("/resources/theme/images/icons/fuel.svg"); + content: ""; + background-image: url("/resources/theme/images/icons/fuel.svg"); + background-size: 16px 16px; display: inline-block; filter: invert(100%); - height: 16px; margin-right: 6px; - width: 16px; } #fuel-percentage::after { diff --git a/client/public/stylesheets/style/style.css b/client/public/stylesheets/style/style.css index b55b79a8..f8643943 100644 --- a/client/public/stylesheets/style/style.css +++ b/client/public/stylesheets/style/style.css @@ -206,9 +206,17 @@ button svg.fill-coalition[data-coalition="red"] * { } .ol-select:not(.ol-select-image)>.ol-select-value:after { - content: url("/resources/theme/images/icons/chevron-down.svg"); + background-image: url("/resources/theme/images/icons/chevron-down.svg"); + content: ""; position: absolute; right: 10px; + width: 15px; + height: 15px; + background-size: 100% 100%; +} + +.ol-select:not(.ol-select-image)>.ol-select-value.ol-select-warning:after { + background-image: url("/resources/theme/images/icons/chevron-down-warning.svg") !important; } .ol-select.is-open:not(.ol-select-image)>.ol-select-value:after { @@ -441,6 +449,7 @@ nav.ol-panel> :last-child { -webkit-filter: invert(100%); height: 16px; width: 16px; + background-size: 100% 100%; } .ol-panel .ol-group-button-toggle button.off::before { @@ -1328,7 +1337,7 @@ dl.ol-data-grid dd { align-content: center; border-top: 1px solid var(--background-grey); display: flex; - justify-content: center; + justify-content: flex-end; padding-top: 15px; row-gap: 10px; } @@ -1362,6 +1371,7 @@ dl.ol-data-grid dd { height: 16px; margin-right: 10px; width: 16px; + background-size: 100% 100%; } .ol-checkbox input[type="checkbox"]:disabled:before { diff --git a/client/public/themes/olympus/images/icons/chevron-down-warning.svg b/client/public/themes/olympus/images/icons/chevron-down-warning.svg new file mode 100644 index 00000000..b919934f --- /dev/null +++ b/client/public/themes/olympus/images/icons/chevron-down-warning.svg @@ -0,0 +1,3 @@ + + + diff --git a/client/public/themes/olympus/images/parrot/parrot.png b/client/public/themes/olympus/images/parrot/parrot.png new file mode 100644 index 00000000..a61beac3 Binary files /dev/null and b/client/public/themes/olympus/images/parrot/parrot.png differ diff --git a/client/public/themes/parrot/images/parrot.svg b/client/public/themes/parrot/images/parrot.svg new file mode 100644 index 00000000..54ff6895 --- /dev/null +++ b/client/public/themes/parrot/images/parrot.svg @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/client/public/themes/parrot/theme.css b/client/public/themes/parrot/theme.css new file mode 100644 index 00000000..7b127637 --- /dev/null +++ b/client/public/themes/parrot/theme.css @@ -0,0 +1,109 @@ +:root { + /** Colours **/ + + /*** Coalition: neutral ***/ + --primary-neutral: #949ba7; + --secondary-neutral-outline: #111111; + --secondary-neutral-text: #111111; + --unit-background-neutral: #CFD9E8; + + /*** Coalition: blue ***/ + --primary-blue: #247be2; + --secondary-blue-outline: #082e44; + --secondary-blue-text: #017DC1; + --unit-background-blue: #3BB9FF; + + /*** Coalition: red ***/ + --primary-red: #ff5858; + --secondary-red-outline: #262222; + --secondary-red-text: #D42121; + --unit-background-red: #FF5858; + + /*** UI Colours **/ + --accent-amber: #ffd828; + --accent-green: #8bff63; + --accent-light-blue: #5ca7ff; + --accent-dark-blue: #017DC1; + --transparent-accent-light-blue: rgba(92, 167, 255, .33); + --accent-light-red: #F5B6B6; + + --background-grey: #3d4651; + --background-slate-blue: #363c43; + --background-offwhite: #f2f2f3; + --background-steel: #202831; + + --secondary-dark-steel: #181e25; + --secondary-gunmetal-grey: #2f2f2f; + --secondary-lighter-grey: #949ba7; + --secondary-light-grey: #797e83; + --secondary-semitransparent-white: #FFFFFFAA; + --secondary-transparent-white: #FFFFFF30; + --secondary-yellow: #ffd46893; + + --background-hover: #f2f2f333; + + --nav-text: #ECECEC; + + --ol-select-secondary: #545F6C; + --ol-switch-off:#686868; + --ol-switch-undefined:#383838; + + /*** General border radii **/ + --border-radius-xs: 2px; + --border-radius-sm: 5px; + --border-radius-md: 10px; + --border-radius-lg: 15px; + + /*** Fonts **/ + --font-weight-bolder: 600; + + /*** Unit marker settings ***/ + /*** All markers **/ + --unit-border-radius: var(--border-radius-xs); + --unit-font-size: 14px; + --unit-font-weight: bolder; + --unit-label-border-width: 2px; + --unit-spotlight-fill: var(--secondary-yellow); + --unit-spotlight-radius: 26px; + --unit-stroke-width: 3px; + --unit-height: 50px; + --unit-width: 50px; + + --unit-health-border-width: 2px; + --unit-health-height: 6px; + --unit-health-width: 36px; + --unit-health-x: 0px; + --unit-health-y: 26px; + + /*** Air units ***/ + --unit-ammo-gap: calc(2px + var(--unit-stroke-width)); + --unit-ammo-border-radius: 50%; + --unit-ammo-border-width: 2px; + --unit-ammo-radius: 2px; + --unit-ammo-spacing: 2px; + --unit-ammo-x: 0px; + --unit-ammo-y: 30px; + --unit-fuel-border-width: 2px; + --unit-fuel-height: 6px; + --unit-fuel-width: 36px; + --unit-fuel-x: 0px; + --unit-fuel-y: 22px; + --unit-vvi-width: 4px; +} + +* { + font-weight:600; +} + +svg { + animation: spin linear infinite 1s; +} + +@keyframes spin { + from { + transform:rotate(0deg); + } + to { + transform:rotate(360deg); + } +} \ No newline at end of file diff --git a/client/routes/resources.js b/client/routes/resources.js index 308243bc..1aa2f537 100644 --- a/client/routes/resources.js +++ b/client/routes/resources.js @@ -1,11 +1,42 @@ const express = require('express'); const router = express.Router(); +const { v4: uuidv4 } = require('uuid'); -// TODO should be user selectable or at least configurable from configuration file -var theme = "olympus"; +var themesMap = {}; router.get('/theme/*', function (req, res, next) { - res.redirect(req.url.replace("theme", "themes/" + theme)); + /* If this is the first time this session makes a request, create a uuid and save it to the map. Default theme is the olympus theme */ + if (!req.cookies.id) { + const id = uuidv4(); + res.cookie('id', id, { httpOnly: true }); + themesMap[id] = "olympus"; + reqTheme = "olympus"; + } + else { + /* If it is present, recover the session theme from the map */ + if (!(req.cookies.id in themesMap)) + themesMap[req.cookies.id] = "olympus"; + reqTheme = themesMap[req.cookies.id]; + } + + /* Yes, this in an easter egg! :D Feel free to ignore it, or activate the parrot theme to check what it does. Why parrots? The story is a bit long, come to the Discord and ask :D */ + if (reqTheme === "parrot" && !req.url.includes(".css")) + res.redirect('/themes/parrot/images/parrot.svg'); + else + res.redirect(req.url.replace("theme", "themes/" + reqTheme)); +}); + +router.put('/theme/:newTheme', function (req, res, next) { + /* Add the theme to the map, if this session already has an id */ + const newTheme = req.params.newTheme; + if (req.cookies.id) { + themesMap[req.cookies.id] = newTheme; + console.log("Theme set to " + newTheme + " for session " + req.cookies.id); + } else { + console.log("Failed to set theme to " + newTheme + ", no session id"); + } + + res.end("Ok"); }); module.exports = router; diff --git a/client/src/olympusapp.ts b/client/src/olympusapp.ts index 8f213b0f..ccafb710 100644 --- a/client/src/olympusapp.ts +++ b/client/src/olympusapp.ts @@ -53,7 +53,6 @@ export class OlympusApp { #weaponsManager: WeaponsManager | null = null; constructor() { - } // TODO add checks on null diff --git a/client/src/server/servermanager.ts b/client/src/server/servermanager.ts index 4402f2c8..13b27566 100644 --- a/client/src/server/servermanager.ts +++ b/client/src/server/servermanager.ts @@ -12,7 +12,7 @@ export class ServerManager { #connected: boolean = false; #paused: boolean = false; #REST_ADDRESS = "http://localhost:30000/olympus"; - #DEMO_ADDRESS = window.location.href + "demo"; + #DEMO_ADDRESS = window.location.href.split('?')[0] + "demo"; /* Remove query parameters */ #username = ""; #password = ""; #sessionHash: string | null = null; @@ -105,7 +105,7 @@ export class ServerManager { getConfig(callback: CallableFunction) { var xmlHttp = new XMLHttpRequest(); - xmlHttp.open("GET", window.location.href + "config", true); + xmlHttp.open("GET", window.location.href.split('?')[0] + "config", true); xmlHttp.onload = function (e) { var data = JSON.parse(xmlHttp.responseText); callback(data); diff --git a/client/views/index.ejs b/client/views/index.ejs index 6856ec4e..774e38e6 100644 --- a/client/views/index.ejs +++ b/client/views/index.ejs @@ -1,5 +1,17 @@ + + Olympus client diff --git a/client/views/panels/unitcontrol.ejs b/client/views/panels/unitcontrol.ejs index 946037de..6179918a 100644 --- a/client/views/panels/unitcontrol.ejs +++ b/client/views/panels/unitcontrol.ejs @@ -112,7 +112,6 @@
Delete unit -
diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..4529edaa --- /dev/null +++ b/package-lock.json @@ -0,0 +1,24 @@ +{ + "name": "DCSOlympus", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "uuid": "^9.0.1" + } + }, + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 00000000..7c18dc8f --- /dev/null +++ b/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "uuid": "^9.0.1" + } +}