diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..4474d59b --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,22 @@ +{ + "tailwindCSS.experimental.configFile": "public/scripts/tailwind.config.js", + "editor.quickSuggestions": { + "strings": true + }, + "tailwindCSS.includeLanguages": { + "elm": "html" + }, + "tailwindCSS.experimental.classRegex": [ + "\\bmod[\\s(<|]+\"[^\"]*\"[\\s(<|]+\"([^\"]*)\"", + "\\bclass[\\s(<|]+\"([^\"]*)\"", + "\\bclass[\\s(]+\"[^\"]*\"[\\s+]+\"([^\"]*)\"", + "\\bclass[\\s<|]+\"[^\"]*\"\\s*\\+{2}\\s*\" ([^\"]*)\"", + "\\bclass[\\s<|]+\"[^\"]*\"\\s*\\+{2}\\s*\" [^\"]*\"\\s*\\+{2}\\s*\" ([^\"]*)\"", + "\\bclass[\\s<|]+\"[^\"]*\"\\s*\\+{2}\\s*\" [^\"]*\"\\s*\\+{2}\\s*\" [^\"]*\"\\s*\\+{2}\\s*\" ([^\"]*)\"", + "\\bclassList[\\s\\[\\(]+\"([^\"]*)\"", + "\\bclassList[\\s\\[\\(]+\"[^\"]*\",\\s[^\\)]+\\)[\\s\\[\\(,]+\"([^\"]*)\"", + "\\bclassList[\\s\\[\\(]+\"[^\"]*\",\\s[^\\)]+\\)[\\s\\[\\(,]+\"[^\"]*\",\\s[^\\)]+\\)[\\s\\[\\(,]+\"([^\"]*)\"", + ], + "elmLS.elmPath": "lamdera", + "elmLS.elmReviewDiagnostics": "warning" +} \ No newline at end of file diff --git a/elm.json b/elm.json index 7e8d48a9..4ad567af 100644 --- a/elm.json +++ b/elm.json @@ -7,8 +7,10 @@ "dependencies": { "direct": { "Elm-Canvas/raster-shapes": "1.1.2", + "Janiczek/elm-bidict": "3.0.0", "Janiczek/elm-raycasting": "1.0.1", "billstclair/elm-sha256": "1.0.9", + "dillonkearns/elm-markdown": "7.0.1", "elm/browser": "1.0.2", "elm/bytes": "1.0.8", "elm/core": "1.0.5", @@ -31,9 +33,11 @@ "elm-explorations/markdown": "1.0.0", "erlandsona/assoc-set": "1.1.0", "justinmimbs/time-extra": "1.1.0", + "jxxcarlson/hex": "4.0.1", "lamdera/codecs": "1.0.0", "lamdera/core": "1.0.0", "pzp1997/assoc-list": "1.0.0", + "robinheghan/fnv1a": "1.0.0", "rtfeldman/elm-iso8601-date-strings": "1.1.3", "rtfeldman/elm-sorter-experiment": "2.1.1", "ryan-haskell/date-format": "1.0.0", @@ -42,7 +46,9 @@ "indirect": { "elm/regex": "1.0.0", "elm/virtual-dom": "1.0.2", - "justinmimbs/date": "3.2.1" + "justinmimbs/date": "3.2.1", + "rtfeldman/elm-hex": "1.0.0", + "skyqrose/assoc-list-extra": "1.0.0" } }, "test-dependencies": { diff --git a/head.html b/head.html new file mode 100644 index 00000000..12d8d5f3 --- /dev/null +++ b/head.html @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/package.json b/package.json index cf09ad94..d4d04e0a 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "postinstall": "elm-tooling install" }, "devDependencies": { - "elm-review": "^2.5.0" + "elm-review": "^2.5.0", + "tailwindcss": "^3.4.12" } } diff --git a/public/images/border-image.png b/public/images/border-image.png deleted file mode 100644 index de3ab40b..00000000 Binary files a/public/images/border-image.png and /dev/null differ diff --git a/public/images/border-image.webp b/public/images/border-image.webp new file mode 100644 index 00000000..1fb2b840 Binary files /dev/null and b/public/images/border-image.webp differ diff --git a/public/images/map_marker.png b/public/images/map_marker.png deleted file mode 100644 index b20c4c91..00000000 Binary files a/public/images/map_marker.png and /dev/null differ diff --git a/public/images/map_marker.webp b/public/images/map_marker.webp new file mode 100644 index 00000000..f5db49d1 Binary files /dev/null and b/public/images/map_marker.webp differ diff --git a/public/images/map_whole.png b/public/images/map_whole.png deleted file mode 100644 index a1dbf06f..00000000 Binary files a/public/images/map_whole.png and /dev/null differ diff --git a/public/images/map_whole.webp b/public/images/map_whole.webp new file mode 100644 index 00000000..4a1196a0 Binary files /dev/null and b/public/images/map_whole.webp differ diff --git a/public/scripts/tailwind.config.js b/public/scripts/tailwind.config.js new file mode 100644 index 00000000..13ceb85a --- /dev/null +++ b/public/scripts/tailwind.config.js @@ -0,0 +1,47 @@ +/** @type {import('tailwindcss').Config} */ +export const content = ['../../src/**/*.elm']; +export const theme = { + colors: { + transparent: "transparent", + current: "currentColor", + black: { + DEFAULT: "#000000", + transparent: "rgba(0, 0, 0, 0.25)", + }, + green: { + 900: "#111810", + 800: "#10240C", + // + 300: "#007C00", + 200: "#00C000", + 100: "#3CF800", + // + "800-half-transparent": "rgba(16, 36, 12, 0.5)", + "300-half-transparent": "rgba(0, 124, 0, 0.5)", + }, + orange: { + DEFAULT: "#FCFF2F", + transparent: "rgba(252, 253, 125, 0.25)", + "fully-transparent": "rgba(252, 253, 125, 0)", + }, + red: "#FC0001", + }, + fontSize: { + lg: "32px", + }, + fontFamily: { + mono: "PixelOperatorMono", + sans: "PixelOperator", + }, + fontWeight: { + normal: 400, + bold: 700, + extraBold: 900, + }, + // + extend: { + spacing: { + 15: '3.75rem', + } + } +}; \ No newline at end of file diff --git a/public/scripts/vendor/tailwindcss.3.4.5.min.js b/public/scripts/vendor/tailwindcss.3.4.5.min.js new file mode 100644 index 00000000..2d18ba44 --- /dev/null +++ b/public/scripts/vendor/tailwindcss.3.4.5.min.js @@ -0,0 +1,62 @@ +(()=>{var wb=Object.create;var li=Object.defineProperty;var bb=Object.getOwnPropertyDescriptor;var vb=Object.getOwnPropertyNames;var xb=Object.getPrototypeOf,kb=Object.prototype.hasOwnProperty;var au=i=>li(i,"__esModule",{value:!0});var ou=i=>{if(typeof require!="undefined")return require(i);throw new Error('Dynamic require of "'+i+'" is not supported')};var C=(i,e)=>()=>(i&&(e=i(i=0)),e);var v=(i,e)=>()=>(e||i((e={exports:{}}).exports,e),e.exports),_e=(i,e)=>{au(i);for(var t in e)li(i,t,{get:e[t],enumerable:!0})},Sb=(i,e,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of vb(e))!kb.call(i,r)&&r!=="default"&&li(i,r,{get:()=>e[r],enumerable:!(t=bb(e,r))||t.enumerable});return i},X=i=>Sb(au(li(i!=null?wb(xb(i)):{},"default",i&&i.__esModule&&"default"in i?{get:()=>i.default,enumerable:!0}:{value:i,enumerable:!0})),i);var h,l=C(()=>{h={platform:"",env:{},versions:{node:"14.17.6"}}});var Cb,re,je=C(()=>{l();Cb=0,re={readFileSync:i=>self[i]||"",statSync:()=>({mtimeMs:Cb++}),promises:{readFile:i=>Promise.resolve(self[i]||"")}}});var Qn=v((PO,uu)=>{l();"use strict";var lu=class{constructor(e={}){if(!(e.maxSize&&e.maxSize>0))throw new TypeError("`maxSize` must be a number greater than 0");if(typeof e.maxAge=="number"&&e.maxAge===0)throw new TypeError("`maxAge` must be a number greater than 0");this.maxSize=e.maxSize,this.maxAge=e.maxAge||1/0,this.onEviction=e.onEviction,this.cache=new Map,this.oldCache=new Map,this._size=0}_emitEvictions(e){if(typeof this.onEviction=="function")for(let[t,r]of e)this.onEviction(t,r.value)}_deleteIfExpired(e,t){return typeof t.expiry=="number"&&t.expiry<=Date.now()?(typeof this.onEviction=="function"&&this.onEviction(e,t.value),this.delete(e)):!1}_getOrDeleteIfExpired(e,t){if(this._deleteIfExpired(e,t)===!1)return t.value}_getItemValue(e,t){return t.expiry?this._getOrDeleteIfExpired(e,t):t.value}_peek(e,t){let r=t.get(e);return this._getItemValue(e,r)}_set(e,t){this.cache.set(e,t),this._size++,this._size>=this.maxSize&&(this._size=0,this._emitEvictions(this.oldCache),this.oldCache=this.cache,this.cache=new Map)}_moveToRecent(e,t){this.oldCache.delete(e),this._set(e,t)}*_entriesAscending(){for(let e of this.oldCache){let[t,r]=e;this.cache.has(t)||this._deleteIfExpired(t,r)===!1&&(yield e)}for(let e of this.cache){let[t,r]=e;this._deleteIfExpired(t,r)===!1&&(yield e)}}get(e){if(this.cache.has(e)){let t=this.cache.get(e);return this._getItemValue(e,t)}if(this.oldCache.has(e)){let t=this.oldCache.get(e);if(this._deleteIfExpired(e,t)===!1)return this._moveToRecent(e,t),t.value}}set(e,t,{maxAge:r=this.maxAge===1/0?void 0:Date.now()+this.maxAge}={}){this.cache.has(e)?this.cache.set(e,{value:t,maxAge:r}):this._set(e,{value:t,expiry:r})}has(e){return this.cache.has(e)?!this._deleteIfExpired(e,this.cache.get(e)):this.oldCache.has(e)?!this._deleteIfExpired(e,this.oldCache.get(e)):!1}peek(e){if(this.cache.has(e))return this._peek(e,this.cache);if(this.oldCache.has(e))return this._peek(e,this.oldCache)}delete(e){let t=this.cache.delete(e);return t&&this._size--,this.oldCache.delete(e)||t}clear(){this.cache.clear(),this.oldCache.clear(),this._size=0}resize(e){if(!(e&&e>0))throw new TypeError("`maxSize` must be a number greater than 0");let t=[...this._entriesAscending()],r=t.length-e;r<0?(this.cache=new Map(t),this.oldCache=new Map,this._size=t.length):(r>0&&this._emitEvictions(t.slice(0,r)),this.oldCache=new Map(t.slice(r)),this.cache=new Map,this._size=0),this.maxSize=e}*keys(){for(let[e]of this)yield e}*values(){for(let[,e]of this)yield e}*[Symbol.iterator](){for(let e of this.cache){let[t,r]=e;this._deleteIfExpired(t,r)===!1&&(yield[t,r.value])}for(let e of this.oldCache){let[t,r]=e;this.cache.has(t)||this._deleteIfExpired(t,r)===!1&&(yield[t,r.value])}}*entriesDescending(){let e=[...this.cache];for(let t=e.length-1;t>=0;--t){let r=e[t],[n,a]=r;this._deleteIfExpired(n,a)===!1&&(yield[n,a.value])}e=[...this.oldCache];for(let t=e.length-1;t>=0;--t){let r=e[t],[n,a]=r;this.cache.has(n)||this._deleteIfExpired(n,a)===!1&&(yield[n,a.value])}}*entriesAscending(){for(let[e,t]of this._entriesAscending())yield[e,t.value]}get size(){if(!this._size)return this.oldCache.size;let e=0;for(let t of this.oldCache.keys())this.cache.has(t)||e++;return Math.min(this._size+e,this.maxSize)}};uu.exports=lu});var fu,cu=C(()=>{l();fu=i=>i&&i._hash});function ui(i){return fu(i,{ignoreUnknown:!0})}var pu=C(()=>{l();cu()});function Xe(i){if(i=`${i}`,i==="0")return"0";if(/^[+-]?(\d+|\d*\.\d+)(e[+-]?\d+)?(%|\w+)?$/.test(i))return i.replace(/^[+-]?/,t=>t==="-"?"":"-");let e=["var","calc","min","max","clamp"];for(let t of e)if(i.includes(`${t}(`))return`calc(${i} * -1)`}var fi=C(()=>{l()});var du,hu=C(()=>{l();du=["preflight","container","accessibility","pointerEvents","visibility","position","inset","isolation","zIndex","order","gridColumn","gridColumnStart","gridColumnEnd","gridRow","gridRowStart","gridRowEnd","float","clear","margin","boxSizing","lineClamp","display","aspectRatio","size","height","maxHeight","minHeight","width","minWidth","maxWidth","flex","flexShrink","flexGrow","flexBasis","tableLayout","captionSide","borderCollapse","borderSpacing","transformOrigin","translate","rotate","skew","scale","transform","animation","cursor","touchAction","userSelect","resize","scrollSnapType","scrollSnapAlign","scrollSnapStop","scrollMargin","scrollPadding","listStylePosition","listStyleType","listStyleImage","appearance","columns","breakBefore","breakInside","breakAfter","gridAutoColumns","gridAutoFlow","gridAutoRows","gridTemplateColumns","gridTemplateRows","flexDirection","flexWrap","placeContent","placeItems","alignContent","alignItems","justifyContent","justifyItems","gap","space","divideWidth","divideStyle","divideColor","divideOpacity","placeSelf","alignSelf","justifySelf","overflow","overscrollBehavior","scrollBehavior","textOverflow","hyphens","whitespace","textWrap","wordBreak","borderRadius","borderWidth","borderStyle","borderColor","borderOpacity","backgroundColor","backgroundOpacity","backgroundImage","gradientColorStops","boxDecorationBreak","backgroundSize","backgroundAttachment","backgroundClip","backgroundPosition","backgroundRepeat","backgroundOrigin","fill","stroke","strokeWidth","objectFit","objectPosition","padding","textAlign","textIndent","verticalAlign","fontFamily","fontSize","fontWeight","textTransform","fontStyle","fontVariantNumeric","lineHeight","letterSpacing","textColor","textOpacity","textDecoration","textDecorationColor","textDecorationStyle","textDecorationThickness","textUnderlineOffset","fontSmoothing","placeholderColor","placeholderOpacity","caretColor","accentColor","opacity","backgroundBlendMode","mixBlendMode","boxShadow","boxShadowColor","outlineStyle","outlineWidth","outlineOffset","outlineColor","ringWidth","ringColor","ringOpacity","ringOffsetWidth","ringOffsetColor","blur","brightness","contrast","dropShadow","grayscale","hueRotate","invert","saturate","sepia","filter","backdropBlur","backdropBrightness","backdropContrast","backdropGrayscale","backdropHueRotate","backdropInvert","backdropOpacity","backdropSaturate","backdropSepia","backdropFilter","transitionProperty","transitionDelay","transitionDuration","transitionTimingFunction","willChange","contain","content","forcedColorAdjust"]});function mu(i,e){return i===void 0?e:Array.isArray(i)?i:[...new Set(e.filter(r=>i!==!1&&i[r]!==!1).concat(Object.keys(i).filter(r=>i[r]!==!1)))]}var gu=C(()=>{l()});var yu={};_e(yu,{default:()=>Oe});var Oe,ci=C(()=>{l();Oe=new Proxy({},{get:()=>String})});function Jn(i,e,t){typeof h!="undefined"&&h.env.JEST_WORKER_ID||t&&wu.has(t)||(t&&wu.add(t),console.warn(""),e.forEach(r=>console.warn(i,"-",r)))}function Xn(i){return Oe.dim(i)}var wu,F,Ee=C(()=>{l();ci();wu=new Set;F={info(i,e){Jn(Oe.bold(Oe.cyan("info")),...Array.isArray(i)?[i]:[e,i])},warn(i,e){["content-problems"].includes(i)||Jn(Oe.bold(Oe.yellow("warn")),...Array.isArray(i)?[i]:[e,i])},risk(i,e){Jn(Oe.bold(Oe.magenta("risk")),...Array.isArray(i)?[i]:[e,i])}}});var bu={};_e(bu,{default:()=>Kn});function ar({version:i,from:e,to:t}){F.warn(`${e}-color-renamed`,[`As of Tailwind CSS ${i}, \`${e}\` has been renamed to \`${t}\`.`,"Update your configuration file to silence this warning."])}var Kn,Zn=C(()=>{l();Ee();Kn={inherit:"inherit",current:"currentColor",transparent:"transparent",black:"#000",white:"#fff",slate:{50:"#f8fafc",100:"#f1f5f9",200:"#e2e8f0",300:"#cbd5e1",400:"#94a3b8",500:"#64748b",600:"#475569",700:"#334155",800:"#1e293b",900:"#0f172a",950:"#020617"},gray:{50:"#f9fafb",100:"#f3f4f6",200:"#e5e7eb",300:"#d1d5db",400:"#9ca3af",500:"#6b7280",600:"#4b5563",700:"#374151",800:"#1f2937",900:"#111827",950:"#030712"},zinc:{50:"#fafafa",100:"#f4f4f5",200:"#e4e4e7",300:"#d4d4d8",400:"#a1a1aa",500:"#71717a",600:"#52525b",700:"#3f3f46",800:"#27272a",900:"#18181b",950:"#09090b"},neutral:{50:"#fafafa",100:"#f5f5f5",200:"#e5e5e5",300:"#d4d4d4",400:"#a3a3a3",500:"#737373",600:"#525252",700:"#404040",800:"#262626",900:"#171717",950:"#0a0a0a"},stone:{50:"#fafaf9",100:"#f5f5f4",200:"#e7e5e4",300:"#d6d3d1",400:"#a8a29e",500:"#78716c",600:"#57534e",700:"#44403c",800:"#292524",900:"#1c1917",950:"#0c0a09"},red:{50:"#fef2f2",100:"#fee2e2",200:"#fecaca",300:"#fca5a5",400:"#f87171",500:"#ef4444",600:"#dc2626",700:"#b91c1c",800:"#991b1b",900:"#7f1d1d",950:"#450a0a"},orange:{50:"#fff7ed",100:"#ffedd5",200:"#fed7aa",300:"#fdba74",400:"#fb923c",500:"#f97316",600:"#ea580c",700:"#c2410c",800:"#9a3412",900:"#7c2d12",950:"#431407"},amber:{50:"#fffbeb",100:"#fef3c7",200:"#fde68a",300:"#fcd34d",400:"#fbbf24",500:"#f59e0b",600:"#d97706",700:"#b45309",800:"#92400e",900:"#78350f",950:"#451a03"},yellow:{50:"#fefce8",100:"#fef9c3",200:"#fef08a",300:"#fde047",400:"#facc15",500:"#eab308",600:"#ca8a04",700:"#a16207",800:"#854d0e",900:"#713f12",950:"#422006"},lime:{50:"#f7fee7",100:"#ecfccb",200:"#d9f99d",300:"#bef264",400:"#a3e635",500:"#84cc16",600:"#65a30d",700:"#4d7c0f",800:"#3f6212",900:"#365314",950:"#1a2e05"},green:{50:"#f0fdf4",100:"#dcfce7",200:"#bbf7d0",300:"#86efac",400:"#4ade80",500:"#22c55e",600:"#16a34a",700:"#15803d",800:"#166534",900:"#14532d",950:"#052e16"},emerald:{50:"#ecfdf5",100:"#d1fae5",200:"#a7f3d0",300:"#6ee7b7",400:"#34d399",500:"#10b981",600:"#059669",700:"#047857",800:"#065f46",900:"#064e3b",950:"#022c22"},teal:{50:"#f0fdfa",100:"#ccfbf1",200:"#99f6e4",300:"#5eead4",400:"#2dd4bf",500:"#14b8a6",600:"#0d9488",700:"#0f766e",800:"#115e59",900:"#134e4a",950:"#042f2e"},cyan:{50:"#ecfeff",100:"#cffafe",200:"#a5f3fc",300:"#67e8f9",400:"#22d3ee",500:"#06b6d4",600:"#0891b2",700:"#0e7490",800:"#155e75",900:"#164e63",950:"#083344"},sky:{50:"#f0f9ff",100:"#e0f2fe",200:"#bae6fd",300:"#7dd3fc",400:"#38bdf8",500:"#0ea5e9",600:"#0284c7",700:"#0369a1",800:"#075985",900:"#0c4a6e",950:"#082f49"},blue:{50:"#eff6ff",100:"#dbeafe",200:"#bfdbfe",300:"#93c5fd",400:"#60a5fa",500:"#3b82f6",600:"#2563eb",700:"#1d4ed8",800:"#1e40af",900:"#1e3a8a",950:"#172554"},indigo:{50:"#eef2ff",100:"#e0e7ff",200:"#c7d2fe",300:"#a5b4fc",400:"#818cf8",500:"#6366f1",600:"#4f46e5",700:"#4338ca",800:"#3730a3",900:"#312e81",950:"#1e1b4b"},violet:{50:"#f5f3ff",100:"#ede9fe",200:"#ddd6fe",300:"#c4b5fd",400:"#a78bfa",500:"#8b5cf6",600:"#7c3aed",700:"#6d28d9",800:"#5b21b6",900:"#4c1d95",950:"#2e1065"},purple:{50:"#faf5ff",100:"#f3e8ff",200:"#e9d5ff",300:"#d8b4fe",400:"#c084fc",500:"#a855f7",600:"#9333ea",700:"#7e22ce",800:"#6b21a8",900:"#581c87",950:"#3b0764"},fuchsia:{50:"#fdf4ff",100:"#fae8ff",200:"#f5d0fe",300:"#f0abfc",400:"#e879f9",500:"#d946ef",600:"#c026d3",700:"#a21caf",800:"#86198f",900:"#701a75",950:"#4a044e"},pink:{50:"#fdf2f8",100:"#fce7f3",200:"#fbcfe8",300:"#f9a8d4",400:"#f472b6",500:"#ec4899",600:"#db2777",700:"#be185d",800:"#9d174d",900:"#831843",950:"#500724"},rose:{50:"#fff1f2",100:"#ffe4e6",200:"#fecdd3",300:"#fda4af",400:"#fb7185",500:"#f43f5e",600:"#e11d48",700:"#be123c",800:"#9f1239",900:"#881337",950:"#4c0519"},get lightBlue(){return ar({version:"v2.2",from:"lightBlue",to:"sky"}),this.sky},get warmGray(){return ar({version:"v3.0",from:"warmGray",to:"stone"}),this.stone},get trueGray(){return ar({version:"v3.0",from:"trueGray",to:"neutral"}),this.neutral},get coolGray(){return ar({version:"v3.0",from:"coolGray",to:"gray"}),this.gray},get blueGray(){return ar({version:"v3.0",from:"blueGray",to:"slate"}),this.slate}}});function es(i,...e){for(let t of e){for(let r in t)i?.hasOwnProperty?.(r)||(i[r]=t[r]);for(let r of Object.getOwnPropertySymbols(t))i?.hasOwnProperty?.(r)||(i[r]=t[r])}return i}var vu=C(()=>{l()});function Ke(i){if(Array.isArray(i))return i;let e=i.split("[").length-1,t=i.split("]").length-1;if(e!==t)throw new Error(`Path is invalid. Has unbalanced brackets: ${i}`);return i.split(/\.(?![^\[]*\])|[\[\]]/g).filter(Boolean)}var pi=C(()=>{l()});function Z(i,e){return di.future.includes(e)?i.future==="all"||(i?.future?.[e]??xu[e]??!1):di.experimental.includes(e)?i.experimental==="all"||(i?.experimental?.[e]??xu[e]??!1):!1}function ku(i){return i.experimental==="all"?di.experimental:Object.keys(i?.experimental??{}).filter(e=>di.experimental.includes(e)&&i.experimental[e])}function Su(i){if(h.env.JEST_WORKER_ID===void 0&&ku(i).length>0){let e=ku(i).map(t=>Oe.yellow(t)).join(", ");F.warn("experimental-flags-enabled",[`You have enabled experimental features: ${e}`,"Experimental features in Tailwind CSS are not covered by semver, may introduce breaking changes, and can change at any time."])}}var xu,di,ze=C(()=>{l();ci();Ee();xu={optimizeUniversalDefaults:!1,generalizedModifiers:!0,disableColorOpacityUtilitiesByDefault:!1,relativeContentPathsByDefault:!1},di={future:["hoverOnlyWhenSupported","respectDefaultRingColorOpacity","disableColorOpacityUtilitiesByDefault","relativeContentPathsByDefault"],experimental:["optimizeUniversalDefaults","generalizedModifiers"]}});function Cu(i){(()=>{if(i.purge||!i.content||!Array.isArray(i.content)&&!(typeof i.content=="object"&&i.content!==null))return!1;if(Array.isArray(i.content))return i.content.every(t=>typeof t=="string"?!0:!(typeof t?.raw!="string"||t?.extension&&typeof t?.extension!="string"));if(typeof i.content=="object"&&i.content!==null){if(Object.keys(i.content).some(t=>!["files","relative","extract","transform"].includes(t)))return!1;if(Array.isArray(i.content.files)){if(!i.content.files.every(t=>typeof t=="string"?!0:!(typeof t?.raw!="string"||t?.extension&&typeof t?.extension!="string")))return!1;if(typeof i.content.extract=="object"){for(let t of Object.values(i.content.extract))if(typeof t!="function")return!1}else if(!(i.content.extract===void 0||typeof i.content.extract=="function"))return!1;if(typeof i.content.transform=="object"){for(let t of Object.values(i.content.transform))if(typeof t!="function")return!1}else if(!(i.content.transform===void 0||typeof i.content.transform=="function"))return!1;if(typeof i.content.relative!="boolean"&&typeof i.content.relative!="undefined")return!1}return!0}return!1})()||F.warn("purge-deprecation",["The `purge`/`content` options have changed in Tailwind CSS v3.0.","Update your configuration file to eliminate this warning.","https://tailwindcss.com/docs/upgrade-guide#configure-content-sources"]),i.safelist=(()=>{let{content:t,purge:r,safelist:n}=i;return Array.isArray(n)?n:Array.isArray(t?.safelist)?t.safelist:Array.isArray(r?.safelist)?r.safelist:Array.isArray(r?.options?.safelist)?r.options.safelist:[]})(),i.blocklist=(()=>{let{blocklist:t}=i;if(Array.isArray(t)){if(t.every(r=>typeof r=="string"))return t;F.warn("blocklist-invalid",["The `blocklist` option must be an array of strings.","https://tailwindcss.com/docs/content-configuration#discarding-classes"])}return[]})(),typeof i.prefix=="function"?(F.warn("prefix-function",["As of Tailwind CSS v3.0, `prefix` cannot be a function.","Update `prefix` in your configuration to be a string to eliminate this warning.","https://tailwindcss.com/docs/upgrade-guide#prefix-cannot-be-a-function"]),i.prefix=""):i.prefix=i.prefix??"",i.content={relative:(()=>{let{content:t}=i;return t?.relative?t.relative:Z(i,"relativeContentPathsByDefault")})(),files:(()=>{let{content:t,purge:r}=i;return Array.isArray(r)?r:Array.isArray(r?.content)?r.content:Array.isArray(t)?t:Array.isArray(t?.content)?t.content:Array.isArray(t?.files)?t.files:[]})(),extract:(()=>{let t=(()=>i.purge?.extract?i.purge.extract:i.content?.extract?i.content.extract:i.purge?.extract?.DEFAULT?i.purge.extract.DEFAULT:i.content?.extract?.DEFAULT?i.content.extract.DEFAULT:i.purge?.options?.extractors?i.purge.options.extractors:i.content?.options?.extractors?i.content.options.extractors:{})(),r={},n=(()=>{if(i.purge?.options?.defaultExtractor)return i.purge.options.defaultExtractor;if(i.content?.options?.defaultExtractor)return i.content.options.defaultExtractor})();if(n!==void 0&&(r.DEFAULT=n),typeof t=="function")r.DEFAULT=t;else if(Array.isArray(t))for(let{extensions:a,extractor:s}of t??[])for(let o of a)r[o]=s;else typeof t=="object"&&t!==null&&Object.assign(r,t);return r})(),transform:(()=>{let t=(()=>i.purge?.transform?i.purge.transform:i.content?.transform?i.content.transform:i.purge?.transform?.DEFAULT?i.purge.transform.DEFAULT:i.content?.transform?.DEFAULT?i.content.transform.DEFAULT:{})(),r={};return typeof t=="function"?r.DEFAULT=t:typeof t=="object"&&t!==null&&Object.assign(r,t),r})()};for(let t of i.content.files)if(typeof t=="string"&&/{([^,]*?)}/g.test(t)){F.warn("invalid-glob-braces",[`The glob pattern ${Xn(t)} in your Tailwind CSS configuration is invalid.`,`Update it to ${Xn(t.replace(/{([^,]*?)}/g,"$1"))} to silence this warning.`]);break}return i}var Au=C(()=>{l();ze();Ee()});function se(i){if(Object.prototype.toString.call(i)!=="[object Object]")return!1;let e=Object.getPrototypeOf(i);return e===null||Object.getPrototypeOf(e)===null}var Ct=C(()=>{l()});function Ze(i){return Array.isArray(i)?i.map(e=>Ze(e)):typeof i=="object"&&i!==null?Object.fromEntries(Object.entries(i).map(([e,t])=>[e,Ze(t)])):i}var hi=C(()=>{l()});function gt(i){return i.replace(/\\,/g,"\\2c ")}var mi=C(()=>{l()});var ts,_u=C(()=>{l();ts={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]}});function or(i,{loose:e=!1}={}){if(typeof i!="string")return null;if(i=i.trim(),i==="transparent")return{mode:"rgb",color:["0","0","0"],alpha:"0"};if(i in ts)return{mode:"rgb",color:ts[i].map(a=>a.toString())};let t=i.replace(_b,(a,s,o,u,c)=>["#",s,s,o,o,u,u,c?c+c:""].join("")).match(Ab);if(t!==null)return{mode:"rgb",color:[parseInt(t[1],16),parseInt(t[2],16),parseInt(t[3],16)].map(a=>a.toString()),alpha:t[4]?(parseInt(t[4],16)/255).toString():void 0};let r=i.match(Ob)??i.match(Eb);if(r===null)return null;let n=[r[2],r[3],r[4]].filter(Boolean).map(a=>a.toString());return n.length===2&&n[0].startsWith("var(")?{mode:r[1],color:[n[0]],alpha:n[1]}:!e&&n.length!==3||n.length<3&&!n.some(a=>/^var\(.*?\)$/.test(a))?null:{mode:r[1],color:n,alpha:r[5]?.toString?.()}}function rs({mode:i,color:e,alpha:t}){let r=t!==void 0;return i==="rgba"||i==="hsla"?`${i}(${e.join(", ")}${r?`, ${t}`:""})`:`${i}(${e.join(" ")}${r?` / ${t}`:""})`}var Ab,_b,et,gi,Ou,tt,Ob,Eb,is=C(()=>{l();_u();Ab=/^#([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})?$/i,_b=/^#([a-f\d])([a-f\d])([a-f\d])([a-f\d])?$/i,et=/(?:\d+|\d*\.\d+)%?/,gi=/(?:\s*,\s*|\s+)/,Ou=/\s*[,/]\s*/,tt=/var\(--(?:[^ )]*?)(?:,(?:[^ )]*?|var\(--[^ )]*?\)))?\)/,Ob=new RegExp(`^(rgba?)\\(\\s*(${et.source}|${tt.source})(?:${gi.source}(${et.source}|${tt.source}))?(?:${gi.source}(${et.source}|${tt.source}))?(?:${Ou.source}(${et.source}|${tt.source}))?\\s*\\)$`),Eb=new RegExp(`^(hsla?)\\(\\s*((?:${et.source})(?:deg|rad|grad|turn)?|${tt.source})(?:${gi.source}(${et.source}|${tt.source}))?(?:${gi.source}(${et.source}|${tt.source}))?(?:${Ou.source}(${et.source}|${tt.source}))?\\s*\\)$`)});function qe(i,e,t){if(typeof i=="function")return i({opacityValue:e});let r=or(i,{loose:!0});return r===null?t:rs({...r,alpha:e})}function oe({color:i,property:e,variable:t}){let r=[].concat(e);if(typeof i=="function")return{[t]:"1",...Object.fromEntries(r.map(a=>[a,i({opacityVariable:t,opacityValue:`var(${t})`})]))};let n=or(i);return n===null?Object.fromEntries(r.map(a=>[a,i])):n.alpha!==void 0?Object.fromEntries(r.map(a=>[a,i])):{[t]:"1",...Object.fromEntries(r.map(a=>[a,rs({...n,alpha:`var(${t})`})]))}}var lr=C(()=>{l();is()});function ie(i,e){let t=[],r=[],n=0,a=!1;for(let s=0;s{l()});function yi(i){return ie(i,",").map(t=>{let r=t.trim(),n={raw:r},a=r.split(Pb),s=new Set;for(let o of a)Eu.lastIndex=0,!s.has("KEYWORD")&&Tb.has(o)?(n.keyword=o,s.add("KEYWORD")):Eu.test(o)?s.has("X")?s.has("Y")?s.has("BLUR")?s.has("SPREAD")||(n.spread=o,s.add("SPREAD")):(n.blur=o,s.add("BLUR")):(n.y=o,s.add("Y")):(n.x=o,s.add("X")):n.color?(n.unknown||(n.unknown=[]),n.unknown.push(o)):n.color=o;return n.valid=n.x!==void 0&&n.y!==void 0,n})}function Tu(i){return i.map(e=>e.valid?[e.keyword,e.x,e.y,e.blur,e.spread,e.color].filter(Boolean).join(" "):e.raw).join(", ")}var Tb,Pb,Eu,ns=C(()=>{l();yt();Tb=new Set(["inset","inherit","initial","revert","unset"]),Pb=/\ +(?![^(]*\))/g,Eu=/^-?(\d+|\.\d+)(.*?)$/g});function ss(i){return Db.some(e=>new RegExp(`^${e}\\(.*\\)`).test(i))}function N(i,e=null,t=!0){let r=e&&Ib.has(e.property);return i.startsWith("--")&&!r?`var(${i})`:i.includes("url(")?i.split(/(url\(.*?\))/g).filter(Boolean).map(n=>/^url\(.*?\)$/.test(n)?n:N(n,e,!1)).join(""):(i=i.replace(/([^\\])_+/g,(n,a)=>a+" ".repeat(n.length-1)).replace(/^_/g," ").replace(/\\_/g,"_"),t&&(i=i.trim()),i=qb(i),i)}function qb(i){let e=["theme"],t=["min-content","max-content","fit-content","safe-area-inset-top","safe-area-inset-right","safe-area-inset-bottom","safe-area-inset-left","titlebar-area-x","titlebar-area-y","titlebar-area-width","titlebar-area-height","keyboard-inset-top","keyboard-inset-right","keyboard-inset-bottom","keyboard-inset-left","keyboard-inset-width","keyboard-inset-height","radial-gradient","linear-gradient","conic-gradient","repeating-radial-gradient","repeating-linear-gradient","repeating-conic-gradient"];return i.replace(/(calc|min|max|clamp)\(.+\)/g,r=>{let n="";function a(){let s=n.trimEnd();return s[s.length-1]}for(let s=0;sr[s+p]===d)},u=function(f){let d=1/0;for(let m of f){let b=r.indexOf(m,s);b!==-1&&bo(f))){let f=t.find(d=>o(d));n+=f,s+=f.length-1}else e.some(f=>o(f))?n+=u([")"]):o("[")?n+=u(["]"]):["+","-","*","/"].includes(c)&&!["(","+","-","*","/",","].includes(a())?n+=` ${c} `:n+=c}return n.replace(/\s+/g," ")})}function as(i){return i.startsWith("url(")}function os(i){return!isNaN(Number(i))||ss(i)}function ur(i){return i.endsWith("%")&&os(i.slice(0,-1))||ss(i)}function fr(i){return i==="0"||new RegExp(`^[+-]?[0-9]*.?[0-9]+(?:[eE][+-]?[0-9]+)?${Mb}$`).test(i)||ss(i)}function Pu(i){return Bb.has(i)}function Du(i){let e=yi(N(i));for(let t of e)if(!t.valid)return!1;return!0}function Iu(i){let e=0;return ie(i,"_").every(r=>(r=N(r),r.startsWith("var(")?!0:or(r,{loose:!0})!==null?(e++,!0):!1))?e>0:!1}function qu(i){let e=0;return ie(i,",").every(r=>(r=N(r),r.startsWith("var(")?!0:as(r)||Nb(r)||["element(","image(","cross-fade(","image-set("].some(n=>r.startsWith(n))?(e++,!0):!1))?e>0:!1}function Nb(i){i=N(i);for(let e of Fb)if(i.startsWith(`${e}(`))return!0;return!1}function Ru(i){let e=0;return ie(i,"_").every(r=>(r=N(r),r.startsWith("var(")?!0:Lb.has(r)||fr(r)||ur(r)?(e++,!0):!1))?e>0:!1}function Mu(i){let e=0;return ie(i,",").every(r=>(r=N(r),r.startsWith("var(")?!0:r.includes(" ")&&!/(['"])([^"']+)\1/g.test(r)||/^\d/g.test(r)?!1:(e++,!0)))?e>0:!1}function Bu(i){return $b.has(i)}function Fu(i){return jb.has(i)}function Nu(i){return zb.has(i)}var Db,Ib,Rb,Mb,Bb,Fb,Lb,$b,jb,zb,cr=C(()=>{l();is();ns();yt();Db=["min","max","clamp","calc"];Ib=new Set(["scroll-timeline-name","timeline-scope","view-timeline-name","font-palette","anchor-name","anchor-scope","position-anchor","position-try-options","scroll-timeline","animation-timeline","view-timeline","position-try"]);Rb=["cm","mm","Q","in","pc","pt","px","em","ex","ch","rem","lh","rlh","vw","vh","vmin","vmax","vb","vi","svw","svh","lvw","lvh","dvw","dvh","cqw","cqh","cqi","cqb","cqmin","cqmax"],Mb=`(?:${Rb.join("|")})`;Bb=new Set(["thin","medium","thick"]);Fb=new Set(["conic-gradient","linear-gradient","radial-gradient","repeating-conic-gradient","repeating-linear-gradient","repeating-radial-gradient"]);Lb=new Set(["center","top","right","bottom","left"]);$b=new Set(["serif","sans-serif","monospace","cursive","fantasy","system-ui","ui-serif","ui-sans-serif","ui-monospace","ui-rounded","math","emoji","fangsong"]);jb=new Set(["xx-small","x-small","small","medium","large","x-large","xx-large","xxx-large"]);zb=new Set(["larger","smaller"])});function Lu(i){let e=["cover","contain"];return ie(i,",").every(t=>{let r=ie(t,"_").filter(Boolean);return r.length===1&&e.includes(r[0])?!0:r.length!==1&&r.length!==2?!1:r.every(n=>fr(n)||ur(n)||n==="auto")})}var $u=C(()=>{l();cr();yt()});function ju(i,e){i.walkClasses(t=>{t.value=e(t.value),t.raws&&t.raws.value&&(t.raws.value=gt(t.raws.value))})}function zu(i,e){if(!rt(i))return;let t=i.slice(1,-1);if(!!e(t))return N(t)}function Vb(i,e={},t){let r=e[i];if(r!==void 0)return Xe(r);if(rt(i)){let n=zu(i,t);return n===void 0?void 0:Xe(n)}}function wi(i,e={},{validate:t=()=>!0}={}){let r=e.values?.[i];return r!==void 0?r:e.supportsNegativeValues&&i.startsWith("-")?Vb(i.slice(1),e.values,t):zu(i,t)}function rt(i){return i.startsWith("[")&&i.endsWith("]")}function Vu(i){let e=i.lastIndexOf("/"),t=i.lastIndexOf("[",e),r=i.indexOf("]",e);return i[e-1]==="]"||i[e+1]==="["||t!==-1&&r!==-1&&t")){let e=i;return({opacityValue:t=1})=>e.replace(//g,t)}return i}function Uu(i){return N(i.slice(1,-1))}function Ub(i,e={},{tailwindConfig:t={}}={}){if(e.values?.[i]!==void 0)return At(e.values?.[i]);let[r,n]=Vu(i);if(n!==void 0){let a=e.values?.[r]??(rt(r)?r.slice(1,-1):void 0);return a===void 0?void 0:(a=At(a),rt(n)?qe(a,Uu(n)):t.theme?.opacity?.[n]===void 0?void 0:qe(a,t.theme.opacity[n]))}return wi(i,e,{validate:Iu})}function Wb(i,e={}){return e.values?.[i]}function ge(i){return(e,t)=>wi(e,t,{validate:i})}function Gb(i,e){let t=i.indexOf(e);return t===-1?[void 0,i]:[i.slice(0,t),i.slice(t+1)]}function us(i,e,t,r){if(t.values&&e in t.values)for(let{type:a}of i??[]){let s=ls[a](e,t,{tailwindConfig:r});if(s!==void 0)return[s,a,null]}if(rt(e)){let a=e.slice(1,-1),[s,o]=Gb(a,":");if(!/^[\w-_]+$/g.test(s))o=a;else if(s!==void 0&&!Wu.includes(s))return[];if(o.length>0&&Wu.includes(s))return[wi(`[${o}]`,t),s,null]}let n=fs(i,e,t,r);for(let a of n)return a;return[]}function*fs(i,e,t,r){let n=Z(r,"generalizedModifiers"),[a,s]=Vu(e);if(n&&t.modifiers!=null&&(t.modifiers==="any"||typeof t.modifiers=="object"&&(s&&rt(s)||s in t.modifiers))||(a=e,s=void 0),s!==void 0&&a===""&&(a="DEFAULT"),s!==void 0&&typeof t.modifiers=="object"){let u=t.modifiers?.[s]??null;u!==null?s=u:rt(s)&&(s=Uu(s))}for(let{type:u}of i??[]){let c=ls[u](a,t,{tailwindConfig:r});c!==void 0&&(yield[c,u,s??null])}}var ls,Wu,pr=C(()=>{l();mi();lr();cr();fi();$u();ze();ls={any:wi,color:Ub,url:ge(as),image:ge(qu),length:ge(fr),percentage:ge(ur),position:ge(Ru),lookup:Wb,"generic-name":ge(Bu),"family-name":ge(Mu),number:ge(os),"line-width":ge(Pu),"absolute-size":ge(Fu),"relative-size":ge(Nu),shadow:ge(Du),size:ge(Lu)},Wu=Object.keys(ls)});function L(i){return typeof i=="function"?i({}):i}var cs=C(()=>{l()});function _t(i){return typeof i=="function"}function dr(i,...e){let t=e.pop();for(let r of e)for(let n in r){let a=t(i[n],r[n]);a===void 0?se(i[n])&&se(r[n])?i[n]=dr({},i[n],r[n],t):i[n]=r[n]:i[n]=a}return i}function Hb(i,...e){return _t(i)?i(...e):i}function Yb(i){return i.reduce((e,{extend:t})=>dr(e,t,(r,n)=>r===void 0?[n]:Array.isArray(r)?[n,...r]:[n,r]),{})}function Qb(i){return{...i.reduce((e,t)=>es(e,t),{}),extend:Yb(i)}}function Gu(i,e){if(Array.isArray(i)&&se(i[0]))return i.concat(e);if(Array.isArray(e)&&se(e[0])&&se(i))return[i,...e];if(Array.isArray(e))return e}function Jb({extend:i,...e}){return dr(e,i,(t,r)=>!_t(t)&&!r.some(_t)?dr({},t,...r,Gu):(n,a)=>dr({},...[t,...r].map(s=>Hb(s,n,a)),Gu))}function*Xb(i){let e=Ke(i);if(e.length===0||(yield e,Array.isArray(i)))return;let t=/^(.*?)\s*\/\s*([^/]+)$/,r=i.match(t);if(r!==null){let[,n,a]=r,s=Ke(n);s.alpha=a,yield s}}function Kb(i){let e=(t,r)=>{for(let n of Xb(t)){let a=0,s=i;for(;s!=null&&a(t[r]=_t(i[r])?i[r](e,ps):i[r],t),{})}function Hu(i){let e=[];return i.forEach(t=>{e=[...e,t];let r=t?.plugins??[];r.length!==0&&r.forEach(n=>{n.__isOptionsFunction&&(n=n()),e=[...e,...Hu([n?.config??{}])]})}),e}function Zb(i){return[...i].reduceRight((t,r)=>_t(r)?r({corePlugins:t}):mu(r,t),du)}function e0(i){return[...i].reduceRight((t,r)=>[...t,...r],[])}function ds(i){let e=[...Hu(i),{prefix:"",important:!1,separator:":"}];return Cu(es({theme:Kb(Jb(Qb(e.map(t=>t?.theme??{})))),corePlugins:Zb(e.map(t=>t.corePlugins)),plugins:e0(i.map(t=>t?.plugins??[]))},...e))}var ps,Yu=C(()=>{l();fi();hu();gu();Zn();vu();pi();Au();Ct();hi();pr();lr();cs();ps={colors:Kn,negative(i){return Object.keys(i).filter(e=>i[e]!=="0").reduce((e,t)=>{let r=Xe(i[t]);return r!==void 0&&(e[`-${t}`]=r),e},{})},breakpoints(i){return Object.keys(i).filter(e=>typeof i[e]=="string").reduce((e,t)=>({...e,[`screen-${t}`]:i[t]}),{})}}});var bi=v((qE,Qu)=>{l();Qu.exports={content:[],presets:[],darkMode:"media",theme:{accentColor:({theme:i})=>({...i("colors"),auto:"auto"}),animation:{none:"none",spin:"spin 1s linear infinite",ping:"ping 1s cubic-bezier(0, 0, 0.2, 1) infinite",pulse:"pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite",bounce:"bounce 1s infinite"},aria:{busy:'busy="true"',checked:'checked="true"',disabled:'disabled="true"',expanded:'expanded="true"',hidden:'hidden="true"',pressed:'pressed="true"',readonly:'readonly="true"',required:'required="true"',selected:'selected="true"'},aspectRatio:{auto:"auto",square:"1 / 1",video:"16 / 9"},backdropBlur:({theme:i})=>i("blur"),backdropBrightness:({theme:i})=>i("brightness"),backdropContrast:({theme:i})=>i("contrast"),backdropGrayscale:({theme:i})=>i("grayscale"),backdropHueRotate:({theme:i})=>i("hueRotate"),backdropInvert:({theme:i})=>i("invert"),backdropOpacity:({theme:i})=>i("opacity"),backdropSaturate:({theme:i})=>i("saturate"),backdropSepia:({theme:i})=>i("sepia"),backgroundColor:({theme:i})=>i("colors"),backgroundImage:{none:"none","gradient-to-t":"linear-gradient(to top, var(--tw-gradient-stops))","gradient-to-tr":"linear-gradient(to top right, var(--tw-gradient-stops))","gradient-to-r":"linear-gradient(to right, var(--tw-gradient-stops))","gradient-to-br":"linear-gradient(to bottom right, var(--tw-gradient-stops))","gradient-to-b":"linear-gradient(to bottom, var(--tw-gradient-stops))","gradient-to-bl":"linear-gradient(to bottom left, var(--tw-gradient-stops))","gradient-to-l":"linear-gradient(to left, var(--tw-gradient-stops))","gradient-to-tl":"linear-gradient(to top left, var(--tw-gradient-stops))"},backgroundOpacity:({theme:i})=>i("opacity"),backgroundPosition:{bottom:"bottom",center:"center",left:"left","left-bottom":"left bottom","left-top":"left top",right:"right","right-bottom":"right bottom","right-top":"right top",top:"top"},backgroundSize:{auto:"auto",cover:"cover",contain:"contain"},blur:{0:"0",none:"",sm:"4px",DEFAULT:"8px",md:"12px",lg:"16px",xl:"24px","2xl":"40px","3xl":"64px"},borderColor:({theme:i})=>({...i("colors"),DEFAULT:i("colors.gray.200","currentColor")}),borderOpacity:({theme:i})=>i("opacity"),borderRadius:{none:"0px",sm:"0.125rem",DEFAULT:"0.25rem",md:"0.375rem",lg:"0.5rem",xl:"0.75rem","2xl":"1rem","3xl":"1.5rem",full:"9999px"},borderSpacing:({theme:i})=>({...i("spacing")}),borderWidth:{DEFAULT:"1px",0:"0px",2:"2px",4:"4px",8:"8px"},boxShadow:{sm:"0 1px 2px 0 rgb(0 0 0 / 0.05)",DEFAULT:"0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",md:"0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",lg:"0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",xl:"0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)","2xl":"0 25px 50px -12px rgb(0 0 0 / 0.25)",inner:"inset 0 2px 4px 0 rgb(0 0 0 / 0.05)",none:"none"},boxShadowColor:({theme:i})=>i("colors"),brightness:{0:"0",50:".5",75:".75",90:".9",95:".95",100:"1",105:"1.05",110:"1.1",125:"1.25",150:"1.5",200:"2"},caretColor:({theme:i})=>i("colors"),colors:({colors:i})=>({inherit:i.inherit,current:i.current,transparent:i.transparent,black:i.black,white:i.white,slate:i.slate,gray:i.gray,zinc:i.zinc,neutral:i.neutral,stone:i.stone,red:i.red,orange:i.orange,amber:i.amber,yellow:i.yellow,lime:i.lime,green:i.green,emerald:i.emerald,teal:i.teal,cyan:i.cyan,sky:i.sky,blue:i.blue,indigo:i.indigo,violet:i.violet,purple:i.purple,fuchsia:i.fuchsia,pink:i.pink,rose:i.rose}),columns:{auto:"auto",1:"1",2:"2",3:"3",4:"4",5:"5",6:"6",7:"7",8:"8",9:"9",10:"10",11:"11",12:"12","3xs":"16rem","2xs":"18rem",xs:"20rem",sm:"24rem",md:"28rem",lg:"32rem",xl:"36rem","2xl":"42rem","3xl":"48rem","4xl":"56rem","5xl":"64rem","6xl":"72rem","7xl":"80rem"},container:{},content:{none:"none"},contrast:{0:"0",50:".5",75:".75",100:"1",125:"1.25",150:"1.5",200:"2"},cursor:{auto:"auto",default:"default",pointer:"pointer",wait:"wait",text:"text",move:"move",help:"help","not-allowed":"not-allowed",none:"none","context-menu":"context-menu",progress:"progress",cell:"cell",crosshair:"crosshair","vertical-text":"vertical-text",alias:"alias",copy:"copy","no-drop":"no-drop",grab:"grab",grabbing:"grabbing","all-scroll":"all-scroll","col-resize":"col-resize","row-resize":"row-resize","n-resize":"n-resize","e-resize":"e-resize","s-resize":"s-resize","w-resize":"w-resize","ne-resize":"ne-resize","nw-resize":"nw-resize","se-resize":"se-resize","sw-resize":"sw-resize","ew-resize":"ew-resize","ns-resize":"ns-resize","nesw-resize":"nesw-resize","nwse-resize":"nwse-resize","zoom-in":"zoom-in","zoom-out":"zoom-out"},divideColor:({theme:i})=>i("borderColor"),divideOpacity:({theme:i})=>i("borderOpacity"),divideWidth:({theme:i})=>i("borderWidth"),dropShadow:{sm:"0 1px 1px rgb(0 0 0 / 0.05)",DEFAULT:["0 1px 2px rgb(0 0 0 / 0.1)","0 1px 1px rgb(0 0 0 / 0.06)"],md:["0 4px 3px rgb(0 0 0 / 0.07)","0 2px 2px rgb(0 0 0 / 0.06)"],lg:["0 10px 8px rgb(0 0 0 / 0.04)","0 4px 3px rgb(0 0 0 / 0.1)"],xl:["0 20px 13px rgb(0 0 0 / 0.03)","0 8px 5px rgb(0 0 0 / 0.08)"],"2xl":"0 25px 25px rgb(0 0 0 / 0.15)",none:"0 0 #0000"},fill:({theme:i})=>({none:"none",...i("colors")}),flex:{1:"1 1 0%",auto:"1 1 auto",initial:"0 1 auto",none:"none"},flexBasis:({theme:i})=>({auto:"auto",...i("spacing"),"1/2":"50%","1/3":"33.333333%","2/3":"66.666667%","1/4":"25%","2/4":"50%","3/4":"75%","1/5":"20%","2/5":"40%","3/5":"60%","4/5":"80%","1/6":"16.666667%","2/6":"33.333333%","3/6":"50%","4/6":"66.666667%","5/6":"83.333333%","1/12":"8.333333%","2/12":"16.666667%","3/12":"25%","4/12":"33.333333%","5/12":"41.666667%","6/12":"50%","7/12":"58.333333%","8/12":"66.666667%","9/12":"75%","10/12":"83.333333%","11/12":"91.666667%",full:"100%"}),flexGrow:{0:"0",DEFAULT:"1"},flexShrink:{0:"0",DEFAULT:"1"},fontFamily:{sans:["ui-sans-serif","system-ui","sans-serif",'"Apple Color Emoji"','"Segoe UI Emoji"','"Segoe UI Symbol"','"Noto Color Emoji"'],serif:["ui-serif","Georgia","Cambria",'"Times New Roman"',"Times","serif"],mono:["ui-monospace","SFMono-Regular","Menlo","Monaco","Consolas",'"Liberation Mono"','"Courier New"',"monospace"]},fontSize:{xs:["0.75rem",{lineHeight:"1rem"}],sm:["0.875rem",{lineHeight:"1.25rem"}],base:["1rem",{lineHeight:"1.5rem"}],lg:["1.125rem",{lineHeight:"1.75rem"}],xl:["1.25rem",{lineHeight:"1.75rem"}],"2xl":["1.5rem",{lineHeight:"2rem"}],"3xl":["1.875rem",{lineHeight:"2.25rem"}],"4xl":["2.25rem",{lineHeight:"2.5rem"}],"5xl":["3rem",{lineHeight:"1"}],"6xl":["3.75rem",{lineHeight:"1"}],"7xl":["4.5rem",{lineHeight:"1"}],"8xl":["6rem",{lineHeight:"1"}],"9xl":["8rem",{lineHeight:"1"}]},fontWeight:{thin:"100",extralight:"200",light:"300",normal:"400",medium:"500",semibold:"600",bold:"700",extrabold:"800",black:"900"},gap:({theme:i})=>i("spacing"),gradientColorStops:({theme:i})=>i("colors"),gradientColorStopPositions:{"0%":"0%","5%":"5%","10%":"10%","15%":"15%","20%":"20%","25%":"25%","30%":"30%","35%":"35%","40%":"40%","45%":"45%","50%":"50%","55%":"55%","60%":"60%","65%":"65%","70%":"70%","75%":"75%","80%":"80%","85%":"85%","90%":"90%","95%":"95%","100%":"100%"},grayscale:{0:"0",DEFAULT:"100%"},gridAutoColumns:{auto:"auto",min:"min-content",max:"max-content",fr:"minmax(0, 1fr)"},gridAutoRows:{auto:"auto",min:"min-content",max:"max-content",fr:"minmax(0, 1fr)"},gridColumn:{auto:"auto","span-1":"span 1 / span 1","span-2":"span 2 / span 2","span-3":"span 3 / span 3","span-4":"span 4 / span 4","span-5":"span 5 / span 5","span-6":"span 6 / span 6","span-7":"span 7 / span 7","span-8":"span 8 / span 8","span-9":"span 9 / span 9","span-10":"span 10 / span 10","span-11":"span 11 / span 11","span-12":"span 12 / span 12","span-full":"1 / -1"},gridColumnEnd:{auto:"auto",1:"1",2:"2",3:"3",4:"4",5:"5",6:"6",7:"7",8:"8",9:"9",10:"10",11:"11",12:"12",13:"13"},gridColumnStart:{auto:"auto",1:"1",2:"2",3:"3",4:"4",5:"5",6:"6",7:"7",8:"8",9:"9",10:"10",11:"11",12:"12",13:"13"},gridRow:{auto:"auto","span-1":"span 1 / span 1","span-2":"span 2 / span 2","span-3":"span 3 / span 3","span-4":"span 4 / span 4","span-5":"span 5 / span 5","span-6":"span 6 / span 6","span-7":"span 7 / span 7","span-8":"span 8 / span 8","span-9":"span 9 / span 9","span-10":"span 10 / span 10","span-11":"span 11 / span 11","span-12":"span 12 / span 12","span-full":"1 / -1"},gridRowEnd:{auto:"auto",1:"1",2:"2",3:"3",4:"4",5:"5",6:"6",7:"7",8:"8",9:"9",10:"10",11:"11",12:"12",13:"13"},gridRowStart:{auto:"auto",1:"1",2:"2",3:"3",4:"4",5:"5",6:"6",7:"7",8:"8",9:"9",10:"10",11:"11",12:"12",13:"13"},gridTemplateColumns:{none:"none",subgrid:"subgrid",1:"repeat(1, minmax(0, 1fr))",2:"repeat(2, minmax(0, 1fr))",3:"repeat(3, minmax(0, 1fr))",4:"repeat(4, minmax(0, 1fr))",5:"repeat(5, minmax(0, 1fr))",6:"repeat(6, minmax(0, 1fr))",7:"repeat(7, minmax(0, 1fr))",8:"repeat(8, minmax(0, 1fr))",9:"repeat(9, minmax(0, 1fr))",10:"repeat(10, minmax(0, 1fr))",11:"repeat(11, minmax(0, 1fr))",12:"repeat(12, minmax(0, 1fr))"},gridTemplateRows:{none:"none",subgrid:"subgrid",1:"repeat(1, minmax(0, 1fr))",2:"repeat(2, minmax(0, 1fr))",3:"repeat(3, minmax(0, 1fr))",4:"repeat(4, minmax(0, 1fr))",5:"repeat(5, minmax(0, 1fr))",6:"repeat(6, minmax(0, 1fr))",7:"repeat(7, minmax(0, 1fr))",8:"repeat(8, minmax(0, 1fr))",9:"repeat(9, minmax(0, 1fr))",10:"repeat(10, minmax(0, 1fr))",11:"repeat(11, minmax(0, 1fr))",12:"repeat(12, minmax(0, 1fr))"},height:({theme:i})=>({auto:"auto",...i("spacing"),"1/2":"50%","1/3":"33.333333%","2/3":"66.666667%","1/4":"25%","2/4":"50%","3/4":"75%","1/5":"20%","2/5":"40%","3/5":"60%","4/5":"80%","1/6":"16.666667%","2/6":"33.333333%","3/6":"50%","4/6":"66.666667%","5/6":"83.333333%",full:"100%",screen:"100vh",svh:"100svh",lvh:"100lvh",dvh:"100dvh",min:"min-content",max:"max-content",fit:"fit-content"}),hueRotate:{0:"0deg",15:"15deg",30:"30deg",60:"60deg",90:"90deg",180:"180deg"},inset:({theme:i})=>({auto:"auto",...i("spacing"),"1/2":"50%","1/3":"33.333333%","2/3":"66.666667%","1/4":"25%","2/4":"50%","3/4":"75%",full:"100%"}),invert:{0:"0",DEFAULT:"100%"},keyframes:{spin:{to:{transform:"rotate(360deg)"}},ping:{"75%, 100%":{transform:"scale(2)",opacity:"0"}},pulse:{"50%":{opacity:".5"}},bounce:{"0%, 100%":{transform:"translateY(-25%)",animationTimingFunction:"cubic-bezier(0.8,0,1,1)"},"50%":{transform:"none",animationTimingFunction:"cubic-bezier(0,0,0.2,1)"}}},letterSpacing:{tighter:"-0.05em",tight:"-0.025em",normal:"0em",wide:"0.025em",wider:"0.05em",widest:"0.1em"},lineHeight:{none:"1",tight:"1.25",snug:"1.375",normal:"1.5",relaxed:"1.625",loose:"2",3:".75rem",4:"1rem",5:"1.25rem",6:"1.5rem",7:"1.75rem",8:"2rem",9:"2.25rem",10:"2.5rem"},listStyleType:{none:"none",disc:"disc",decimal:"decimal"},listStyleImage:{none:"none"},margin:({theme:i})=>({auto:"auto",...i("spacing")}),lineClamp:{1:"1",2:"2",3:"3",4:"4",5:"5",6:"6"},maxHeight:({theme:i})=>({...i("spacing"),none:"none",full:"100%",screen:"100vh",svh:"100svh",lvh:"100lvh",dvh:"100dvh",min:"min-content",max:"max-content",fit:"fit-content"}),maxWidth:({theme:i,breakpoints:e})=>({...i("spacing"),none:"none",xs:"20rem",sm:"24rem",md:"28rem",lg:"32rem",xl:"36rem","2xl":"42rem","3xl":"48rem","4xl":"56rem","5xl":"64rem","6xl":"72rem","7xl":"80rem",full:"100%",min:"min-content",max:"max-content",fit:"fit-content",prose:"65ch",...e(i("screens"))}),minHeight:({theme:i})=>({...i("spacing"),full:"100%",screen:"100vh",svh:"100svh",lvh:"100lvh",dvh:"100dvh",min:"min-content",max:"max-content",fit:"fit-content"}),minWidth:({theme:i})=>({...i("spacing"),full:"100%",min:"min-content",max:"max-content",fit:"fit-content"}),objectPosition:{bottom:"bottom",center:"center",left:"left","left-bottom":"left bottom","left-top":"left top",right:"right","right-bottom":"right bottom","right-top":"right top",top:"top"},opacity:{0:"0",5:"0.05",10:"0.1",15:"0.15",20:"0.2",25:"0.25",30:"0.3",35:"0.35",40:"0.4",45:"0.45",50:"0.5",55:"0.55",60:"0.6",65:"0.65",70:"0.7",75:"0.75",80:"0.8",85:"0.85",90:"0.9",95:"0.95",100:"1"},order:{first:"-9999",last:"9999",none:"0",1:"1",2:"2",3:"3",4:"4",5:"5",6:"6",7:"7",8:"8",9:"9",10:"10",11:"11",12:"12"},outlineColor:({theme:i})=>i("colors"),outlineOffset:{0:"0px",1:"1px",2:"2px",4:"4px",8:"8px"},outlineWidth:{0:"0px",1:"1px",2:"2px",4:"4px",8:"8px"},padding:({theme:i})=>i("spacing"),placeholderColor:({theme:i})=>i("colors"),placeholderOpacity:({theme:i})=>i("opacity"),ringColor:({theme:i})=>({DEFAULT:i("colors.blue.500","#3b82f6"),...i("colors")}),ringOffsetColor:({theme:i})=>i("colors"),ringOffsetWidth:{0:"0px",1:"1px",2:"2px",4:"4px",8:"8px"},ringOpacity:({theme:i})=>({DEFAULT:"0.5",...i("opacity")}),ringWidth:{DEFAULT:"3px",0:"0px",1:"1px",2:"2px",4:"4px",8:"8px"},rotate:{0:"0deg",1:"1deg",2:"2deg",3:"3deg",6:"6deg",12:"12deg",45:"45deg",90:"90deg",180:"180deg"},saturate:{0:"0",50:".5",100:"1",150:"1.5",200:"2"},scale:{0:"0",50:".5",75:".75",90:".9",95:".95",100:"1",105:"1.05",110:"1.1",125:"1.25",150:"1.5"},screens:{sm:"640px",md:"768px",lg:"1024px",xl:"1280px","2xl":"1536px"},scrollMargin:({theme:i})=>({...i("spacing")}),scrollPadding:({theme:i})=>i("spacing"),sepia:{0:"0",DEFAULT:"100%"},skew:{0:"0deg",1:"1deg",2:"2deg",3:"3deg",6:"6deg",12:"12deg"},space:({theme:i})=>({...i("spacing")}),spacing:{px:"1px",0:"0px",.5:"0.125rem",1:"0.25rem",1.5:"0.375rem",2:"0.5rem",2.5:"0.625rem",3:"0.75rem",3.5:"0.875rem",4:"1rem",5:"1.25rem",6:"1.5rem",7:"1.75rem",8:"2rem",9:"2.25rem",10:"2.5rem",11:"2.75rem",12:"3rem",14:"3.5rem",16:"4rem",20:"5rem",24:"6rem",28:"7rem",32:"8rem",36:"9rem",40:"10rem",44:"11rem",48:"12rem",52:"13rem",56:"14rem",60:"15rem",64:"16rem",72:"18rem",80:"20rem",96:"24rem"},stroke:({theme:i})=>({none:"none",...i("colors")}),strokeWidth:{0:"0",1:"1",2:"2"},supports:{},data:{},textColor:({theme:i})=>i("colors"),textDecorationColor:({theme:i})=>i("colors"),textDecorationThickness:{auto:"auto","from-font":"from-font",0:"0px",1:"1px",2:"2px",4:"4px",8:"8px"},textIndent:({theme:i})=>({...i("spacing")}),textOpacity:({theme:i})=>i("opacity"),textUnderlineOffset:{auto:"auto",0:"0px",1:"1px",2:"2px",4:"4px",8:"8px"},transformOrigin:{center:"center",top:"top","top-right":"top right",right:"right","bottom-right":"bottom right",bottom:"bottom","bottom-left":"bottom left",left:"left","top-left":"top left"},transitionDelay:{0:"0s",75:"75ms",100:"100ms",150:"150ms",200:"200ms",300:"300ms",500:"500ms",700:"700ms",1e3:"1000ms"},transitionDuration:{DEFAULT:"150ms",0:"0s",75:"75ms",100:"100ms",150:"150ms",200:"200ms",300:"300ms",500:"500ms",700:"700ms",1e3:"1000ms"},transitionProperty:{none:"none",all:"all",DEFAULT:"color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter",colors:"color, background-color, border-color, text-decoration-color, fill, stroke",opacity:"opacity",shadow:"box-shadow",transform:"transform"},transitionTimingFunction:{DEFAULT:"cubic-bezier(0.4, 0, 0.2, 1)",linear:"linear",in:"cubic-bezier(0.4, 0, 1, 1)",out:"cubic-bezier(0, 0, 0.2, 1)","in-out":"cubic-bezier(0.4, 0, 0.2, 1)"},translate:({theme:i})=>({...i("spacing"),"1/2":"50%","1/3":"33.333333%","2/3":"66.666667%","1/4":"25%","2/4":"50%","3/4":"75%",full:"100%"}),size:({theme:i})=>({auto:"auto",...i("spacing"),"1/2":"50%","1/3":"33.333333%","2/3":"66.666667%","1/4":"25%","2/4":"50%","3/4":"75%","1/5":"20%","2/5":"40%","3/5":"60%","4/5":"80%","1/6":"16.666667%","2/6":"33.333333%","3/6":"50%","4/6":"66.666667%","5/6":"83.333333%","1/12":"8.333333%","2/12":"16.666667%","3/12":"25%","4/12":"33.333333%","5/12":"41.666667%","6/12":"50%","7/12":"58.333333%","8/12":"66.666667%","9/12":"75%","10/12":"83.333333%","11/12":"91.666667%",full:"100%",min:"min-content",max:"max-content",fit:"fit-content"}),width:({theme:i})=>({auto:"auto",...i("spacing"),"1/2":"50%","1/3":"33.333333%","2/3":"66.666667%","1/4":"25%","2/4":"50%","3/4":"75%","1/5":"20%","2/5":"40%","3/5":"60%","4/5":"80%","1/6":"16.666667%","2/6":"33.333333%","3/6":"50%","4/6":"66.666667%","5/6":"83.333333%","1/12":"8.333333%","2/12":"16.666667%","3/12":"25%","4/12":"33.333333%","5/12":"41.666667%","6/12":"50%","7/12":"58.333333%","8/12":"66.666667%","9/12":"75%","10/12":"83.333333%","11/12":"91.666667%",full:"100%",screen:"100vw",svw:"100svw",lvw:"100lvw",dvw:"100dvw",min:"min-content",max:"max-content",fit:"fit-content"}),willChange:{auto:"auto",scroll:"scroll-position",contents:"contents",transform:"transform"},zIndex:{auto:"auto",0:"0",10:"10",20:"20",30:"30",40:"40",50:"50"}},plugins:[]}});function vi(i){let e=(i?.presets??[Ju.default]).slice().reverse().flatMap(n=>vi(n instanceof Function?n():n)),t={respectDefaultRingColorOpacity:{theme:{ringColor:({theme:n})=>({DEFAULT:"#3b82f67f",...n("colors")})}},disableColorOpacityUtilitiesByDefault:{corePlugins:{backgroundOpacity:!1,borderOpacity:!1,divideOpacity:!1,placeholderOpacity:!1,ringOpacity:!1,textOpacity:!1}}},r=Object.keys(t).filter(n=>Z(i,n)).map(n=>t[n]);return[i,...r,...e]}var Ju,Xu=C(()=>{l();Ju=X(bi());ze()});var Ku={};_e(Ku,{default:()=>hr});function hr(...i){let[,...e]=vi(i[0]);return ds([...i,...e])}var hs=C(()=>{l();Yu();Xu()});var Zu={};_e(Zu,{default:()=>ee});var ee,wt=C(()=>{l();ee={resolve:i=>i,extname:i=>"."+i.split(".").pop()}});function xi(i){return typeof i=="object"&&i!==null}function r0(i){return Object.keys(i).length===0}function ef(i){return typeof i=="string"||i instanceof String}function ms(i){return xi(i)&&i.config===void 0&&!r0(i)?null:xi(i)&&i.config!==void 0&&ef(i.config)?ee.resolve(i.config):xi(i)&&i.config!==void 0&&xi(i.config)?null:ef(i)?ee.resolve(i):i0()}function i0(){for(let i of t0)try{let e=ee.resolve(i);return re.accessSync(e),e}catch(e){}return null}var t0,tf=C(()=>{l();je();wt();t0=["./tailwind.config.js","./tailwind.config.cjs","./tailwind.config.mjs","./tailwind.config.ts","./tailwind.config.cts","./tailwind.config.mts"]});var rf={};_e(rf,{default:()=>gs});var gs,ys=C(()=>{l();gs={parse:i=>({href:i})}});var ws=v(()=>{l()});var ki=v((VE,af)=>{l();"use strict";var nf=(ci(),yu),sf=ws(),Ot=class extends Error{constructor(e,t,r,n,a,s){super(e);this.name="CssSyntaxError",this.reason=e,a&&(this.file=a),n&&(this.source=n),s&&(this.plugin=s),typeof t!="undefined"&&typeof r!="undefined"&&(typeof t=="number"?(this.line=t,this.column=r):(this.line=t.line,this.column=t.column,this.endLine=r.line,this.endColumn=r.column)),this.setMessage(),Error.captureStackTrace&&Error.captureStackTrace(this,Ot)}setMessage(){this.message=this.plugin?this.plugin+": ":"",this.message+=this.file?this.file:"",typeof this.line!="undefined"&&(this.message+=":"+this.line+":"+this.column),this.message+=": "+this.reason}showSourceCode(e){if(!this.source)return"";let t=this.source;e==null&&(e=nf.isColorSupported),sf&&e&&(t=sf(t));let r=t.split(/\r?\n/),n=Math.max(this.line-3,0),a=Math.min(this.line+2,r.length),s=String(a).length,o,u;if(e){let{bold:c,red:f,gray:d}=nf.createColors(!0);o=p=>c(f(p)),u=p=>d(p)}else o=u=c=>c;return r.slice(n,a).map((c,f)=>{let d=n+1+f,p=" "+(" "+d).slice(-s)+" | ";if(d===this.line){let m=u(p.replace(/\d/g," "))+c.slice(0,this.column-1).replace(/[^\t]/g," ");return o(">")+u(p)+c+` + `+m+o("^")}return" "+u(p)+c}).join(` +`)}toString(){let e=this.showSourceCode();return e&&(e=` + +`+e+` +`),this.name+": "+this.message+e}};af.exports=Ot;Ot.default=Ot});var Si=v((UE,bs)=>{l();"use strict";bs.exports.isClean=Symbol("isClean");bs.exports.my=Symbol("my")});var vs=v((WE,lf)=>{l();"use strict";var of={colon:": ",indent:" ",beforeDecl:` +`,beforeRule:` +`,beforeOpen:" ",beforeClose:` +`,beforeComment:` +`,after:` +`,emptyBody:"",commentLeft:" ",commentRight:" ",semicolon:!1};function n0(i){return i[0].toUpperCase()+i.slice(1)}var Ci=class{constructor(e){this.builder=e}stringify(e,t){if(!this[e.type])throw new Error("Unknown AST node type "+e.type+". Maybe you need to change PostCSS stringifier.");this[e.type](e,t)}document(e){this.body(e)}root(e){this.body(e),e.raws.after&&this.builder(e.raws.after)}comment(e){let t=this.raw(e,"left","commentLeft"),r=this.raw(e,"right","commentRight");this.builder("/*"+t+e.text+r+"*/",e)}decl(e,t){let r=this.raw(e,"between","colon"),n=e.prop+r+this.rawValue(e,"value");e.important&&(n+=e.raws.important||" !important"),t&&(n+=";"),this.builder(n,e)}rule(e){this.block(e,this.rawValue(e,"selector")),e.raws.ownSemicolon&&this.builder(e.raws.ownSemicolon,e,"end")}atrule(e,t){let r="@"+e.name,n=e.params?this.rawValue(e,"params"):"";if(typeof e.raws.afterName!="undefined"?r+=e.raws.afterName:n&&(r+=" "),e.nodes)this.block(e,r+n);else{let a=(e.raws.between||"")+(t?";":"");this.builder(r+n+a,e)}}body(e){let t=e.nodes.length-1;for(;t>0&&e.nodes[t].type==="comment";)t-=1;let r=this.raw(e,"semicolon");for(let n=0;n{if(n=u.raws[t],typeof n!="undefined")return!1})}return typeof n=="undefined"&&(n=of[r]),s.rawCache[r]=n,n}rawSemicolon(e){let t;return e.walk(r=>{if(r.nodes&&r.nodes.length&&r.last.type==="decl"&&(t=r.raws.semicolon,typeof t!="undefined"))return!1}),t}rawEmptyBody(e){let t;return e.walk(r=>{if(r.nodes&&r.nodes.length===0&&(t=r.raws.after,typeof t!="undefined"))return!1}),t}rawIndent(e){if(e.raws.indent)return e.raws.indent;let t;return e.walk(r=>{let n=r.parent;if(n&&n!==e&&n.parent&&n.parent===e&&typeof r.raws.before!="undefined"){let a=r.raws.before.split(` +`);return t=a[a.length-1],t=t.replace(/\S/g,""),!1}}),t}rawBeforeComment(e,t){let r;return e.walkComments(n=>{if(typeof n.raws.before!="undefined")return r=n.raws.before,r.includes(` +`)&&(r=r.replace(/[^\n]+$/,"")),!1}),typeof r=="undefined"?r=this.raw(t,null,"beforeDecl"):r&&(r=r.replace(/\S/g,"")),r}rawBeforeDecl(e,t){let r;return e.walkDecls(n=>{if(typeof n.raws.before!="undefined")return r=n.raws.before,r.includes(` +`)&&(r=r.replace(/[^\n]+$/,"")),!1}),typeof r=="undefined"?r=this.raw(t,null,"beforeRule"):r&&(r=r.replace(/\S/g,"")),r}rawBeforeRule(e){let t;return e.walk(r=>{if(r.nodes&&(r.parent!==e||e.first!==r)&&typeof r.raws.before!="undefined")return t=r.raws.before,t.includes(` +`)&&(t=t.replace(/[^\n]+$/,"")),!1}),t&&(t=t.replace(/\S/g,"")),t}rawBeforeClose(e){let t;return e.walk(r=>{if(r.nodes&&r.nodes.length>0&&typeof r.raws.after!="undefined")return t=r.raws.after,t.includes(` +`)&&(t=t.replace(/[^\n]+$/,"")),!1}),t&&(t=t.replace(/\S/g,"")),t}rawBeforeOpen(e){let t;return e.walk(r=>{if(r.type!=="decl"&&(t=r.raws.between,typeof t!="undefined"))return!1}),t}rawColon(e){let t;return e.walkDecls(r=>{if(typeof r.raws.between!="undefined")return t=r.raws.between.replace(/[^\s:]/g,""),!1}),t}beforeAfter(e,t){let r;e.type==="decl"?r=this.raw(e,null,"beforeDecl"):e.type==="comment"?r=this.raw(e,null,"beforeComment"):t==="before"?r=this.raw(e,null,"beforeRule"):r=this.raw(e,null,"beforeClose");let n=e.parent,a=0;for(;n&&n.type!=="root";)a+=1,n=n.parent;if(r.includes(` +`)){let s=this.raw(e,null,"indent");if(s.length)for(let o=0;o{l();"use strict";var s0=vs();function xs(i,e){new s0(e).stringify(i)}uf.exports=xs;xs.default=xs});var gr=v((HE,ff)=>{l();"use strict";var{isClean:Ai,my:a0}=Si(),o0=ki(),l0=vs(),u0=mr();function ks(i,e){let t=new i.constructor;for(let r in i){if(!Object.prototype.hasOwnProperty.call(i,r)||r==="proxyCache")continue;let n=i[r],a=typeof n;r==="parent"&&a==="object"?e&&(t[r]=e):r==="source"?t[r]=n:Array.isArray(n)?t[r]=n.map(s=>ks(s,t)):(a==="object"&&n!==null&&(n=ks(n)),t[r]=n)}return t}var _i=class{constructor(e={}){this.raws={},this[Ai]=!1,this[a0]=!0;for(let t in e)if(t==="nodes"){this.nodes=[];for(let r of e[t])typeof r.clone=="function"?this.append(r.clone()):this.append(r)}else this[t]=e[t]}error(e,t={}){if(this.source){let{start:r,end:n}=this.rangeBy(t);return this.source.input.error(e,{line:r.line,column:r.column},{line:n.line,column:n.column},t)}return new o0(e)}warn(e,t,r){let n={node:this};for(let a in r)n[a]=r[a];return e.warn(t,n)}remove(){return this.parent&&this.parent.removeChild(this),this.parent=void 0,this}toString(e=u0){e.stringify&&(e=e.stringify);let t="";return e(this,r=>{t+=r}),t}assign(e={}){for(let t in e)this[t]=e[t];return this}clone(e={}){let t=ks(this);for(let r in e)t[r]=e[r];return t}cloneBefore(e={}){let t=this.clone(e);return this.parent.insertBefore(this,t),t}cloneAfter(e={}){let t=this.clone(e);return this.parent.insertAfter(this,t),t}replaceWith(...e){if(this.parent){let t=this,r=!1;for(let n of e)n===this?r=!0:r?(this.parent.insertAfter(t,n),t=n):this.parent.insertBefore(t,n);r||this.remove()}return this}next(){if(!this.parent)return;let e=this.parent.index(this);return this.parent.nodes[e+1]}prev(){if(!this.parent)return;let e=this.parent.index(this);return this.parent.nodes[e-1]}before(e){return this.parent.insertBefore(this,e),this}after(e){return this.parent.insertAfter(this,e),this}root(){let e=this;for(;e.parent&&e.parent.type!=="document";)e=e.parent;return e}raw(e,t){return new l0().raw(this,e,t)}cleanRaws(e){delete this.raws.before,delete this.raws.after,e||delete this.raws.between}toJSON(e,t){let r={},n=t==null;t=t||new Map;let a=0;for(let s in this){if(!Object.prototype.hasOwnProperty.call(this,s)||s==="parent"||s==="proxyCache")continue;let o=this[s];if(Array.isArray(o))r[s]=o.map(u=>typeof u=="object"&&u.toJSON?u.toJSON(null,t):u);else if(typeof o=="object"&&o.toJSON)r[s]=o.toJSON(null,t);else if(s==="source"){let u=t.get(o.input);u==null&&(u=a,t.set(o.input,a),a++),r[s]={inputId:u,start:o.start,end:o.end}}else r[s]=o}return n&&(r.inputs=[...t.keys()].map(s=>s.toJSON())),r}positionInside(e){let t=this.toString(),r=this.source.start.column,n=this.source.start.line;for(let a=0;ae.root().toProxy():e[t]}}}toProxy(){return this.proxyCache||(this.proxyCache=new Proxy(this,this.getProxyProcessor())),this.proxyCache}addToError(e){if(e.postcssNode=this,e.stack&&this.source&&/\n\s{4}at /.test(e.stack)){let t=this.source;e.stack=e.stack.replace(/\n\s{4}at /,`$&${t.input.from}:${t.start.line}:${t.start.column}$&`)}return e}markDirty(){if(this[Ai]){this[Ai]=!1;let e=this;for(;e=e.parent;)e[Ai]=!1}}get proxyOf(){return this}};ff.exports=_i;_i.default=_i});var yr=v((YE,cf)=>{l();"use strict";var f0=gr(),Oi=class extends f0{constructor(e){e&&typeof e.value!="undefined"&&typeof e.value!="string"&&(e={...e,value:String(e.value)});super(e);this.type="decl"}get variable(){return this.prop.startsWith("--")||this.prop[0]==="$"}};cf.exports=Oi;Oi.default=Oi});var Ss=v((QE,pf)=>{l();pf.exports=function(i,e){return{generate:()=>{let t="";return i(e,r=>{t+=r}),[t]}}}});var wr=v((JE,df)=>{l();"use strict";var c0=gr(),Ei=class extends c0{constructor(e){super(e);this.type="comment"}};df.exports=Ei;Ei.default=Ei});var it=v((XE,kf)=>{l();"use strict";var{isClean:hf,my:mf}=Si(),gf=yr(),yf=wr(),p0=gr(),wf,Cs,As,bf;function vf(i){return i.map(e=>(e.nodes&&(e.nodes=vf(e.nodes)),delete e.source,e))}function xf(i){if(i[hf]=!1,i.proxyOf.nodes)for(let e of i.proxyOf.nodes)xf(e)}var be=class extends p0{push(e){return e.parent=this,this.proxyOf.nodes.push(e),this}each(e){if(!this.proxyOf.nodes)return;let t=this.getIterator(),r,n;for(;this.indexes[t]{let n;try{n=e(t,r)}catch(a){throw t.addToError(a)}return n!==!1&&t.walk&&(n=t.walk(e)),n})}walkDecls(e,t){return t?e instanceof RegExp?this.walk((r,n)=>{if(r.type==="decl"&&e.test(r.prop))return t(r,n)}):this.walk((r,n)=>{if(r.type==="decl"&&r.prop===e)return t(r,n)}):(t=e,this.walk((r,n)=>{if(r.type==="decl")return t(r,n)}))}walkRules(e,t){return t?e instanceof RegExp?this.walk((r,n)=>{if(r.type==="rule"&&e.test(r.selector))return t(r,n)}):this.walk((r,n)=>{if(r.type==="rule"&&r.selector===e)return t(r,n)}):(t=e,this.walk((r,n)=>{if(r.type==="rule")return t(r,n)}))}walkAtRules(e,t){return t?e instanceof RegExp?this.walk((r,n)=>{if(r.type==="atrule"&&e.test(r.name))return t(r,n)}):this.walk((r,n)=>{if(r.type==="atrule"&&r.name===e)return t(r,n)}):(t=e,this.walk((r,n)=>{if(r.type==="atrule")return t(r,n)}))}walkComments(e){return this.walk((t,r)=>{if(t.type==="comment")return e(t,r)})}append(...e){for(let t of e){let r=this.normalize(t,this.last);for(let n of r)this.proxyOf.nodes.push(n)}return this.markDirty(),this}prepend(...e){e=e.reverse();for(let t of e){let r=this.normalize(t,this.first,"prepend").reverse();for(let n of r)this.proxyOf.nodes.unshift(n);for(let n in this.indexes)this.indexes[n]=this.indexes[n]+r.length}return this.markDirty(),this}cleanRaws(e){if(super.cleanRaws(e),this.nodes)for(let t of this.nodes)t.cleanRaws(e)}insertBefore(e,t){let r=this.index(e),n=r===0?"prepend":!1,a=this.normalize(t,this.proxyOf.nodes[r],n).reverse();r=this.index(e);for(let o of a)this.proxyOf.nodes.splice(r,0,o);let s;for(let o in this.indexes)s=this.indexes[o],r<=s&&(this.indexes[o]=s+a.length);return this.markDirty(),this}insertAfter(e,t){let r=this.index(e),n=this.normalize(t,this.proxyOf.nodes[r]).reverse();r=this.index(e);for(let s of n)this.proxyOf.nodes.splice(r+1,0,s);let a;for(let s in this.indexes)a=this.indexes[s],r=e&&(this.indexes[r]=t-1);return this.markDirty(),this}removeAll(){for(let e of this.proxyOf.nodes)e.parent=void 0;return this.proxyOf.nodes=[],this.markDirty(),this}replaceValues(e,t,r){return r||(r=t,t={}),this.walkDecls(n=>{t.props&&!t.props.includes(n.prop)||t.fast&&!n.value.includes(t.fast)||(n.value=n.value.replace(e,r))}),this.markDirty(),this}every(e){return this.nodes.every(e)}some(e){return this.nodes.some(e)}index(e){return typeof e=="number"?e:(e.proxyOf&&(e=e.proxyOf),this.proxyOf.nodes.indexOf(e))}get first(){if(!!this.proxyOf.nodes)return this.proxyOf.nodes[0]}get last(){if(!!this.proxyOf.nodes)return this.proxyOf.nodes[this.proxyOf.nodes.length-1]}normalize(e,t){if(typeof e=="string")e=vf(wf(e).nodes);else if(Array.isArray(e)){e=e.slice(0);for(let n of e)n.parent&&n.parent.removeChild(n,"ignore")}else if(e.type==="root"&&this.type!=="document"){e=e.nodes.slice(0);for(let n of e)n.parent&&n.parent.removeChild(n,"ignore")}else if(e.type)e=[e];else if(e.prop){if(typeof e.value=="undefined")throw new Error("Value field is missed in node creation");typeof e.value!="string"&&(e.value=String(e.value)),e=[new gf(e)]}else if(e.selector)e=[new Cs(e)];else if(e.name)e=[new As(e)];else if(e.text)e=[new yf(e)];else throw new Error("Unknown node type in node creation");return e.map(n=>(n[mf]||be.rebuild(n),n=n.proxyOf,n.parent&&n.parent.removeChild(n),n[hf]&&xf(n),typeof n.raws.before=="undefined"&&t&&typeof t.raws.before!="undefined"&&(n.raws.before=t.raws.before.replace(/\S/g,"")),n.parent=this.proxyOf,n))}getProxyProcessor(){return{set(e,t,r){return e[t]===r||(e[t]=r,(t==="name"||t==="params"||t==="selector")&&e.markDirty()),!0},get(e,t){return t==="proxyOf"?e:e[t]?t==="each"||typeof t=="string"&&t.startsWith("walk")?(...r)=>e[t](...r.map(n=>typeof n=="function"?(a,s)=>n(a.toProxy(),s):n)):t==="every"||t==="some"?r=>e[t]((n,...a)=>r(n.toProxy(),...a)):t==="root"?()=>e.root().toProxy():t==="nodes"?e.nodes.map(r=>r.toProxy()):t==="first"||t==="last"?e[t].toProxy():e[t]:e[t]}}}getIterator(){this.lastEach||(this.lastEach=0),this.indexes||(this.indexes={}),this.lastEach+=1;let e=this.lastEach;return this.indexes[e]=0,e}};be.registerParse=i=>{wf=i};be.registerRule=i=>{Cs=i};be.registerAtRule=i=>{As=i};be.registerRoot=i=>{bf=i};kf.exports=be;be.default=be;be.rebuild=i=>{i.type==="atrule"?Object.setPrototypeOf(i,As.prototype):i.type==="rule"?Object.setPrototypeOf(i,Cs.prototype):i.type==="decl"?Object.setPrototypeOf(i,gf.prototype):i.type==="comment"?Object.setPrototypeOf(i,yf.prototype):i.type==="root"&&Object.setPrototypeOf(i,bf.prototype),i[mf]=!0,i.nodes&&i.nodes.forEach(e=>{be.rebuild(e)})}});var Ti=v((KE,Af)=>{l();"use strict";var d0=it(),Sf,Cf,Et=class extends d0{constructor(e){super({type:"document",...e});this.nodes||(this.nodes=[])}toResult(e={}){return new Sf(new Cf,this,e).stringify()}};Et.registerLazyResult=i=>{Sf=i};Et.registerProcessor=i=>{Cf=i};Af.exports=Et;Et.default=Et});var _s=v((ZE,Of)=>{l();"use strict";var _f={};Of.exports=function(e){_f[e]||(_f[e]=!0,typeof console!="undefined"&&console.warn&&console.warn(e))}});var Os=v((eT,Ef)=>{l();"use strict";var Pi=class{constructor(e,t={}){if(this.type="warning",this.text=e,t.node&&t.node.source){let r=t.node.rangeBy(t);this.line=r.start.line,this.column=r.start.column,this.endLine=r.end.line,this.endColumn=r.end.column}for(let r in t)this[r]=t[r]}toString(){return this.node?this.node.error(this.text,{plugin:this.plugin,index:this.index,word:this.word}).message:this.plugin?this.plugin+": "+this.text:this.text}};Ef.exports=Pi;Pi.default=Pi});var Ii=v((tT,Tf)=>{l();"use strict";var h0=Os(),Di=class{constructor(e,t,r){this.processor=e,this.messages=[],this.root=t,this.opts=r,this.css=void 0,this.map=void 0}toString(){return this.css}warn(e,t={}){t.plugin||this.lastPlugin&&this.lastPlugin.postcssPlugin&&(t.plugin=this.lastPlugin.postcssPlugin);let r=new h0(e,t);return this.messages.push(r),r}warnings(){return this.messages.filter(e=>e.type==="warning")}get content(){return this.css}};Tf.exports=Di;Di.default=Di});var Rf=v((rT,qf)=>{l();"use strict";var Es="'".charCodeAt(0),Pf='"'.charCodeAt(0),qi="\\".charCodeAt(0),Df="/".charCodeAt(0),Ri=` +`.charCodeAt(0),br=" ".charCodeAt(0),Mi="\f".charCodeAt(0),Bi=" ".charCodeAt(0),Fi="\r".charCodeAt(0),m0="[".charCodeAt(0),g0="]".charCodeAt(0),y0="(".charCodeAt(0),w0=")".charCodeAt(0),b0="{".charCodeAt(0),v0="}".charCodeAt(0),x0=";".charCodeAt(0),k0="*".charCodeAt(0),S0=":".charCodeAt(0),C0="@".charCodeAt(0),Ni=/[\t\n\f\r "#'()/;[\\\]{}]/g,Li=/[\t\n\f\r !"#'():;@[\\\]{}]|\/(?=\*)/g,A0=/.[\n"'(/\\]/,If=/[\da-f]/i;qf.exports=function(e,t={}){let r=e.css.valueOf(),n=t.ignoreErrors,a,s,o,u,c,f,d,p,m,b,x=r.length,y=0,w=[],k=[];function S(){return y}function _(R){throw e.error("Unclosed "+R,y)}function E(){return k.length===0&&y>=x}function I(R){if(k.length)return k.pop();if(y>=x)return;let J=R?R.ignoreUnclosed:!1;switch(a=r.charCodeAt(y),a){case Ri:case br:case Bi:case Fi:case Mi:{s=y;do s+=1,a=r.charCodeAt(s);while(a===br||a===Ri||a===Bi||a===Fi||a===Mi);b=["space",r.slice(y,s)],y=s-1;break}case m0:case g0:case b0:case v0:case S0:case x0:case w0:{let fe=String.fromCharCode(a);b=[fe,fe,y];break}case y0:{if(p=w.length?w.pop()[1]:"",m=r.charCodeAt(y+1),p==="url"&&m!==Es&&m!==Pf&&m!==br&&m!==Ri&&m!==Bi&&m!==Mi&&m!==Fi){s=y;do{if(f=!1,s=r.indexOf(")",s+1),s===-1)if(n||J){s=y;break}else _("bracket");for(d=s;r.charCodeAt(d-1)===qi;)d-=1,f=!f}while(f);b=["brackets",r.slice(y,s+1),y,s],y=s}else s=r.indexOf(")",y+1),u=r.slice(y,s+1),s===-1||A0.test(u)?b=["(","(",y]:(b=["brackets",u,y,s],y=s);break}case Es:case Pf:{o=a===Es?"'":'"',s=y;do{if(f=!1,s=r.indexOf(o,s+1),s===-1)if(n||J){s=y+1;break}else _("string");for(d=s;r.charCodeAt(d-1)===qi;)d-=1,f=!f}while(f);b=["string",r.slice(y,s+1),y,s],y=s;break}case C0:{Ni.lastIndex=y+1,Ni.test(r),Ni.lastIndex===0?s=r.length-1:s=Ni.lastIndex-2,b=["at-word",r.slice(y,s+1),y,s],y=s;break}case qi:{for(s=y,c=!0;r.charCodeAt(s+1)===qi;)s+=1,c=!c;if(a=r.charCodeAt(s+1),c&&a!==Df&&a!==br&&a!==Ri&&a!==Bi&&a!==Fi&&a!==Mi&&(s+=1,If.test(r.charAt(s)))){for(;If.test(r.charAt(s+1));)s+=1;r.charCodeAt(s+1)===br&&(s+=1)}b=["word",r.slice(y,s+1),y,s],y=s;break}default:{a===Df&&r.charCodeAt(y+1)===k0?(s=r.indexOf("*/",y+2)+1,s===0&&(n||J?s=r.length:_("comment")),b=["comment",r.slice(y,s+1),y,s],y=s):(Li.lastIndex=y+1,Li.test(r),Li.lastIndex===0?s=r.length-1:s=Li.lastIndex-2,b=["word",r.slice(y,s+1),y,s],w.push(b),y=s);break}}return y++,b}function q(R){k.push(R)}return{back:q,nextToken:I,endOfFile:E,position:S}}});var $i=v((iT,Bf)=>{l();"use strict";var Mf=it(),vr=class extends Mf{constructor(e){super(e);this.type="atrule"}append(...e){return this.proxyOf.nodes||(this.nodes=[]),super.append(...e)}prepend(...e){return this.proxyOf.nodes||(this.nodes=[]),super.prepend(...e)}};Bf.exports=vr;vr.default=vr;Mf.registerAtRule(vr)});var Tt=v((nT,$f)=>{l();"use strict";var Ff=it(),Nf,Lf,bt=class extends Ff{constructor(e){super(e);this.type="root",this.nodes||(this.nodes=[])}removeChild(e,t){let r=this.index(e);return!t&&r===0&&this.nodes.length>1&&(this.nodes[1].raws.before=this.nodes[r].raws.before),super.removeChild(e)}normalize(e,t,r){let n=super.normalize(e);if(t){if(r==="prepend")this.nodes.length>1?t.raws.before=this.nodes[1].raws.before:delete t.raws.before;else if(this.first!==t)for(let a of n)a.raws.before=t.raws.before}return n}toResult(e={}){return new Nf(new Lf,this,e).stringify()}};bt.registerLazyResult=i=>{Nf=i};bt.registerProcessor=i=>{Lf=i};$f.exports=bt;bt.default=bt;Ff.registerRoot(bt)});var Ts=v((sT,jf)=>{l();"use strict";var xr={split(i,e,t){let r=[],n="",a=!1,s=0,o=!1,u="",c=!1;for(let f of i)c?c=!1:f==="\\"?c=!0:o?f===u&&(o=!1):f==='"'||f==="'"?(o=!0,u=f):f==="("?s+=1:f===")"?s>0&&(s-=1):s===0&&e.includes(f)&&(a=!0),a?(n!==""&&r.push(n.trim()),n="",a=!1):n+=f;return(t||n!=="")&&r.push(n.trim()),r},space(i){let e=[" ",` +`," "];return xr.split(i,e)},comma(i){return xr.split(i,[","],!0)}};jf.exports=xr;xr.default=xr});var ji=v((aT,Vf)=>{l();"use strict";var zf=it(),_0=Ts(),kr=class extends zf{constructor(e){super(e);this.type="rule",this.nodes||(this.nodes=[])}get selectors(){return _0.comma(this.selector)}set selectors(e){let t=this.selector?this.selector.match(/,\s*/):null,r=t?t[0]:","+this.raw("between","beforeOpen");this.selector=e.join(r)}};Vf.exports=kr;kr.default=kr;zf.registerRule(kr)});var Yf=v((oT,Hf)=>{l();"use strict";var O0=yr(),E0=Rf(),T0=wr(),P0=$i(),D0=Tt(),Uf=ji(),Wf={empty:!0,space:!0};function I0(i){for(let e=i.length-1;e>=0;e--){let t=i[e],r=t[3]||t[2];if(r)return r}}var Gf=class{constructor(e){this.input=e,this.root=new D0,this.current=this.root,this.spaces="",this.semicolon=!1,this.customProperty=!1,this.createTokenizer(),this.root.source={input:e,start:{offset:0,line:1,column:1}}}createTokenizer(){this.tokenizer=E0(this.input)}parse(){let e;for(;!this.tokenizer.endOfFile();)switch(e=this.tokenizer.nextToken(),e[0]){case"space":this.spaces+=e[1];break;case";":this.freeSemicolon(e);break;case"}":this.end(e);break;case"comment":this.comment(e);break;case"at-word":this.atrule(e);break;case"{":this.emptyRule(e);break;default:this.other(e);break}this.endFile()}comment(e){let t=new T0;this.init(t,e[2]),t.source.end=this.getPosition(e[3]||e[2]);let r=e[1].slice(2,-2);if(/^\s*$/.test(r))t.text="",t.raws.left=r,t.raws.right="";else{let n=r.match(/^(\s*)([^]*\S)(\s*)$/);t.text=n[2],t.raws.left=n[1],t.raws.right=n[3]}}emptyRule(e){let t=new Uf;this.init(t,e[2]),t.selector="",t.raws.between="",this.current=t}other(e){let t=!1,r=null,n=!1,a=null,s=[],o=e[1].startsWith("--"),u=[],c=e;for(;c;){if(r=c[0],u.push(c),r==="("||r==="[")a||(a=c),s.push(r==="("?")":"]");else if(o&&n&&r==="{")a||(a=c),s.push("}");else if(s.length===0)if(r===";")if(n){this.decl(u,o);return}else break;else if(r==="{"){this.rule(u);return}else if(r==="}"){this.tokenizer.back(u.pop()),t=!0;break}else r===":"&&(n=!0);else r===s[s.length-1]&&(s.pop(),s.length===0&&(a=null));c=this.tokenizer.nextToken()}if(this.tokenizer.endOfFile()&&(t=!0),s.length>0&&this.unclosedBracket(a),t&&n){if(!o)for(;u.length&&(c=u[u.length-1][0],!(c!=="space"&&c!=="comment"));)this.tokenizer.back(u.pop());this.decl(u,o)}else this.unknownWord(u)}rule(e){e.pop();let t=new Uf;this.init(t,e[0][2]),t.raws.between=this.spacesAndCommentsFromEnd(e),this.raw(t,"selector",e),this.current=t}decl(e,t){let r=new O0;this.init(r,e[0][2]);let n=e[e.length-1];for(n[0]===";"&&(this.semicolon=!0,e.pop()),r.source.end=this.getPosition(n[3]||n[2]||I0(e));e[0][0]!=="word";)e.length===1&&this.unknownWord(e),r.raws.before+=e.shift()[1];for(r.source.start=this.getPosition(e[0][2]),r.prop="";e.length;){let c=e[0][0];if(c===":"||c==="space"||c==="comment")break;r.prop+=e.shift()[1]}r.raws.between="";let a;for(;e.length;)if(a=e.shift(),a[0]===":"){r.raws.between+=a[1];break}else a[0]==="word"&&/\w/.test(a[1])&&this.unknownWord([a]),r.raws.between+=a[1];(r.prop[0]==="_"||r.prop[0]==="*")&&(r.raws.before+=r.prop[0],r.prop=r.prop.slice(1));let s=[],o;for(;e.length&&(o=e[0][0],!(o!=="space"&&o!=="comment"));)s.push(e.shift());this.precheckMissedSemicolon(e);for(let c=e.length-1;c>=0;c--){if(a=e[c],a[1].toLowerCase()==="!important"){r.important=!0;let f=this.stringFrom(e,c);f=this.spacesFromEnd(e)+f,f!==" !important"&&(r.raws.important=f);break}else if(a[1].toLowerCase()==="important"){let f=e.slice(0),d="";for(let p=c;p>0;p--){let m=f[p][0];if(d.trim().indexOf("!")===0&&m!=="space")break;d=f.pop()[1]+d}d.trim().indexOf("!")===0&&(r.important=!0,r.raws.important=d,e=f)}if(a[0]!=="space"&&a[0]!=="comment")break}e.some(c=>c[0]!=="space"&&c[0]!=="comment")&&(r.raws.between+=s.map(c=>c[1]).join(""),s=[]),this.raw(r,"value",s.concat(e),t),r.value.includes(":")&&!t&&this.checkMissedSemicolon(e)}atrule(e){let t=new P0;t.name=e[1].slice(1),t.name===""&&this.unnamedAtrule(t,e),this.init(t,e[2]);let r,n,a,s=!1,o=!1,u=[],c=[];for(;!this.tokenizer.endOfFile();){if(e=this.tokenizer.nextToken(),r=e[0],r==="("||r==="["?c.push(r==="("?")":"]"):r==="{"&&c.length>0?c.push("}"):r===c[c.length-1]&&c.pop(),c.length===0)if(r===";"){t.source.end=this.getPosition(e[2]),this.semicolon=!0;break}else if(r==="{"){o=!0;break}else if(r==="}"){if(u.length>0){for(a=u.length-1,n=u[a];n&&n[0]==="space";)n=u[--a];n&&(t.source.end=this.getPosition(n[3]||n[2]))}this.end(e);break}else u.push(e);else u.push(e);if(this.tokenizer.endOfFile()){s=!0;break}}t.raws.between=this.spacesAndCommentsFromEnd(u),u.length?(t.raws.afterName=this.spacesAndCommentsFromStart(u),this.raw(t,"params",u),s&&(e=u[u.length-1],t.source.end=this.getPosition(e[3]||e[2]),this.spaces=t.raws.between,t.raws.between="")):(t.raws.afterName="",t.params=""),o&&(t.nodes=[],this.current=t)}end(e){this.current.nodes&&this.current.nodes.length&&(this.current.raws.semicolon=this.semicolon),this.semicolon=!1,this.current.raws.after=(this.current.raws.after||"")+this.spaces,this.spaces="",this.current.parent?(this.current.source.end=this.getPosition(e[2]),this.current=this.current.parent):this.unexpectedClose(e)}endFile(){this.current.parent&&this.unclosedBlock(),this.current.nodes&&this.current.nodes.length&&(this.current.raws.semicolon=this.semicolon),this.current.raws.after=(this.current.raws.after||"")+this.spaces}freeSemicolon(e){if(this.spaces+=e[1],this.current.nodes){let t=this.current.nodes[this.current.nodes.length-1];t&&t.type==="rule"&&!t.raws.ownSemicolon&&(t.raws.ownSemicolon=this.spaces,this.spaces="")}}getPosition(e){let t=this.input.fromOffset(e);return{offset:e,line:t.line,column:t.col}}init(e,t){this.current.push(e),e.source={start:this.getPosition(t),input:this.input},e.raws.before=this.spaces,this.spaces="",e.type!=="comment"&&(this.semicolon=!1)}raw(e,t,r,n){let a,s,o=r.length,u="",c=!0,f,d;for(let p=0;pm+b[1],"");e.raws[t]={value:u,raw:p}}e[t]=u}spacesAndCommentsFromEnd(e){let t,r="";for(;e.length&&(t=e[e.length-1][0],!(t!=="space"&&t!=="comment"));)r=e.pop()[1]+r;return r}spacesAndCommentsFromStart(e){let t,r="";for(;e.length&&(t=e[0][0],!(t!=="space"&&t!=="comment"));)r+=e.shift()[1];return r}spacesFromEnd(e){let t,r="";for(;e.length&&(t=e[e.length-1][0],t==="space");)r=e.pop()[1]+r;return r}stringFrom(e,t){let r="";for(let n=t;n=0&&(n=e[a],!(n[0]!=="space"&&(r+=1,r===2)));a--);throw this.input.error("Missed semicolon",n[0]==="word"?n[3]+1:n[2])}};Hf.exports=Gf});var Qf=v(()=>{l()});var Xf=v((fT,Jf)=>{l();var q0="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict",R0=(i,e=21)=>(t=e)=>{let r="",n=t;for(;n--;)r+=i[Math.random()*i.length|0];return r},M0=(i=21)=>{let e="",t=i;for(;t--;)e+=q0[Math.random()*64|0];return e};Jf.exports={nanoid:M0,customAlphabet:R0}});var Ps=v((cT,Kf)=>{l();Kf.exports={}});var Vi=v((pT,rc)=>{l();"use strict";var{SourceMapConsumer:B0,SourceMapGenerator:F0}=Qf(),{fileURLToPath:Zf,pathToFileURL:zi}=(ys(),rf),{resolve:Ds,isAbsolute:Is}=(wt(),Zu),{nanoid:N0}=Xf(),qs=ws(),ec=ki(),L0=Ps(),Rs=Symbol("fromOffsetCache"),$0=Boolean(B0&&F0),tc=Boolean(Ds&&Is),Sr=class{constructor(e,t={}){if(e===null||typeof e=="undefined"||typeof e=="object"&&!e.toString)throw new Error(`PostCSS received ${e} instead of CSS string`);if(this.css=e.toString(),this.css[0]==="\uFEFF"||this.css[0]==="\uFFFE"?(this.hasBOM=!0,this.css=this.css.slice(1)):this.hasBOM=!1,t.from&&(!tc||/^\w+:\/\//.test(t.from)||Is(t.from)?this.file=t.from:this.file=Ds(t.from)),tc&&$0){let r=new L0(this.css,t);if(r.text){this.map=r;let n=r.consumer().file;!this.file&&n&&(this.file=this.mapResolve(n))}}this.file||(this.id=""),this.map&&(this.map.file=this.from)}fromOffset(e){let t,r;if(this[Rs])r=this[Rs];else{let a=this.css.split(` +`);r=new Array(a.length);let s=0;for(let o=0,u=a.length;o=t)n=r.length-1;else{let a=r.length-2,s;for(;n>1),e=r[s+1])n=s+1;else{n=s;break}}return{line:n+1,col:e-r[n]+1}}error(e,t,r,n={}){let a,s,o;if(t&&typeof t=="object"){let c=t,f=r;if(typeof c.offset=="number"){let d=this.fromOffset(c.offset);t=d.line,r=d.col}else t=c.line,r=c.column;if(typeof f.offset=="number"){let d=this.fromOffset(f.offset);s=d.line,o=d.col}else s=f.line,o=f.column}else if(!r){let c=this.fromOffset(t);t=c.line,r=c.col}let u=this.origin(t,r,s,o);return u?a=new ec(e,u.endLine===void 0?u.line:{line:u.line,column:u.column},u.endLine===void 0?u.column:{line:u.endLine,column:u.endColumn},u.source,u.file,n.plugin):a=new ec(e,s===void 0?t:{line:t,column:r},s===void 0?r:{line:s,column:o},this.css,this.file,n.plugin),a.input={line:t,column:r,endLine:s,endColumn:o,source:this.css},this.file&&(zi&&(a.input.url=zi(this.file).toString()),a.input.file=this.file),a}origin(e,t,r,n){if(!this.map)return!1;let a=this.map.consumer(),s=a.originalPositionFor({line:e,column:t});if(!s.source)return!1;let o;typeof r=="number"&&(o=a.originalPositionFor({line:r,column:n}));let u;Is(s.source)?u=zi(s.source):u=new URL(s.source,this.map.consumer().sourceRoot||zi(this.map.mapFile));let c={url:u.toString(),line:s.line,column:s.column,endLine:o&&o.line,endColumn:o&&o.column};if(u.protocol==="file:")if(Zf)c.file=Zf(u);else throw new Error("file: protocol is not available in this PostCSS build");let f=a.sourceContentFor(s.source);return f&&(c.source=f),c}mapResolve(e){return/^\w+:\/\//.test(e)?e:Ds(this.map.consumer().sourceRoot||this.map.root||".",e)}get from(){return this.file||this.id}toJSON(){let e={};for(let t of["hasBOM","css","file","id"])this[t]!=null&&(e[t]=this[t]);return this.map&&(e.map={...this.map},e.map.consumerCache&&(e.map.consumerCache=void 0)),e}};rc.exports=Sr;Sr.default=Sr;qs&&qs.registerInput&&qs.registerInput(Sr)});var Wi=v((dT,ic)=>{l();"use strict";var j0=it(),z0=Yf(),V0=Vi();function Ui(i,e){let t=new V0(i,e),r=new z0(t);try{r.parse()}catch(n){throw n}return r.root}ic.exports=Ui;Ui.default=Ui;j0.registerParse(Ui)});var Fs=v((mT,oc)=>{l();"use strict";var{isClean:Re,my:U0}=Si(),W0=Ss(),G0=mr(),H0=it(),Y0=Ti(),hT=_s(),nc=Ii(),Q0=Wi(),J0=Tt(),X0={document:"Document",root:"Root",atrule:"AtRule",rule:"Rule",decl:"Declaration",comment:"Comment"},K0={postcssPlugin:!0,prepare:!0,Once:!0,Document:!0,Root:!0,Declaration:!0,Rule:!0,AtRule:!0,Comment:!0,DeclarationExit:!0,RuleExit:!0,AtRuleExit:!0,CommentExit:!0,RootExit:!0,DocumentExit:!0,OnceExit:!0},Z0={postcssPlugin:!0,prepare:!0,Once:!0},Pt=0;function Cr(i){return typeof i=="object"&&typeof i.then=="function"}function sc(i){let e=!1,t=X0[i.type];return i.type==="decl"?e=i.prop.toLowerCase():i.type==="atrule"&&(e=i.name.toLowerCase()),e&&i.append?[t,t+"-"+e,Pt,t+"Exit",t+"Exit-"+e]:e?[t,t+"-"+e,t+"Exit",t+"Exit-"+e]:i.append?[t,Pt,t+"Exit"]:[t,t+"Exit"]}function ac(i){let e;return i.type==="document"?e=["Document",Pt,"DocumentExit"]:i.type==="root"?e=["Root",Pt,"RootExit"]:e=sc(i),{node:i,events:e,eventIndex:0,visitors:[],visitorIndex:0,iterator:0}}function Ms(i){return i[Re]=!1,i.nodes&&i.nodes.forEach(e=>Ms(e)),i}var Bs={},Ve=class{constructor(e,t,r){this.stringified=!1,this.processed=!1;let n;if(typeof t=="object"&&t!==null&&(t.type==="root"||t.type==="document"))n=Ms(t);else if(t instanceof Ve||t instanceof nc)n=Ms(t.root),t.map&&(typeof r.map=="undefined"&&(r.map={}),r.map.inline||(r.map.inline=!1),r.map.prev=t.map);else{let a=Q0;r.syntax&&(a=r.syntax.parse),r.parser&&(a=r.parser),a.parse&&(a=a.parse);try{n=a(t,r)}catch(s){this.processed=!0,this.error=s}n&&!n[U0]&&H0.rebuild(n)}this.result=new nc(e,n,r),this.helpers={...Bs,result:this.result,postcss:Bs},this.plugins=this.processor.plugins.map(a=>typeof a=="object"&&a.prepare?{...a,...a.prepare(this.result)}:a)}get[Symbol.toStringTag](){return"LazyResult"}get processor(){return this.result.processor}get opts(){return this.result.opts}get css(){return this.stringify().css}get content(){return this.stringify().content}get map(){return this.stringify().map}get root(){return this.sync().root}get messages(){return this.sync().messages}warnings(){return this.sync().warnings()}toString(){return this.css}then(e,t){return this.async().then(e,t)}catch(e){return this.async().catch(e)}finally(e){return this.async().then(e,e)}async(){return this.error?Promise.reject(this.error):this.processed?Promise.resolve(this.result):(this.processing||(this.processing=this.runAsync()),this.processing)}sync(){if(this.error)throw this.error;if(this.processed)return this.result;if(this.processed=!0,this.processing)throw this.getAsyncError();for(let e of this.plugins){let t=this.runOnRoot(e);if(Cr(t))throw this.getAsyncError()}if(this.prepareVisitors(),this.hasListener){let e=this.result.root;for(;!e[Re];)e[Re]=!0,this.walkSync(e);if(this.listeners.OnceExit)if(e.type==="document")for(let t of e.nodes)this.visitSync(this.listeners.OnceExit,t);else this.visitSync(this.listeners.OnceExit,e)}return this.result}stringify(){if(this.error)throw this.error;if(this.stringified)return this.result;this.stringified=!0,this.sync();let e=this.result.opts,t=G0;e.syntax&&(t=e.syntax.stringify),e.stringifier&&(t=e.stringifier),t.stringify&&(t=t.stringify);let n=new W0(t,this.result.root,this.result.opts).generate();return this.result.css=n[0],this.result.map=n[1],this.result}walkSync(e){e[Re]=!0;let t=sc(e);for(let r of t)if(r===Pt)e.nodes&&e.each(n=>{n[Re]||this.walkSync(n)});else{let n=this.listeners[r];if(n&&this.visitSync(n,e.toProxy()))return}}visitSync(e,t){for(let[r,n]of e){this.result.lastPlugin=r;let a;try{a=n(t,this.helpers)}catch(s){throw this.handleError(s,t.proxyOf)}if(t.type!=="root"&&t.type!=="document"&&!t.parent)return!0;if(Cr(a))throw this.getAsyncError()}}runOnRoot(e){this.result.lastPlugin=e;try{if(typeof e=="object"&&e.Once){if(this.result.root.type==="document"){let t=this.result.root.nodes.map(r=>e.Once(r,this.helpers));return Cr(t[0])?Promise.all(t):t}return e.Once(this.result.root,this.helpers)}else if(typeof e=="function")return e(this.result.root,this.result)}catch(t){throw this.handleError(t)}}getAsyncError(){throw new Error("Use process(css).then(cb) to work with async plugins")}handleError(e,t){let r=this.result.lastPlugin;try{t&&t.addToError(e),this.error=e,e.name==="CssSyntaxError"&&!e.plugin?(e.plugin=r.postcssPlugin,e.setMessage()):r.postcssVersion}catch(n){console&&console.error&&console.error(n)}return e}async runAsync(){this.plugin=0;for(let e=0;e0;){let r=this.visitTick(t);if(Cr(r))try{await r}catch(n){let a=t[t.length-1].node;throw this.handleError(n,a)}}}if(this.listeners.OnceExit)for(let[t,r]of this.listeners.OnceExit){this.result.lastPlugin=t;try{if(e.type==="document"){let n=e.nodes.map(a=>r(a,this.helpers));await Promise.all(n)}else await r(e,this.helpers)}catch(n){throw this.handleError(n)}}}return this.processed=!0,this.stringify()}prepareVisitors(){this.listeners={};let e=(t,r,n)=>{this.listeners[r]||(this.listeners[r]=[]),this.listeners[r].push([t,n])};for(let t of this.plugins)if(typeof t=="object")for(let r in t){if(!K0[r]&&/^[A-Z]/.test(r))throw new Error(`Unknown event ${r} in ${t.postcssPlugin}. Try to update PostCSS (${this.processor.version} now).`);if(!Z0[r])if(typeof t[r]=="object")for(let n in t[r])n==="*"?e(t,r,t[r][n]):e(t,r+"-"+n.toLowerCase(),t[r][n]);else typeof t[r]=="function"&&e(t,r,t[r])}this.hasListener=Object.keys(this.listeners).length>0}visitTick(e){let t=e[e.length-1],{node:r,visitors:n}=t;if(r.type!=="root"&&r.type!=="document"&&!r.parent){e.pop();return}if(n.length>0&&t.visitorIndex{Bs=i};oc.exports=Ve;Ve.default=Ve;J0.registerLazyResult(Ve);Y0.registerLazyResult(Ve)});var uc=v((yT,lc)=>{l();"use strict";var ev=Ss(),tv=mr(),gT=_s(),rv=Wi(),iv=Ii(),Gi=class{constructor(e,t,r){t=t.toString(),this.stringified=!1,this._processor=e,this._css=t,this._opts=r,this._map=void 0;let n,a=tv;this.result=new iv(this._processor,n,this._opts),this.result.css=t;let s=this;Object.defineProperty(this.result,"root",{get(){return s.root}});let o=new ev(a,n,this._opts,t);if(o.isMap()){let[u,c]=o.generate();u&&(this.result.css=u),c&&(this.result.map=c)}}get[Symbol.toStringTag](){return"NoWorkResult"}get processor(){return this.result.processor}get opts(){return this.result.opts}get css(){return this.result.css}get content(){return this.result.css}get map(){return this.result.map}get root(){if(this._root)return this._root;let e,t=rv;try{e=t(this._css,this._opts)}catch(r){this.error=r}if(this.error)throw this.error;return this._root=e,e}get messages(){return[]}warnings(){return[]}toString(){return this._css}then(e,t){return this.async().then(e,t)}catch(e){return this.async().catch(e)}finally(e){return this.async().then(e,e)}async(){return this.error?Promise.reject(this.error):Promise.resolve(this.result)}sync(){if(this.error)throw this.error;return this.result}};lc.exports=Gi;Gi.default=Gi});var cc=v((wT,fc)=>{l();"use strict";var nv=uc(),sv=Fs(),av=Ti(),ov=Tt(),Dt=class{constructor(e=[]){this.version="8.4.24",this.plugins=this.normalize(e)}use(e){return this.plugins=this.plugins.concat(this.normalize([e])),this}process(e,t={}){return this.plugins.length===0&&typeof t.parser=="undefined"&&typeof t.stringifier=="undefined"&&typeof t.syntax=="undefined"?new nv(this,e,t):new sv(this,e,t)}normalize(e){let t=[];for(let r of e)if(r.postcss===!0?r=r():r.postcss&&(r=r.postcss),typeof r=="object"&&Array.isArray(r.plugins))t=t.concat(r.plugins);else if(typeof r=="object"&&r.postcssPlugin)t.push(r);else if(typeof r=="function")t.push(r);else if(!(typeof r=="object"&&(r.parse||r.stringify)))throw new Error(r+" is not a PostCSS plugin");return t}};fc.exports=Dt;Dt.default=Dt;ov.registerProcessor(Dt);av.registerProcessor(Dt)});var dc=v((bT,pc)=>{l();"use strict";var lv=yr(),uv=Ps(),fv=wr(),cv=$i(),pv=Vi(),dv=Tt(),hv=ji();function Ar(i,e){if(Array.isArray(i))return i.map(n=>Ar(n));let{inputs:t,...r}=i;if(t){e=[];for(let n of t){let a={...n,__proto__:pv.prototype};a.map&&(a.map={...a.map,__proto__:uv.prototype}),e.push(a)}}if(r.nodes&&(r.nodes=i.nodes.map(n=>Ar(n,e))),r.source){let{inputId:n,...a}=r.source;r.source=a,n!=null&&(r.source.input=e[n])}if(r.type==="root")return new dv(r);if(r.type==="decl")return new lv(r);if(r.type==="rule")return new hv(r);if(r.type==="comment")return new fv(r);if(r.type==="atrule")return new cv(r);throw new Error("Unknown node type: "+i.type)}pc.exports=Ar;Ar.default=Ar});var ye=v((vT,vc)=>{l();"use strict";var mv=ki(),hc=yr(),gv=Fs(),yv=it(),Ns=cc(),wv=mr(),bv=dc(),mc=Ti(),vv=Os(),gc=wr(),yc=$i(),xv=Ii(),kv=Vi(),Sv=Wi(),Cv=Ts(),wc=ji(),bc=Tt(),Av=gr();function j(...i){return i.length===1&&Array.isArray(i[0])&&(i=i[0]),new Ns(i)}j.plugin=function(e,t){let r=!1;function n(...s){console&&console.warn&&!r&&(r=!0,console.warn(e+`: postcss.plugin was deprecated. Migration guide: +https://evilmartians.com/chronicles/postcss-8-plugin-migration`),h.env.LANG&&h.env.LANG.startsWith("cn")&&console.warn(e+`: \u91CC\u9762 postcss.plugin \u88AB\u5F03\u7528. \u8FC1\u79FB\u6307\u5357: +https://www.w3ctech.com/topic/2226`));let o=t(...s);return o.postcssPlugin=e,o.postcssVersion=new Ns().version,o}let a;return Object.defineProperty(n,"postcss",{get(){return a||(a=n()),a}}),n.process=function(s,o,u){return j([n(u)]).process(s,o)},n};j.stringify=wv;j.parse=Sv;j.fromJSON=bv;j.list=Cv;j.comment=i=>new gc(i);j.atRule=i=>new yc(i);j.decl=i=>new hc(i);j.rule=i=>new wc(i);j.root=i=>new bc(i);j.document=i=>new mc(i);j.CssSyntaxError=mv;j.Declaration=hc;j.Container=yv;j.Processor=Ns;j.Document=mc;j.Comment=gc;j.Warning=vv;j.AtRule=yc;j.Result=xv;j.Input=kv;j.Rule=wc;j.Root=bc;j.Node=Av;gv.registerPostcss(j);vc.exports=j;j.default=j});var U,z,xT,kT,ST,CT,AT,_T,OT,ET,TT,PT,DT,IT,qT,RT,MT,BT,FT,NT,LT,$T,jT,zT,VT,UT,nt=C(()=>{l();U=X(ye()),z=U.default,xT=U.default.stringify,kT=U.default.fromJSON,ST=U.default.plugin,CT=U.default.parse,AT=U.default.list,_T=U.default.document,OT=U.default.comment,ET=U.default.atRule,TT=U.default.rule,PT=U.default.decl,DT=U.default.root,IT=U.default.CssSyntaxError,qT=U.default.Declaration,RT=U.default.Container,MT=U.default.Processor,BT=U.default.Document,FT=U.default.Comment,NT=U.default.Warning,LT=U.default.AtRule,$T=U.default.Result,jT=U.default.Input,zT=U.default.Rule,VT=U.default.Root,UT=U.default.Node});var Ls=v((GT,xc)=>{l();xc.exports=function(i,e,t,r,n){for(e=e.split?e.split("."):e,r=0;r{l();"use strict";Hi.__esModule=!0;Hi.default=Ev;function _v(i){for(var e=i.toLowerCase(),t="",r=!1,n=0;n<6&&e[n]!==void 0;n++){var a=e.charCodeAt(n),s=a>=97&&a<=102||a>=48&&a<=57;if(r=a===32,!s)break;t+=e[n]}if(t.length!==0){var o=parseInt(t,16),u=o>=55296&&o<=57343;return u||o===0||o>1114111?["\uFFFD",t.length+(r?1:0)]:[String.fromCodePoint(o),t.length+(r?1:0)]}}var Ov=/\\/;function Ev(i){var e=Ov.test(i);if(!e)return i;for(var t="",r=0;r{l();"use strict";Qi.__esModule=!0;Qi.default=Tv;function Tv(i){for(var e=arguments.length,t=new Array(e>1?e-1:0),r=1;r0;){var n=t.shift();if(!i[n])return;i=i[n]}return i}Sc.exports=Qi.default});var _c=v((Ji,Ac)=>{l();"use strict";Ji.__esModule=!0;Ji.default=Pv;function Pv(i){for(var e=arguments.length,t=new Array(e>1?e-1:0),r=1;r0;){var n=t.shift();i[n]||(i[n]={}),i=i[n]}}Ac.exports=Ji.default});var Ec=v((Xi,Oc)=>{l();"use strict";Xi.__esModule=!0;Xi.default=Dv;function Dv(i){for(var e="",t=i.indexOf("/*"),r=0;t>=0;){e=e+i.slice(r,t);var n=i.indexOf("*/",t+2);if(n<0)return e;r=n+2,t=i.indexOf("/*",r)}return e=e+i.slice(r),e}Oc.exports=Xi.default});var _r=v(Me=>{l();"use strict";Me.__esModule=!0;Me.unesc=Me.stripComments=Me.getProp=Me.ensureObject=void 0;var Iv=Ki(Yi());Me.unesc=Iv.default;var qv=Ki(Cc());Me.getProp=qv.default;var Rv=Ki(_c());Me.ensureObject=Rv.default;var Mv=Ki(Ec());Me.stripComments=Mv.default;function Ki(i){return i&&i.__esModule?i:{default:i}}});var Ue=v((Or,Dc)=>{l();"use strict";Or.__esModule=!0;Or.default=void 0;var Tc=_r();function Pc(i,e){for(var t=0;tr||this.source.end.linen||this.source.end.line===r&&this.source.end.column{l();"use strict";W.__esModule=!0;W.UNIVERSAL=W.TAG=W.STRING=W.SELECTOR=W.ROOT=W.PSEUDO=W.NESTING=W.ID=W.COMMENT=W.COMBINATOR=W.CLASS=W.ATTRIBUTE=void 0;var Lv="tag";W.TAG=Lv;var $v="string";W.STRING=$v;var jv="selector";W.SELECTOR=jv;var zv="root";W.ROOT=zv;var Vv="pseudo";W.PSEUDO=Vv;var Uv="nesting";W.NESTING=Uv;var Wv="id";W.ID=Wv;var Gv="comment";W.COMMENT=Gv;var Hv="combinator";W.COMBINATOR=Hv;var Yv="class";W.CLASS=Yv;var Qv="attribute";W.ATTRIBUTE=Qv;var Jv="universal";W.UNIVERSAL=Jv});var Zi=v((Er,Mc)=>{l();"use strict";Er.__esModule=!0;Er.default=void 0;var Xv=Zv(Ue()),We=Kv(ae());function Ic(i){if(typeof WeakMap!="function")return null;var e=new WeakMap,t=new WeakMap;return(Ic=function(n){return n?t:e})(i)}function Kv(i,e){if(!e&&i&&i.__esModule)return i;if(i===null||typeof i!="object"&&typeof i!="function")return{default:i};var t=Ic(e);if(t&&t.has(i))return t.get(i);var r={},n=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in i)if(a!=="default"&&Object.prototype.hasOwnProperty.call(i,a)){var s=n?Object.getOwnPropertyDescriptor(i,a):null;s&&(s.get||s.set)?Object.defineProperty(r,a,s):r[a]=i[a]}return r.default=i,t&&t.set(i,r),r}function Zv(i){return i&&i.__esModule?i:{default:i}}function ex(i,e){var t=typeof Symbol!="undefined"&&i[Symbol.iterator]||i["@@iterator"];if(t)return(t=t.call(i)).next.bind(t);if(Array.isArray(i)||(t=tx(i))||e&&i&&typeof i.length=="number"){t&&(i=t);var r=0;return function(){return r>=i.length?{done:!0}:{done:!1,value:i[r++]}}}throw new TypeError(`Invalid attempt to iterate non-iterable instance. +In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function tx(i,e){if(!!i){if(typeof i=="string")return qc(i,e);var t=Object.prototype.toString.call(i).slice(8,-1);if(t==="Object"&&i.constructor&&(t=i.constructor.name),t==="Map"||t==="Set")return Array.from(i);if(t==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t))return qc(i,e)}}function qc(i,e){(e==null||e>i.length)&&(e=i.length);for(var t=0,r=new Array(e);t=n&&(this.indexes[s]=a-1);return this},t.removeAll=function(){for(var n=ex(this.nodes),a;!(a=n()).done;){var s=a.value;s.parent=void 0}return this.nodes=[],this},t.empty=function(){return this.removeAll()},t.insertAfter=function(n,a){a.parent=this;var s=this.index(n);this.nodes.splice(s+1,0,a),a.parent=this;var o;for(var u in this.indexes)o=this.indexes[u],s<=o&&(this.indexes[u]=o+1);return this},t.insertBefore=function(n,a){a.parent=this;var s=this.index(n);this.nodes.splice(s,0,a),a.parent=this;var o;for(var u in this.indexes)o=this.indexes[u],o<=s&&(this.indexes[u]=o+1);return this},t._findChildAtPosition=function(n,a){var s=void 0;return this.each(function(o){if(o.atPosition){var u=o.atPosition(n,a);if(u)return s=u,!1}else if(o.isAtPosition(n,a))return s=o,!1}),s},t.atPosition=function(n,a){if(this.isAtPosition(n,a))return this._findChildAtPosition(n,a)||this},t._inferEndPosition=function(){this.last&&this.last.source&&this.last.source.end&&(this.source=this.source||{},this.source.end=this.source.end||{},Object.assign(this.source.end,this.last.source.end))},t.each=function(n){this.lastEach||(this.lastEach=0),this.indexes||(this.indexes={}),this.lastEach++;var a=this.lastEach;if(this.indexes[a]=0,!!this.length){for(var s,o;this.indexes[a]{l();"use strict";Tr.__esModule=!0;Tr.default=void 0;var sx=ox(Zi()),ax=ae();function ox(i){return i&&i.__esModule?i:{default:i}}function Bc(i,e){for(var t=0;t{l();"use strict";Pr.__esModule=!0;Pr.default=void 0;var cx=dx(Zi()),px=ae();function dx(i){return i&&i.__esModule?i:{default:i}}function hx(i,e){i.prototype=Object.create(e.prototype),i.prototype.constructor=i,Vs(i,e)}function Vs(i,e){return Vs=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(r,n){return r.__proto__=n,r},Vs(i,e)}var mx=function(i){hx(e,i);function e(t){var r;return r=i.call(this,t)||this,r.type=px.SELECTOR,r}return e}(cx.default);Pr.default=mx;Nc.exports=Pr.default});var en=v((QT,Lc)=>{l();"use strict";var gx={},yx=gx.hasOwnProperty,wx=function(e,t){if(!e)return t;var r={};for(var n in t)r[n]=yx.call(e,n)?e[n]:t[n];return r},bx=/[ -,\.\/:-@\[-\^`\{-~]/,vx=/[ -,\.\/:-@\[\]\^`\{-~]/,xx=/(^|\\+)?(\\[A-F0-9]{1,6})\x20(?![a-fA-F0-9\x20])/g,Ws=function i(e,t){t=wx(t,i.options),t.quotes!="single"&&t.quotes!="double"&&(t.quotes="single");for(var r=t.quotes=="double"?'"':"'",n=t.isIdentifier,a=e.charAt(0),s="",o=0,u=e.length;o126){if(f>=55296&&f<=56319&&o{l();"use strict";Dr.__esModule=!0;Dr.default=void 0;var kx=$c(en()),Sx=_r(),Cx=$c(Ue()),Ax=ae();function $c(i){return i&&i.__esModule?i:{default:i}}function jc(i,e){for(var t=0;t{l();"use strict";Ir.__esModule=!0;Ir.default=void 0;var Tx=Dx(Ue()),Px=ae();function Dx(i){return i&&i.__esModule?i:{default:i}}function Ix(i,e){i.prototype=Object.create(e.prototype),i.prototype.constructor=i,Ys(i,e)}function Ys(i,e){return Ys=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(r,n){return r.__proto__=n,r},Ys(i,e)}var qx=function(i){Ix(e,i);function e(t){var r;return r=i.call(this,t)||this,r.type=Px.COMMENT,r}return e}(Tx.default);Ir.default=qx;Vc.exports=Ir.default});var Xs=v((qr,Uc)=>{l();"use strict";qr.__esModule=!0;qr.default=void 0;var Rx=Bx(Ue()),Mx=ae();function Bx(i){return i&&i.__esModule?i:{default:i}}function Fx(i,e){i.prototype=Object.create(e.prototype),i.prototype.constructor=i,Js(i,e)}function Js(i,e){return Js=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(r,n){return r.__proto__=n,r},Js(i,e)}var Nx=function(i){Fx(e,i);function e(r){var n;return n=i.call(this,r)||this,n.type=Mx.ID,n}var t=e.prototype;return t.valueToString=function(){return"#"+i.prototype.valueToString.call(this)},e}(Rx.default);qr.default=Nx;Uc.exports=qr.default});var tn=v((Rr,Hc)=>{l();"use strict";Rr.__esModule=!0;Rr.default=void 0;var Lx=Wc(en()),$x=_r(),jx=Wc(Ue());function Wc(i){return i&&i.__esModule?i:{default:i}}function Gc(i,e){for(var t=0;t{l();"use strict";Mr.__esModule=!0;Mr.default=void 0;var Wx=Hx(tn()),Gx=ae();function Hx(i){return i&&i.__esModule?i:{default:i}}function Yx(i,e){i.prototype=Object.create(e.prototype),i.prototype.constructor=i,Zs(i,e)}function Zs(i,e){return Zs=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(r,n){return r.__proto__=n,r},Zs(i,e)}var Qx=function(i){Yx(e,i);function e(t){var r;return r=i.call(this,t)||this,r.type=Gx.TAG,r}return e}(Wx.default);Mr.default=Qx;Yc.exports=Mr.default});var ra=v((Br,Qc)=>{l();"use strict";Br.__esModule=!0;Br.default=void 0;var Jx=Kx(Ue()),Xx=ae();function Kx(i){return i&&i.__esModule?i:{default:i}}function Zx(i,e){i.prototype=Object.create(e.prototype),i.prototype.constructor=i,ta(i,e)}function ta(i,e){return ta=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(r,n){return r.__proto__=n,r},ta(i,e)}var e1=function(i){Zx(e,i);function e(t){var r;return r=i.call(this,t)||this,r.type=Xx.STRING,r}return e}(Jx.default);Br.default=e1;Qc.exports=Br.default});var na=v((Fr,Jc)=>{l();"use strict";Fr.__esModule=!0;Fr.default=void 0;var t1=i1(Zi()),r1=ae();function i1(i){return i&&i.__esModule?i:{default:i}}function n1(i,e){i.prototype=Object.create(e.prototype),i.prototype.constructor=i,ia(i,e)}function ia(i,e){return ia=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(r,n){return r.__proto__=n,r},ia(i,e)}var s1=function(i){n1(e,i);function e(r){var n;return n=i.call(this,r)||this,n.type=r1.PSEUDO,n}var t=e.prototype;return t.toString=function(){var n=this.length?"("+this.map(String).join(",")+")":"";return[this.rawSpaceBefore,this.stringifyProperty("value"),n,this.rawSpaceAfter].join("")},e}(t1.default);Fr.default=s1;Jc.exports=Fr.default});var Xc={};_e(Xc,{deprecate:()=>a1});function a1(i){return i}var Kc=C(()=>{l()});var ep=v((JT,Zc)=>{l();Zc.exports=(Kc(),Xc).deprecate});var fa=v($r=>{l();"use strict";$r.__esModule=!0;$r.default=void 0;$r.unescapeValue=la;var Nr=aa(en()),o1=aa(Yi()),l1=aa(tn()),u1=ae(),sa;function aa(i){return i&&i.__esModule?i:{default:i}}function tp(i,e){for(var t=0;t0&&!n.quoted&&o.before.length===0&&!(n.spaces.value&&n.spaces.value.after)&&(o.before=" "),rp(s,o)}))),a.push("]"),a.push(this.rawSpaceAfter),a.join("")},f1(e,[{key:"quoted",get:function(){var n=this.quoteMark;return n==="'"||n==='"'},set:function(n){h1()}},{key:"quoteMark",get:function(){return this._quoteMark},set:function(n){if(!this._constructed){this._quoteMark=n;return}this._quoteMark!==n&&(this._quoteMark=n,this._syncRawValue())}},{key:"qualifiedAttribute",get:function(){return this.qualifiedName(this.raws.attribute||this.attribute)}},{key:"insensitiveFlag",get:function(){return this.insensitive?"i":""}},{key:"value",get:function(){return this._value},set:function(n){if(this._constructed){var a=la(n),s=a.deprecatedUsage,o=a.unescaped,u=a.quoteMark;if(s&&d1(),o===this._value&&u===this._quoteMark)return;this._value=o,this._quoteMark=u,this._syncRawValue()}else this._value=n}},{key:"insensitive",get:function(){return this._insensitive},set:function(n){n||(this._insensitive=!1,this.raws&&(this.raws.insensitiveFlag==="I"||this.raws.insensitiveFlag==="i")&&(this.raws.insensitiveFlag=void 0)),this._insensitive=n}},{key:"attribute",get:function(){return this._attribute},set:function(n){this._handleEscapes("attribute",n),this._attribute=n}}]),e}(l1.default);$r.default=rn;rn.NO_QUOTE=null;rn.SINGLE_QUOTE="'";rn.DOUBLE_QUOTE='"';var ua=(sa={"'":{quotes:"single",wrap:!0},'"':{quotes:"double",wrap:!0}},sa[null]={isIdentifier:!0},sa);function rp(i,e){return""+e.before+i+e.after}});var pa=v((jr,ip)=>{l();"use strict";jr.__esModule=!0;jr.default=void 0;var y1=b1(tn()),w1=ae();function b1(i){return i&&i.__esModule?i:{default:i}}function v1(i,e){i.prototype=Object.create(e.prototype),i.prototype.constructor=i,ca(i,e)}function ca(i,e){return ca=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(r,n){return r.__proto__=n,r},ca(i,e)}var x1=function(i){v1(e,i);function e(t){var r;return r=i.call(this,t)||this,r.type=w1.UNIVERSAL,r.value="*",r}return e}(y1.default);jr.default=x1;ip.exports=jr.default});var ha=v((zr,np)=>{l();"use strict";zr.__esModule=!0;zr.default=void 0;var k1=C1(Ue()),S1=ae();function C1(i){return i&&i.__esModule?i:{default:i}}function A1(i,e){i.prototype=Object.create(e.prototype),i.prototype.constructor=i,da(i,e)}function da(i,e){return da=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(r,n){return r.__proto__=n,r},da(i,e)}var _1=function(i){A1(e,i);function e(t){var r;return r=i.call(this,t)||this,r.type=S1.COMBINATOR,r}return e}(k1.default);zr.default=_1;np.exports=zr.default});var ga=v((Vr,sp)=>{l();"use strict";Vr.__esModule=!0;Vr.default=void 0;var O1=T1(Ue()),E1=ae();function T1(i){return i&&i.__esModule?i:{default:i}}function P1(i,e){i.prototype=Object.create(e.prototype),i.prototype.constructor=i,ma(i,e)}function ma(i,e){return ma=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(r,n){return r.__proto__=n,r},ma(i,e)}var D1=function(i){P1(e,i);function e(t){var r;return r=i.call(this,t)||this,r.type=E1.NESTING,r.value="&",r}return e}(O1.default);Vr.default=D1;sp.exports=Vr.default});var op=v((nn,ap)=>{l();"use strict";nn.__esModule=!0;nn.default=I1;function I1(i){return i.sort(function(e,t){return e-t})}ap.exports=nn.default});var ya=v(D=>{l();"use strict";D.__esModule=!0;D.word=D.tilde=D.tab=D.str=D.space=D.slash=D.singleQuote=D.semicolon=D.plus=D.pipe=D.openSquare=D.openParenthesis=D.newline=D.greaterThan=D.feed=D.equals=D.doubleQuote=D.dollar=D.cr=D.comment=D.comma=D.combinator=D.colon=D.closeSquare=D.closeParenthesis=D.caret=D.bang=D.backslash=D.at=D.asterisk=D.ampersand=void 0;var q1=38;D.ampersand=q1;var R1=42;D.asterisk=R1;var M1=64;D.at=M1;var B1=44;D.comma=B1;var F1=58;D.colon=F1;var N1=59;D.semicolon=N1;var L1=40;D.openParenthesis=L1;var $1=41;D.closeParenthesis=$1;var j1=91;D.openSquare=j1;var z1=93;D.closeSquare=z1;var V1=36;D.dollar=V1;var U1=126;D.tilde=U1;var W1=94;D.caret=W1;var G1=43;D.plus=G1;var H1=61;D.equals=H1;var Y1=124;D.pipe=Y1;var Q1=62;D.greaterThan=Q1;var J1=32;D.space=J1;var lp=39;D.singleQuote=lp;var X1=34;D.doubleQuote=X1;var K1=47;D.slash=K1;var Z1=33;D.bang=Z1;var ek=92;D.backslash=ek;var tk=13;D.cr=tk;var rk=12;D.feed=rk;var ik=10;D.newline=ik;var nk=9;D.tab=nk;var sk=lp;D.str=sk;var ak=-1;D.comment=ak;var ok=-2;D.word=ok;var lk=-3;D.combinator=lk});var cp=v(Ur=>{l();"use strict";Ur.__esModule=!0;Ur.FIELDS=void 0;Ur.default=mk;var O=uk(ya()),It,V;function up(i){if(typeof WeakMap!="function")return null;var e=new WeakMap,t=new WeakMap;return(up=function(n){return n?t:e})(i)}function uk(i,e){if(!e&&i&&i.__esModule)return i;if(i===null||typeof i!="object"&&typeof i!="function")return{default:i};var t=up(e);if(t&&t.has(i))return t.get(i);var r={},n=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in i)if(a!=="default"&&Object.prototype.hasOwnProperty.call(i,a)){var s=n?Object.getOwnPropertyDescriptor(i,a):null;s&&(s.get||s.set)?Object.defineProperty(r,a,s):r[a]=i[a]}return r.default=i,t&&t.set(i,r),r}var fk=(It={},It[O.tab]=!0,It[O.newline]=!0,It[O.cr]=!0,It[O.feed]=!0,It),ck=(V={},V[O.space]=!0,V[O.tab]=!0,V[O.newline]=!0,V[O.cr]=!0,V[O.feed]=!0,V[O.ampersand]=!0,V[O.asterisk]=!0,V[O.bang]=!0,V[O.comma]=!0,V[O.colon]=!0,V[O.semicolon]=!0,V[O.openParenthesis]=!0,V[O.closeParenthesis]=!0,V[O.openSquare]=!0,V[O.closeSquare]=!0,V[O.singleQuote]=!0,V[O.doubleQuote]=!0,V[O.plus]=!0,V[O.pipe]=!0,V[O.tilde]=!0,V[O.greaterThan]=!0,V[O.equals]=!0,V[O.dollar]=!0,V[O.caret]=!0,V[O.slash]=!0,V),wa={},fp="0123456789abcdefABCDEF";for(sn=0;sn0?(k=s+x,S=w-y[x].length):(k=s,S=a),E=O.comment,s=k,p=k,d=w-S):c===O.slash?(w=o,E=c,p=s,d=o-a,u=w+1):(w=pk(t,o),E=O.word,p=s,d=w-a),u=w+1;break}e.push([E,s,o-a,p,d,o,u]),S&&(a=S,S=null),o=u}return e}});var bp=v((Wr,wp)=>{l();"use strict";Wr.__esModule=!0;Wr.default=void 0;var gk=ve(zs()),ba=ve(Us()),yk=ve(Hs()),pp=ve(Qs()),wk=ve(Xs()),bk=ve(ea()),va=ve(ra()),vk=ve(na()),dp=an(fa()),xk=ve(pa()),xa=ve(ha()),kk=ve(ga()),Sk=ve(op()),A=an(cp()),T=an(ya()),Ck=an(ae()),Y=_r(),vt,ka;function hp(i){if(typeof WeakMap!="function")return null;var e=new WeakMap,t=new WeakMap;return(hp=function(n){return n?t:e})(i)}function an(i,e){if(!e&&i&&i.__esModule)return i;if(i===null||typeof i!="object"&&typeof i!="function")return{default:i};var t=hp(e);if(t&&t.has(i))return t.get(i);var r={},n=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in i)if(a!=="default"&&Object.prototype.hasOwnProperty.call(i,a)){var s=n?Object.getOwnPropertyDescriptor(i,a):null;s&&(s.get||s.set)?Object.defineProperty(r,a,s):r[a]=i[a]}return r.default=i,t&&t.set(i,r),r}function ve(i){return i&&i.__esModule?i:{default:i}}function mp(i,e){for(var t=0;t0){var s=this.current.last;if(s){var o=this.convertWhitespaceNodesToSpace(a),u=o.space,c=o.rawSpace;c!==void 0&&(s.rawSpaceAfter+=c),s.spaces.after+=u}else a.forEach(function(E){return r.newNode(E)})}return}var f=this.currToken,d=void 0;n>this.position&&(d=this.parseWhitespaceEquivalentTokens(n));var p;if(this.isNamedCombinator()?p=this.namedCombinator():this.currToken[A.FIELDS.TYPE]===T.combinator?(p=new xa.default({value:this.content(),source:qt(this.currToken),sourceIndex:this.currToken[A.FIELDS.START_POS]}),this.position++):Sa[this.currToken[A.FIELDS.TYPE]]||d||this.unexpected(),p){if(d){var m=this.convertWhitespaceNodesToSpace(d),b=m.space,x=m.rawSpace;p.spaces.before=b,p.rawSpaceBefore=x}}else{var y=this.convertWhitespaceNodesToSpace(d,!0),w=y.space,k=y.rawSpace;k||(k=w);var S={},_={spaces:{}};w.endsWith(" ")&&k.endsWith(" ")?(S.before=w.slice(0,w.length-1),_.spaces.before=k.slice(0,k.length-1)):w.startsWith(" ")&&k.startsWith(" ")?(S.after=w.slice(1),_.spaces.after=k.slice(1)):_.value=k,p=new xa.default({value:" ",source:Ca(f,this.tokens[this.position-1]),sourceIndex:f[A.FIELDS.START_POS],spaces:S,raws:_})}return this.currToken&&this.currToken[A.FIELDS.TYPE]===T.space&&(p.spaces.after=this.optionalSpace(this.content()),this.position++),this.newNode(p)},e.comma=function(){if(this.position===this.tokens.length-1){this.root.trailingComma=!0,this.position++;return}this.current._inferEndPosition();var r=new ba.default({source:{start:gp(this.tokens[this.position+1])}});this.current.parent.append(r),this.current=r,this.position++},e.comment=function(){var r=this.currToken;this.newNode(new pp.default({value:this.content(),source:qt(r),sourceIndex:r[A.FIELDS.START_POS]})),this.position++},e.error=function(r,n){throw this.root.error(r,n)},e.missingBackslash=function(){return this.error("Expected a backslash preceding the semicolon.",{index:this.currToken[A.FIELDS.START_POS]})},e.missingParenthesis=function(){return this.expected("opening parenthesis",this.currToken[A.FIELDS.START_POS])},e.missingSquareBracket=function(){return this.expected("opening square bracket",this.currToken[A.FIELDS.START_POS])},e.unexpected=function(){return this.error("Unexpected '"+this.content()+"'. Escaping special characters with \\ may help.",this.currToken[A.FIELDS.START_POS])},e.unexpectedPipe=function(){return this.error("Unexpected '|'.",this.currToken[A.FIELDS.START_POS])},e.namespace=function(){var r=this.prevToken&&this.content(this.prevToken)||!0;if(this.nextToken[A.FIELDS.TYPE]===T.word)return this.position++,this.word(r);if(this.nextToken[A.FIELDS.TYPE]===T.asterisk)return this.position++,this.universal(r);this.unexpectedPipe()},e.nesting=function(){if(this.nextToken){var r=this.content(this.nextToken);if(r==="|"){this.position++;return}}var n=this.currToken;this.newNode(new kk.default({value:this.content(),source:qt(n),sourceIndex:n[A.FIELDS.START_POS]})),this.position++},e.parentheses=function(){var r=this.current.last,n=1;if(this.position++,r&&r.type===Ck.PSEUDO){var a=new ba.default({source:{start:gp(this.tokens[this.position-1])}}),s=this.current;for(r.append(a),this.current=a;this.position1&&r.nextToken&&r.nextToken[A.FIELDS.TYPE]===T.openParenthesis&&r.error("Misplaced parenthesis.",{index:r.nextToken[A.FIELDS.START_POS]})});else return this.expected(["pseudo-class","pseudo-element"],this.currToken[A.FIELDS.START_POS])},e.space=function(){var r=this.content();this.position===0||this.prevToken[A.FIELDS.TYPE]===T.comma||this.prevToken[A.FIELDS.TYPE]===T.openParenthesis||this.current.nodes.every(function(n){return n.type==="comment"})?(this.spaces=this.optionalSpace(r),this.position++):this.position===this.tokens.length-1||this.nextToken[A.FIELDS.TYPE]===T.comma||this.nextToken[A.FIELDS.TYPE]===T.closeParenthesis?(this.current.last.spaces.after=this.optionalSpace(r),this.position++):this.combinator()},e.string=function(){var r=this.currToken;this.newNode(new va.default({value:this.content(),source:qt(r),sourceIndex:r[A.FIELDS.START_POS]})),this.position++},e.universal=function(r){var n=this.nextToken;if(n&&this.content(n)==="|")return this.position++,this.namespace();var a=this.currToken;this.newNode(new xk.default({value:this.content(),source:qt(a),sourceIndex:a[A.FIELDS.START_POS]}),r),this.position++},e.splitWord=function(r,n){for(var a=this,s=this.nextToken,o=this.content();s&&~[T.dollar,T.caret,T.equals,T.word].indexOf(s[A.FIELDS.TYPE]);){this.position++;var u=this.content();if(o+=u,u.lastIndexOf("\\")===u.length-1){var c=this.nextToken;c&&c[A.FIELDS.TYPE]===T.space&&(o+=this.requiredSpace(this.content(c)),this.position++)}s=this.nextToken}var f=Aa(o,".").filter(function(b){var x=o[b-1]==="\\",y=/^\d+\.\d+%$/.test(o);return!x&&!y}),d=Aa(o,"#").filter(function(b){return o[b-1]!=="\\"}),p=Aa(o,"#{");p.length&&(d=d.filter(function(b){return!~p.indexOf(b)}));var m=(0,Sk.default)(Ok([0].concat(f,d)));m.forEach(function(b,x){var y=m[x+1]||o.length,w=o.slice(b,y);if(x===0&&n)return n.call(a,w,m.length);var k,S=a.currToken,_=S[A.FIELDS.START_POS]+m[x],E=xt(S[1],S[2]+b,S[3],S[2]+(y-1));if(~f.indexOf(b)){var I={value:w.slice(1),source:E,sourceIndex:_};k=new yk.default(Rt(I,"value"))}else if(~d.indexOf(b)){var q={value:w.slice(1),source:E,sourceIndex:_};k=new wk.default(Rt(q,"value"))}else{var R={value:w,source:E,sourceIndex:_};Rt(R,"value"),k=new bk.default(R)}a.newNode(k,r),r=null}),this.position++},e.word=function(r){var n=this.nextToken;return n&&this.content(n)==="|"?(this.position++,this.namespace()):this.splitWord(r)},e.loop=function(){for(;this.position{l();"use strict";Gr.__esModule=!0;Gr.default=void 0;var Tk=Pk(bp());function Pk(i){return i&&i.__esModule?i:{default:i}}var Dk=function(){function i(t,r){this.func=t||function(){},this.funcRes=null,this.options=r}var e=i.prototype;return e._shouldUpdateSelector=function(r,n){n===void 0&&(n={});var a=Object.assign({},this.options,n);return a.updateSelector===!1?!1:typeof r!="string"},e._isLossy=function(r){r===void 0&&(r={});var n=Object.assign({},this.options,r);return n.lossless===!1},e._root=function(r,n){n===void 0&&(n={});var a=new Tk.default(r,this._parseOptions(n));return a.root},e._parseOptions=function(r){return{lossy:this._isLossy(r)}},e._run=function(r,n){var a=this;return n===void 0&&(n={}),new Promise(function(s,o){try{var u=a._root(r,n);Promise.resolve(a.func(u)).then(function(c){var f=void 0;return a._shouldUpdateSelector(r,n)&&(f=u.toString(),r.selector=f),{transform:c,root:u,string:f}}).then(s,o)}catch(c){o(c);return}})},e._runSync=function(r,n){n===void 0&&(n={});var a=this._root(r,n),s=this.func(a);if(s&&typeof s.then=="function")throw new Error("Selector processor returned a promise to a synchronous call.");var o=void 0;return n.updateSelector&&typeof r!="string"&&(o=a.toString(),r.selector=o),{transform:s,root:a,string:o}},e.ast=function(r,n){return this._run(r,n).then(function(a){return a.root})},e.astSync=function(r,n){return this._runSync(r,n).root},e.transform=function(r,n){return this._run(r,n).then(function(a){return a.transform})},e.transformSync=function(r,n){return this._runSync(r,n).transform},e.process=function(r,n){return this._run(r,n).then(function(a){return a.string||a.root.toString()})},e.processSync=function(r,n){var a=this._runSync(r,n);return a.string||a.root.toString()},i}();Gr.default=Dk;vp.exports=Gr.default});var kp=v(G=>{l();"use strict";G.__esModule=!0;G.universal=G.tag=G.string=G.selector=G.root=G.pseudo=G.nesting=G.id=G.comment=G.combinator=G.className=G.attribute=void 0;var Ik=xe(fa()),qk=xe(Hs()),Rk=xe(ha()),Mk=xe(Qs()),Bk=xe(Xs()),Fk=xe(ga()),Nk=xe(na()),Lk=xe(zs()),$k=xe(Us()),jk=xe(ra()),zk=xe(ea()),Vk=xe(pa());function xe(i){return i&&i.__esModule?i:{default:i}}var Uk=function(e){return new Ik.default(e)};G.attribute=Uk;var Wk=function(e){return new qk.default(e)};G.className=Wk;var Gk=function(e){return new Rk.default(e)};G.combinator=Gk;var Hk=function(e){return new Mk.default(e)};G.comment=Hk;var Yk=function(e){return new Bk.default(e)};G.id=Yk;var Qk=function(e){return new Fk.default(e)};G.nesting=Qk;var Jk=function(e){return new Nk.default(e)};G.pseudo=Jk;var Xk=function(e){return new Lk.default(e)};G.root=Xk;var Kk=function(e){return new $k.default(e)};G.selector=Kk;var Zk=function(e){return new jk.default(e)};G.string=Zk;var eS=function(e){return new zk.default(e)};G.tag=eS;var tS=function(e){return new Vk.default(e)};G.universal=tS});var _p=v($=>{l();"use strict";$.__esModule=!0;$.isComment=$.isCombinator=$.isClassName=$.isAttribute=void 0;$.isContainer=dS;$.isIdentifier=void 0;$.isNamespace=hS;$.isNesting=void 0;$.isNode=_a;$.isPseudo=void 0;$.isPseudoClass=pS;$.isPseudoElement=Ap;$.isUniversal=$.isTag=$.isString=$.isSelector=$.isRoot=void 0;var Q=ae(),ce,rS=(ce={},ce[Q.ATTRIBUTE]=!0,ce[Q.CLASS]=!0,ce[Q.COMBINATOR]=!0,ce[Q.COMMENT]=!0,ce[Q.ID]=!0,ce[Q.NESTING]=!0,ce[Q.PSEUDO]=!0,ce[Q.ROOT]=!0,ce[Q.SELECTOR]=!0,ce[Q.STRING]=!0,ce[Q.TAG]=!0,ce[Q.UNIVERSAL]=!0,ce);function _a(i){return typeof i=="object"&&rS[i.type]}function ke(i,e){return _a(e)&&e.type===i}var Sp=ke.bind(null,Q.ATTRIBUTE);$.isAttribute=Sp;var iS=ke.bind(null,Q.CLASS);$.isClassName=iS;var nS=ke.bind(null,Q.COMBINATOR);$.isCombinator=nS;var sS=ke.bind(null,Q.COMMENT);$.isComment=sS;var aS=ke.bind(null,Q.ID);$.isIdentifier=aS;var oS=ke.bind(null,Q.NESTING);$.isNesting=oS;var Oa=ke.bind(null,Q.PSEUDO);$.isPseudo=Oa;var lS=ke.bind(null,Q.ROOT);$.isRoot=lS;var uS=ke.bind(null,Q.SELECTOR);$.isSelector=uS;var fS=ke.bind(null,Q.STRING);$.isString=fS;var Cp=ke.bind(null,Q.TAG);$.isTag=Cp;var cS=ke.bind(null,Q.UNIVERSAL);$.isUniversal=cS;function Ap(i){return Oa(i)&&i.value&&(i.value.startsWith("::")||i.value.toLowerCase()===":before"||i.value.toLowerCase()===":after"||i.value.toLowerCase()===":first-letter"||i.value.toLowerCase()===":first-line")}function pS(i){return Oa(i)&&!Ap(i)}function dS(i){return!!(_a(i)&&i.walk)}function hS(i){return Sp(i)||Cp(i)}});var Op=v(Te=>{l();"use strict";Te.__esModule=!0;var Ea=ae();Object.keys(Ea).forEach(function(i){i==="default"||i==="__esModule"||i in Te&&Te[i]===Ea[i]||(Te[i]=Ea[i])});var Ta=kp();Object.keys(Ta).forEach(function(i){i==="default"||i==="__esModule"||i in Te&&Te[i]===Ta[i]||(Te[i]=Ta[i])});var Pa=_p();Object.keys(Pa).forEach(function(i){i==="default"||i==="__esModule"||i in Te&&Te[i]===Pa[i]||(Te[i]=Pa[i])})});var Be=v((Hr,Tp)=>{l();"use strict";Hr.__esModule=!0;Hr.default=void 0;var mS=wS(xp()),gS=yS(Op());function Ep(i){if(typeof WeakMap!="function")return null;var e=new WeakMap,t=new WeakMap;return(Ep=function(n){return n?t:e})(i)}function yS(i,e){if(!e&&i&&i.__esModule)return i;if(i===null||typeof i!="object"&&typeof i!="function")return{default:i};var t=Ep(e);if(t&&t.has(i))return t.get(i);var r={},n=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in i)if(a!=="default"&&Object.prototype.hasOwnProperty.call(i,a)){var s=n?Object.getOwnPropertyDescriptor(i,a):null;s&&(s.get||s.set)?Object.defineProperty(r,a,s):r[a]=i[a]}return r.default=i,t&&t.set(i,r),r}function wS(i){return i&&i.__esModule?i:{default:i}}var Da=function(e){return new mS.default(e)};Object.assign(Da,gS);delete Da.__esModule;var bS=Da;Hr.default=bS;Tp.exports=Hr.default});function Ge(i){return["fontSize","outline"].includes(i)?e=>(typeof e=="function"&&(e=e({})),Array.isArray(e)&&(e=e[0]),e):i==="fontFamily"?e=>{typeof e=="function"&&(e=e({}));let t=Array.isArray(e)&&se(e[1])?e[0]:e;return Array.isArray(t)?t.join(", "):t}:["boxShadow","transitionProperty","transitionDuration","transitionDelay","transitionTimingFunction","backgroundImage","backgroundSize","backgroundColor","cursor","animation"].includes(i)?e=>(typeof e=="function"&&(e=e({})),Array.isArray(e)&&(e=e.join(", ")),e):["gridTemplateColumns","gridTemplateRows","objectPosition"].includes(i)?e=>(typeof e=="function"&&(e=e({})),typeof e=="string"&&(e=z.list.comma(e).join(" ")),e):(e,t={})=>(typeof e=="function"&&(e=e(t)),e)}var Yr=C(()=>{l();nt();Ct()});var Bp=v((a3,Ba)=>{l();var{Rule:Pp,AtRule:vS}=ye(),Dp=Be();function Ia(i,e){let t;try{Dp(r=>{t=r}).processSync(i)}catch(r){throw i.includes(":")?e?e.error("Missed semicolon"):r:e?e.error(r.message):r}return t.at(0)}function Ip(i,e){let t=!1;return i.each(r=>{if(r.type==="nesting"){let n=e.clone({});r.value!=="&"?r.replaceWith(Ia(r.value.replace("&",n.toString()))):r.replaceWith(n),t=!0}else"nodes"in r&&r.nodes&&Ip(r,e)&&(t=!0)}),t}function qp(i,e){let t=[];return i.selectors.forEach(r=>{let n=Ia(r,i);e.selectors.forEach(a=>{if(!a)return;let s=Ia(a,e);Ip(s,n)||(s.prepend(Dp.combinator({value:" "})),s.prepend(n.clone({}))),t.push(s.toString())})}),t}function on(i,e){let t=i.prev();for(e.after(i);t&&t.type==="comment";){let r=t.prev();e.after(t),t=r}return i}function xS(i){return function e(t,r,n,a=n){let s=[];if(r.each(o=>{o.type==="rule"&&n?a&&(o.selectors=qp(t,o)):o.type==="atrule"&&o.nodes?i[o.name]?e(t,o,a):r[Ra]!==!1&&s.push(o):s.push(o)}),n&&s.length){let o=t.clone({nodes:[]});for(let u of s)o.append(u);r.prepend(o)}}}function qa(i,e,t){let r=new Pp({selector:i,nodes:[]});return r.append(e),t.after(r),r}function Rp(i,e){let t={};for(let r of i)t[r]=!0;if(e)for(let r of e)t[r.replace(/^@/,"")]=!0;return t}function kS(i){i=i.trim();let e=i.match(/^\((.*)\)$/);if(!e)return{type:"basic",selector:i};let t=e[1].match(/^(with(?:out)?):(.+)$/);if(t){let r=t[1]==="with",n=Object.fromEntries(t[2].trim().split(/\s+/).map(s=>[s,!0]));if(r&&n.all)return{type:"noop"};let a=s=>!!n[s];return n.all?a=()=>!0:r&&(a=s=>s==="all"?!1:!n[s]),{type:"withrules",escapes:a}}return{type:"unknown"}}function SS(i){let e=[],t=i.parent;for(;t&&t instanceof vS;)e.push(t),t=t.parent;return e}function CS(i){let e=i[Mp];if(!e)i.after(i.nodes);else{let t=i.nodes,r,n=-1,a,s,o,u=SS(i);if(u.forEach((c,f)=>{if(e(c.name))r=c,n=f,s=o;else{let d=o;o=c.clone({nodes:[]}),d&&o.append(d),a=a||o}}),r?s?(a.append(t),r.after(s)):r.after(t):i.after(t),i.next()&&r){let c;u.slice(0,n+1).forEach((f,d,p)=>{let m=c;c=f.clone({nodes:[]}),m&&c.append(m);let b=[],y=(p[d-1]||i).next();for(;y;)b.push(y),y=y.next();c.append(b)}),c&&(s||t[t.length-1]).after(c)}}i.remove()}var Ra=Symbol("rootRuleMergeSel"),Mp=Symbol("rootRuleEscapes");function AS(i){let{params:e}=i,{type:t,selector:r,escapes:n}=kS(e);if(t==="unknown")throw i.error(`Unknown @${i.name} parameter ${JSON.stringify(e)}`);if(t==="basic"&&r){let a=new Pp({selector:r,nodes:i.nodes});i.removeAll(),i.append(a)}i[Mp]=n,i[Ra]=n?!n("all"):t==="noop"}var Ma=Symbol("hasRootRule");Ba.exports=(i={})=>{let e=Rp(["media","supports","layer","container"],i.bubble),t=xS(e),r=Rp(["document","font-face","keyframes","-webkit-keyframes","-moz-keyframes"],i.unwrap),n=(i.rootRuleName||"at-root").replace(/^@/,""),a=i.preserveEmpty;return{postcssPlugin:"postcss-nested",Once(s){s.walkAtRules(n,o=>{AS(o),s[Ma]=!0})},Rule(s){let o=!1,u=s,c=!1,f=[];s.each(d=>{d.type==="rule"?(f.length&&(u=qa(s.selector,f,u),f=[]),c=!0,o=!0,d.selectors=qp(s,d),u=on(d,u)):d.type==="atrule"?(f.length&&(u=qa(s.selector,f,u),f=[]),d.name===n?(o=!0,t(s,d,!0,d[Ra]),u=on(d,u)):e[d.name]?(c=!0,o=!0,t(s,d,!0),u=on(d,u)):r[d.name]?(c=!0,o=!0,t(s,d,!1),u=on(d,u)):c&&f.push(d)):d.type==="decl"&&c&&f.push(d)}),f.length&&(u=qa(s.selector,f,u)),o&&a!==!0&&(s.raws.semicolon=!0,s.nodes.length===0&&s.remove())},RootExit(s){s[Ma]&&(s.walkAtRules(n,CS),s[Ma]=!1)}}};Ba.exports.postcss=!0});var $p=v((o3,Lp)=>{l();"use strict";var Fp=/-(\w|$)/g,Np=(i,e)=>e.toUpperCase(),_S=i=>(i=i.toLowerCase(),i==="float"?"cssFloat":i.startsWith("-ms-")?i.substr(1).replace(Fp,Np):i.replace(Fp,Np));Lp.exports=_S});var La=v((l3,jp)=>{l();var OS=$p(),ES={boxFlex:!0,boxFlexGroup:!0,columnCount:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,strokeDashoffset:!0,strokeOpacity:!0,strokeWidth:!0};function Fa(i){return typeof i.nodes=="undefined"?!0:Na(i)}function Na(i){let e,t={};return i.each(r=>{if(r.type==="atrule")e="@"+r.name,r.params&&(e+=" "+r.params),typeof t[e]=="undefined"?t[e]=Fa(r):Array.isArray(t[e])?t[e].push(Fa(r)):t[e]=[t[e],Fa(r)];else if(r.type==="rule"){let n=Na(r);if(t[r.selector])for(let a in n)t[r.selector][a]=n[a];else t[r.selector]=n}else if(r.type==="decl"){r.prop[0]==="-"&&r.prop[1]==="-"||r.parent&&r.parent.selector===":export"?e=r.prop:e=OS(r.prop);let n=r.value;!isNaN(r.value)&&ES[e]&&(n=parseFloat(r.value)),r.important&&(n+=" !important"),typeof t[e]=="undefined"?t[e]=n:Array.isArray(t[e])?t[e].push(n):t[e]=[t[e],n]}}),t}jp.exports=Na});var ln=v((u3,Wp)=>{l();var Qr=ye(),zp=/\s*!important\s*$/i,TS={"box-flex":!0,"box-flex-group":!0,"column-count":!0,flex:!0,"flex-grow":!0,"flex-positive":!0,"flex-shrink":!0,"flex-negative":!0,"font-weight":!0,"line-clamp":!0,"line-height":!0,opacity:!0,order:!0,orphans:!0,"tab-size":!0,widows:!0,"z-index":!0,zoom:!0,"fill-opacity":!0,"stroke-dashoffset":!0,"stroke-opacity":!0,"stroke-width":!0};function PS(i){return i.replace(/([A-Z])/g,"-$1").replace(/^ms-/,"-ms-").toLowerCase()}function Vp(i,e,t){t===!1||t===null||(e.startsWith("--")||(e=PS(e)),typeof t=="number"&&(t===0||TS[e]?t=t.toString():t+="px"),e==="css-float"&&(e="float"),zp.test(t)?(t=t.replace(zp,""),i.push(Qr.decl({prop:e,value:t,important:!0}))):i.push(Qr.decl({prop:e,value:t})))}function Up(i,e,t){let r=Qr.atRule({name:e[1],params:e[3]||""});typeof t=="object"&&(r.nodes=[],$a(t,r)),i.push(r)}function $a(i,e){let t,r,n;for(t in i)if(r=i[t],!(r===null||typeof r=="undefined"))if(t[0]==="@"){let a=t.match(/@(\S+)(\s+([\W\w]*)\s*)?/);if(Array.isArray(r))for(let s of r)Up(e,a,s);else Up(e,a,r)}else if(Array.isArray(r))for(let a of r)Vp(e,t,a);else typeof r=="object"?(n=Qr.rule({selector:t}),$a(r,n),e.push(n)):Vp(e,t,r)}Wp.exports=function(i){let e=Qr.root();return $a(i,e),e}});var ja=v((f3,Gp)=>{l();var DS=La();Gp.exports=function(e){return console&&console.warn&&e.warnings().forEach(t=>{let r=t.plugin||"PostCSS";console.warn(r+": "+t.text)}),DS(e.root)}});var Yp=v((c3,Hp)=>{l();var IS=ye(),qS=ja(),RS=ln();Hp.exports=function(e){let t=IS(e);return async r=>{let n=await t.process(r,{parser:RS,from:void 0});return qS(n)}}});var Jp=v((p3,Qp)=>{l();var MS=ye(),BS=ja(),FS=ln();Qp.exports=function(i){let e=MS(i);return t=>{let r=e.process(t,{parser:FS,from:void 0});return BS(r)}}});var Kp=v((d3,Xp)=>{l();var NS=La(),LS=ln(),$S=Yp(),jS=Jp();Xp.exports={objectify:NS,parse:LS,async:$S,sync:jS}});var Mt,Zp,h3,m3,g3,y3,ed=C(()=>{l();Mt=X(Kp()),Zp=Mt.default,h3=Mt.default.objectify,m3=Mt.default.parse,g3=Mt.default.async,y3=Mt.default.sync});function Bt(i){return Array.isArray(i)?i.flatMap(e=>z([(0,td.default)({bubble:["screen"]})]).process(e,{parser:Zp}).root.nodes):Bt([i])}var td,za=C(()=>{l();nt();td=X(Bp());ed()});function Ft(i,e,t=!1){if(i==="")return e;let r=typeof e=="string"?(0,rd.default)().astSync(e):e;return r.walkClasses(n=>{let a=n.value,s=t&&a.startsWith("-");n.value=s?`-${i}${a.slice(1)}`:`${i}${a}`}),typeof e=="string"?r.toString():r}var rd,un=C(()=>{l();rd=X(Be())});function pe(i){let e=id.default.className();return e.value=i,gt(e?.raws?.value??e.value)}var id,Nt=C(()=>{l();id=X(Be());mi()});function Va(i){return gt(`.${pe(i)}`)}function fn(i,e){return Va(Jr(i,e))}function Jr(i,e){return e==="DEFAULT"?i:e==="-"||e==="-DEFAULT"?`-${i}`:e.startsWith("-")?`-${i}${e}`:e.startsWith("/")?`${i}${e}`:`${i}-${e}`}var Ua=C(()=>{l();Nt();mi()});function P(i,e=[[i,[i]]],{filterDefault:t=!1,...r}={}){let n=Ge(i);return function({matchUtilities:a,theme:s}){for(let o of e){let u=Array.isArray(o[0])?o:[o];a(u.reduce((c,[f,d])=>Object.assign(c,{[f]:p=>d.reduce((m,b)=>Array.isArray(b)?Object.assign(m,{[b[0]]:b[1]}):Object.assign(m,{[b]:n(p)}),{})}),{}),{...r,values:t?Object.fromEntries(Object.entries(s(i)??{}).filter(([c])=>c!=="DEFAULT")):s(i)})}}}var nd=C(()=>{l();Yr()});function st(i){return i=Array.isArray(i)?i:[i],i.map(e=>{let t=e.values.map(r=>r.raw!==void 0?r.raw:[r.min&&`(min-width: ${r.min})`,r.max&&`(max-width: ${r.max})`].filter(Boolean).join(" and "));return e.not?`not all and ${t}`:t}).join(", ")}var cn=C(()=>{l()});function Wa(i){return i.split(YS).map(t=>{let r=t.trim(),n={value:r},a=r.split(QS),s=new Set;for(let o of a)!s.has("DIRECTIONS")&&zS.has(o)?(n.direction=o,s.add("DIRECTIONS")):!s.has("PLAY_STATES")&&VS.has(o)?(n.playState=o,s.add("PLAY_STATES")):!s.has("FILL_MODES")&&US.has(o)?(n.fillMode=o,s.add("FILL_MODES")):!s.has("ITERATION_COUNTS")&&(WS.has(o)||JS.test(o))?(n.iterationCount=o,s.add("ITERATION_COUNTS")):!s.has("TIMING_FUNCTION")&&GS.has(o)||!s.has("TIMING_FUNCTION")&&HS.some(u=>o.startsWith(`${u}(`))?(n.timingFunction=o,s.add("TIMING_FUNCTION")):!s.has("DURATION")&&sd.test(o)?(n.duration=o,s.add("DURATION")):!s.has("DELAY")&&sd.test(o)?(n.delay=o,s.add("DELAY")):s.has("NAME")?(n.unknown||(n.unknown=[]),n.unknown.push(o)):(n.name=o,s.add("NAME"));return n})}var zS,VS,US,WS,GS,HS,YS,QS,sd,JS,ad=C(()=>{l();zS=new Set(["normal","reverse","alternate","alternate-reverse"]),VS=new Set(["running","paused"]),US=new Set(["none","forwards","backwards","both"]),WS=new Set(["infinite"]),GS=new Set(["linear","ease","ease-in","ease-out","ease-in-out","step-start","step-end"]),HS=["cubic-bezier","steps"],YS=/\,(?![^(]*\))/g,QS=/\ +(?![^(]*\))/g,sd=/^(-?[\d.]+m?s)$/,JS=/^(\d+)$/});var od,ne,ld=C(()=>{l();od=i=>Object.assign({},...Object.entries(i??{}).flatMap(([e,t])=>typeof t=="object"?Object.entries(od(t)).map(([r,n])=>({[e+(r==="DEFAULT"?"":`-${r}`)]:n})):[{[`${e}`]:t}])),ne=od});var fd,ud=C(()=>{fd="3.4.5"});function at(i,e=!0){return Array.isArray(i)?i.map(t=>{if(e&&Array.isArray(t))throw new Error("The tuple syntax is not supported for `screens`.");if(typeof t=="string")return{name:t.toString(),not:!1,values:[{min:t,max:void 0}]};let[r,n]=t;return r=r.toString(),typeof n=="string"?{name:r,not:!1,values:[{min:n,max:void 0}]}:Array.isArray(n)?{name:r,not:!1,values:n.map(a=>pd(a))}:{name:r,not:!1,values:[pd(n)]}}):at(Object.entries(i??{}),!1)}function pn(i){return i.values.length!==1?{result:!1,reason:"multiple-values"}:i.values[0].raw!==void 0?{result:!1,reason:"raw-values"}:i.values[0].min!==void 0&&i.values[0].max!==void 0?{result:!1,reason:"min-and-max"}:{result:!0,reason:null}}function cd(i,e,t){let r=dn(e,i),n=dn(t,i),a=pn(r),s=pn(n);if(a.reason==="multiple-values"||s.reason==="multiple-values")throw new Error("Attempted to sort a screen with multiple values. This should never happen. Please open a bug report.");if(a.reason==="raw-values"||s.reason==="raw-values")throw new Error("Attempted to sort a screen with raw values. This should never happen. Please open a bug report.");if(a.reason==="min-and-max"||s.reason==="min-and-max")throw new Error("Attempted to sort a screen with both min and max values. This should never happen. Please open a bug report.");let{min:o,max:u}=r.values[0],{min:c,max:f}=n.values[0];e.not&&([o,u]=[u,o]),t.not&&([c,f]=[f,c]),o=o===void 0?o:parseFloat(o),u=u===void 0?u:parseFloat(u),c=c===void 0?c:parseFloat(c),f=f===void 0?f:parseFloat(f);let[d,p]=i==="min"?[o,c]:[f,u];return d-p}function dn(i,e){return typeof i=="object"?i:{name:"arbitrary-screen",values:[{[e]:i}]}}function pd({"min-width":i,min:e=i,max:t,raw:r}={}){return{min:e,max:t,raw:r}}var hn=C(()=>{l()});function mn(i,e){i.walkDecls(t=>{if(e.includes(t.prop)){t.remove();return}for(let r of e)t.value.includes(`/ var(${r})`)&&(t.value=t.value.replace(`/ var(${r})`,""))})}var dd=C(()=>{l()});var H,Pe,Fe,K,hd,md=C(()=>{l();je();wt();nt();nd();cn();Nt();ad();ld();lr();cs();Ct();Yr();ud();Ee();hn();ns();dd();ze();cr();Xr();H={childVariant:({addVariant:i})=>{i("*","& > *")},pseudoElementVariants:({addVariant:i})=>{i("first-letter","&::first-letter"),i("first-line","&::first-line"),i("marker",[({container:e})=>(mn(e,["--tw-text-opacity"]),"& *::marker"),({container:e})=>(mn(e,["--tw-text-opacity"]),"&::marker")]),i("selection",["& *::selection","&::selection"]),i("file","&::file-selector-button"),i("placeholder","&::placeholder"),i("backdrop","&::backdrop"),i("before",({container:e})=>(e.walkRules(t=>{let r=!1;t.walkDecls("content",()=>{r=!0}),r||t.prepend(z.decl({prop:"content",value:"var(--tw-content)"}))}),"&::before")),i("after",({container:e})=>(e.walkRules(t=>{let r=!1;t.walkDecls("content",()=>{r=!0}),r||t.prepend(z.decl({prop:"content",value:"var(--tw-content)"}))}),"&::after"))},pseudoClassVariants:({addVariant:i,matchVariant:e,config:t,prefix:r})=>{let n=[["first","&:first-child"],["last","&:last-child"],["only","&:only-child"],["odd","&:nth-child(odd)"],["even","&:nth-child(even)"],"first-of-type","last-of-type","only-of-type",["visited",({container:s})=>(mn(s,["--tw-text-opacity","--tw-border-opacity","--tw-bg-opacity"]),"&:visited")],"target",["open","&[open]"],"default","checked","indeterminate","placeholder-shown","autofill","optional","required","valid","invalid","in-range","out-of-range","read-only","empty","focus-within",["hover",Z(t(),"hoverOnlyWhenSupported")?"@media (hover: hover) and (pointer: fine) { &:hover }":"&:hover"],"focus","focus-visible","active","enabled","disabled"].map(s=>Array.isArray(s)?s:[s,`&:${s}`]);for(let[s,o]of n)i(s,u=>typeof o=="function"?o(u):o);let a={group:(s,{modifier:o})=>o?[`:merge(${r(".group")}\\/${pe(o)})`," &"]:[`:merge(${r(".group")})`," &"],peer:(s,{modifier:o})=>o?[`:merge(${r(".peer")}\\/${pe(o)})`," ~ &"]:[`:merge(${r(".peer")})`," ~ &"]};for(let[s,o]of Object.entries(a))e(s,(u="",c)=>{let f=N(typeof u=="function"?u(c):u);f.includes("&")||(f="&"+f);let[d,p]=o("",c),m=null,b=null,x=0;for(let y=0;y{i("ltr",'&:where([dir="ltr"], [dir="ltr"] *)'),i("rtl",'&:where([dir="rtl"], [dir="rtl"] *)')},reducedMotionVariants:({addVariant:i})=>{i("motion-safe","@media (prefers-reduced-motion: no-preference)"),i("motion-reduce","@media (prefers-reduced-motion: reduce)")},darkVariants:({config:i,addVariant:e})=>{let[t,r=".dark"]=[].concat(i("darkMode","media"));if(t===!1&&(t="media",F.warn("darkmode-false",["The `darkMode` option in your Tailwind CSS configuration is set to `false`, which now behaves the same as `media`.","Change `darkMode` to `media` or remove it entirely.","https://tailwindcss.com/docs/upgrade-guide#remove-dark-mode-configuration"])),t==="variant"){let n;if(Array.isArray(r)||typeof r=="function"?n=r:typeof r=="string"&&(n=[r]),Array.isArray(n))for(let a of n)a===".dark"?(t=!1,F.warn("darkmode-variant-without-selector",["When using `variant` for `darkMode`, you must provide a selector.",'Example: `darkMode: ["variant", ".your-selector &"]`'])):a.includes("&")||(t=!1,F.warn("darkmode-variant-without-ampersand",["When using `variant` for `darkMode`, your selector must contain `&`.",'Example `darkMode: ["variant", ".your-selector &"]`']));r=n}t==="selector"?e("dark",`&:where(${r}, ${r} *)`):t==="media"?e("dark","@media (prefers-color-scheme: dark)"):t==="variant"?e("dark",r):t==="class"&&e("dark",`&:is(${r} *)`)},printVariant:({addVariant:i})=>{i("print","@media print")},screenVariants:({theme:i,addVariant:e,matchVariant:t})=>{let r=i("screens")??{},n=Object.values(r).every(w=>typeof w=="string"),a=at(i("screens")),s=new Set([]);function o(w){return w.match(/(\D+)$/)?.[1]??"(none)"}function u(w){w!==void 0&&s.add(o(w))}function c(w){return u(w),s.size===1}for(let w of a)for(let k of w.values)u(k.min),u(k.max);let f=s.size<=1;function d(w){return Object.fromEntries(a.filter(k=>pn(k).result).map(k=>{let{min:S,max:_}=k.values[0];if(w==="min"&&S!==void 0)return k;if(w==="min"&&_!==void 0)return{...k,not:!k.not};if(w==="max"&&_!==void 0)return k;if(w==="max"&&S!==void 0)return{...k,not:!k.not}}).map(k=>[k.name,k]))}function p(w){return(k,S)=>cd(w,k.value,S.value)}let m=p("max"),b=p("min");function x(w){return k=>{if(n)if(f){if(typeof k=="string"&&!c(k))return F.warn("minmax-have-mixed-units",["The `min-*` and `max-*` variants are not supported with a `screens` configuration containing mixed units."]),[]}else return F.warn("mixed-screen-units",["The `min-*` and `max-*` variants are not supported with a `screens` configuration containing mixed units."]),[];else return F.warn("complex-screen-config",["The `min-*` and `max-*` variants are not supported with a `screens` configuration containing objects."]),[];return[`@media ${st(dn(k,w))}`]}}t("max",x("max"),{sort:m,values:n?d("max"):{}});let y="min-screens";for(let w of a)e(w.name,`@media ${st(w)}`,{id:y,sort:n&&f?b:void 0,value:w});t("min",x("min"),{id:y,sort:b})},supportsVariants:({matchVariant:i,theme:e})=>{i("supports",(t="")=>{let r=N(t),n=/^\w*\s*\(/.test(r);return r=n?r.replace(/\b(and|or|not)\b/g," $1 "):r,n?`@supports ${r}`:(r.includes(":")||(r=`${r}: var(--tw)`),r.startsWith("(")&&r.endsWith(")")||(r=`(${r})`),`@supports ${r}`)},{values:e("supports")??{}})},hasVariants:({matchVariant:i,prefix:e})=>{i("has",t=>`&:has(${N(t)})`,{values:{},[ot]:{respectPrefix:!1}}),i("group-has",(t,{modifier:r})=>r?`:merge(${e(".group")}\\/${r}):has(${N(t)}) &`:`:merge(${e(".group")}):has(${N(t)}) &`,{values:{},[ot]:{respectPrefix:!1}}),i("peer-has",(t,{modifier:r})=>r?`:merge(${e(".peer")}\\/${r}):has(${N(t)}) ~ &`:`:merge(${e(".peer")}):has(${N(t)}) ~ &`,{values:{},[ot]:{respectPrefix:!1}})},ariaVariants:({matchVariant:i,theme:e})=>{i("aria",t=>`&[aria-${N(t)}]`,{values:e("aria")??{}}),i("group-aria",(t,{modifier:r})=>r?`:merge(.group\\/${r})[aria-${N(t)}] &`:`:merge(.group)[aria-${N(t)}] &`,{values:e("aria")??{}}),i("peer-aria",(t,{modifier:r})=>r?`:merge(.peer\\/${r})[aria-${N(t)}] ~ &`:`:merge(.peer)[aria-${N(t)}] ~ &`,{values:e("aria")??{}})},dataVariants:({matchVariant:i,theme:e})=>{i("data",t=>`&[data-${N(t)}]`,{values:e("data")??{}}),i("group-data",(t,{modifier:r})=>r?`:merge(.group\\/${r})[data-${N(t)}] &`:`:merge(.group)[data-${N(t)}] &`,{values:e("data")??{}}),i("peer-data",(t,{modifier:r})=>r?`:merge(.peer\\/${r})[data-${N(t)}] ~ &`:`:merge(.peer)[data-${N(t)}] ~ &`,{values:e("data")??{}})},orientationVariants:({addVariant:i})=>{i("portrait","@media (orientation: portrait)"),i("landscape","@media (orientation: landscape)")},prefersContrastVariants:({addVariant:i})=>{i("contrast-more","@media (prefers-contrast: more)"),i("contrast-less","@media (prefers-contrast: less)")},forcedColorsVariants:({addVariant:i})=>{i("forced-colors","@media (forced-colors: active)")}},Pe=["translate(var(--tw-translate-x), var(--tw-translate-y))","rotate(var(--tw-rotate))","skewX(var(--tw-skew-x))","skewY(var(--tw-skew-y))","scaleX(var(--tw-scale-x))","scaleY(var(--tw-scale-y))"].join(" "),Fe=["var(--tw-blur)","var(--tw-brightness)","var(--tw-contrast)","var(--tw-grayscale)","var(--tw-hue-rotate)","var(--tw-invert)","var(--tw-saturate)","var(--tw-sepia)","var(--tw-drop-shadow)"].join(" "),K=["var(--tw-backdrop-blur)","var(--tw-backdrop-brightness)","var(--tw-backdrop-contrast)","var(--tw-backdrop-grayscale)","var(--tw-backdrop-hue-rotate)","var(--tw-backdrop-invert)","var(--tw-backdrop-opacity)","var(--tw-backdrop-saturate)","var(--tw-backdrop-sepia)"].join(" "),hd={preflight:({addBase:i})=>{let e=z.parse(`*,::after,::before{box-sizing:border-box;border-width:0;border-style:solid;border-color:theme('borderColor.DEFAULT', currentColor)}::after,::before{--tw-content:''}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;font-family:theme('fontFamily.sans', ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:theme('fontFamily.sans[1].fontFeatureSettings', normal);font-variation-settings:theme('fontFamily.sans[1].fontVariationSettings', normal);-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:theme('fontFamily.mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:theme('fontFamily.mono[1].fontFeatureSettings', normal);font-variation-settings:theme('fontFamily.mono[1].fontVariationSettings', normal);font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::placeholder,textarea::placeholder{opacity:1;color:theme('colors.gray.4', #9ca3af)}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}`);i([z.comment({text:`! tailwindcss v${fd} | MIT License | https://tailwindcss.com`}),...e.nodes])},container:(()=>{function i(t=[]){return t.flatMap(r=>r.values.map(n=>n.min)).filter(r=>r!==void 0)}function e(t,r,n){if(typeof n=="undefined")return[];if(!(typeof n=="object"&&n!==null))return[{screen:"DEFAULT",minWidth:0,padding:n}];let a=[];n.DEFAULT&&a.push({screen:"DEFAULT",minWidth:0,padding:n.DEFAULT});for(let s of t)for(let o of r)for(let{min:u}of o.values)u===s&&a.push({minWidth:s,padding:n[o.name]});return a}return function({addComponents:t,theme:r}){let n=at(r("container.screens",r("screens"))),a=i(n),s=e(a,n,r("container.padding")),o=c=>{let f=s.find(d=>d.minWidth===c);return f?{paddingRight:f.padding,paddingLeft:f.padding}:{}},u=Array.from(new Set(a.slice().sort((c,f)=>parseInt(c)-parseInt(f)))).map(c=>({[`@media (min-width: ${c})`]:{".container":{"max-width":c,...o(c)}}}));t([{".container":Object.assign({width:"100%"},r("container.center",!1)?{marginRight:"auto",marginLeft:"auto"}:{},o(0))},...u])}})(),accessibility:({addUtilities:i})=>{i({".sr-only":{position:"absolute",width:"1px",height:"1px",padding:"0",margin:"-1px",overflow:"hidden",clip:"rect(0, 0, 0, 0)",whiteSpace:"nowrap",borderWidth:"0"},".not-sr-only":{position:"static",width:"auto",height:"auto",padding:"0",margin:"0",overflow:"visible",clip:"auto",whiteSpace:"normal"}})},pointerEvents:({addUtilities:i})=>{i({".pointer-events-none":{"pointer-events":"none"},".pointer-events-auto":{"pointer-events":"auto"}})},visibility:({addUtilities:i})=>{i({".visible":{visibility:"visible"},".invisible":{visibility:"hidden"},".collapse":{visibility:"collapse"}})},position:({addUtilities:i})=>{i({".static":{position:"static"},".fixed":{position:"fixed"},".absolute":{position:"absolute"},".relative":{position:"relative"},".sticky":{position:"sticky"}})},inset:P("inset",[["inset",["inset"]],[["inset-x",["left","right"]],["inset-y",["top","bottom"]]],[["start",["inset-inline-start"]],["end",["inset-inline-end"]],["top",["top"]],["right",["right"]],["bottom",["bottom"]],["left",["left"]]]],{supportsNegativeValues:!0}),isolation:({addUtilities:i})=>{i({".isolate":{isolation:"isolate"},".isolation-auto":{isolation:"auto"}})},zIndex:P("zIndex",[["z",["zIndex"]]],{supportsNegativeValues:!0}),order:P("order",void 0,{supportsNegativeValues:!0}),gridColumn:P("gridColumn",[["col",["gridColumn"]]]),gridColumnStart:P("gridColumnStart",[["col-start",["gridColumnStart"]]],{supportsNegativeValues:!0}),gridColumnEnd:P("gridColumnEnd",[["col-end",["gridColumnEnd"]]],{supportsNegativeValues:!0}),gridRow:P("gridRow",[["row",["gridRow"]]]),gridRowStart:P("gridRowStart",[["row-start",["gridRowStart"]]],{supportsNegativeValues:!0}),gridRowEnd:P("gridRowEnd",[["row-end",["gridRowEnd"]]],{supportsNegativeValues:!0}),float:({addUtilities:i})=>{i({".float-start":{float:"inline-start"},".float-end":{float:"inline-end"},".float-right":{float:"right"},".float-left":{float:"left"},".float-none":{float:"none"}})},clear:({addUtilities:i})=>{i({".clear-start":{clear:"inline-start"},".clear-end":{clear:"inline-end"},".clear-left":{clear:"left"},".clear-right":{clear:"right"},".clear-both":{clear:"both"},".clear-none":{clear:"none"}})},margin:P("margin",[["m",["margin"]],[["mx",["margin-left","margin-right"]],["my",["margin-top","margin-bottom"]]],[["ms",["margin-inline-start"]],["me",["margin-inline-end"]],["mt",["margin-top"]],["mr",["margin-right"]],["mb",["margin-bottom"]],["ml",["margin-left"]]]],{supportsNegativeValues:!0}),boxSizing:({addUtilities:i})=>{i({".box-border":{"box-sizing":"border-box"},".box-content":{"box-sizing":"content-box"}})},lineClamp:({matchUtilities:i,addUtilities:e,theme:t})=>{i({"line-clamp":r=>({overflow:"hidden",display:"-webkit-box","-webkit-box-orient":"vertical","-webkit-line-clamp":`${r}`})},{values:t("lineClamp")}),e({".line-clamp-none":{overflow:"visible",display:"block","-webkit-box-orient":"horizontal","-webkit-line-clamp":"none"}})},display:({addUtilities:i})=>{i({".block":{display:"block"},".inline-block":{display:"inline-block"},".inline":{display:"inline"},".flex":{display:"flex"},".inline-flex":{display:"inline-flex"},".table":{display:"table"},".inline-table":{display:"inline-table"},".table-caption":{display:"table-caption"},".table-cell":{display:"table-cell"},".table-column":{display:"table-column"},".table-column-group":{display:"table-column-group"},".table-footer-group":{display:"table-footer-group"},".table-header-group":{display:"table-header-group"},".table-row-group":{display:"table-row-group"},".table-row":{display:"table-row"},".flow-root":{display:"flow-root"},".grid":{display:"grid"},".inline-grid":{display:"inline-grid"},".contents":{display:"contents"},".list-item":{display:"list-item"},".hidden":{display:"none"}})},aspectRatio:P("aspectRatio",[["aspect",["aspect-ratio"]]]),size:P("size",[["size",["width","height"]]]),height:P("height",[["h",["height"]]]),maxHeight:P("maxHeight",[["max-h",["maxHeight"]]]),minHeight:P("minHeight",[["min-h",["minHeight"]]]),width:P("width",[["w",["width"]]]),minWidth:P("minWidth",[["min-w",["minWidth"]]]),maxWidth:P("maxWidth",[["max-w",["maxWidth"]]]),flex:P("flex"),flexShrink:P("flexShrink",[["flex-shrink",["flex-shrink"]],["shrink",["flex-shrink"]]]),flexGrow:P("flexGrow",[["flex-grow",["flex-grow"]],["grow",["flex-grow"]]]),flexBasis:P("flexBasis",[["basis",["flex-basis"]]]),tableLayout:({addUtilities:i})=>{i({".table-auto":{"table-layout":"auto"},".table-fixed":{"table-layout":"fixed"}})},captionSide:({addUtilities:i})=>{i({".caption-top":{"caption-side":"top"},".caption-bottom":{"caption-side":"bottom"}})},borderCollapse:({addUtilities:i})=>{i({".border-collapse":{"border-collapse":"collapse"},".border-separate":{"border-collapse":"separate"}})},borderSpacing:({addDefaults:i,matchUtilities:e,theme:t})=>{i("border-spacing",{"--tw-border-spacing-x":0,"--tw-border-spacing-y":0}),e({"border-spacing":r=>({"--tw-border-spacing-x":r,"--tw-border-spacing-y":r,"@defaults border-spacing":{},"border-spacing":"var(--tw-border-spacing-x) var(--tw-border-spacing-y)"}),"border-spacing-x":r=>({"--tw-border-spacing-x":r,"@defaults border-spacing":{},"border-spacing":"var(--tw-border-spacing-x) var(--tw-border-spacing-y)"}),"border-spacing-y":r=>({"--tw-border-spacing-y":r,"@defaults border-spacing":{},"border-spacing":"var(--tw-border-spacing-x) var(--tw-border-spacing-y)"})},{values:t("borderSpacing")})},transformOrigin:P("transformOrigin",[["origin",["transformOrigin"]]]),translate:P("translate",[[["translate-x",[["@defaults transform",{}],"--tw-translate-x",["transform",Pe]]],["translate-y",[["@defaults transform",{}],"--tw-translate-y",["transform",Pe]]]]],{supportsNegativeValues:!0}),rotate:P("rotate",[["rotate",[["@defaults transform",{}],"--tw-rotate",["transform",Pe]]]],{supportsNegativeValues:!0}),skew:P("skew",[[["skew-x",[["@defaults transform",{}],"--tw-skew-x",["transform",Pe]]],["skew-y",[["@defaults transform",{}],"--tw-skew-y",["transform",Pe]]]]],{supportsNegativeValues:!0}),scale:P("scale",[["scale",[["@defaults transform",{}],"--tw-scale-x","--tw-scale-y",["transform",Pe]]],[["scale-x",[["@defaults transform",{}],"--tw-scale-x",["transform",Pe]]],["scale-y",[["@defaults transform",{}],"--tw-scale-y",["transform",Pe]]]]],{supportsNegativeValues:!0}),transform:({addDefaults:i,addUtilities:e})=>{i("transform",{"--tw-translate-x":"0","--tw-translate-y":"0","--tw-rotate":"0","--tw-skew-x":"0","--tw-skew-y":"0","--tw-scale-x":"1","--tw-scale-y":"1"}),e({".transform":{"@defaults transform":{},transform:Pe},".transform-cpu":{transform:Pe},".transform-gpu":{transform:Pe.replace("translate(var(--tw-translate-x), var(--tw-translate-y))","translate3d(var(--tw-translate-x), var(--tw-translate-y), 0)")},".transform-none":{transform:"none"}})},animation:({matchUtilities:i,theme:e,config:t})=>{let r=a=>pe(t("prefix")+a),n=Object.fromEntries(Object.entries(e("keyframes")??{}).map(([a,s])=>[a,{[`@keyframes ${r(a)}`]:s}]));i({animate:a=>{let s=Wa(a);return[...s.flatMap(o=>n[o.name]),{animation:s.map(({name:o,value:u})=>o===void 0||n[o]===void 0?u:u.replace(o,r(o))).join(", ")}]}},{values:e("animation")})},cursor:P("cursor"),touchAction:({addDefaults:i,addUtilities:e})=>{i("touch-action",{"--tw-pan-x":" ","--tw-pan-y":" ","--tw-pinch-zoom":" "});let t="var(--tw-pan-x) var(--tw-pan-y) var(--tw-pinch-zoom)";e({".touch-auto":{"touch-action":"auto"},".touch-none":{"touch-action":"none"},".touch-pan-x":{"@defaults touch-action":{},"--tw-pan-x":"pan-x","touch-action":t},".touch-pan-left":{"@defaults touch-action":{},"--tw-pan-x":"pan-left","touch-action":t},".touch-pan-right":{"@defaults touch-action":{},"--tw-pan-x":"pan-right","touch-action":t},".touch-pan-y":{"@defaults touch-action":{},"--tw-pan-y":"pan-y","touch-action":t},".touch-pan-up":{"@defaults touch-action":{},"--tw-pan-y":"pan-up","touch-action":t},".touch-pan-down":{"@defaults touch-action":{},"--tw-pan-y":"pan-down","touch-action":t},".touch-pinch-zoom":{"@defaults touch-action":{},"--tw-pinch-zoom":"pinch-zoom","touch-action":t},".touch-manipulation":{"touch-action":"manipulation"}})},userSelect:({addUtilities:i})=>{i({".select-none":{"user-select":"none"},".select-text":{"user-select":"text"},".select-all":{"user-select":"all"},".select-auto":{"user-select":"auto"}})},resize:({addUtilities:i})=>{i({".resize-none":{resize:"none"},".resize-y":{resize:"vertical"},".resize-x":{resize:"horizontal"},".resize":{resize:"both"}})},scrollSnapType:({addDefaults:i,addUtilities:e})=>{i("scroll-snap-type",{"--tw-scroll-snap-strictness":"proximity"}),e({".snap-none":{"scroll-snap-type":"none"},".snap-x":{"@defaults scroll-snap-type":{},"scroll-snap-type":"x var(--tw-scroll-snap-strictness)"},".snap-y":{"@defaults scroll-snap-type":{},"scroll-snap-type":"y var(--tw-scroll-snap-strictness)"},".snap-both":{"@defaults scroll-snap-type":{},"scroll-snap-type":"both var(--tw-scroll-snap-strictness)"},".snap-mandatory":{"--tw-scroll-snap-strictness":"mandatory"},".snap-proximity":{"--tw-scroll-snap-strictness":"proximity"}})},scrollSnapAlign:({addUtilities:i})=>{i({".snap-start":{"scroll-snap-align":"start"},".snap-end":{"scroll-snap-align":"end"},".snap-center":{"scroll-snap-align":"center"},".snap-align-none":{"scroll-snap-align":"none"}})},scrollSnapStop:({addUtilities:i})=>{i({".snap-normal":{"scroll-snap-stop":"normal"},".snap-always":{"scroll-snap-stop":"always"}})},scrollMargin:P("scrollMargin",[["scroll-m",["scroll-margin"]],[["scroll-mx",["scroll-margin-left","scroll-margin-right"]],["scroll-my",["scroll-margin-top","scroll-margin-bottom"]]],[["scroll-ms",["scroll-margin-inline-start"]],["scroll-me",["scroll-margin-inline-end"]],["scroll-mt",["scroll-margin-top"]],["scroll-mr",["scroll-margin-right"]],["scroll-mb",["scroll-margin-bottom"]],["scroll-ml",["scroll-margin-left"]]]],{supportsNegativeValues:!0}),scrollPadding:P("scrollPadding",[["scroll-p",["scroll-padding"]],[["scroll-px",["scroll-padding-left","scroll-padding-right"]],["scroll-py",["scroll-padding-top","scroll-padding-bottom"]]],[["scroll-ps",["scroll-padding-inline-start"]],["scroll-pe",["scroll-padding-inline-end"]],["scroll-pt",["scroll-padding-top"]],["scroll-pr",["scroll-padding-right"]],["scroll-pb",["scroll-padding-bottom"]],["scroll-pl",["scroll-padding-left"]]]]),listStylePosition:({addUtilities:i})=>{i({".list-inside":{"list-style-position":"inside"},".list-outside":{"list-style-position":"outside"}})},listStyleType:P("listStyleType",[["list",["listStyleType"]]]),listStyleImage:P("listStyleImage",[["list-image",["listStyleImage"]]]),appearance:({addUtilities:i})=>{i({".appearance-none":{appearance:"none"},".appearance-auto":{appearance:"auto"}})},columns:P("columns",[["columns",["columns"]]]),breakBefore:({addUtilities:i})=>{i({".break-before-auto":{"break-before":"auto"},".break-before-avoid":{"break-before":"avoid"},".break-before-all":{"break-before":"all"},".break-before-avoid-page":{"break-before":"avoid-page"},".break-before-page":{"break-before":"page"},".break-before-left":{"break-before":"left"},".break-before-right":{"break-before":"right"},".break-before-column":{"break-before":"column"}})},breakInside:({addUtilities:i})=>{i({".break-inside-auto":{"break-inside":"auto"},".break-inside-avoid":{"break-inside":"avoid"},".break-inside-avoid-page":{"break-inside":"avoid-page"},".break-inside-avoid-column":{"break-inside":"avoid-column"}})},breakAfter:({addUtilities:i})=>{i({".break-after-auto":{"break-after":"auto"},".break-after-avoid":{"break-after":"avoid"},".break-after-all":{"break-after":"all"},".break-after-avoid-page":{"break-after":"avoid-page"},".break-after-page":{"break-after":"page"},".break-after-left":{"break-after":"left"},".break-after-right":{"break-after":"right"},".break-after-column":{"break-after":"column"}})},gridAutoColumns:P("gridAutoColumns",[["auto-cols",["gridAutoColumns"]]]),gridAutoFlow:({addUtilities:i})=>{i({".grid-flow-row":{gridAutoFlow:"row"},".grid-flow-col":{gridAutoFlow:"column"},".grid-flow-dense":{gridAutoFlow:"dense"},".grid-flow-row-dense":{gridAutoFlow:"row dense"},".grid-flow-col-dense":{gridAutoFlow:"column dense"}})},gridAutoRows:P("gridAutoRows",[["auto-rows",["gridAutoRows"]]]),gridTemplateColumns:P("gridTemplateColumns",[["grid-cols",["gridTemplateColumns"]]]),gridTemplateRows:P("gridTemplateRows",[["grid-rows",["gridTemplateRows"]]]),flexDirection:({addUtilities:i})=>{i({".flex-row":{"flex-direction":"row"},".flex-row-reverse":{"flex-direction":"row-reverse"},".flex-col":{"flex-direction":"column"},".flex-col-reverse":{"flex-direction":"column-reverse"}})},flexWrap:({addUtilities:i})=>{i({".flex-wrap":{"flex-wrap":"wrap"},".flex-wrap-reverse":{"flex-wrap":"wrap-reverse"},".flex-nowrap":{"flex-wrap":"nowrap"}})},placeContent:({addUtilities:i})=>{i({".place-content-center":{"place-content":"center"},".place-content-start":{"place-content":"start"},".place-content-end":{"place-content":"end"},".place-content-between":{"place-content":"space-between"},".place-content-around":{"place-content":"space-around"},".place-content-evenly":{"place-content":"space-evenly"},".place-content-baseline":{"place-content":"baseline"},".place-content-stretch":{"place-content":"stretch"}})},placeItems:({addUtilities:i})=>{i({".place-items-start":{"place-items":"start"},".place-items-end":{"place-items":"end"},".place-items-center":{"place-items":"center"},".place-items-baseline":{"place-items":"baseline"},".place-items-stretch":{"place-items":"stretch"}})},alignContent:({addUtilities:i})=>{i({".content-normal":{"align-content":"normal"},".content-center":{"align-content":"center"},".content-start":{"align-content":"flex-start"},".content-end":{"align-content":"flex-end"},".content-between":{"align-content":"space-between"},".content-around":{"align-content":"space-around"},".content-evenly":{"align-content":"space-evenly"},".content-baseline":{"align-content":"baseline"},".content-stretch":{"align-content":"stretch"}})},alignItems:({addUtilities:i})=>{i({".items-start":{"align-items":"flex-start"},".items-end":{"align-items":"flex-end"},".items-center":{"align-items":"center"},".items-baseline":{"align-items":"baseline"},".items-stretch":{"align-items":"stretch"}})},justifyContent:({addUtilities:i})=>{i({".justify-normal":{"justify-content":"normal"},".justify-start":{"justify-content":"flex-start"},".justify-end":{"justify-content":"flex-end"},".justify-center":{"justify-content":"center"},".justify-between":{"justify-content":"space-between"},".justify-around":{"justify-content":"space-around"},".justify-evenly":{"justify-content":"space-evenly"},".justify-stretch":{"justify-content":"stretch"}})},justifyItems:({addUtilities:i})=>{i({".justify-items-start":{"justify-items":"start"},".justify-items-end":{"justify-items":"end"},".justify-items-center":{"justify-items":"center"},".justify-items-stretch":{"justify-items":"stretch"}})},gap:P("gap",[["gap",["gap"]],[["gap-x",["columnGap"]],["gap-y",["rowGap"]]]]),space:({matchUtilities:i,addUtilities:e,theme:t})=>{i({"space-x":r=>(r=r==="0"?"0px":r,{"& > :not([hidden]) ~ :not([hidden])":{"--tw-space-x-reverse":"0","margin-right":`calc(${r} * var(--tw-space-x-reverse))`,"margin-left":`calc(${r} * calc(1 - var(--tw-space-x-reverse)))`}}),"space-y":r=>(r=r==="0"?"0px":r,{"& > :not([hidden]) ~ :not([hidden])":{"--tw-space-y-reverse":"0","margin-top":`calc(${r} * calc(1 - var(--tw-space-y-reverse)))`,"margin-bottom":`calc(${r} * var(--tw-space-y-reverse))`}})},{values:t("space"),supportsNegativeValues:!0}),e({".space-y-reverse > :not([hidden]) ~ :not([hidden])":{"--tw-space-y-reverse":"1"},".space-x-reverse > :not([hidden]) ~ :not([hidden])":{"--tw-space-x-reverse":"1"}})},divideWidth:({matchUtilities:i,addUtilities:e,theme:t})=>{i({"divide-x":r=>(r=r==="0"?"0px":r,{"& > :not([hidden]) ~ :not([hidden])":{"@defaults border-width":{},"--tw-divide-x-reverse":"0","border-right-width":`calc(${r} * var(--tw-divide-x-reverse))`,"border-left-width":`calc(${r} * calc(1 - var(--tw-divide-x-reverse)))`}}),"divide-y":r=>(r=r==="0"?"0px":r,{"& > :not([hidden]) ~ :not([hidden])":{"@defaults border-width":{},"--tw-divide-y-reverse":"0","border-top-width":`calc(${r} * calc(1 - var(--tw-divide-y-reverse)))`,"border-bottom-width":`calc(${r} * var(--tw-divide-y-reverse))`}})},{values:t("divideWidth"),type:["line-width","length","any"]}),e({".divide-y-reverse > :not([hidden]) ~ :not([hidden])":{"@defaults border-width":{},"--tw-divide-y-reverse":"1"},".divide-x-reverse > :not([hidden]) ~ :not([hidden])":{"@defaults border-width":{},"--tw-divide-x-reverse":"1"}})},divideStyle:({addUtilities:i})=>{i({".divide-solid > :not([hidden]) ~ :not([hidden])":{"border-style":"solid"},".divide-dashed > :not([hidden]) ~ :not([hidden])":{"border-style":"dashed"},".divide-dotted > :not([hidden]) ~ :not([hidden])":{"border-style":"dotted"},".divide-double > :not([hidden]) ~ :not([hidden])":{"border-style":"double"},".divide-none > :not([hidden]) ~ :not([hidden])":{"border-style":"none"}})},divideColor:({matchUtilities:i,theme:e,corePlugins:t})=>{i({divide:r=>t("divideOpacity")?{["& > :not([hidden]) ~ :not([hidden])"]:oe({color:r,property:"border-color",variable:"--tw-divide-opacity"})}:{["& > :not([hidden]) ~ :not([hidden])"]:{"border-color":L(r)}}},{values:(({DEFAULT:r,...n})=>n)(ne(e("divideColor"))),type:["color","any"]})},divideOpacity:({matchUtilities:i,theme:e})=>{i({"divide-opacity":t=>({["& > :not([hidden]) ~ :not([hidden])"]:{"--tw-divide-opacity":t}})},{values:e("divideOpacity")})},placeSelf:({addUtilities:i})=>{i({".place-self-auto":{"place-self":"auto"},".place-self-start":{"place-self":"start"},".place-self-end":{"place-self":"end"},".place-self-center":{"place-self":"center"},".place-self-stretch":{"place-self":"stretch"}})},alignSelf:({addUtilities:i})=>{i({".self-auto":{"align-self":"auto"},".self-start":{"align-self":"flex-start"},".self-end":{"align-self":"flex-end"},".self-center":{"align-self":"center"},".self-stretch":{"align-self":"stretch"},".self-baseline":{"align-self":"baseline"}})},justifySelf:({addUtilities:i})=>{i({".justify-self-auto":{"justify-self":"auto"},".justify-self-start":{"justify-self":"start"},".justify-self-end":{"justify-self":"end"},".justify-self-center":{"justify-self":"center"},".justify-self-stretch":{"justify-self":"stretch"}})},overflow:({addUtilities:i})=>{i({".overflow-auto":{overflow:"auto"},".overflow-hidden":{overflow:"hidden"},".overflow-clip":{overflow:"clip"},".overflow-visible":{overflow:"visible"},".overflow-scroll":{overflow:"scroll"},".overflow-x-auto":{"overflow-x":"auto"},".overflow-y-auto":{"overflow-y":"auto"},".overflow-x-hidden":{"overflow-x":"hidden"},".overflow-y-hidden":{"overflow-y":"hidden"},".overflow-x-clip":{"overflow-x":"clip"},".overflow-y-clip":{"overflow-y":"clip"},".overflow-x-visible":{"overflow-x":"visible"},".overflow-y-visible":{"overflow-y":"visible"},".overflow-x-scroll":{"overflow-x":"scroll"},".overflow-y-scroll":{"overflow-y":"scroll"}})},overscrollBehavior:({addUtilities:i})=>{i({".overscroll-auto":{"overscroll-behavior":"auto"},".overscroll-contain":{"overscroll-behavior":"contain"},".overscroll-none":{"overscroll-behavior":"none"},".overscroll-y-auto":{"overscroll-behavior-y":"auto"},".overscroll-y-contain":{"overscroll-behavior-y":"contain"},".overscroll-y-none":{"overscroll-behavior-y":"none"},".overscroll-x-auto":{"overscroll-behavior-x":"auto"},".overscroll-x-contain":{"overscroll-behavior-x":"contain"},".overscroll-x-none":{"overscroll-behavior-x":"none"}})},scrollBehavior:({addUtilities:i})=>{i({".scroll-auto":{"scroll-behavior":"auto"},".scroll-smooth":{"scroll-behavior":"smooth"}})},textOverflow:({addUtilities:i})=>{i({".truncate":{overflow:"hidden","text-overflow":"ellipsis","white-space":"nowrap"},".overflow-ellipsis":{"text-overflow":"ellipsis"},".text-ellipsis":{"text-overflow":"ellipsis"},".text-clip":{"text-overflow":"clip"}})},hyphens:({addUtilities:i})=>{i({".hyphens-none":{hyphens:"none"},".hyphens-manual":{hyphens:"manual"},".hyphens-auto":{hyphens:"auto"}})},whitespace:({addUtilities:i})=>{i({".whitespace-normal":{"white-space":"normal"},".whitespace-nowrap":{"white-space":"nowrap"},".whitespace-pre":{"white-space":"pre"},".whitespace-pre-line":{"white-space":"pre-line"},".whitespace-pre-wrap":{"white-space":"pre-wrap"},".whitespace-break-spaces":{"white-space":"break-spaces"}})},textWrap:({addUtilities:i})=>{i({".text-wrap":{"text-wrap":"wrap"},".text-nowrap":{"text-wrap":"nowrap"},".text-balance":{"text-wrap":"balance"},".text-pretty":{"text-wrap":"pretty"}})},wordBreak:({addUtilities:i})=>{i({".break-normal":{"overflow-wrap":"normal","word-break":"normal"},".break-words":{"overflow-wrap":"break-word"},".break-all":{"word-break":"break-all"},".break-keep":{"word-break":"keep-all"}})},borderRadius:P("borderRadius",[["rounded",["border-radius"]],[["rounded-s",["border-start-start-radius","border-end-start-radius"]],["rounded-e",["border-start-end-radius","border-end-end-radius"]],["rounded-t",["border-top-left-radius","border-top-right-radius"]],["rounded-r",["border-top-right-radius","border-bottom-right-radius"]],["rounded-b",["border-bottom-right-radius","border-bottom-left-radius"]],["rounded-l",["border-top-left-radius","border-bottom-left-radius"]]],[["rounded-ss",["border-start-start-radius"]],["rounded-se",["border-start-end-radius"]],["rounded-ee",["border-end-end-radius"]],["rounded-es",["border-end-start-radius"]],["rounded-tl",["border-top-left-radius"]],["rounded-tr",["border-top-right-radius"]],["rounded-br",["border-bottom-right-radius"]],["rounded-bl",["border-bottom-left-radius"]]]]),borderWidth:P("borderWidth",[["border",[["@defaults border-width",{}],"border-width"]],[["border-x",[["@defaults border-width",{}],"border-left-width","border-right-width"]],["border-y",[["@defaults border-width",{}],"border-top-width","border-bottom-width"]]],[["border-s",[["@defaults border-width",{}],"border-inline-start-width"]],["border-e",[["@defaults border-width",{}],"border-inline-end-width"]],["border-t",[["@defaults border-width",{}],"border-top-width"]],["border-r",[["@defaults border-width",{}],"border-right-width"]],["border-b",[["@defaults border-width",{}],"border-bottom-width"]],["border-l",[["@defaults border-width",{}],"border-left-width"]]]],{type:["line-width","length"]}),borderStyle:({addUtilities:i})=>{i({".border-solid":{"border-style":"solid"},".border-dashed":{"border-style":"dashed"},".border-dotted":{"border-style":"dotted"},".border-double":{"border-style":"double"},".border-hidden":{"border-style":"hidden"},".border-none":{"border-style":"none"}})},borderColor:({matchUtilities:i,theme:e,corePlugins:t})=>{i({border:r=>t("borderOpacity")?oe({color:r,property:"border-color",variable:"--tw-border-opacity"}):{"border-color":L(r)}},{values:(({DEFAULT:r,...n})=>n)(ne(e("borderColor"))),type:["color","any"]}),i({"border-x":r=>t("borderOpacity")?oe({color:r,property:["border-left-color","border-right-color"],variable:"--tw-border-opacity"}):{"border-left-color":L(r),"border-right-color":L(r)},"border-y":r=>t("borderOpacity")?oe({color:r,property:["border-top-color","border-bottom-color"],variable:"--tw-border-opacity"}):{"border-top-color":L(r),"border-bottom-color":L(r)}},{values:(({DEFAULT:r,...n})=>n)(ne(e("borderColor"))),type:["color","any"]}),i({"border-s":r=>t("borderOpacity")?oe({color:r,property:"border-inline-start-color",variable:"--tw-border-opacity"}):{"border-inline-start-color":L(r)},"border-e":r=>t("borderOpacity")?oe({color:r,property:"border-inline-end-color",variable:"--tw-border-opacity"}):{"border-inline-end-color":L(r)},"border-t":r=>t("borderOpacity")?oe({color:r,property:"border-top-color",variable:"--tw-border-opacity"}):{"border-top-color":L(r)},"border-r":r=>t("borderOpacity")?oe({color:r,property:"border-right-color",variable:"--tw-border-opacity"}):{"border-right-color":L(r)},"border-b":r=>t("borderOpacity")?oe({color:r,property:"border-bottom-color",variable:"--tw-border-opacity"}):{"border-bottom-color":L(r)},"border-l":r=>t("borderOpacity")?oe({color:r,property:"border-left-color",variable:"--tw-border-opacity"}):{"border-left-color":L(r)}},{values:(({DEFAULT:r,...n})=>n)(ne(e("borderColor"))),type:["color","any"]})},borderOpacity:P("borderOpacity",[["border-opacity",["--tw-border-opacity"]]]),backgroundColor:({matchUtilities:i,theme:e,corePlugins:t})=>{i({bg:r=>t("backgroundOpacity")?oe({color:r,property:"background-color",variable:"--tw-bg-opacity"}):{"background-color":L(r)}},{values:ne(e("backgroundColor")),type:["color","any"]})},backgroundOpacity:P("backgroundOpacity",[["bg-opacity",["--tw-bg-opacity"]]]),backgroundImage:P("backgroundImage",[["bg",["background-image"]]],{type:["lookup","image","url"]}),gradientColorStops:(()=>{function i(e){return qe(e,0,"rgb(255 255 255 / 0)")}return function({matchUtilities:e,theme:t,addDefaults:r}){r("gradient-color-stops",{"--tw-gradient-from-position":" ","--tw-gradient-via-position":" ","--tw-gradient-to-position":" "});let n={values:ne(t("gradientColorStops")),type:["color","any"]},a={values:t("gradientColorStopPositions"),type:["length","percentage"]};e({from:s=>{let o=i(s);return{"@defaults gradient-color-stops":{},"--tw-gradient-from":`${L(s)} var(--tw-gradient-from-position)`,"--tw-gradient-to":`${o} var(--tw-gradient-to-position)`,"--tw-gradient-stops":"var(--tw-gradient-from), var(--tw-gradient-to)"}}},n),e({from:s=>({"--tw-gradient-from-position":s})},a),e({via:s=>{let o=i(s);return{"@defaults gradient-color-stops":{},"--tw-gradient-to":`${o} var(--tw-gradient-to-position)`,"--tw-gradient-stops":`var(--tw-gradient-from), ${L(s)} var(--tw-gradient-via-position), var(--tw-gradient-to)`}}},n),e({via:s=>({"--tw-gradient-via-position":s})},a),e({to:s=>({"@defaults gradient-color-stops":{},"--tw-gradient-to":`${L(s)} var(--tw-gradient-to-position)`})},n),e({to:s=>({"--tw-gradient-to-position":s})},a)}})(),boxDecorationBreak:({addUtilities:i})=>{i({".decoration-slice":{"box-decoration-break":"slice"},".decoration-clone":{"box-decoration-break":"clone"},".box-decoration-slice":{"box-decoration-break":"slice"},".box-decoration-clone":{"box-decoration-break":"clone"}})},backgroundSize:P("backgroundSize",[["bg",["background-size"]]],{type:["lookup","length","percentage","size"]}),backgroundAttachment:({addUtilities:i})=>{i({".bg-fixed":{"background-attachment":"fixed"},".bg-local":{"background-attachment":"local"},".bg-scroll":{"background-attachment":"scroll"}})},backgroundClip:({addUtilities:i})=>{i({".bg-clip-border":{"background-clip":"border-box"},".bg-clip-padding":{"background-clip":"padding-box"},".bg-clip-content":{"background-clip":"content-box"},".bg-clip-text":{"background-clip":"text"}})},backgroundPosition:P("backgroundPosition",[["bg",["background-position"]]],{type:["lookup",["position",{preferOnConflict:!0}]]}),backgroundRepeat:({addUtilities:i})=>{i({".bg-repeat":{"background-repeat":"repeat"},".bg-no-repeat":{"background-repeat":"no-repeat"},".bg-repeat-x":{"background-repeat":"repeat-x"},".bg-repeat-y":{"background-repeat":"repeat-y"},".bg-repeat-round":{"background-repeat":"round"},".bg-repeat-space":{"background-repeat":"space"}})},backgroundOrigin:({addUtilities:i})=>{i({".bg-origin-border":{"background-origin":"border-box"},".bg-origin-padding":{"background-origin":"padding-box"},".bg-origin-content":{"background-origin":"content-box"}})},fill:({matchUtilities:i,theme:e})=>{i({fill:t=>({fill:L(t)})},{values:ne(e("fill")),type:["color","any"]})},stroke:({matchUtilities:i,theme:e})=>{i({stroke:t=>({stroke:L(t)})},{values:ne(e("stroke")),type:["color","url","any"]})},strokeWidth:P("strokeWidth",[["stroke",["stroke-width"]]],{type:["length","number","percentage"]}),objectFit:({addUtilities:i})=>{i({".object-contain":{"object-fit":"contain"},".object-cover":{"object-fit":"cover"},".object-fill":{"object-fit":"fill"},".object-none":{"object-fit":"none"},".object-scale-down":{"object-fit":"scale-down"}})},objectPosition:P("objectPosition",[["object",["object-position"]]]),padding:P("padding",[["p",["padding"]],[["px",["padding-left","padding-right"]],["py",["padding-top","padding-bottom"]]],[["ps",["padding-inline-start"]],["pe",["padding-inline-end"]],["pt",["padding-top"]],["pr",["padding-right"]],["pb",["padding-bottom"]],["pl",["padding-left"]]]]),textAlign:({addUtilities:i})=>{i({".text-left":{"text-align":"left"},".text-center":{"text-align":"center"},".text-right":{"text-align":"right"},".text-justify":{"text-align":"justify"},".text-start":{"text-align":"start"},".text-end":{"text-align":"end"}})},textIndent:P("textIndent",[["indent",["text-indent"]]],{supportsNegativeValues:!0}),verticalAlign:({addUtilities:i,matchUtilities:e})=>{i({".align-baseline":{"vertical-align":"baseline"},".align-top":{"vertical-align":"top"},".align-middle":{"vertical-align":"middle"},".align-bottom":{"vertical-align":"bottom"},".align-text-top":{"vertical-align":"text-top"},".align-text-bottom":{"vertical-align":"text-bottom"},".align-sub":{"vertical-align":"sub"},".align-super":{"vertical-align":"super"}}),e({align:t=>({"vertical-align":t})})},fontFamily:({matchUtilities:i,theme:e})=>{i({font:t=>{let[r,n={}]=Array.isArray(t)&&se(t[1])?t:[t],{fontFeatureSettings:a,fontVariationSettings:s}=n;return{"font-family":Array.isArray(r)?r.join(", "):r,...a===void 0?{}:{"font-feature-settings":a},...s===void 0?{}:{"font-variation-settings":s}}}},{values:e("fontFamily"),type:["lookup","generic-name","family-name"]})},fontSize:({matchUtilities:i,theme:e})=>{i({text:(t,{modifier:r})=>{let[n,a]=Array.isArray(t)?t:[t];if(r)return{"font-size":n,"line-height":r};let{lineHeight:s,letterSpacing:o,fontWeight:u}=se(a)?a:{lineHeight:a};return{"font-size":n,...s===void 0?{}:{"line-height":s},...o===void 0?{}:{"letter-spacing":o},...u===void 0?{}:{"font-weight":u}}}},{values:e("fontSize"),modifiers:e("lineHeight"),type:["absolute-size","relative-size","length","percentage"]})},fontWeight:P("fontWeight",[["font",["fontWeight"]]],{type:["lookup","number","any"]}),textTransform:({addUtilities:i})=>{i({".uppercase":{"text-transform":"uppercase"},".lowercase":{"text-transform":"lowercase"},".capitalize":{"text-transform":"capitalize"},".normal-case":{"text-transform":"none"}})},fontStyle:({addUtilities:i})=>{i({".italic":{"font-style":"italic"},".not-italic":{"font-style":"normal"}})},fontVariantNumeric:({addDefaults:i,addUtilities:e})=>{let t="var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)";i("font-variant-numeric",{"--tw-ordinal":" ","--tw-slashed-zero":" ","--tw-numeric-figure":" ","--tw-numeric-spacing":" ","--tw-numeric-fraction":" "}),e({".normal-nums":{"font-variant-numeric":"normal"},".ordinal":{"@defaults font-variant-numeric":{},"--tw-ordinal":"ordinal","font-variant-numeric":t},".slashed-zero":{"@defaults font-variant-numeric":{},"--tw-slashed-zero":"slashed-zero","font-variant-numeric":t},".lining-nums":{"@defaults font-variant-numeric":{},"--tw-numeric-figure":"lining-nums","font-variant-numeric":t},".oldstyle-nums":{"@defaults font-variant-numeric":{},"--tw-numeric-figure":"oldstyle-nums","font-variant-numeric":t},".proportional-nums":{"@defaults font-variant-numeric":{},"--tw-numeric-spacing":"proportional-nums","font-variant-numeric":t},".tabular-nums":{"@defaults font-variant-numeric":{},"--tw-numeric-spacing":"tabular-nums","font-variant-numeric":t},".diagonal-fractions":{"@defaults font-variant-numeric":{},"--tw-numeric-fraction":"diagonal-fractions","font-variant-numeric":t},".stacked-fractions":{"@defaults font-variant-numeric":{},"--tw-numeric-fraction":"stacked-fractions","font-variant-numeric":t}})},lineHeight:P("lineHeight",[["leading",["lineHeight"]]]),letterSpacing:P("letterSpacing",[["tracking",["letterSpacing"]]],{supportsNegativeValues:!0}),textColor:({matchUtilities:i,theme:e,corePlugins:t})=>{i({text:r=>t("textOpacity")?oe({color:r,property:"color",variable:"--tw-text-opacity"}):{color:L(r)}},{values:ne(e("textColor")),type:["color","any"]})},textOpacity:P("textOpacity",[["text-opacity",["--tw-text-opacity"]]]),textDecoration:({addUtilities:i})=>{i({".underline":{"text-decoration-line":"underline"},".overline":{"text-decoration-line":"overline"},".line-through":{"text-decoration-line":"line-through"},".no-underline":{"text-decoration-line":"none"}})},textDecorationColor:({matchUtilities:i,theme:e})=>{i({decoration:t=>({"text-decoration-color":L(t)})},{values:ne(e("textDecorationColor")),type:["color","any"]})},textDecorationStyle:({addUtilities:i})=>{i({".decoration-solid":{"text-decoration-style":"solid"},".decoration-double":{"text-decoration-style":"double"},".decoration-dotted":{"text-decoration-style":"dotted"},".decoration-dashed":{"text-decoration-style":"dashed"},".decoration-wavy":{"text-decoration-style":"wavy"}})},textDecorationThickness:P("textDecorationThickness",[["decoration",["text-decoration-thickness"]]],{type:["length","percentage"]}),textUnderlineOffset:P("textUnderlineOffset",[["underline-offset",["text-underline-offset"]]],{type:["length","percentage","any"]}),fontSmoothing:({addUtilities:i})=>{i({".antialiased":{"-webkit-font-smoothing":"antialiased","-moz-osx-font-smoothing":"grayscale"},".subpixel-antialiased":{"-webkit-font-smoothing":"auto","-moz-osx-font-smoothing":"auto"}})},placeholderColor:({matchUtilities:i,theme:e,corePlugins:t})=>{i({placeholder:r=>t("placeholderOpacity")?{"&::placeholder":oe({color:r,property:"color",variable:"--tw-placeholder-opacity"})}:{"&::placeholder":{color:L(r)}}},{values:ne(e("placeholderColor")),type:["color","any"]})},placeholderOpacity:({matchUtilities:i,theme:e})=>{i({"placeholder-opacity":t=>({["&::placeholder"]:{"--tw-placeholder-opacity":t}})},{values:e("placeholderOpacity")})},caretColor:({matchUtilities:i,theme:e})=>{i({caret:t=>({"caret-color":L(t)})},{values:ne(e("caretColor")),type:["color","any"]})},accentColor:({matchUtilities:i,theme:e})=>{i({accent:t=>({"accent-color":L(t)})},{values:ne(e("accentColor")),type:["color","any"]})},opacity:P("opacity",[["opacity",["opacity"]]]),backgroundBlendMode:({addUtilities:i})=>{i({".bg-blend-normal":{"background-blend-mode":"normal"},".bg-blend-multiply":{"background-blend-mode":"multiply"},".bg-blend-screen":{"background-blend-mode":"screen"},".bg-blend-overlay":{"background-blend-mode":"overlay"},".bg-blend-darken":{"background-blend-mode":"darken"},".bg-blend-lighten":{"background-blend-mode":"lighten"},".bg-blend-color-dodge":{"background-blend-mode":"color-dodge"},".bg-blend-color-burn":{"background-blend-mode":"color-burn"},".bg-blend-hard-light":{"background-blend-mode":"hard-light"},".bg-blend-soft-light":{"background-blend-mode":"soft-light"},".bg-blend-difference":{"background-blend-mode":"difference"},".bg-blend-exclusion":{"background-blend-mode":"exclusion"},".bg-blend-hue":{"background-blend-mode":"hue"},".bg-blend-saturation":{"background-blend-mode":"saturation"},".bg-blend-color":{"background-blend-mode":"color"},".bg-blend-luminosity":{"background-blend-mode":"luminosity"}})},mixBlendMode:({addUtilities:i})=>{i({".mix-blend-normal":{"mix-blend-mode":"normal"},".mix-blend-multiply":{"mix-blend-mode":"multiply"},".mix-blend-screen":{"mix-blend-mode":"screen"},".mix-blend-overlay":{"mix-blend-mode":"overlay"},".mix-blend-darken":{"mix-blend-mode":"darken"},".mix-blend-lighten":{"mix-blend-mode":"lighten"},".mix-blend-color-dodge":{"mix-blend-mode":"color-dodge"},".mix-blend-color-burn":{"mix-blend-mode":"color-burn"},".mix-blend-hard-light":{"mix-blend-mode":"hard-light"},".mix-blend-soft-light":{"mix-blend-mode":"soft-light"},".mix-blend-difference":{"mix-blend-mode":"difference"},".mix-blend-exclusion":{"mix-blend-mode":"exclusion"},".mix-blend-hue":{"mix-blend-mode":"hue"},".mix-blend-saturation":{"mix-blend-mode":"saturation"},".mix-blend-color":{"mix-blend-mode":"color"},".mix-blend-luminosity":{"mix-blend-mode":"luminosity"},".mix-blend-plus-darker":{"mix-blend-mode":"plus-darker"},".mix-blend-plus-lighter":{"mix-blend-mode":"plus-lighter"}})},boxShadow:(()=>{let i=Ge("boxShadow"),e=["var(--tw-ring-offset-shadow, 0 0 #0000)","var(--tw-ring-shadow, 0 0 #0000)","var(--tw-shadow)"].join(", ");return function({matchUtilities:t,addDefaults:r,theme:n}){r("box-shadow",{"--tw-ring-offset-shadow":"0 0 #0000","--tw-ring-shadow":"0 0 #0000","--tw-shadow":"0 0 #0000","--tw-shadow-colored":"0 0 #0000"}),t({shadow:a=>{a=i(a);let s=yi(a);for(let o of s)!o.valid||(o.color="var(--tw-shadow-color)");return{"@defaults box-shadow":{},"--tw-shadow":a==="none"?"0 0 #0000":a,"--tw-shadow-colored":a==="none"?"0 0 #0000":Tu(s),"box-shadow":e}}},{values:n("boxShadow"),type:["shadow"]})}})(),boxShadowColor:({matchUtilities:i,theme:e})=>{i({shadow:t=>({"--tw-shadow-color":L(t),"--tw-shadow":"var(--tw-shadow-colored)"})},{values:ne(e("boxShadowColor")),type:["color","any"]})},outlineStyle:({addUtilities:i})=>{i({".outline-none":{outline:"2px solid transparent","outline-offset":"2px"},".outline":{"outline-style":"solid"},".outline-dashed":{"outline-style":"dashed"},".outline-dotted":{"outline-style":"dotted"},".outline-double":{"outline-style":"double"}})},outlineWidth:P("outlineWidth",[["outline",["outline-width"]]],{type:["length","number","percentage"]}),outlineOffset:P("outlineOffset",[["outline-offset",["outline-offset"]]],{type:["length","number","percentage","any"],supportsNegativeValues:!0}),outlineColor:({matchUtilities:i,theme:e})=>{i({outline:t=>({"outline-color":L(t)})},{values:ne(e("outlineColor")),type:["color","any"]})},ringWidth:({matchUtilities:i,addDefaults:e,addUtilities:t,theme:r,config:n})=>{let a=(()=>{if(Z(n(),"respectDefaultRingColorOpacity"))return r("ringColor.DEFAULT");let s=r("ringOpacity.DEFAULT","0.5");return r("ringColor")?.DEFAULT?qe(r("ringColor")?.DEFAULT,s,`rgb(147 197 253 / ${s})`):`rgb(147 197 253 / ${s})`})();e("ring-width",{"--tw-ring-inset":" ","--tw-ring-offset-width":r("ringOffsetWidth.DEFAULT","0px"),"--tw-ring-offset-color":r("ringOffsetColor.DEFAULT","#fff"),"--tw-ring-color":a,"--tw-ring-offset-shadow":"0 0 #0000","--tw-ring-shadow":"0 0 #0000","--tw-shadow":"0 0 #0000","--tw-shadow-colored":"0 0 #0000"}),i({ring:s=>({"@defaults ring-width":{},"--tw-ring-offset-shadow":"var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)","--tw-ring-shadow":`var(--tw-ring-inset) 0 0 0 calc(${s} + var(--tw-ring-offset-width)) var(--tw-ring-color)`,"box-shadow":["var(--tw-ring-offset-shadow)","var(--tw-ring-shadow)","var(--tw-shadow, 0 0 #0000)"].join(", ")})},{values:r("ringWidth"),type:"length"}),t({".ring-inset":{"@defaults ring-width":{},"--tw-ring-inset":"inset"}})},ringColor:({matchUtilities:i,theme:e,corePlugins:t})=>{i({ring:r=>t("ringOpacity")?oe({color:r,property:"--tw-ring-color",variable:"--tw-ring-opacity"}):{"--tw-ring-color":L(r)}},{values:Object.fromEntries(Object.entries(ne(e("ringColor"))).filter(([r])=>r!=="DEFAULT")),type:["color","any"]})},ringOpacity:i=>{let{config:e}=i;return P("ringOpacity",[["ring-opacity",["--tw-ring-opacity"]]],{filterDefault:!Z(e(),"respectDefaultRingColorOpacity")})(i)},ringOffsetWidth:P("ringOffsetWidth",[["ring-offset",["--tw-ring-offset-width"]]],{type:"length"}),ringOffsetColor:({matchUtilities:i,theme:e})=>{i({"ring-offset":t=>({"--tw-ring-offset-color":L(t)})},{values:ne(e("ringOffsetColor")),type:["color","any"]})},blur:({matchUtilities:i,theme:e})=>{i({blur:t=>({"--tw-blur":t.trim()===""?" ":`blur(${t})`,"@defaults filter":{},filter:Fe})},{values:e("blur")})},brightness:({matchUtilities:i,theme:e})=>{i({brightness:t=>({"--tw-brightness":`brightness(${t})`,"@defaults filter":{},filter:Fe})},{values:e("brightness")})},contrast:({matchUtilities:i,theme:e})=>{i({contrast:t=>({"--tw-contrast":`contrast(${t})`,"@defaults filter":{},filter:Fe})},{values:e("contrast")})},dropShadow:({matchUtilities:i,theme:e})=>{i({"drop-shadow":t=>({"--tw-drop-shadow":Array.isArray(t)?t.map(r=>`drop-shadow(${r})`).join(" "):`drop-shadow(${t})`,"@defaults filter":{},filter:Fe})},{values:e("dropShadow")})},grayscale:({matchUtilities:i,theme:e})=>{i({grayscale:t=>({"--tw-grayscale":`grayscale(${t})`,"@defaults filter":{},filter:Fe})},{values:e("grayscale")})},hueRotate:({matchUtilities:i,theme:e})=>{i({"hue-rotate":t=>({"--tw-hue-rotate":`hue-rotate(${t})`,"@defaults filter":{},filter:Fe})},{values:e("hueRotate"),supportsNegativeValues:!0})},invert:({matchUtilities:i,theme:e})=>{i({invert:t=>({"--tw-invert":`invert(${t})`,"@defaults filter":{},filter:Fe})},{values:e("invert")})},saturate:({matchUtilities:i,theme:e})=>{i({saturate:t=>({"--tw-saturate":`saturate(${t})`,"@defaults filter":{},filter:Fe})},{values:e("saturate")})},sepia:({matchUtilities:i,theme:e})=>{i({sepia:t=>({"--tw-sepia":`sepia(${t})`,"@defaults filter":{},filter:Fe})},{values:e("sepia")})},filter:({addDefaults:i,addUtilities:e})=>{i("filter",{"--tw-blur":" ","--tw-brightness":" ","--tw-contrast":" ","--tw-grayscale":" ","--tw-hue-rotate":" ","--tw-invert":" ","--tw-saturate":" ","--tw-sepia":" ","--tw-drop-shadow":" "}),e({".filter":{"@defaults filter":{},filter:Fe},".filter-none":{filter:"none"}})},backdropBlur:({matchUtilities:i,theme:e})=>{i({"backdrop-blur":t=>({"--tw-backdrop-blur":t.trim()===""?" ":`blur(${t})`,"@defaults backdrop-filter":{},"-webkit-backdrop-filter":K,"backdrop-filter":K})},{values:e("backdropBlur")})},backdropBrightness:({matchUtilities:i,theme:e})=>{i({"backdrop-brightness":t=>({"--tw-backdrop-brightness":`brightness(${t})`,"@defaults backdrop-filter":{},"-webkit-backdrop-filter":K,"backdrop-filter":K})},{values:e("backdropBrightness")})},backdropContrast:({matchUtilities:i,theme:e})=>{i({"backdrop-contrast":t=>({"--tw-backdrop-contrast":`contrast(${t})`,"@defaults backdrop-filter":{},"-webkit-backdrop-filter":K,"backdrop-filter":K})},{values:e("backdropContrast")})},backdropGrayscale:({matchUtilities:i,theme:e})=>{i({"backdrop-grayscale":t=>({"--tw-backdrop-grayscale":`grayscale(${t})`,"@defaults backdrop-filter":{},"-webkit-backdrop-filter":K,"backdrop-filter":K})},{values:e("backdropGrayscale")})},backdropHueRotate:({matchUtilities:i,theme:e})=>{i({"backdrop-hue-rotate":t=>({"--tw-backdrop-hue-rotate":`hue-rotate(${t})`,"@defaults backdrop-filter":{},"-webkit-backdrop-filter":K,"backdrop-filter":K})},{values:e("backdropHueRotate"),supportsNegativeValues:!0})},backdropInvert:({matchUtilities:i,theme:e})=>{i({"backdrop-invert":t=>({"--tw-backdrop-invert":`invert(${t})`,"@defaults backdrop-filter":{},"-webkit-backdrop-filter":K,"backdrop-filter":K})},{values:e("backdropInvert")})},backdropOpacity:({matchUtilities:i,theme:e})=>{i({"backdrop-opacity":t=>({"--tw-backdrop-opacity":`opacity(${t})`,"@defaults backdrop-filter":{},"-webkit-backdrop-filter":K,"backdrop-filter":K})},{values:e("backdropOpacity")})},backdropSaturate:({matchUtilities:i,theme:e})=>{i({"backdrop-saturate":t=>({"--tw-backdrop-saturate":`saturate(${t})`,"@defaults backdrop-filter":{},"-webkit-backdrop-filter":K,"backdrop-filter":K})},{values:e("backdropSaturate")})},backdropSepia:({matchUtilities:i,theme:e})=>{i({"backdrop-sepia":t=>({"--tw-backdrop-sepia":`sepia(${t})`,"@defaults backdrop-filter":{},"-webkit-backdrop-filter":K,"backdrop-filter":K})},{values:e("backdropSepia")})},backdropFilter:({addDefaults:i,addUtilities:e})=>{i("backdrop-filter",{"--tw-backdrop-blur":" ","--tw-backdrop-brightness":" ","--tw-backdrop-contrast":" ","--tw-backdrop-grayscale":" ","--tw-backdrop-hue-rotate":" ","--tw-backdrop-invert":" ","--tw-backdrop-opacity":" ","--tw-backdrop-saturate":" ","--tw-backdrop-sepia":" "}),e({".backdrop-filter":{"@defaults backdrop-filter":{},"-webkit-backdrop-filter":K,"backdrop-filter":K},".backdrop-filter-none":{"-webkit-backdrop-filter":"none","backdrop-filter":"none"}})},transitionProperty:({matchUtilities:i,theme:e})=>{let t=e("transitionTimingFunction.DEFAULT"),r=e("transitionDuration.DEFAULT");i({transition:n=>({"transition-property":n,...n==="none"?{}:{"transition-timing-function":t,"transition-duration":r}})},{values:e("transitionProperty")})},transitionDelay:P("transitionDelay",[["delay",["transitionDelay"]]]),transitionDuration:P("transitionDuration",[["duration",["transitionDuration"]]],{filterDefault:!0}),transitionTimingFunction:P("transitionTimingFunction",[["ease",["transitionTimingFunction"]]],{filterDefault:!0}),willChange:P("willChange",[["will-change",["will-change"]]]),contain:({addDefaults:i,addUtilities:e})=>{let t="var(--tw-contain-size) var(--tw-contain-layout) var(--tw-contain-paint) var(--tw-contain-style)";i("contain",{"--tw-contain-size":" ","--tw-contain-layout":" ","--tw-contain-paint":" ","--tw-contain-style":" "}),e({".contain-none":{contain:"none"},".contain-content":{contain:"content"},".contain-strict":{contain:"strict"},".contain-size":{"@defaults contain":{},"--tw-contain-size":"size",contain:t},".contain-inline-size":{"@defaults contain":{},"--tw-contain-size":"inline-size",contain:t},".contain-layout":{"@defaults contain":{},"--tw-contain-layout":"layout",contain:t},".contain-paint":{"@defaults contain":{},"--tw-contain-paint":"paint",contain:t},".contain-style":{"@defaults contain":{},"--tw-contain-style":"style",contain:t}})},content:P("content",[["content",["--tw-content",["content","var(--tw-content)"]]]]),forcedColorAdjust:({addUtilities:i})=>{i({".forced-color-adjust-auto":{"forced-color-adjust":"auto"},".forced-color-adjust-none":{"forced-color-adjust":"none"}})}}});function KS(i){if(i===void 0)return!1;if(i==="true"||i==="1")return!0;if(i==="false"||i==="0")return!1;if(i==="*")return!0;let e=i.split(",").map(t=>t.split(":")[0]);return e.includes("-tailwindcss")?!1:!!e.includes("tailwindcss")}var De,gd,yd,gn,Ga,He,Kr,lt=C(()=>{l();De=typeof h!="undefined"?{NODE_ENV:"production",DEBUG:KS(h.env.DEBUG)}:{NODE_ENV:"production",DEBUG:!1},gd=new Map,yd=new Map,gn=new Map,Ga=new Map,He=new String("*"),Kr=Symbol("__NONE__")});function Lt(i){let e=[],t=!1;for(let r=0;r0)}var wd,bd,ZS,Ha=C(()=>{l();wd=new Map([["{","}"],["[","]"],["(",")"]]),bd=new Map(Array.from(wd.entries()).map(([i,e])=>[e,i])),ZS=new Set(['"',"'","`"])});function $t(i){let[e]=vd(i);return e.forEach(([t,r])=>t.removeChild(r)),i.nodes.push(...e.map(([,t])=>t)),i}function vd(i){let e=[],t=null;for(let r of i.nodes)if(r.type==="combinator")e=e.filter(([,n])=>Qa(n).includes("jumpable")),t=null;else if(r.type==="pseudo"){eC(r)?(t=r,e.push([i,r,null])):t&&tC(r,t)?e.push([i,r,t]):t=null;for(let n of r.nodes??[]){let[a,s]=vd(n);t=s||t,e.push(...a)}}return[e,t]}function xd(i){return i.value.startsWith("::")||Ya[i.value]!==void 0}function eC(i){return xd(i)&&Qa(i).includes("terminal")}function tC(i,e){return i.type!=="pseudo"||xd(i)?!1:Qa(e).includes("actionable")}function Qa(i){return Ya[i.value]??Ya.__default__}var Ya,yn=C(()=>{l();Ya={"::after":["terminal","jumpable"],"::backdrop":["terminal","jumpable"],"::before":["terminal","jumpable"],"::cue":["terminal"],"::cue-region":["terminal"],"::first-letter":["terminal","jumpable"],"::first-line":["terminal","jumpable"],"::grammar-error":["terminal"],"::marker":["terminal","jumpable"],"::part":["terminal","actionable"],"::placeholder":["terminal","jumpable"],"::selection":["terminal","jumpable"],"::slotted":["terminal"],"::spelling-error":["terminal"],"::target-text":["terminal"],"::file-selector-button":["terminal","actionable"],"::deep":["actionable"],"::v-deep":["actionable"],"::ng-deep":["actionable"],":after":["terminal","jumpable"],":before":["terminal","jumpable"],":first-letter":["terminal","jumpable"],":first-line":["terminal","jumpable"],":where":[],":is":[],":has":[],__default__:["terminal","actionable"]}});function jt(i,{context:e,candidate:t}){let r=e?.tailwindConfig.prefix??"",n=i.map(s=>{let o=(0,Ne.default)().astSync(s.format);return{...s,ast:s.respectPrefix?Ft(r,o):o}}),a=Ne.default.root({nodes:[Ne.default.selector({nodes:[Ne.default.className({value:pe(t)})]})]});for(let{ast:s}of n)[a,s]=iC(a,s),s.walkNesting(o=>o.replaceWith(...a.nodes[0].nodes)),a=s;return a}function Sd(i){let e=[];for(;i.prev()&&i.prev().type!=="combinator";)i=i.prev();for(;i&&i.type!=="combinator";)e.push(i),i=i.next();return e}function rC(i){return i.sort((e,t)=>e.type==="tag"&&t.type==="class"?-1:e.type==="class"&&t.type==="tag"?1:e.type==="class"&&t.type==="pseudo"&&t.value.startsWith("::")?-1:e.type==="pseudo"&&e.value.startsWith("::")&&t.type==="class"?1:i.index(e)-i.index(t)),i}function Xa(i,e){let t=!1;i.walk(r=>{if(r.type==="class"&&r.value===e)return t=!0,!1}),t||i.remove()}function wn(i,e,{context:t,candidate:r,base:n}){let a=t?.tailwindConfig?.separator??":";n=n??ie(r,a).pop();let s=(0,Ne.default)().astSync(i);if(s.walkClasses(f=>{f.raws&&f.value.includes(n)&&(f.raws.value=pe((0,kd.default)(f.raws.value)))}),s.each(f=>Xa(f,n)),s.length===0)return null;let o=Array.isArray(e)?jt(e,{context:t,candidate:r}):e;if(o===null)return s.toString();let u=Ne.default.comment({value:"/*__simple__*/"}),c=Ne.default.comment({value:"/*__simple__*/"});return s.walkClasses(f=>{if(f.value!==n)return;let d=f.parent,p=o.nodes[0].nodes;if(d.nodes.length===1){f.replaceWith(...p);return}let m=Sd(f);d.insertBefore(m[0],u),d.insertAfter(m[m.length-1],c);for(let x of p)d.insertBefore(m[0],x.clone());f.remove(),m=Sd(u);let b=d.index(u);d.nodes.splice(b,m.length,...rC(Ne.default.selector({nodes:m})).nodes),u.remove(),c.remove()}),s.walkPseudos(f=>{f.value===Ja&&f.replaceWith(f.nodes)}),s.each(f=>$t(f)),s.toString()}function iC(i,e){let t=[];return i.walkPseudos(r=>{r.value===Ja&&t.push({pseudo:r,value:r.nodes[0].toString()})}),e.walkPseudos(r=>{if(r.value!==Ja)return;let n=r.nodes[0].toString(),a=t.find(c=>c.value===n);if(!a)return;let s=[],o=r.next();for(;o&&o.type!=="combinator";)s.push(o),o=o.next();let u=o;a.pseudo.parent.insertAfter(a.pseudo,Ne.default.selector({nodes:s.map(c=>c.clone())})),r.remove(),s.forEach(c=>c.remove()),u&&u.type==="combinator"&&u.remove()}),[i,e]}var Ne,kd,Ja,Ka=C(()=>{l();Ne=X(Be()),kd=X(Yi());Nt();un();yn();yt();Ja=":merge"});function bn(i,e){let t=(0,Za.default)().astSync(i);return t.each(r=>{r.nodes[0].type==="pseudo"&&r.nodes[0].value===":is"&&r.nodes.every(a=>a.type!=="combinator")||(r.nodes=[Za.default.pseudo({value:":is",nodes:[r.clone()]})]),$t(r)}),`${e} ${t.toString()}`}var Za,eo=C(()=>{l();Za=X(Be());yn()});function to(i){return nC.transformSync(i)}function*sC(i){let e=1/0;for(;e>=0;){let t,r=!1;if(e===1/0&&i.endsWith("]")){let s=i.indexOf("[");i[s-1]==="-"?t=s-1:i[s-1]==="/"?(t=s-1,r=!0):t=-1}else e===1/0&&i.includes("/")?(t=i.lastIndexOf("/"),r=!0):t=i.lastIndexOf("-",e);if(t<0)break;let n=i.slice(0,t),a=i.slice(r?t:t+1);e=t-1,!(n===""||a==="/")&&(yield[n,a])}}function aC(i,e){if(i.length===0||e.tailwindConfig.prefix==="")return i;for(let t of i){let[r]=t;if(r.options.respectPrefix){let n=z.root({nodes:[t[1].clone()]}),a=t[1].raws.tailwind.classCandidate;n.walkRules(s=>{let o=a.startsWith("-");s.selector=Ft(e.tailwindConfig.prefix,s.selector,o)}),t[1]=n.nodes[0]}}return i}function oC(i,e){if(i.length===0)return i;let t=[];function r(n){return n.parent&&n.parent.type==="atrule"&&n.parent.name==="keyframes"}for(let[n,a]of i){let s=z.root({nodes:[a.clone()]});s.walkRules(o=>{if(r(o))return;let u=(0,vn.default)().astSync(o.selector);u.each(c=>Xa(c,e)),ju(u,c=>c===e?`!${c}`:c),o.selector=u.toString(),o.walkDecls(c=>c.important=!0)}),t.push([{...n,important:!0},s.nodes[0]])}return t}function lC(i,e,t){if(e.length===0)return e;let r={modifier:null,value:Kr};{let[n,...a]=ie(i,"/");if(a.length>1&&(n=n+"/"+a.slice(0,-1).join("/"),a=a.slice(-1)),a.length&&!t.variantMap.has(i)&&(i=n,r.modifier=a[0],!Z(t.tailwindConfig,"generalizedModifiers")))return[]}if(i.endsWith("]")&&!i.startsWith("[")){let n=/(.)(-?)\[(.*)\]/g.exec(i);if(n){let[,a,s,o]=n;if(a==="@"&&s==="-")return[];if(a!=="@"&&s==="")return[];i=i.replace(`${s}[${o}]`,""),r.value=o}}if(no(i)&&!t.variantMap.has(i)){let n=t.offsets.recordVariant(i),a=N(i.slice(1,-1)),s=ie(a,",");if(s.length>1)return[];if(!s.every(Cn))return[];let o=s.map((u,c)=>[t.offsets.applyParallelOffset(n,c),Zr(u.trim())]);t.variantMap.set(i,o)}if(t.variantMap.has(i)){let n=no(i),a=t.variantOptions.get(i)?.[ot]??{},s=t.variantMap.get(i).slice(),o=[],u=(()=>!(n||a.respectPrefix===!1))();for(let[c,f]of e){if(c.layer==="user")continue;let d=z.root({nodes:[f.clone()]});for(let[p,m,b]of s){let w=function(){x.raws.neededBackup||(x.raws.neededBackup=!0,x.walkRules(E=>E.raws.originalSelector=E.selector))},k=function(E){return w(),x.each(I=>{I.type==="rule"&&(I.selectors=I.selectors.map(q=>E({get className(){return to(q)},selector:q})))}),x},x=(b??d).clone(),y=[],S=m({get container(){return w(),x},separator:t.tailwindConfig.separator,modifySelectors:k,wrap(E){let I=x.nodes;x.removeAll(),E.append(I),x.append(E)},format(E){y.push({format:E,respectPrefix:u})},args:r});if(Array.isArray(S)){for(let[E,I]of S.entries())s.push([t.offsets.applyParallelOffset(p,E),I,x.clone()]);continue}if(typeof S=="string"&&y.push({format:S,respectPrefix:u}),S===null)continue;x.raws.neededBackup&&(delete x.raws.neededBackup,x.walkRules(E=>{let I=E.raws.originalSelector;if(!I||(delete E.raws.originalSelector,I===E.selector))return;let q=E.selector,R=(0,vn.default)(J=>{J.walkClasses(fe=>{fe.value=`${i}${t.tailwindConfig.separator}${fe.value}`})}).processSync(I);y.push({format:q.replace(R,"&"),respectPrefix:u}),E.selector=I})),x.nodes[0].raws.tailwind={...x.nodes[0].raws.tailwind,parentLayer:c.layer};let _=[{...c,sort:t.offsets.applyVariantOffset(c.sort,p,Object.assign(r,t.variantOptions.get(i))),collectedFormats:(c.collectedFormats??[]).concat(y)},x.nodes[0]];o.push(_)}}return o}return[]}function ro(i,e,t={}){return!se(i)&&!Array.isArray(i)?[[i],t]:Array.isArray(i)?ro(i[0],e,i[1]):(e.has(i)||e.set(i,Bt(i)),[e.get(i),t])}function fC(i){return uC.test(i)}function cC(i){if(!i.includes("://"))return!1;try{let e=new URL(i);return e.scheme!==""&&e.host!==""}catch(e){return!1}}function Cd(i){let e=!0;return i.walkDecls(t=>{if(!Ad(t.prop,t.value))return e=!1,!1}),e}function Ad(i,e){if(cC(`${i}:${e}`))return!1;try{return z.parse(`a{${i}:${e}}`).toResult(),!0}catch(t){return!1}}function pC(i,e){let[,t,r]=i.match(/^\[([a-zA-Z0-9-_]+):(\S+)\]$/)??[];if(r===void 0||!fC(t)||!Lt(r))return null;let n=N(r,{property:t});return Ad(t,n)?[[{sort:e.offsets.arbitraryProperty(i),layer:"utilities",options:{respectImportant:!0}},()=>({[Va(i)]:{[t]:n}})]]:null}function*dC(i,e){e.candidateRuleMap.has(i)&&(yield[e.candidateRuleMap.get(i),"DEFAULT"]),yield*function*(o){o!==null&&(yield[o,"DEFAULT"])}(pC(i,e));let t=i,r=!1,n=e.tailwindConfig.prefix,a=n.length,s=t.startsWith(n)||t.startsWith(`-${n}`);t[a]==="-"&&s&&(r=!0,t=n+t.slice(a+1)),r&&e.candidateRuleMap.has(t)&&(yield[e.candidateRuleMap.get(t),"-DEFAULT"]);for(let[o,u]of sC(t))e.candidateRuleMap.has(o)&&(yield[e.candidateRuleMap.get(o),r?`-${u}`:u])}function hC(i,e){return i===He?[He]:ie(i,e)}function*mC(i,e){for(let t of i)t[1].raws.tailwind={...t[1].raws.tailwind,classCandidate:e,preserveSource:t[0].options?.preserveSource??!1},yield t}function*io(i,e){let t=e.tailwindConfig.separator,[r,...n]=hC(i,t).reverse(),a=!1;r.startsWith("!")&&(a=!0,r=r.slice(1));for(let s of dC(r,e)){let o=[],u=new Map,[c,f]=s,d=c.length===1;for(let[p,m]of c){let b=[];if(typeof m=="function")for(let x of[].concat(m(f,{isOnlyPlugin:d}))){let[y,w]=ro(x,e.postCssNodeCache);for(let k of y)b.push([{...p,options:{...p.options,...w}},k])}else if(f==="DEFAULT"||f==="-DEFAULT"){let x=m,[y,w]=ro(x,e.postCssNodeCache);for(let k of y)b.push([{...p,options:{...p.options,...w}},k])}if(b.length>0){let x=Array.from(fs(p.options?.types??[],f,p.options??{},e.tailwindConfig)).map(([y,w])=>w);x.length>0&&u.set(b,x),o.push(b)}}if(no(f)){if(o.length>1){let b=function(y){return y.length===1?y[0]:y.find(w=>{let k=u.get(w);return w.some(([{options:S},_])=>Cd(_)?S.types.some(({type:E,preferOnConflict:I})=>k.includes(E)&&I):!1)})},[p,m]=o.reduce((y,w)=>(w.some(([{options:S}])=>S.types.some(({type:_})=>_==="any"))?y[0].push(w):y[1].push(w),y),[[],[]]),x=b(m)??b(p);if(x)o=[x];else{let y=o.map(k=>new Set([...u.get(k)??[]]));for(let k of y)for(let S of k){let _=!1;for(let E of y)k!==E&&E.has(S)&&(E.delete(S),_=!0);_&&k.delete(S)}let w=[];for(let[k,S]of y.entries())for(let _ of S){let E=o[k].map(([,I])=>I).flat().map(I=>I.toString().split(` +`).slice(1,-1).map(q=>q.trim()).map(q=>` ${q}`).join(` +`)).join(` + +`);w.push(` Use \`${i.replace("[",`[${_}:`)}\` for \`${E.trim()}\``);break}F.warn([`The class \`${i}\` is ambiguous and matches multiple utilities.`,...w,`If this is content and not a class, replace it with \`${i.replace("[","[").replace("]","]")}\` to silence this warning.`]);continue}}o=o.map(p=>p.filter(m=>Cd(m[1])))}o=o.flat(),o=Array.from(mC(o,r)),o=aC(o,e),a&&(o=oC(o,r));for(let p of n)o=lC(p,o,e);for(let p of o)p[1].raws.tailwind={...p[1].raws.tailwind,candidate:i},p=gC(p,{context:e,candidate:i}),p!==null&&(yield p)}}function gC(i,{context:e,candidate:t}){if(!i[0].collectedFormats)return i;let r=!0,n;try{n=jt(i[0].collectedFormats,{context:e,candidate:t})}catch{return null}let a=z.root({nodes:[i[1].clone()]});return a.walkRules(s=>{if(!xn(s))try{let o=wn(s.selector,n,{candidate:t,context:e});if(o===null){s.remove();return}s.selector=o}catch{return r=!1,!1}}),!r||a.nodes.length===0?null:(i[1]=a.nodes[0],i)}function xn(i){return i.parent&&i.parent.type==="atrule"&&i.parent.name==="keyframes"}function yC(i){if(i===!0)return e=>{xn(e)||e.walkDecls(t=>{t.parent.type==="rule"&&!xn(t.parent)&&(t.important=!0)})};if(typeof i=="string")return e=>{xn(e)||(e.selectors=e.selectors.map(t=>bn(t,i)))}}function kn(i,e,t=!1){let r=[],n=yC(e.tailwindConfig.important);for(let a of i){if(e.notClassCache.has(a))continue;if(e.candidateRuleCache.has(a)){r=r.concat(Array.from(e.candidateRuleCache.get(a)));continue}let s=Array.from(io(a,e));if(s.length===0){e.notClassCache.add(a);continue}e.classCache.set(a,s);let o=e.candidateRuleCache.get(a)??new Set;e.candidateRuleCache.set(a,o);for(let u of s){let[{sort:c,options:f},d]=u;if(f.respectImportant&&n){let m=z.root({nodes:[d.clone()]});m.walkRules(n),d=m.nodes[0]}let p=[c,t?d.clone():d];o.add(p),e.ruleCache.add(p),r.push(p)}}return r}function no(i){return i.startsWith("[")&&i.endsWith("]")}var vn,nC,uC,Sn=C(()=>{l();nt();vn=X(Be());za();Ct();un();pr();Ee();lt();Ka();Ua();cr();Xr();Ha();yt();ze();eo();nC=(0,vn.default)(i=>i.first.filter(({type:e})=>e==="class").pop().value);uC=/^[a-z_-]/});var _d,Od=C(()=>{l();_d={}});function wC(i){try{return _d.createHash("md5").update(i,"utf-8").digest("binary")}catch(e){return""}}function Ed(i,e){let t=e.toString();if(!t.includes("@tailwind"))return!1;let r=Ga.get(i),n=wC(t),a=r!==n;return Ga.set(i,n),a}var Td=C(()=>{l();Od();lt()});function An(i){return(i>0n)-(i<0n)}var Pd=C(()=>{l()});function Dd(i,e){let t=0n,r=0n;for(let[n,a]of e)i&n&&(t=t|n,r=r|a);return i&~t|r}var Id=C(()=>{l()});function qd(i){let e=null;for(let t of i)e=e??t,e=e>t?e:t;return e}function bC(i,e){let t=i.length,r=e.length,n=t{l();Pd();Id();so=class{constructor(){this.offsets={defaults:0n,base:0n,components:0n,utilities:0n,variants:0n,user:0n},this.layerPositions={defaults:0n,base:1n,components:2n,utilities:3n,user:4n,variants:5n},this.reservedVariantBits=0n,this.variantOffsets=new Map}create(e){return{layer:e,parentLayer:e,arbitrary:0n,variants:0n,parallelIndex:0n,index:this.offsets[e]++,propertyOffset:0n,property:"",options:[]}}arbitraryProperty(e){return{...this.create("utilities"),arbitrary:1n,property:e}}forVariant(e,t=0){let r=this.variantOffsets.get(e);if(r===void 0)throw new Error(`Cannot find offset for unknown variant ${e}`);return{...this.create("variants"),variants:r<n.startsWith("[")).sort(([n],[a])=>bC(n,a)),t=e.map(([,n])=>n).sort((n,a)=>An(n-a));return e.map(([,n],a)=>[n,t[a]]).filter(([n,a])=>n!==a)}remapArbitraryVariantOffsets(e){let t=this.recalculateVariantOffsets();return t.length===0?e:e.map(r=>{let[n,a]=r;return n={...n,variants:Dd(n.variants,t)},[n,a]})}sortArbitraryProperties(e){let t=new Set;for(let[s]of e)s.arbitrary===1n&&t.add(s.property);if(t.size===0)return e;let r=Array.from(t).sort(),n=new Map,a=1n;for(let s of r)n.set(s,a++);return e.map(s=>{let[o,u]=s;return o={...o,propertyOffset:n.get(o.property)??0n},[o,u]})}sort(e){return e=this.remapArbitraryVariantOffsets(e),e=this.sortArbitraryProperties(e),e.sort(([t],[r])=>An(this.compare(t,r)))}}});function uo(i,e){let t=i.tailwindConfig.prefix;return typeof t=="function"?t(e):t+e}function Bd({type:i="any",...e}){let t=[].concat(i);return{...e,types:t.map(r=>Array.isArray(r)?{type:r[0],...r[1]}:{type:r,preferOnConflict:!1})}}function vC(i){let e=[],t="",r=0;for(let n=0;n0&&e.push(t.trim()),e=e.filter(n=>n!==""),e}function xC(i,e,{before:t=[]}={}){if(t=[].concat(t),t.length<=0){i.push(e);return}let r=i.length-1;for(let n of t){let a=i.indexOf(n);a!==-1&&(r=Math.min(r,a))}i.splice(r,0,e)}function Fd(i){return Array.isArray(i)?i.flatMap(e=>!Array.isArray(e)&&!se(e)?e:Bt(e)):Fd([i])}function kC(i,e){return(0,ao.default)(r=>{let n=[];return e&&e(r),r.walkClasses(a=>{n.push(a.value)}),n}).transformSync(i)}function SC(i){i.walkPseudos(e=>{e.value===":not"&&e.remove()})}function CC(i,e={containsNonOnDemandable:!1},t=0){let r=[],n=[];i.type==="rule"?n.push(...i.selectors):i.type==="atrule"&&i.walkRules(a=>n.push(...a.selectors));for(let a of n){let s=kC(a,SC);s.length===0&&(e.containsNonOnDemandable=!0);for(let o of s)r.push(o)}return t===0?[e.containsNonOnDemandable||r.length===0,r]:r}function _n(i){return Fd(i).flatMap(e=>{let t=new Map,[r,n]=CC(e);return r&&n.unshift(He),n.map(a=>(t.has(e)||t.set(e,e),[a,t.get(e)]))})}function Cn(i){return i.startsWith("@")||i.includes("&")}function Zr(i){i=i.replace(/\n+/g,"").replace(/\s{1,}/g," ").trim();let e=vC(i).map(t=>{if(!t.startsWith("@"))return({format:a})=>a(t);let[,r,n]=/@(\S*)( .+|[({].*)?/g.exec(t);return({wrap:a})=>a(z.atRule({name:r,params:n?.trim()??""}))}).reverse();return t=>{for(let r of e)r(t)}}function AC(i,e,{variantList:t,variantMap:r,offsets:n,classList:a}){function s(p,m){return p?(0,Md.default)(i,p,m):i}function o(p){return Ft(i.prefix,p)}function u(p,m){return p===He?He:m.respectPrefix?e.tailwindConfig.prefix+p:p}function c(p,m,b={}){let x=Ke(p),y=s(["theme",...x],m);return Ge(x[0])(y,b)}let f=0,d={postcss:z,prefix:o,e:pe,config:s,theme:c,corePlugins:p=>Array.isArray(i.corePlugins)?i.corePlugins.includes(p):s(["corePlugins",p],!0),variants:()=>[],addBase(p){for(let[m,b]of _n(p)){let x=u(m,{}),y=n.create("base");e.candidateRuleMap.has(x)||e.candidateRuleMap.set(x,[]),e.candidateRuleMap.get(x).push([{sort:y,layer:"base"},b])}},addDefaults(p,m){let b={[`@defaults ${p}`]:m};for(let[x,y]of _n(b)){let w=u(x,{});e.candidateRuleMap.has(w)||e.candidateRuleMap.set(w,[]),e.candidateRuleMap.get(w).push([{sort:n.create("defaults"),layer:"defaults"},y])}},addComponents(p,m){m=Object.assign({},{preserveSource:!1,respectPrefix:!0,respectImportant:!1},Array.isArray(m)?{}:m);for(let[x,y]of _n(p)){let w=u(x,m);a.add(w),e.candidateRuleMap.has(w)||e.candidateRuleMap.set(w,[]),e.candidateRuleMap.get(w).push([{sort:n.create("components"),layer:"components",options:m},y])}},addUtilities(p,m){m=Object.assign({},{preserveSource:!1,respectPrefix:!0,respectImportant:!0},Array.isArray(m)?{}:m);for(let[x,y]of _n(p)){let w=u(x,m);a.add(w),e.candidateRuleMap.has(w)||e.candidateRuleMap.set(w,[]),e.candidateRuleMap.get(w).push([{sort:n.create("utilities"),layer:"utilities",options:m},y])}},matchUtilities:function(p,m){m=Bd({...{respectPrefix:!0,respectImportant:!0,modifiers:!1},...m});let x=n.create("utilities");for(let y in p){let S=function(E,{isOnlyPlugin:I}){let[q,R,J]=us(m.types,E,m,i);if(q===void 0)return[];if(!m.types.some(({type:te})=>te===R))if(I)F.warn([`Unnecessary typehint \`${R}\` in \`${y}-${E}\`.`,`You can safely update it to \`${y}-${E.replace(R+":","")}\`.`]);else return[];if(!Lt(q))return[];let fe={get modifier(){return m.modifiers||F.warn(`modifier-used-without-options-for-${y}`,["Your plugin must set `modifiers: true` in its options to support modifiers."]),J}},he=Z(i,"generalizedModifiers");return[].concat(he?k(q,fe):k(q)).filter(Boolean).map(te=>({[fn(y,E)]:te}))},w=u(y,m),k=p[y];a.add([w,m]);let _=[{sort:x,layer:"utilities",options:m},S];e.candidateRuleMap.has(w)||e.candidateRuleMap.set(w,[]),e.candidateRuleMap.get(w).push(_)}},matchComponents:function(p,m){m=Bd({...{respectPrefix:!0,respectImportant:!1,modifiers:!1},...m});let x=n.create("components");for(let y in p){let S=function(E,{isOnlyPlugin:I}){let[q,R,J]=us(m.types,E,m,i);if(q===void 0)return[];if(!m.types.some(({type:te})=>te===R))if(I)F.warn([`Unnecessary typehint \`${R}\` in \`${y}-${E}\`.`,`You can safely update it to \`${y}-${E.replace(R+":","")}\`.`]);else return[];if(!Lt(q))return[];let fe={get modifier(){return m.modifiers||F.warn(`modifier-used-without-options-for-${y}`,["Your plugin must set `modifiers: true` in its options to support modifiers."]),J}},he=Z(i,"generalizedModifiers");return[].concat(he?k(q,fe):k(q)).filter(Boolean).map(te=>({[fn(y,E)]:te}))},w=u(y,m),k=p[y];a.add([w,m]);let _=[{sort:x,layer:"components",options:m},S];e.candidateRuleMap.has(w)||e.candidateRuleMap.set(w,[]),e.candidateRuleMap.get(w).push(_)}},addVariant(p,m,b={}){m=[].concat(m).map(x=>{if(typeof x!="string")return(y={})=>{let{args:w,modifySelectors:k,container:S,separator:_,wrap:E,format:I}=y,q=x(Object.assign({modifySelectors:k,container:S,separator:_},b.type===oo.MatchVariant&&{args:w,wrap:E,format:I}));if(typeof q=="string"&&!Cn(q))throw new Error(`Your custom variant \`${p}\` has an invalid format string. Make sure it's an at-rule or contains a \`&\` placeholder.`);return Array.isArray(q)?q.filter(R=>typeof R=="string").map(R=>Zr(R)):q&&typeof q=="string"&&Zr(q)(y)};if(!Cn(x))throw new Error(`Your custom variant \`${p}\` has an invalid format string. Make sure it's an at-rule or contains a \`&\` placeholder.`);return Zr(x)}),xC(t,p,b),r.set(p,m),e.variantOptions.set(p,b)},matchVariant(p,m,b){let x=b?.id??++f,y=p==="@",w=Z(i,"generalizedModifiers");for(let[S,_]of Object.entries(b?.values??{}))S!=="DEFAULT"&&d.addVariant(y?`${p}${S}`:`${p}-${S}`,({args:E,container:I})=>m(_,w?{modifier:E?.modifier,container:I}:{container:I}),{...b,value:_,id:x,type:oo.MatchVariant,variantInfo:lo.Base});let k="DEFAULT"in(b?.values??{});d.addVariant(p,({args:S,container:_})=>S?.value===Kr&&!k?null:m(S?.value===Kr?b.values.DEFAULT:S?.value??(typeof S=="string"?S:""),w?{modifier:S?.modifier,container:_}:{container:_}),{...b,id:x,type:oo.MatchVariant,variantInfo:lo.Dynamic})}};return d}function On(i){return fo.has(i)||fo.set(i,new Map),fo.get(i)}function Nd(i,e){let t=!1,r=new Map;for(let n of i){if(!n)continue;let a=gs.parse(n),s=a.hash?a.href.replace(a.hash,""):a.href;s=a.search?s.replace(a.search,""):s;let o=re.statSync(decodeURIComponent(s),{throwIfNoEntry:!1})?.mtimeMs;!o||((!e.has(n)||o>e.get(n))&&(t=!0),r.set(n,o))}return[t,r]}function Ld(i){i.walkAtRules(e=>{["responsive","variants"].includes(e.name)&&(Ld(e),e.before(e.nodes),e.remove())})}function _C(i){let e=[];return i.each(t=>{t.type==="atrule"&&["responsive","variants"].includes(t.name)&&(t.name="layer",t.params="utilities")}),i.walkAtRules("layer",t=>{if(Ld(t),t.params==="base"){for(let r of t.nodes)e.push(function({addBase:n}){n(r,{respectPrefix:!1})});t.remove()}else if(t.params==="components"){for(let r of t.nodes)e.push(function({addComponents:n}){n(r,{respectPrefix:!1,preserveSource:!0})});t.remove()}else if(t.params==="utilities"){for(let r of t.nodes)e.push(function({addUtilities:n}){n(r,{respectPrefix:!1,preserveSource:!0})});t.remove()}}),e}function OC(i,e){let t=Object.entries({...H,...hd}).map(([u,c])=>i.tailwindConfig.corePlugins.includes(u)?c:null).filter(Boolean),r=i.tailwindConfig.plugins.map(u=>(u.__isOptionsFunction&&(u=u()),typeof u=="function"?u:u.handler)),n=_C(e),a=[H.childVariant,H.pseudoElementVariants,H.pseudoClassVariants,H.hasVariants,H.ariaVariants,H.dataVariants],s=[H.supportsVariants,H.reducedMotionVariants,H.prefersContrastVariants,H.screenVariants,H.orientationVariants,H.directionVariants,H.darkVariants,H.forcedColorsVariants,H.printVariant];return(i.tailwindConfig.darkMode==="class"||Array.isArray(i.tailwindConfig.darkMode)&&i.tailwindConfig.darkMode[0]==="class")&&(s=[H.supportsVariants,H.reducedMotionVariants,H.prefersContrastVariants,H.darkVariants,H.screenVariants,H.orientationVariants,H.directionVariants,H.forcedColorsVariants,H.printVariant]),[...t,...a,...r,...s,...n]}function EC(i,e){let t=[],r=new Map;e.variantMap=r;let n=new so;e.offsets=n;let a=new Set,s=AC(e.tailwindConfig,e,{variantList:t,variantMap:r,offsets:n,classList:a});for(let f of i)if(Array.isArray(f))for(let d of f)d(s);else f?.(s);n.recordVariants(t,f=>r.get(f).length);for(let[f,d]of r.entries())e.variantMap.set(f,d.map((p,m)=>[n.forVariant(f,m),p]));let o=(e.tailwindConfig.safelist??[]).filter(Boolean);if(o.length>0){let f=[];for(let d of o){if(typeof d=="string"){e.changedContent.push({content:d,extension:"html"});continue}if(d instanceof RegExp){F.warn("root-regex",["Regular expressions in `safelist` work differently in Tailwind CSS v3.0.","Update your `safelist` configuration to eliminate this warning.","https://tailwindcss.com/docs/content-configuration#safelisting-classes"]);continue}f.push(d)}if(f.length>0){let d=new Map,p=e.tailwindConfig.prefix.length,m=f.some(b=>b.pattern.source.includes("!"));for(let b of a){let x=Array.isArray(b)?(()=>{let[y,w]=b,S=Object.keys(w?.values??{}).map(_=>Jr(y,_));return w?.supportsNegativeValues&&(S=[...S,...S.map(_=>"-"+_)],S=[...S,...S.map(_=>_.slice(0,p)+"-"+_.slice(p))]),w.types.some(({type:_})=>_==="color")&&(S=[...S,...S.flatMap(_=>Object.keys(e.tailwindConfig.theme.opacity).map(E=>`${_}/${E}`))]),m&&w?.respectImportant&&(S=[...S,...S.map(_=>"!"+_)]),S})():[b];for(let y of x)for(let{pattern:w,variants:k=[]}of f)if(w.lastIndex=0,d.has(w)||d.set(w,0),!!w.test(y)){d.set(w,d.get(w)+1),e.changedContent.push({content:y,extension:"html"});for(let S of k)e.changedContent.push({content:S+e.tailwindConfig.separator+y,extension:"html"})}}for(let[b,x]of d.entries())x===0&&F.warn([`The safelist pattern \`${b}\` doesn't match any Tailwind CSS classes.`,"Fix this pattern or remove it from your `safelist` configuration.","https://tailwindcss.com/docs/content-configuration#safelisting-classes"])}}let u=[].concat(e.tailwindConfig.darkMode??"media")[1]??"dark",c=[uo(e,u),uo(e,"group"),uo(e,"peer")];e.getClassOrder=function(d){let p=[...d].sort((y,w)=>y===w?0:y[y,null])),b=kn(new Set(p),e,!0);b=e.offsets.sort(b);let x=BigInt(c.length);for(let[,y]of b){let w=y.raws.tailwind.candidate;m.set(w,m.get(w)??x++)}return d.map(y=>{let w=m.get(y)??null,k=c.indexOf(y);return w===null&&k!==-1&&(w=BigInt(k)),[y,w]})},e.getClassList=function(d={}){let p=[];for(let m of a)if(Array.isArray(m)){let[b,x]=m,y=[],w=Object.keys(x?.modifiers??{});x?.types?.some(({type:_})=>_==="color")&&w.push(...Object.keys(e.tailwindConfig.theme.opacity??{}));let k={modifiers:w},S=d.includeMetadata&&w.length>0;for(let[_,E]of Object.entries(x?.values??{})){if(E==null)continue;let I=Jr(b,_);if(p.push(S?[I,k]:I),x?.supportsNegativeValues&&Xe(E)){let q=Jr(b,`-${_}`);y.push(S?[q,k]:q)}}p.push(...y)}else p.push(m);return p},e.getVariants=function(){let d=Math.random().toString(36).substring(7).toUpperCase(),p=[];for(let[m,b]of e.variantOptions.entries())b.variantInfo!==lo.Base&&p.push({name:m,isArbitrary:b.type===Symbol.for("MATCH_VARIANT"),values:Object.keys(b.values??{}),hasDash:m!=="@",selectors({modifier:x,value:y}={}){let w=`TAILWINDPLACEHOLDER${d}`,k=z.rule({selector:`.${w}`}),S=z.root({nodes:[k.clone()]}),_=S.toString(),E=(e.variantMap.get(m)??[]).flatMap(([le,me])=>me),I=[];for(let le of E){let me=[],ai={args:{modifier:x,value:b.values?.[y]??y},separator:e.tailwindConfig.separator,modifySelectors(Ae){return S.each(Yn=>{Yn.type==="rule"&&(Yn.selectors=Yn.selectors.map(su=>Ae({get className(){return to(su)},selector:su})))}),S},format(Ae){me.push(Ae)},wrap(Ae){me.push(`@${Ae.name} ${Ae.params} { & }`)},container:S},oi=le(ai);if(me.length>0&&I.push(me),Array.isArray(oi))for(let Ae of oi)me=[],Ae(ai),I.push(me)}let q=[],R=S.toString();_!==R&&(S.walkRules(le=>{let me=le.selector,ai=(0,ao.default)(oi=>{oi.walkClasses(Ae=>{Ae.value=`${m}${e.tailwindConfig.separator}${Ae.value}`})}).processSync(me);q.push(me.replace(ai,"&").replace(w,"&"))}),S.walkAtRules(le=>{q.push(`@${le.name} (${le.params}) { & }`)}));let J=!(y in(b.values??{})),fe=b[ot]??{},he=(()=>!(J||fe.respectPrefix===!1))();I=I.map(le=>le.map(me=>({format:me,respectPrefix:he}))),q=q.map(le=>({format:le,respectPrefix:he}));let Ie={candidate:w,context:e},te=I.map(le=>wn(`.${w}`,jt(le,Ie),Ie).replace(`.${w}`,"&").replace("{ & }","").trim());return q.length>0&&te.push(jt(q,Ie).toString().replace(`.${w}`,"&")),te}});return p}}function $d(i,e){!i.classCache.has(e)||(i.notClassCache.add(e),i.classCache.delete(e),i.applyClassCache.delete(e),i.candidateRuleMap.delete(e),i.candidateRuleCache.delete(e),i.stylesheetCache=null)}function TC(i,e){let t=e.raws.tailwind.candidate;if(!!t){for(let r of i.ruleCache)r[1].raws.tailwind.candidate===t&&i.ruleCache.delete(r);$d(i,t)}}function co(i,e=[],t=z.root()){let r={disposables:[],ruleCache:new Set,candidateRuleCache:new Map,classCache:new Map,applyClassCache:new Map,notClassCache:new Set(i.blocklist??[]),postCssNodeCache:new Map,candidateRuleMap:new Map,tailwindConfig:i,changedContent:e,variantMap:new Map,stylesheetCache:null,variantOptions:new Map,markInvalidUtilityCandidate:a=>$d(r,a),markInvalidUtilityNode:a=>TC(r,a)},n=OC(r,t);return EC(n,r),r}function jd(i,e,t,r,n,a){let s=e.opts.from,o=r!==null;De.DEBUG&&console.log("Source path:",s);let u;if(o&&zt.has(s))u=zt.get(s);else if(ei.has(n)){let p=ei.get(n);ut.get(p).add(s),zt.set(s,p),u=p}let c=Ed(s,i);if(u){let[p,m]=Nd([...a],On(u));if(!p&&!c)return[u,!1,m]}if(zt.has(s)){let p=zt.get(s);if(ut.has(p)&&(ut.get(p).delete(s),ut.get(p).size===0)){ut.delete(p);for(let[m,b]of ei)b===p&&ei.delete(m);for(let m of p.disposables.splice(0))m(p)}}De.DEBUG&&console.log("Setting up new context...");let f=co(t,[],i);Object.assign(f,{userConfigPath:r});let[,d]=Nd([...a],On(f));return ei.set(n,f),zt.set(s,f),ut.has(f)||ut.set(f,new Set),ut.get(f).add(s),[f,!0,d]}var Md,ao,ot,oo,lo,fo,zt,ei,ut,Xr=C(()=>{l();je();ys();nt();Md=X(Ls()),ao=X(Be());Yr();za();un();Ct();Nt();Ua();pr();md();lt();lt();pi();Ee();fi();Ha();Sn();Td();Rd();ze();Ka();ot=Symbol(),oo={AddVariant:Symbol.for("ADD_VARIANT"),MatchVariant:Symbol.for("MATCH_VARIANT")},lo={Base:1<<0,Dynamic:1<<1};fo=new WeakMap;zt=gd,ei=yd,ut=gn});function po(i){return i.ignore?[]:i.glob?h.env.ROLLUP_WATCH==="true"?[{type:"dependency",file:i.base}]:[{type:"dir-dependency",dir:i.base,glob:i.glob}]:[{type:"dependency",file:i.base}]}var zd=C(()=>{l()});function Vd(i,e){return{handler:i,config:e}}var Ud,Wd=C(()=>{l();Vd.withOptions=function(i,e=()=>({})){let t=function(r){return{__options:r,handler:i(r),config:e(r)}};return t.__isOptionsFunction=!0,t.__pluginFunction=i,t.__configFunction=e,t};Ud=Vd});var ho={};_e(ho,{default:()=>PC});var PC,mo=C(()=>{l();Wd();PC=Ud});var Hd=v((c6,Gd)=>{l();var DC=(mo(),ho).default,IC={overflow:"hidden",display:"-webkit-box","-webkit-box-orient":"vertical"},qC=DC(function({matchUtilities:i,addUtilities:e,theme:t,variants:r}){let n=t("lineClamp");i({"line-clamp":a=>({...IC,"-webkit-line-clamp":`${a}`})},{values:n}),e([{".line-clamp-none":{"-webkit-line-clamp":"unset"}}],r("lineClamp"))},{theme:{lineClamp:{1:"1",2:"2",3:"3",4:"4",5:"5",6:"6"}},variants:{lineClamp:["responsive"]}});Gd.exports=qC});function go(i){i.content.files.length===0&&F.warn("content-problems",["The `content` option in your Tailwind CSS configuration is missing or empty.","Configure your content sources or your generated CSS will be missing styles.","https://tailwindcss.com/docs/content-configuration"]);try{let e=Hd();i.plugins.includes(e)&&(F.warn("line-clamp-in-core",["As of Tailwind CSS v3.3, the `@tailwindcss/line-clamp` plugin is now included by default.","Remove it from the `plugins` array in your configuration to eliminate this warning."]),i.plugins=i.plugins.filter(t=>t!==e))}catch{}return i}var Yd=C(()=>{l();Ee()});var Qd,Jd=C(()=>{l();Qd=()=>!1});var En,Xd=C(()=>{l();En={sync:i=>[].concat(i),generateTasks:i=>[{dynamic:!1,base:".",negative:[],positive:[].concat(i),patterns:[].concat(i)}],escapePath:i=>i}});var yo,Kd=C(()=>{l();yo=i=>i});var Zd,eh=C(()=>{l();Zd=()=>""});function th(i){let e=i,t=Zd(i);return t!=="."&&(e=i.substr(t.length),e.charAt(0)==="/"&&(e=e.substr(1))),e.substr(0,2)==="./"?e=e.substr(2):e.charAt(0)==="/"&&(e=e.substr(1)),{base:t,glob:e}}var rh=C(()=>{l();eh()});function ih(i,e){let t=e.content.files;t=t.filter(o=>typeof o=="string"),t=t.map(yo);let r=En.generateTasks(t),n=[],a=[];for(let o of r)n.push(...o.positive.map(u=>nh(u,!1))),a.push(...o.negative.map(u=>nh(u,!0)));let s=[...n,...a];return s=MC(i,s),s=s.flatMap(BC),s=s.map(RC),s}function nh(i,e){let t={original:i,base:i,ignore:e,pattern:i,glob:null};return Qd(i)&&Object.assign(t,th(i)),t}function RC(i){let e=yo(i.base);return e=En.escapePath(e),i.pattern=i.glob?`${e}/${i.glob}`:e,i.pattern=i.ignore?`!${i.pattern}`:i.pattern,i}function MC(i,e){let t=[];return i.userConfigPath&&i.tailwindConfig.content.relative&&(t=[ee.dirname(i.userConfigPath)]),e.map(r=>(r.base=ee.resolve(...t,r.base),r))}function BC(i){let e=[i];try{let t=re.realpathSync(i.base);t!==i.base&&e.push({...i,base:t})}catch{}return e}function sh(i,e,t){let r=i.tailwindConfig.content.files.filter(s=>typeof s.raw=="string").map(({raw:s,extension:o="html"})=>({content:s,extension:o})),[n,a]=FC(e,t);for(let s of n){let o=ee.extname(s).slice(1);r.push({file:s,extension:o})}return[r,a]}function FC(i,e){let t=i.map(s=>s.pattern),r=new Map,n=new Set;De.DEBUG&&console.time("Finding changed files");let a=En.sync(t,{absolute:!0});for(let s of a){let o=e.get(s)||-1/0,u=re.statSync(s).mtimeMs;u>o&&(n.add(s),r.set(s,u))}return De.DEBUG&&console.timeEnd("Finding changed files"),[n,r]}var ah=C(()=>{l();je();wt();Jd();Xd();Kd();rh();lt()});function oh(){}var lh=C(()=>{l()});function jC(i,e){for(let t of e){let r=`${i}${t}`;if(re.existsSync(r)&&re.statSync(r).isFile())return r}for(let t of e){let r=`${i}/index${t}`;if(re.existsSync(r))return r}return null}function*uh(i,e,t,r=ee.extname(i)){let n=jC(ee.resolve(e,i),NC.includes(r)?LC:$C);if(n===null||t.has(n))return;t.add(n),yield n,e=ee.dirname(n),r=ee.extname(n);let a=re.readFileSync(n,"utf-8");for(let s of[...a.matchAll(/import[\s\S]*?['"](.{3,}?)['"]/gi),...a.matchAll(/import[\s\S]*from[\s\S]*?['"](.{3,}?)['"]/gi),...a.matchAll(/require\(['"`](.+)['"`]\)/gi)])!s[1].startsWith(".")||(yield*uh(s[1],e,t,r))}function wo(i){return i===null?new Set:new Set(uh(i,ee.dirname(i),new Set))}var NC,LC,$C,fh=C(()=>{l();je();wt();NC=[".js",".cjs",".mjs"],LC=["",".js",".cjs",".mjs",".ts",".cts",".mts",".jsx",".tsx"],$C=["",".ts",".cts",".mts",".tsx",".js",".cjs",".mjs",".jsx"]});function zC(i,e){if(bo.has(i))return bo.get(i);let t=ih(i,e);return bo.set(i,t).get(i)}function VC(i){let e=ms(i);if(e!==null){let[r,n,a,s]=ph.get(e)||[],o=wo(e),u=!1,c=new Map;for(let p of o){let m=re.statSync(p).mtimeMs;c.set(p,m),(!s||!s.has(p)||m>s.get(p))&&(u=!0)}if(!u)return[r,e,n,a];for(let p of o)delete ou.cache[p];let f=go(hr(oh(e))),d=ui(f);return ph.set(e,[f,d,o,c]),[f,e,d,o]}let t=hr(i?.config??i??{});return t=go(t),[t,null,ui(t),[]]}function vo(i){return({tailwindDirectives:e,registerDependency:t})=>(r,n)=>{let[a,s,o,u]=VC(i),c=new Set(u);if(e.size>0){c.add(n.opts.from);for(let b of n.messages)b.type==="dependency"&&c.add(b.file)}let[f,,d]=jd(r,n,a,s,o,c),p=On(f),m=zC(f,a);if(e.size>0){for(let y of m)for(let w of po(y))t(w);let[b,x]=sh(f,m,p);for(let y of b)f.changedContent.push(y);for(let[y,w]of x.entries())d.set(y,w)}for(let b of u)t({type:"dependency",file:b});for(let[b,x]of d.entries())p.set(b,x);return f}}var ch,ph,bo,dh=C(()=>{l();je();ch=X(Qn());pu();hs();tf();Xr();zd();Yd();ah();lh();fh();ph=new ch.default({maxSize:100}),bo=new WeakMap});function xo(i){let e=new Set,t=new Set,r=new Set;if(i.walkAtRules(n=>{n.name==="apply"&&r.add(n),n.name==="import"&&(n.params==='"tailwindcss/base"'||n.params==="'tailwindcss/base'"?(n.name="tailwind",n.params="base"):n.params==='"tailwindcss/components"'||n.params==="'tailwindcss/components'"?(n.name="tailwind",n.params="components"):n.params==='"tailwindcss/utilities"'||n.params==="'tailwindcss/utilities'"?(n.name="tailwind",n.params="utilities"):(n.params==='"tailwindcss/screens"'||n.params==="'tailwindcss/screens'"||n.params==='"tailwindcss/variants"'||n.params==="'tailwindcss/variants'")&&(n.name="tailwind",n.params="variants")),n.name==="tailwind"&&(n.params==="screens"&&(n.params="variants"),e.add(n.params)),["layer","responsive","variants"].includes(n.name)&&(["responsive","variants"].includes(n.name)&&F.warn(`${n.name}-at-rule-deprecated`,[`The \`@${n.name}\` directive has been deprecated in Tailwind CSS v3.0.`,"Use `@layer utilities` or `@layer components` instead.","https://tailwindcss.com/docs/upgrade-guide#replace-variants-with-layer"]),t.add(n))}),!e.has("base")||!e.has("components")||!e.has("utilities")){for(let n of t)if(n.name==="layer"&&["base","components","utilities"].includes(n.params)){if(!e.has(n.params))throw n.error(`\`@layer ${n.params}\` is used but no matching \`@tailwind ${n.params}\` directive is present.`)}else if(n.name==="responsive"){if(!e.has("utilities"))throw n.error("`@responsive` is used but `@tailwind utilities` is missing.")}else if(n.name==="variants"&&!e.has("utilities"))throw n.error("`@variants` is used but `@tailwind utilities` is missing.")}return{tailwindDirectives:e,applyDirectives:r}}var hh=C(()=>{l();Ee()});function kt(i,e=void 0,t=void 0){return i.map(r=>{let n=r.clone();return t!==void 0&&(n.raws.tailwind={...n.raws.tailwind,...t}),e!==void 0&&mh(n,a=>{if(a.raws.tailwind?.preserveSource===!0&&a.source)return!1;a.source=e}),n})}function mh(i,e){e(i)!==!1&&i.each?.(t=>mh(t,e))}var gh=C(()=>{l()});function ko(i){return i=Array.isArray(i)?i:[i],i=i.map(e=>e instanceof RegExp?e.source:e),i.join("")}function we(i){return new RegExp(ko(i),"g")}function ft(i){return`(?:${i.map(ko).join("|")})`}function So(i){return`(?:${ko(i)})?`}function wh(i){return i&&UC.test(i)?i.replace(yh,"\\$&"):i||""}var yh,UC,bh=C(()=>{l();yh=/[\\^$.*+?()[\]{}|]/g,UC=RegExp(yh.source)});function vh(i){let e=Array.from(WC(i));return t=>{let r=[];for(let n of e)for(let a of t.match(n)??[])r.push(YC(a));for(let n of r.slice()){let a=ie(n,".");for(let s=0;s=a.length-1){r.push(o);continue}let u=parseInt(a[s+1]);isNaN(u)?r.push(o):s++}}return r}}function*WC(i){let e=i.tailwindConfig.separator,t=i.tailwindConfig.prefix!==""?So(we([/-?/,wh(i.tailwindConfig.prefix)])):"",r=ft([/\[[^\s:'"`]+:[^\s\[\]]+\]/,/\[[^\s:'"`\]]+:[^\s]+?\[[^\s]+\][^\s]+?\]/,we([ft([/-?(?:\w+)/,/@(?:\w+)/]),So(ft([we([ft([/-(?:\w+-)*\['[^\s]+'\]/,/-(?:\w+-)*\["[^\s]+"\]/,/-(?:\w+-)*\[`[^\s]+`\]/,/-(?:\w+-)*\[(?:[^\s\[\]]+\[[^\s\[\]]+\])*[^\s:\[\]]+\]/]),/(?![{([]])/,/(?:\/[^\s'"`\\><$]*)?/]),we([ft([/-(?:\w+-)*\['[^\s]+'\]/,/-(?:\w+-)*\["[^\s]+"\]/,/-(?:\w+-)*\[`[^\s]+`\]/,/-(?:\w+-)*\[(?:[^\s\[\]]+\[[^\s\[\]]+\])*[^\s\[\]]+\]/]),/(?![{([]])/,/(?:\/[^\s'"`\\$]*)?/]),/[-\/][^\s'"`\\$={><]*/]))])]),n=[ft([we([/@\[[^\s"'`]+\](\/[^\s"'`]+)?/,e]),we([/([^\s"'`\[\\]+-)?\[[^\s"'`]+\]\/[\w_-]+/,e]),we([/([^\s"'`\[\\]+-)?\[[^\s"'`]+\]/,e]),we([/[^\s"'`\[\\]+/,e])]),ft([we([/([^\s"'`\[\\]+-)?\[[^\s`]+\]\/[\w_-]+/,e]),we([/([^\s"'`\[\\]+-)?\[[^\s`]+\]/,e]),we([/[^\s`\[\\]+/,e])])];for(let a of n)yield we(["((?=((",a,")+))\\2)?",/!?/,t,r])}function YC(i){if(!i.includes("-["))return i;let e=0,t=[],r=i.matchAll(GC);r=Array.from(r).flatMap(n=>{let[,...a]=n;return a.map((s,o)=>Object.assign([],n,{index:n.index+o,0:s}))});for(let n of r){let a=n[0],s=t[t.length-1];if(a===s?t.pop():(a==="'"||a==='"'||a==="`")&&t.push(a),!s){if(a==="["){e++;continue}else if(a==="]"){e--;continue}if(e<0)return i.substring(0,n.index-1);if(e===0&&!HC.test(a))return i.substring(0,n.index)}}return i}var GC,HC,xh=C(()=>{l();bh();yt();GC=/([\[\]'"`])([^\[\]'"`])?/g,HC=/[^"'`\s<>\]]+/});function QC(i,e){let t=i.tailwindConfig.content.extract;return t[e]||t.DEFAULT||Sh[e]||Sh.DEFAULT(i)}function JC(i,e){let t=i.content.transform;return t[e]||t.DEFAULT||Ch[e]||Ch.DEFAULT}function XC(i,e,t,r){ti.has(e)||ti.set(e,new kh.default({maxSize:25e3}));for(let n of i.split(` +`))if(n=n.trim(),!r.has(n))if(r.add(n),ti.get(e).has(n))for(let a of ti.get(e).get(n))t.add(a);else{let a=e(n).filter(o=>o!=="!*"),s=new Set(a);for(let o of s)t.add(o);ti.get(e).set(n,s)}}function KC(i,e){let t=e.offsets.sort(i),r={base:new Set,defaults:new Set,components:new Set,utilities:new Set,variants:new Set};for(let[n,a]of t)r[n.layer].add(a);return r}function Co(i){return async e=>{let t={base:null,components:null,utilities:null,variants:null};if(e.walkAtRules(y=>{y.name==="tailwind"&&Object.keys(t).includes(y.params)&&(t[y.params]=y)}),Object.values(t).every(y=>y===null))return e;let r=new Set([...i.candidates??[],He]),n=new Set;Ye.DEBUG&&console.time("Reading changed files");let a=[];for(let y of i.changedContent){let w=JC(i.tailwindConfig,y.extension),k=QC(i,y.extension);a.push([y,{transformer:w,extractor:k}])}let s=500;for(let y=0;y{S=k?await re.promises.readFile(k,"utf8"):S,XC(_(S),E,r,n)}))}Ye.DEBUG&&console.timeEnd("Reading changed files");let o=i.classCache.size;Ye.DEBUG&&console.time("Generate rules"),Ye.DEBUG&&console.time("Sorting candidates");let u=new Set([...r].sort((y,w)=>y===w?0:y{let w=y.raws.tailwind?.parentLayer;return w==="components"?t.components!==null:w==="utilities"?t.utilities!==null:!0});t.variants?(t.variants.before(kt(b,t.variants.source,{layer:"variants"})),t.variants.remove()):b.length>0&&e.append(kt(b,e.source,{layer:"variants"})),e.source.end=e.source.end??e.source.start;let x=b.some(y=>y.raws.tailwind?.parentLayer==="utilities");t.utilities&&p.size===0&&!x&&F.warn("content-problems",["No utility classes were detected in your source files. If this is unexpected, double-check the `content` option in your Tailwind CSS configuration.","https://tailwindcss.com/docs/content-configuration"]),Ye.DEBUG&&(console.log("Potential classes: ",r.size),console.log("Active contexts: ",gn.size)),i.changedContent=[],e.walkAtRules("layer",y=>{Object.keys(t).includes(y.params)&&y.remove()})}}var kh,Ye,Sh,Ch,ti,Ah=C(()=>{l();je();kh=X(Qn());lt();Sn();Ee();gh();xh();Ye=De,Sh={DEFAULT:vh},Ch={DEFAULT:i=>i,svelte:i=>i.replace(/(?:^|\s)class:/g," ")};ti=new WeakMap});function Pn(i){let e=new Map;z.root({nodes:[i.clone()]}).walkRules(a=>{(0,Tn.default)(s=>{s.walkClasses(o=>{let u=o.parent.toString(),c=e.get(u);c||e.set(u,c=new Set),c.add(o.value)})}).processSync(a.selector)});let r=Array.from(e.values(),a=>Array.from(a)),n=r.flat();return Object.assign(n,{groups:r})}function Ao(i){return ZC.astSync(i)}function _h(i,e){let t=new Set;for(let r of i)t.add(r.split(e).pop());return Array.from(t)}function Oh(i,e){let t=i.tailwindConfig.prefix;return typeof t=="function"?t(e):t+e}function*Eh(i){for(yield i;i.parent;)yield i.parent,i=i.parent}function e2(i,e={}){let t=i.nodes;i.nodes=[];let r=i.clone(e);return i.nodes=t,r}function t2(i){for(let e of Eh(i))if(i!==e){if(e.type==="root")break;i=e2(e,{nodes:[i]})}return i}function r2(i,e){let t=new Map;return i.walkRules(r=>{for(let s of Eh(r))if(s.raws.tailwind?.layer!==void 0)return;let n=t2(r),a=e.offsets.create("user");for(let s of Pn(r)){let o=t.get(s)||[];t.set(s,o),o.push([{layer:"user",sort:a,important:!1},n])}}),t}function i2(i,e){for(let t of i){if(e.notClassCache.has(t)||e.applyClassCache.has(t))continue;if(e.classCache.has(t)){e.applyClassCache.set(t,e.classCache.get(t).map(([n,a])=>[n,a.clone()]));continue}let r=Array.from(io(t,e));if(r.length===0){e.notClassCache.add(t);continue}e.applyClassCache.set(t,r)}return e.applyClassCache}function n2(i){let e=null;return{get:t=>(e=e||i(),e.get(t)),has:t=>(e=e||i(),e.has(t))}}function s2(i){return{get:e=>i.flatMap(t=>t.get(e)||[]),has:e=>i.some(t=>t.has(e))}}function Th(i){let e=i.split(/[\s\t\n]+/g);return e[e.length-1]==="!important"?[e.slice(0,-1),!0]:[e,!1]}function Ph(i,e,t){let r=new Set,n=[];if(i.walkAtRules("apply",u=>{let[c]=Th(u.params);for(let f of c)r.add(f);n.push(u)}),n.length===0)return;let a=s2([t,i2(r,e)]);function s(u,c,f){let d=Ao(u),p=Ao(c),b=Ao(`.${pe(f)}`).nodes[0].nodes[0];return d.each(x=>{let y=new Set;p.each(w=>{let k=!1;w=w.clone(),w.walkClasses(S=>{S.value===b.value&&(k||(S.replaceWith(...x.nodes.map(_=>_.clone())),y.add(w),k=!0))})});for(let w of y){let k=[[]];for(let S of w.nodes)S.type==="combinator"?(k.push(S),k.push([])):k[k.length-1].push(S);w.nodes=[];for(let S of k)Array.isArray(S)&&S.sort((_,E)=>_.type==="tag"&&E.type==="class"?-1:_.type==="class"&&E.type==="tag"?1:_.type==="class"&&E.type==="pseudo"&&E.value.startsWith("::")?-1:_.type==="pseudo"&&_.value.startsWith("::")&&E.type==="class"?1:0),w.nodes=w.nodes.concat(S)}x.replaceWith(...y)}),d.toString()}let o=new Map;for(let u of n){let[c]=o.get(u.parent)||[[],u.source];o.set(u.parent,[c,u.source]);let[f,d]=Th(u.params);if(u.parent.type==="atrule"){if(u.parent.name==="screen"){let p=u.parent.params;throw u.error(`@apply is not supported within nested at-rules like @screen. We suggest you write this as @apply ${f.map(m=>`${p}:${m}`).join(" ")} instead.`)}throw u.error(`@apply is not supported within nested at-rules like @${u.parent.name}. You can fix this by un-nesting @${u.parent.name}.`)}for(let p of f){if([Oh(e,"group"),Oh(e,"peer")].includes(p))throw u.error(`@apply should not be used with the '${p}' utility`);if(!a.has(p))throw u.error(`The \`${p}\` class does not exist. If \`${p}\` is a custom class, make sure it is defined within a \`@layer\` directive.`);let m=a.get(p);for(let[,b]of m)b.type!=="atrule"&&b.walkRules(()=>{throw u.error([`The \`${p}\` class cannot be used with \`@apply\` because \`@apply\` does not currently support nested CSS.`,"Rewrite the selector without nesting or configure the `tailwindcss/nesting` plugin:","https://tailwindcss.com/docs/using-with-preprocessors#nesting"].join(` +`))});c.push([p,d,m])}}for(let[u,[c,f]]of o){let d=[];for(let[m,b,x]of c){let y=[m,..._h([m],e.tailwindConfig.separator)];for(let[w,k]of x){let S=Pn(u),_=Pn(k);if(_=_.groups.filter(R=>R.some(J=>y.includes(J))).flat(),_=_.concat(_h(_,e.tailwindConfig.separator)),S.some(R=>_.includes(R)))throw k.error(`You cannot \`@apply\` the \`${m}\` utility here because it creates a circular dependency.`);let I=z.root({nodes:[k.clone()]});I.walk(R=>{R.source=f}),(k.type!=="atrule"||k.type==="atrule"&&k.name!=="keyframes")&&I.walkRules(R=>{if(!Pn(R).some(te=>te===m)){R.remove();return}let J=typeof e.tailwindConfig.important=="string"?e.tailwindConfig.important:null,he=u.raws.tailwind!==void 0&&J&&u.selector.indexOf(J)===0?u.selector.slice(J.length):u.selector;he===""&&(he=u.selector),R.selector=s(he,R.selector,m),J&&he!==u.selector&&(R.selector=bn(R.selector,J)),R.walkDecls(te=>{te.important=w.important||b});let Ie=(0,Tn.default)().astSync(R.selector);Ie.each(te=>$t(te)),R.selector=Ie.toString()}),!!I.nodes[0]&&d.push([w.sort,I.nodes[0]])}}let p=e.offsets.sort(d).map(m=>m[1]);u.after(p)}for(let u of n)u.parent.nodes.length>1?u.remove():u.parent.remove();Ph(i,e,t)}function _o(i){return e=>{let t=n2(()=>r2(e,i));Ph(e,i,t)}}var Tn,ZC,Dh=C(()=>{l();nt();Tn=X(Be());Sn();Nt();eo();yn();ZC=(0,Tn.default)()});var Ih=v((uD,Dn)=>{l();(function(){"use strict";function i(r,n,a){if(!r)return null;i.caseSensitive||(r=r.toLowerCase());var s=i.threshold===null?null:i.threshold*r.length,o=i.thresholdAbsolute,u;s!==null&&o!==null?u=Math.min(s,o):s!==null?u=s:o!==null?u=o:u=null;var c,f,d,p,m,b=n.length;for(m=0;ma)return a+1;var u=[],c,f,d,p,m;for(c=0;c<=o;c++)u[c]=[c];for(f=0;f<=s;f++)u[0][f]=f;for(c=1;c<=o;c++){for(d=e,p=1,c>a&&(p=c-a),m=o+1,m>a+c&&(m=a+c),f=1;f<=s;f++)fm?u[c][f]=a+1:n.charAt(c-1)===r.charAt(f-1)?u[c][f]=u[c-1][f-1]:u[c][f]=Math.min(u[c-1][f-1]+1,Math.min(u[c][f-1]+1,u[c-1][f]+1)),u[c][f]a)return a+1}return u[o][s]}})()});var Rh=v((fD,qh)=>{l();var Oo="(".charCodeAt(0),Eo=")".charCodeAt(0),In="'".charCodeAt(0),To='"'.charCodeAt(0),Po="\\".charCodeAt(0),Vt="/".charCodeAt(0),Do=",".charCodeAt(0),Io=":".charCodeAt(0),qn="*".charCodeAt(0),a2="u".charCodeAt(0),o2="U".charCodeAt(0),l2="+".charCodeAt(0),u2=/^[a-f0-9?-]+$/i;qh.exports=function(i){for(var e=[],t=i,r,n,a,s,o,u,c,f,d=0,p=t.charCodeAt(d),m=t.length,b=[{nodes:e}],x=0,y,w="",k="",S="";d{l();Mh.exports=function i(e,t,r){var n,a,s,o;for(n=0,a=e.length;n{l();function Fh(i,e){var t=i.type,r=i.value,n,a;return e&&(a=e(i))!==void 0?a:t==="word"||t==="space"?r:t==="string"?(n=i.quote||"",n+r+(i.unclosed?"":n)):t==="comment"?"/*"+r+(i.unclosed?"":"*/"):t==="div"?(i.before||"")+r+(i.after||""):Array.isArray(i.nodes)?(n=Nh(i.nodes,e),t!=="function"?n:r+"("+(i.before||"")+n+(i.after||"")+(i.unclosed?"":")")):r}function Nh(i,e){var t,r;if(Array.isArray(i)){for(t="",r=i.length-1;~r;r-=1)t=Fh(i[r],e)+t;return t}return Fh(i,e)}Lh.exports=Nh});var zh=v((dD,jh)=>{l();var Rn="-".charCodeAt(0),Mn="+".charCodeAt(0),qo=".".charCodeAt(0),f2="e".charCodeAt(0),c2="E".charCodeAt(0);function p2(i){var e=i.charCodeAt(0),t;if(e===Mn||e===Rn){if(t=i.charCodeAt(1),t>=48&&t<=57)return!0;var r=i.charCodeAt(2);return t===qo&&r>=48&&r<=57}return e===qo?(t=i.charCodeAt(1),t>=48&&t<=57):e>=48&&e<=57}jh.exports=function(i){var e=0,t=i.length,r,n,a;if(t===0||!p2(i))return!1;for(r=i.charCodeAt(e),(r===Mn||r===Rn)&&e++;e57));)e+=1;if(r=i.charCodeAt(e),n=i.charCodeAt(e+1),r===qo&&n>=48&&n<=57)for(e+=2;e57));)e+=1;if(r=i.charCodeAt(e),n=i.charCodeAt(e+1),a=i.charCodeAt(e+2),(r===f2||r===c2)&&(n>=48&&n<=57||(n===Mn||n===Rn)&&a>=48&&a<=57))for(e+=n===Mn||n===Rn?3:2;e57));)e+=1;return{number:i.slice(0,e),unit:i.slice(e)}}});var Gh=v((hD,Wh)=>{l();var d2=Rh(),Vh=Bh(),Uh=$h();function ct(i){return this instanceof ct?(this.nodes=d2(i),this):new ct(i)}ct.prototype.toString=function(){return Array.isArray(this.nodes)?Uh(this.nodes):""};ct.prototype.walk=function(i,e){return Vh(this.nodes,i,e),this};ct.unit=zh();ct.walk=Vh;ct.stringify=Uh;Wh.exports=ct});function Mo(i){return typeof i=="object"&&i!==null}function h2(i,e){let t=Ke(e);do if(t.pop(),(0,ri.default)(i,t)!==void 0)break;while(t.length);return t.length?t:void 0}function Ut(i){return typeof i=="string"?i:i.reduce((e,t,r)=>t.includes(".")?`${e}[${t}]`:r===0?t:`${e}.${t}`,"")}function Yh(i){return i.map(e=>`'${e}'`).join(", ")}function Qh(i){return Yh(Object.keys(i))}function Bo(i,e,t,r={}){let n=Array.isArray(e)?Ut(e):e.replace(/^['"]+|['"]+$/g,""),a=Array.isArray(e)?e:Ke(n),s=(0,ri.default)(i.theme,a,t);if(s===void 0){let u=`'${n}' does not exist in your theme config.`,c=a.slice(0,-1),f=(0,ri.default)(i.theme,c);if(Mo(f)){let d=Object.keys(f).filter(m=>Bo(i,[...c,m]).isValid),p=(0,Hh.default)(a[a.length-1],d);p?u+=` Did you mean '${Ut([...c,p])}'?`:d.length>0&&(u+=` '${Ut(c)}' has the following valid keys: ${Yh(d)}`)}else{let d=h2(i.theme,n);if(d){let p=(0,ri.default)(i.theme,d);Mo(p)?u+=` '${Ut(d)}' has the following keys: ${Qh(p)}`:u+=` '${Ut(d)}' is not an object.`}else u+=` Your theme has the following top-level keys: ${Qh(i.theme)}`}return{isValid:!1,error:u}}if(!(typeof s=="string"||typeof s=="number"||typeof s=="function"||s instanceof String||s instanceof Number||Array.isArray(s))){let u=`'${n}' was found but does not resolve to a string.`;if(Mo(s)){let c=Object.keys(s).filter(f=>Bo(i,[...a,f]).isValid);c.length&&(u+=` Did you mean something like '${Ut([...a,c[0]])}'?`)}return{isValid:!1,error:u}}let[o]=a;return{isValid:!0,value:Ge(o)(s,r)}}function m2(i,e,t){e=e.map(n=>Jh(i,n,t));let r=[""];for(let n of e)n.type==="div"&&n.value===","?r.push(""):r[r.length-1]+=Ro.default.stringify(n);return r}function Jh(i,e,t){if(e.type==="function"&&t[e.value]!==void 0){let r=m2(i,e.nodes,t);e.type="word",e.value=t[e.value](i,...r)}return e}function g2(i,e,t){return Object.keys(t).some(n=>e.includes(`${n}(`))?(0,Ro.default)(e).walk(n=>{Jh(i,n,t)}).toString():e}function*w2(i){i=i.replace(/^['"]+|['"]+$/g,"");let e=i.match(/^([^\s]+)(?![^\[]*\])(?:\s*\/\s*([^\/\s]+))$/),t;yield[i,void 0],e&&(i=e[1],t=e[2],yield[i,t])}function b2(i,e,t){let r=Array.from(w2(e)).map(([n,a])=>Object.assign(Bo(i,n,t,{opacityValue:a}),{resolvedPath:n,alpha:a}));return r.find(n=>n.isValid)??r[0]}function Xh(i){let e=i.tailwindConfig,t={theme:(r,n,...a)=>{let{isValid:s,value:o,error:u,alpha:c}=b2(e,n,a.length?a:void 0);if(!s){let p=r.parent,m=p?.raws.tailwind?.candidate;if(p&&m!==void 0){i.markInvalidUtilityNode(p),p.remove(),F.warn("invalid-theme-key-in-class",[`The utility \`${m}\` contains an invalid theme value and was not generated.`]);return}throw r.error(u)}let f=At(o),d=f!==void 0&&typeof f=="function";return(c!==void 0||d)&&(c===void 0&&(c=1),o=qe(f,c,f)),o},screen:(r,n)=>{n=n.replace(/^['"]+/g,"").replace(/['"]+$/g,"");let s=at(e.theme.screens).find(({name:o})=>o===n);if(!s)throw r.error(`The '${n}' screen does not exist in your theme.`);return st(s)}};return r=>{r.walk(n=>{let a=y2[n.type];a!==void 0&&(n[a]=g2(n,n[a],t))})}}var ri,Hh,Ro,y2,Kh=C(()=>{l();ri=X(Ls()),Hh=X(Ih());Yr();Ro=X(Gh());hn();cn();pi();lr();pr();Ee();y2={atrule:"params",decl:"value"}});function Zh({tailwindConfig:{theme:i}}){return function(e){e.walkAtRules("screen",t=>{let r=t.params,a=at(i.screens).find(({name:s})=>s===r);if(!a)throw t.error(`No \`${r}\` screen found.`);t.name="media",t.params=st(a)})}}var em=C(()=>{l();hn();cn()});function v2(i){let e=i.filter(o=>o.type!=="pseudo"||o.nodes.length>0?!0:o.value.startsWith("::")||[":before",":after",":first-line",":first-letter"].includes(o.value)).reverse(),t=new Set(["tag","class","id","attribute"]),r=e.findIndex(o=>t.has(o.type));if(r===-1)return e.reverse().join("").trim();let n=e[r],a=tm[n.type]?tm[n.type](n):n;e=e.slice(0,r);let s=e.findIndex(o=>o.type==="combinator"&&o.value===">");return s!==-1&&(e.splice(0,s),e.unshift(Bn.default.universal())),[a,...e.reverse()].join("").trim()}function k2(i){return Fo.has(i)||Fo.set(i,x2.transformSync(i)),Fo.get(i)}function No({tailwindConfig:i}){return e=>{let t=new Map,r=new Set;if(e.walkAtRules("defaults",n=>{if(n.nodes&&n.nodes.length>0){r.add(n);return}let a=n.params;t.has(a)||t.set(a,new Set),t.get(a).add(n.parent),n.remove()}),Z(i,"optimizeUniversalDefaults"))for(let n of r){let a=new Map,s=t.get(n.params)??[];for(let o of s)for(let u of k2(o.selector)){let c=u.includes(":-")||u.includes("::-")||u.includes(":has")?u:"__DEFAULT__",f=a.get(c)??new Set;a.set(c,f),f.add(u)}if(Z(i,"optimizeUniversalDefaults")){if(a.size===0){n.remove();continue}for(let[,o]of a){let u=z.rule({source:n.source});u.selectors=[...o],u.append(n.nodes.map(c=>c.clone())),n.before(u)}}n.remove()}else if(r.size){let n=z.rule({selectors:["*","::before","::after"]});for(let s of r)n.append(s.nodes),n.parent||s.before(n),n.source||(n.source=s.source),s.remove();let a=n.clone({selectors:["::backdrop"]});n.after(a)}}}var Bn,tm,x2,Fo,rm=C(()=>{l();nt();Bn=X(Be());ze();tm={id(i){return Bn.default.attribute({attribute:"id",operator:"=",value:i.value,quoteMark:'"'})}};x2=(0,Bn.default)(i=>i.map(e=>{let t=e.split(r=>r.type==="combinator"&&r.value===" ").pop();return v2(t)})),Fo=new Map});function Lo(){function i(e){let t=null;e.each(r=>{if(!S2.has(r.type)){t=null;return}if(t===null){t=r;return}let n=im[r.type];r.type==="atrule"&&r.name==="font-face"?t=r:n.every(a=>(r[a]??"").replace(/\s+/g," ")===(t[a]??"").replace(/\s+/g," "))?(r.nodes&&t.append(r.nodes),r.remove()):t=r}),e.each(r=>{r.type==="atrule"&&i(r)})}return e=>{i(e)}}var im,S2,nm=C(()=>{l();im={atrule:["name","params"],rule:["selector"]},S2=new Set(Object.keys(im))});function $o(){return i=>{i.walkRules(e=>{let t=new Map,r=new Set([]),n=new Map;e.walkDecls(a=>{if(a.parent===e){if(t.has(a.prop)){if(t.get(a.prop).value===a.value){r.add(t.get(a.prop)),t.set(a.prop,a);return}n.has(a.prop)||n.set(a.prop,new Set),n.get(a.prop).add(t.get(a.prop)),n.get(a.prop).add(a)}t.set(a.prop,a)}});for(let a of r)a.remove();for(let a of n.values()){let s=new Map;for(let o of a){let u=A2(o.value);u!==null&&(s.has(u)||s.set(u,new Set),s.get(u).add(o))}for(let o of s.values()){let u=Array.from(o).slice(0,-1);for(let c of u)c.remove()}}})}}function A2(i){let e=/^-?\d*.?\d+([\w%]+)?$/g.exec(i);return e?e[1]??C2:null}var C2,sm=C(()=>{l();C2=Symbol("unitless-number")});function _2(i){if(!i.walkAtRules)return;let e=new Set;if(i.walkAtRules("apply",t=>{e.add(t.parent)}),e.size!==0)for(let t of e){let r=[],n=[];for(let a of t.nodes)a.type==="atrule"&&a.name==="apply"?(n.length>0&&(r.push(n),n=[]),r.push([a])):n.push(a);if(n.length>0&&r.push(n),r.length!==1){for(let a of[...r].reverse()){let s=t.clone({nodes:[]});s.append(a),t.after(s)}t.remove()}}}function Fn(){return i=>{_2(i)}}var am=C(()=>{l()});function Nn(i){return async function(e,t){let{tailwindDirectives:r,applyDirectives:n}=xo(e);Fn()(e,t);let a=i({tailwindDirectives:r,applyDirectives:n,registerDependency(s){t.messages.push({plugin:"tailwindcss",parent:t.opts.from,...s})},createContext(s,o){return co(s,o,e)}})(e,t);if(a.tailwindConfig.separator==="-")throw new Error("The '-' character cannot be used as a custom separator in JIT mode due to parsing ambiguity. Please use another character like '_' instead.");Su(a.tailwindConfig),await Co(a)(e,t),Fn()(e,t),_o(a)(e,t),Xh(a)(e,t),Zh(a)(e,t),No(a)(e,t),Lo(a)(e,t),$o(a)(e,t)}}var om=C(()=>{l();hh();Ah();Dh();Kh();em();rm();nm();sm();am();Xr();ze()});function lm(i,e){let t=null,r=null;return i.walkAtRules("config",n=>{if(r=n.source?.input.file??e.opts.from??null,r===null)throw n.error("The `@config` directive cannot be used without setting `from` in your PostCSS config.");if(t)throw n.error("Only one `@config` directive is allowed per file.");let a=n.params.match(/(['"])(.*?)\1/);if(!a)throw n.error("A path is required when using the `@config` directive.");let s=a[2];if(ee.isAbsolute(s))throw n.error("The `@config` directive cannot be used with an absolute path.");if(t=ee.resolve(ee.dirname(r),s),!re.existsSync(t))throw n.error(`The config file at "${s}" does not exist. Make sure the path is correct and the file exists.`);n.remove()}),t||null}var um=C(()=>{l();je();wt()});var fm=v((XD,jo)=>{l();dh();om();lt();um();jo.exports=function(e){return{postcssPlugin:"tailwindcss",plugins:[De.DEBUG&&function(t){return console.log(` +`),console.time("JIT TOTAL"),t},async function(t,r){e=lm(t,r)??e;let n=vo(e);if(t.type==="document"){let a=t.nodes.filter(s=>s.type==="root");for(let s of a)s.type==="root"&&await Nn(n)(s,r);return}await Nn(n)(t,r)},De.DEBUG&&function(t){return console.timeEnd("JIT TOTAL"),console.log(` +`),t}].filter(Boolean)}};jo.exports.postcss=!0});var pm=v((KD,cm)=>{l();cm.exports=fm()});var zo=v((ZD,dm)=>{l();dm.exports=()=>["and_chr 114","and_uc 15.5","chrome 114","chrome 113","chrome 109","edge 114","firefox 114","ios_saf 16.5","ios_saf 16.4","ios_saf 16.3","ios_saf 16.1","opera 99","safari 16.5","samsung 21"]});var Ln={};_e(Ln,{agents:()=>O2,feature:()=>E2});function E2(){return{status:"cr",title:"CSS Feature Queries",stats:{ie:{"6":"n","7":"n","8":"n","9":"n","10":"n","11":"n","5.5":"n"},edge:{"12":"y","13":"y","14":"y","15":"y","16":"y","17":"y","18":"y","79":"y","80":"y","81":"y","83":"y","84":"y","85":"y","86":"y","87":"y","88":"y","89":"y","90":"y","91":"y","92":"y","93":"y","94":"y","95":"y","96":"y","97":"y","98":"y","99":"y","100":"y","101":"y","102":"y","103":"y","104":"y","105":"y","106":"y","107":"y","108":"y","109":"y","110":"y","111":"y","112":"y","113":"y","114":"y"},firefox:{"2":"n","3":"n","4":"n","5":"n","6":"n","7":"n","8":"n","9":"n","10":"n","11":"n","12":"n","13":"n","14":"n","15":"n","16":"n","17":"n","18":"n","19":"n","20":"n","21":"n","22":"y","23":"y","24":"y","25":"y","26":"y","27":"y","28":"y","29":"y","30":"y","31":"y","32":"y","33":"y","34":"y","35":"y","36":"y","37":"y","38":"y","39":"y","40":"y","41":"y","42":"y","43":"y","44":"y","45":"y","46":"y","47":"y","48":"y","49":"y","50":"y","51":"y","52":"y","53":"y","54":"y","55":"y","56":"y","57":"y","58":"y","59":"y","60":"y","61":"y","62":"y","63":"y","64":"y","65":"y","66":"y","67":"y","68":"y","69":"y","70":"y","71":"y","72":"y","73":"y","74":"y","75":"y","76":"y","77":"y","78":"y","79":"y","80":"y","81":"y","82":"y","83":"y","84":"y","85":"y","86":"y","87":"y","88":"y","89":"y","90":"y","91":"y","92":"y","93":"y","94":"y","95":"y","96":"y","97":"y","98":"y","99":"y","100":"y","101":"y","102":"y","103":"y","104":"y","105":"y","106":"y","107":"y","108":"y","109":"y","110":"y","111":"y","112":"y","113":"y","114":"y","115":"y","116":"y","117":"y","3.5":"n","3.6":"n"},chrome:{"4":"n","5":"n","6":"n","7":"n","8":"n","9":"n","10":"n","11":"n","12":"n","13":"n","14":"n","15":"n","16":"n","17":"n","18":"n","19":"n","20":"n","21":"n","22":"n","23":"n","24":"n","25":"n","26":"n","27":"n","28":"y","29":"y","30":"y","31":"y","32":"y","33":"y","34":"y","35":"y","36":"y","37":"y","38":"y","39":"y","40":"y","41":"y","42":"y","43":"y","44":"y","45":"y","46":"y","47":"y","48":"y","49":"y","50":"y","51":"y","52":"y","53":"y","54":"y","55":"y","56":"y","57":"y","58":"y","59":"y","60":"y","61":"y","62":"y","63":"y","64":"y","65":"y","66":"y","67":"y","68":"y","69":"y","70":"y","71":"y","72":"y","73":"y","74":"y","75":"y","76":"y","77":"y","78":"y","79":"y","80":"y","81":"y","83":"y","84":"y","85":"y","86":"y","87":"y","88":"y","89":"y","90":"y","91":"y","92":"y","93":"y","94":"y","95":"y","96":"y","97":"y","98":"y","99":"y","100":"y","101":"y","102":"y","103":"y","104":"y","105":"y","106":"y","107":"y","108":"y","109":"y","110":"y","111":"y","112":"y","113":"y","114":"y","115":"y","116":"y","117":"y"},safari:{"4":"n","5":"n","6":"n","7":"n","8":"n","9":"y","10":"y","11":"y","12":"y","13":"y","14":"y","15":"y","17":"y","9.1":"y","10.1":"y","11.1":"y","12.1":"y","13.1":"y","14.1":"y","15.1":"y","15.2-15.3":"y","15.4":"y","15.5":"y","15.6":"y","16.0":"y","16.1":"y","16.2":"y","16.3":"y","16.4":"y","16.5":"y","16.6":"y",TP:"y","3.1":"n","3.2":"n","5.1":"n","6.1":"n","7.1":"n"},opera:{"9":"n","11":"n","12":"n","15":"y","16":"y","17":"y","18":"y","19":"y","20":"y","21":"y","22":"y","23":"y","24":"y","25":"y","26":"y","27":"y","28":"y","29":"y","30":"y","31":"y","32":"y","33":"y","34":"y","35":"y","36":"y","37":"y","38":"y","39":"y","40":"y","41":"y","42":"y","43":"y","44":"y","45":"y","46":"y","47":"y","48":"y","49":"y","50":"y","51":"y","52":"y","53":"y","54":"y","55":"y","56":"y","57":"y","58":"y","60":"y","62":"y","63":"y","64":"y","65":"y","66":"y","67":"y","68":"y","69":"y","70":"y","71":"y","72":"y","73":"y","74":"y","75":"y","76":"y","77":"y","78":"y","79":"y","80":"y","81":"y","82":"y","83":"y","84":"y","85":"y","86":"y","87":"y","88":"y","89":"y","90":"y","91":"y","92":"y","93":"y","94":"y","95":"y","96":"y","97":"y","98":"y","99":"y","100":"y","12.1":"y","9.5-9.6":"n","10.0-10.1":"n","10.5":"n","10.6":"n","11.1":"n","11.5":"n","11.6":"n"},ios_saf:{"8":"n","17":"y","9.0-9.2":"y","9.3":"y","10.0-10.2":"y","10.3":"y","11.0-11.2":"y","11.3-11.4":"y","12.0-12.1":"y","12.2-12.5":"y","13.0-13.1":"y","13.2":"y","13.3":"y","13.4-13.7":"y","14.0-14.4":"y","14.5-14.8":"y","15.0-15.1":"y","15.2-15.3":"y","15.4":"y","15.5":"y","15.6":"y","16.0":"y","16.1":"y","16.2":"y","16.3":"y","16.4":"y","16.5":"y","16.6":"y","3.2":"n","4.0-4.1":"n","4.2-4.3":"n","5.0-5.1":"n","6.0-6.1":"n","7.0-7.1":"n","8.1-8.4":"n"},op_mini:{all:"y"},android:{"3":"n","4":"n","114":"y","4.4":"y","4.4.3-4.4.4":"y","2.1":"n","2.2":"n","2.3":"n","4.1":"n","4.2-4.3":"n"},bb:{"7":"n","10":"n"},op_mob:{"10":"n","11":"n","12":"n","73":"y","11.1":"n","11.5":"n","12.1":"n"},and_chr:{"114":"y"},and_ff:{"115":"y"},ie_mob:{"10":"n","11":"n"},and_uc:{"15.5":"y"},samsung:{"4":"y","20":"y","21":"y","5.0-5.4":"y","6.2-6.4":"y","7.2-7.4":"y","8.2":"y","9.2":"y","10.1":"y","11.1-11.2":"y","12.0":"y","13.0":"y","14.0":"y","15.0":"y","16.0":"y","17.0":"y","18.0":"y","19.0":"y"},and_qq:{"13.1":"y"},baidu:{"13.18":"y"},kaios:{"2.5":"y","3.0-3.1":"y"}}}}var O2,$n=C(()=>{l();O2={ie:{prefix:"ms"},edge:{prefix:"webkit",prefix_exceptions:{"12":"ms","13":"ms","14":"ms","15":"ms","16":"ms","17":"ms","18":"ms"}},firefox:{prefix:"moz"},chrome:{prefix:"webkit"},safari:{prefix:"webkit"},opera:{prefix:"webkit",prefix_exceptions:{"9":"o","11":"o","12":"o","9.5-9.6":"o","10.0-10.1":"o","10.5":"o","10.6":"o","11.1":"o","11.5":"o","11.6":"o","12.1":"o"}},ios_saf:{prefix:"webkit"},op_mini:{prefix:"o"},android:{prefix:"webkit"},bb:{prefix:"webkit"},op_mob:{prefix:"o",prefix_exceptions:{"73":"webkit"}},and_chr:{prefix:"webkit"},and_ff:{prefix:"moz"},ie_mob:{prefix:"ms"},and_uc:{prefix:"webkit",prefix_exceptions:{"15.5":"webkit"}},samsung:{prefix:"webkit"},and_qq:{prefix:"webkit"},baidu:{prefix:"webkit"},kaios:{prefix:"moz"}}});var hm=v(()=>{l()});var ue=v((r4,pt)=>{l();var{list:Vo}=ye();pt.exports.error=function(i){let e=new Error(i);throw e.autoprefixer=!0,e};pt.exports.uniq=function(i){return[...new Set(i)]};pt.exports.removeNote=function(i){return i.includes(" ")?i.split(" ")[0]:i};pt.exports.escapeRegexp=function(i){return i.replace(/[$()*+-.?[\\\]^{|}]/g,"\\$&")};pt.exports.regexp=function(i,e=!0){return e&&(i=this.escapeRegexp(i)),new RegExp(`(^|[\\s,(])(${i}($|[\\s(,]))`,"gi")};pt.exports.editList=function(i,e){let t=Vo.comma(i),r=e(t,[]);if(t===r)return i;let n=i.match(/,\s*/);return n=n?n[0]:", ",r.join(n)};pt.exports.splitSelector=function(i){return Vo.comma(i).map(e=>Vo.space(e).map(t=>t.split(/(?=\.|#)/g)))}});var dt=v((i4,ym)=>{l();var T2=zo(),mm=($n(),Ln).agents,P2=ue(),gm=class{static prefixes(){if(this.prefixesCache)return this.prefixesCache;this.prefixesCache=[];for(let e in mm)this.prefixesCache.push(`-${mm[e].prefix}-`);return this.prefixesCache=P2.uniq(this.prefixesCache).sort((e,t)=>t.length-e.length),this.prefixesCache}static withPrefix(e){return this.prefixesRegexp||(this.prefixesRegexp=new RegExp(this.prefixes().join("|"))),this.prefixesRegexp.test(e)}constructor(e,t,r,n){this.data=e,this.options=r||{},this.browserslistOpts=n||{},this.selected=this.parse(t)}parse(e){let t={};for(let r in this.browserslistOpts)t[r]=this.browserslistOpts[r];return t.path=this.options.from,T2(e,t)}prefix(e){let[t,r]=e.split(" "),n=this.data[t],a=n.prefix_exceptions&&n.prefix_exceptions[r];return a||(a=n.prefix),`-${a}-`}isSelected(e){return this.selected.includes(e)}};ym.exports=gm});var ii=v((n4,wm)=>{l();wm.exports={prefix(i){let e=i.match(/^(-\w+-)/);return e?e[0]:""},unprefixed(i){return i.replace(/^-\w+-/,"")}}});var Wt=v((s4,vm)=>{l();var D2=dt(),bm=ii(),I2=ue();function Uo(i,e){let t=new i.constructor;for(let r of Object.keys(i||{})){let n=i[r];r==="parent"&&typeof n=="object"?e&&(t[r]=e):r==="source"||r===null?t[r]=n:Array.isArray(n)?t[r]=n.map(a=>Uo(a,t)):r!=="_autoprefixerPrefix"&&r!=="_autoprefixerValues"&&r!=="proxyCache"&&(typeof n=="object"&&n!==null&&(n=Uo(n,t)),t[r]=n)}return t}var jn=class{static hack(e){return this.hacks||(this.hacks={}),e.names.map(t=>(this.hacks[t]=e,this.hacks[t]))}static load(e,t,r){let n=this.hacks&&this.hacks[e];return n?new n(e,t,r):new this(e,t,r)}static clone(e,t){let r=Uo(e);for(let n in t)r[n]=t[n];return r}constructor(e,t,r){this.prefixes=t,this.name=e,this.all=r}parentPrefix(e){let t;return typeof e._autoprefixerPrefix!="undefined"?t=e._autoprefixerPrefix:e.type==="decl"&&e.prop[0]==="-"?t=bm.prefix(e.prop):e.type==="root"?t=!1:e.type==="rule"&&e.selector.includes(":-")&&/:(-\w+-)/.test(e.selector)?t=e.selector.match(/:(-\w+-)/)[1]:e.type==="atrule"&&e.name[0]==="-"?t=bm.prefix(e.name):t=this.parentPrefix(e.parent),D2.prefixes().includes(t)||(t=!1),e._autoprefixerPrefix=t,e._autoprefixerPrefix}process(e,t){if(!this.check(e))return;let r=this.parentPrefix(e),n=this.prefixes.filter(s=>!r||r===I2.removeNote(s)),a=[];for(let s of n)this.add(e,s,a.concat([s]),t)&&a.push(s);return a}clone(e,t){return jn.clone(e,t)}};vm.exports=jn});var M=v((a4,Sm)=>{l();var q2=Wt(),R2=dt(),xm=ue(),km=class extends q2{check(){return!0}prefixed(e,t){return t+e}normalize(e){return e}otherPrefixes(e,t){for(let r of R2.prefixes())if(r!==t&&e.includes(r))return!0;return!1}set(e,t){return e.prop=this.prefixed(e.prop,t),e}needCascade(e){return e._autoprefixerCascade||(e._autoprefixerCascade=this.all.options.cascade!==!1&&e.raw("before").includes(` +`)),e._autoprefixerCascade}maxPrefixed(e,t){if(t._autoprefixerMax)return t._autoprefixerMax;let r=0;for(let n of e)n=xm.removeNote(n),n.length>r&&(r=n.length);return t._autoprefixerMax=r,t._autoprefixerMax}calcBefore(e,t,r=""){let a=this.maxPrefixed(e,t)-xm.removeNote(r).length,s=t.raw("before");return a>0&&(s+=Array(a).fill(" ").join("")),s}restoreBefore(e){let t=e.raw("before").split(` +`),r=t[t.length-1];this.all.group(e).up(n=>{let a=n.raw("before").split(` +`),s=a[a.length-1];s.lengths.prop===n.prop&&s.value===n.value)))return this.needCascade(e)&&(n.raws.before=this.calcBefore(r,e,t)),e.parent.insertBefore(e,n)}isAlready(e,t){let r=this.all.group(e).up(n=>n.prop===t);return r||(r=this.all.group(e).down(n=>n.prop===t)),r}add(e,t,r,n){let a=this.prefixed(e.prop,t);if(!(this.isAlready(e,a)||this.otherPrefixes(e.value,t)))return this.insert(e,t,r,n)}process(e,t){if(!this.needCascade(e)){super.process(e,t);return}let r=super.process(e,t);!r||!r.length||(this.restoreBefore(e),e.raws.before=this.calcBefore(r,e))}old(e,t){return[this.prefixed(e,t)]}};Sm.exports=km});var Am=v((o4,Cm)=>{l();Cm.exports=function i(e){return{mul:t=>new i(e*t),div:t=>new i(e/t),simplify:()=>new i(e),toString:()=>e.toString()}}});var Em=v((l4,Om)=>{l();var M2=Am(),B2=Wt(),Wo=ue(),F2=/(min|max)-resolution\s*:\s*\d*\.?\d+(dppx|dpcm|dpi|x)/gi,N2=/(min|max)-resolution(\s*:\s*)(\d*\.?\d+)(dppx|dpcm|dpi|x)/i,_m=class extends B2{prefixName(e,t){return e==="-moz-"?t+"--moz-device-pixel-ratio":e+t+"-device-pixel-ratio"}prefixQuery(e,t,r,n,a){return n=new M2(n),a==="dpi"?n=n.div(96):a==="dpcm"&&(n=n.mul(2.54).div(96)),n=n.simplify(),e==="-o-"&&(n=n.n+"/"+n.d),this.prefixName(e,t)+r+n}clean(e){if(!this.bad){this.bad=[];for(let t of this.prefixes)this.bad.push(this.prefixName(t,"min")),this.bad.push(this.prefixName(t,"max"))}e.params=Wo.editList(e.params,t=>t.filter(r=>this.bad.every(n=>!r.includes(n))))}process(e){let t=this.parentPrefix(e),r=t?[t]:this.prefixes;e.params=Wo.editList(e.params,(n,a)=>{for(let s of n){if(!s.includes("min-resolution")&&!s.includes("max-resolution")){a.push(s);continue}for(let o of r){let u=s.replace(F2,c=>{let f=c.match(N2);return this.prefixQuery(o,f[1],f[2],f[3],f[4])});a.push(u)}a.push(s)}return Wo.uniq(a)})}};Om.exports=_m});var Pm=v((u4,Tm)=>{l();var Go="(".charCodeAt(0),Ho=")".charCodeAt(0),zn="'".charCodeAt(0),Yo='"'.charCodeAt(0),Qo="\\".charCodeAt(0),Gt="/".charCodeAt(0),Jo=",".charCodeAt(0),Xo=":".charCodeAt(0),Vn="*".charCodeAt(0),L2="u".charCodeAt(0),$2="U".charCodeAt(0),j2="+".charCodeAt(0),z2=/^[a-f0-9?-]+$/i;Tm.exports=function(i){for(var e=[],t=i,r,n,a,s,o,u,c,f,d=0,p=t.charCodeAt(d),m=t.length,b=[{nodes:e}],x=0,y,w="",k="",S="";d{l();Dm.exports=function i(e,t,r){var n,a,s,o;for(n=0,a=e.length;n{l();function qm(i,e){var t=i.type,r=i.value,n,a;return e&&(a=e(i))!==void 0?a:t==="word"||t==="space"?r:t==="string"?(n=i.quote||"",n+r+(i.unclosed?"":n)):t==="comment"?"/*"+r+(i.unclosed?"":"*/"):t==="div"?(i.before||"")+r+(i.after||""):Array.isArray(i.nodes)?(n=Rm(i.nodes,e),t!=="function"?n:r+"("+(i.before||"")+n+(i.after||"")+(i.unclosed?"":")")):r}function Rm(i,e){var t,r;if(Array.isArray(i)){for(t="",r=i.length-1;~r;r-=1)t=qm(i[r],e)+t;return t}return qm(i,e)}Mm.exports=Rm});var Nm=v((p4,Fm)=>{l();var Un="-".charCodeAt(0),Wn="+".charCodeAt(0),Ko=".".charCodeAt(0),V2="e".charCodeAt(0),U2="E".charCodeAt(0);function W2(i){var e=i.charCodeAt(0),t;if(e===Wn||e===Un){if(t=i.charCodeAt(1),t>=48&&t<=57)return!0;var r=i.charCodeAt(2);return t===Ko&&r>=48&&r<=57}return e===Ko?(t=i.charCodeAt(1),t>=48&&t<=57):e>=48&&e<=57}Fm.exports=function(i){var e=0,t=i.length,r,n,a;if(t===0||!W2(i))return!1;for(r=i.charCodeAt(e),(r===Wn||r===Un)&&e++;e57));)e+=1;if(r=i.charCodeAt(e),n=i.charCodeAt(e+1),r===Ko&&n>=48&&n<=57)for(e+=2;e57));)e+=1;if(r=i.charCodeAt(e),n=i.charCodeAt(e+1),a=i.charCodeAt(e+2),(r===V2||r===U2)&&(n>=48&&n<=57||(n===Wn||n===Un)&&a>=48&&a<=57))for(e+=n===Wn||n===Un?3:2;e57));)e+=1;return{number:i.slice(0,e),unit:i.slice(e)}}});var Gn=v((d4,jm)=>{l();var G2=Pm(),Lm=Im(),$m=Bm();function ht(i){return this instanceof ht?(this.nodes=G2(i),this):new ht(i)}ht.prototype.toString=function(){return Array.isArray(this.nodes)?$m(this.nodes):""};ht.prototype.walk=function(i,e){return Lm(this.nodes,i,e),this};ht.unit=Nm();ht.walk=Lm;ht.stringify=$m;jm.exports=ht});var Gm=v((h4,Wm)=>{l();var{list:H2}=ye(),zm=Gn(),Y2=dt(),Vm=ii(),Um=class{constructor(e){this.props=["transition","transition-property"],this.prefixes=e}add(e,t){let r,n,a=this.prefixes.add[e.prop],s=this.ruleVendorPrefixes(e),o=s||a&&a.prefixes||[],u=this.parse(e.value),c=u.map(m=>this.findProp(m)),f=[];if(c.some(m=>m[0]==="-"))return;for(let m of u){if(n=this.findProp(m),n[0]==="-")continue;let b=this.prefixes.add[n];if(!(!b||!b.prefixes))for(r of b.prefixes){if(s&&!s.some(y=>r.includes(y)))continue;let x=this.prefixes.prefixed(n,r);x!=="-ms-transform"&&!c.includes(x)&&(this.disabled(n,r)||f.push(this.clone(n,x,m)))}}u=u.concat(f);let d=this.stringify(u),p=this.stringify(this.cleanFromUnprefixed(u,"-webkit-"));if(o.includes("-webkit-")&&this.cloneBefore(e,`-webkit-${e.prop}`,p),this.cloneBefore(e,e.prop,p),o.includes("-o-")){let m=this.stringify(this.cleanFromUnprefixed(u,"-o-"));this.cloneBefore(e,`-o-${e.prop}`,m)}for(r of o)if(r!=="-webkit-"&&r!=="-o-"){let m=this.stringify(this.cleanOtherPrefixes(u,r));this.cloneBefore(e,r+e.prop,m)}d!==e.value&&!this.already(e,e.prop,d)&&(this.checkForWarning(t,e),e.cloneBefore(),e.value=d)}findProp(e){let t=e[0].value;if(/^\d/.test(t)){for(let[r,n]of e.entries())if(r!==0&&n.type==="word")return n.value}return t}already(e,t,r){return e.parent.some(n=>n.prop===t&&n.value===r)}cloneBefore(e,t,r){this.already(e,t,r)||e.cloneBefore({prop:t,value:r})}checkForWarning(e,t){if(t.prop!=="transition-property")return;let r=!1,n=!1;t.parent.each(a=>{if(a.type!=="decl"||a.prop.indexOf("transition-")!==0)return;let s=H2.comma(a.value);if(a.prop==="transition-property"){s.forEach(o=>{let u=this.prefixes.add[o];u&&u.prefixes&&u.prefixes.length>0&&(r=!0)});return}return n=n||s.length>1,!1}),r&&n&&t.warn(e,"Replace transition-property to transition, because Autoprefixer could not support any cases of transition-property and other transition-*")}remove(e){let t=this.parse(e.value);t=t.filter(s=>{let o=this.prefixes.remove[this.findProp(s)];return!o||!o.remove});let r=this.stringify(t);if(e.value===r)return;if(t.length===0){e.remove();return}let n=e.parent.some(s=>s.prop===e.prop&&s.value===r),a=e.parent.some(s=>s!==e&&s.prop===e.prop&&s.value.length>r.length);if(n||a){e.remove();return}e.value=r}parse(e){let t=zm(e),r=[],n=[];for(let a of t.nodes)n.push(a),a.type==="div"&&a.value===","&&(r.push(n),n=[]);return r.push(n),r.filter(a=>a.length>0)}stringify(e){if(e.length===0)return"";let t=[];for(let r of e)r[r.length-1].type!=="div"&&r.push(this.div(e)),t=t.concat(r);return t[0].type==="div"&&(t=t.slice(1)),t[t.length-1].type==="div"&&(t=t.slice(0,-2+1||void 0)),zm.stringify({nodes:t})}clone(e,t,r){let n=[],a=!1;for(let s of r)!a&&s.type==="word"&&s.value===e?(n.push({type:"word",value:t}),a=!0):n.push(s);return n}div(e){for(let t of e)for(let r of t)if(r.type==="div"&&r.value===",")return r;return{type:"div",value:",",after:" "}}cleanOtherPrefixes(e,t){return e.filter(r=>{let n=Vm.prefix(this.findProp(r));return n===""||n===t})}cleanFromUnprefixed(e,t){let r=e.map(a=>this.findProp(a)).filter(a=>a.slice(0,t.length)===t).map(a=>this.prefixes.unprefixed(a)),n=[];for(let a of e){let s=this.findProp(a),o=Vm.prefix(s);!r.includes(s)&&(o===t||o==="")&&n.push(a)}return n}disabled(e,t){let r=["order","justify-content","align-self","align-content"];if(e.includes("flex")||r.includes(e)){if(this.prefixes.options.flexbox===!1)return!0;if(this.prefixes.options.flexbox==="no-2009")return t.includes("2009")}}ruleVendorPrefixes(e){let{parent:t}=e;if(t.type!=="rule")return!1;if(!t.selector.includes(":-"))return!1;let r=Y2.prefixes().filter(n=>t.selector.includes(":"+n));return r.length>0?r:!1}};Wm.exports=Um});var Ht=v((m4,Ym)=>{l();var Q2=ue(),Hm=class{constructor(e,t,r,n){this.unprefixed=e,this.prefixed=t,this.string=r||t,this.regexp=n||Q2.regexp(t)}check(e){return e.includes(this.string)?!!e.match(this.regexp):!1}};Ym.exports=Hm});var Se=v((g4,Jm)=>{l();var J2=Wt(),X2=Ht(),K2=ii(),Z2=ue(),Qm=class extends J2{static save(e,t){let r=t.prop,n=[];for(let a in t._autoprefixerValues){let s=t._autoprefixerValues[a];if(s===t.value)continue;let o,u=K2.prefix(r);if(u==="-pie-")continue;if(u===a){o=t.value=s,n.push(o);continue}let c=e.prefixed(r,a),f=t.parent;if(!f.every(b=>b.prop!==c)){n.push(o);continue}let d=s.replace(/\s+/," ");if(f.some(b=>b.prop===t.prop&&b.value.replace(/\s+/," ")===d)){n.push(o);continue}let m=this.clone(t,{value:s});o=t.parent.insertBefore(t,m),n.push(o)}return n}check(e){let t=e.value;return t.includes(this.name)?!!t.match(this.regexp()):!1}regexp(){return this.regexpCache||(this.regexpCache=Z2.regexp(this.name))}replace(e,t){return e.replace(this.regexp(),`$1${t}$2`)}value(e){return e.raws.value&&e.raws.value.value===e.value?e.raws.value.raw:e.value}add(e,t){e._autoprefixerValues||(e._autoprefixerValues={});let r=e._autoprefixerValues[t]||this.value(e),n;do if(n=r,r=this.replace(r,t),r===!1)return;while(r!==n);e._autoprefixerValues[t]=r}old(e){return new X2(this.name,e+this.name)}};Jm.exports=Qm});var mt=v((y4,Xm)=>{l();Xm.exports={}});var el=v((w4,eg)=>{l();var Km=Gn(),eA=Se(),tA=mt().insertAreas,rA=/(^|[^-])linear-gradient\(\s*(top|left|right|bottom)/i,iA=/(^|[^-])radial-gradient\(\s*\d+(\w*|%)\s+\d+(\w*|%)\s*,/i,nA=/(!\s*)?autoprefixer:\s*ignore\s+next/i,sA=/(!\s*)?autoprefixer\s*grid:\s*(on|off|(no-)?autoplace)/i,aA=["width","height","min-width","max-width","min-height","max-height","inline-size","min-inline-size","max-inline-size","block-size","min-block-size","max-block-size"];function Zo(i){return i.parent.some(e=>e.prop==="grid-template"||e.prop==="grid-template-areas")}function oA(i){let e=i.parent.some(r=>r.prop==="grid-template-rows"),t=i.parent.some(r=>r.prop==="grid-template-columns");return e&&t}var Zm=class{constructor(e){this.prefixes=e}add(e,t){let r=this.prefixes.add["@resolution"],n=this.prefixes.add["@keyframes"],a=this.prefixes.add["@viewport"],s=this.prefixes.add["@supports"];e.walkAtRules(f=>{if(f.name==="keyframes"){if(!this.disabled(f,t))return n&&n.process(f)}else if(f.name==="viewport"){if(!this.disabled(f,t))return a&&a.process(f)}else if(f.name==="supports"){if(this.prefixes.options.supports!==!1&&!this.disabled(f,t))return s.process(f)}else if(f.name==="media"&&f.params.includes("-resolution")&&!this.disabled(f,t))return r&&r.process(f)}),e.walkRules(f=>{if(!this.disabled(f,t))return this.prefixes.add.selectors.map(d=>d.process(f,t))});function o(f){return f.parent.nodes.some(d=>{if(d.type!=="decl")return!1;let p=d.prop==="display"&&/(inline-)?grid/.test(d.value),m=d.prop.startsWith("grid-template"),b=/^grid-([A-z]+-)?gap/.test(d.prop);return p||m||b})}function u(f){return f.parent.some(d=>d.prop==="display"&&/(inline-)?flex/.test(d.value))}let c=this.gridStatus(e,t)&&this.prefixes.add["grid-area"]&&this.prefixes.add["grid-area"].prefixes;return e.walkDecls(f=>{if(this.disabledDecl(f,t))return;let d=f.parent,p=f.prop,m=f.value;if(p==="grid-row-span"){t.warn("grid-row-span is not part of final Grid Layout. Use grid-row.",{node:f});return}else if(p==="grid-column-span"){t.warn("grid-column-span is not part of final Grid Layout. Use grid-column.",{node:f});return}else if(p==="display"&&m==="box"){t.warn("You should write display: flex by final spec instead of display: box",{node:f});return}else if(p==="text-emphasis-position")(m==="under"||m==="over")&&t.warn("You should use 2 values for text-emphasis-position For example, `under left` instead of just `under`.",{node:f});else if(/^(align|justify|place)-(items|content)$/.test(p)&&u(f))(m==="start"||m==="end")&&t.warn(`${m} value has mixed support, consider using flex-${m} instead`,{node:f});else if(p==="text-decoration-skip"&&m==="ink")t.warn("Replace text-decoration-skip: ink to text-decoration-skip-ink: auto, because spec had been changed",{node:f});else{if(c&&this.gridStatus(f,t))if(f.value==="subgrid"&&t.warn("IE does not support subgrid",{node:f}),/^(align|justify|place)-items$/.test(p)&&o(f)){let x=p.replace("-items","-self");t.warn(`IE does not support ${p} on grid containers. Try using ${x} on child elements instead: ${f.parent.selector} > * { ${x}: ${f.value} }`,{node:f})}else if(/^(align|justify|place)-content$/.test(p)&&o(f))t.warn(`IE does not support ${f.prop} on grid containers`,{node:f});else if(p==="display"&&f.value==="contents"){t.warn("Please do not use display: contents; if you have grid setting enabled",{node:f});return}else if(f.prop==="grid-gap"){let x=this.gridStatus(f,t);x==="autoplace"&&!oA(f)&&!Zo(f)?t.warn("grid-gap only works if grid-template(-areas) is being used or both rows and columns have been declared and cells have not been manually placed inside the explicit grid",{node:f}):(x===!0||x==="no-autoplace")&&!Zo(f)&&t.warn("grid-gap only works if grid-template(-areas) is being used",{node:f})}else if(p==="grid-auto-columns"){t.warn("grid-auto-columns is not supported by IE",{node:f});return}else if(p==="grid-auto-rows"){t.warn("grid-auto-rows is not supported by IE",{node:f});return}else if(p==="grid-auto-flow"){let x=d.some(w=>w.prop==="grid-template-rows"),y=d.some(w=>w.prop==="grid-template-columns");Zo(f)?t.warn("grid-auto-flow is not supported by IE",{node:f}):m.includes("dense")?t.warn("grid-auto-flow: dense is not supported by IE",{node:f}):!x&&!y&&t.warn("grid-auto-flow works only if grid-template-rows and grid-template-columns are present in the same rule",{node:f});return}else if(m.includes("auto-fit")){t.warn("auto-fit value is not supported by IE",{node:f,word:"auto-fit"});return}else if(m.includes("auto-fill")){t.warn("auto-fill value is not supported by IE",{node:f,word:"auto-fill"});return}else p.startsWith("grid-template")&&m.includes("[")&&t.warn("Autoprefixer currently does not support line names. Try using grid-template-areas instead.",{node:f,word:"["});if(m.includes("radial-gradient"))if(iA.test(f.value))t.warn("Gradient has outdated direction syntax. New syntax is like `closest-side at 0 0` instead of `0 0, closest-side`.",{node:f});else{let x=Km(m);for(let y of x.nodes)if(y.type==="function"&&y.value==="radial-gradient")for(let w of y.nodes)w.type==="word"&&(w.value==="cover"?t.warn("Gradient has outdated direction syntax. Replace `cover` to `farthest-corner`.",{node:f}):w.value==="contain"&&t.warn("Gradient has outdated direction syntax. Replace `contain` to `closest-side`.",{node:f}))}m.includes("linear-gradient")&&rA.test(m)&&t.warn("Gradient has outdated direction syntax. New syntax is like `to left` instead of `right`.",{node:f})}aA.includes(f.prop)&&(f.value.includes("-fill-available")||(f.value.includes("fill-available")?t.warn("Replace fill-available to stretch, because spec had been changed",{node:f}):f.value.includes("fill")&&Km(m).nodes.some(y=>y.type==="word"&&y.value==="fill")&&t.warn("Replace fill to stretch, because spec had been changed",{node:f})));let b;if(f.prop==="transition"||f.prop==="transition-property")return this.prefixes.transition.add(f,t);if(f.prop==="align-self"){if(this.displayType(f)!=="grid"&&this.prefixes.options.flexbox!==!1&&(b=this.prefixes.add["align-self"],b&&b.prefixes&&b.process(f)),this.gridStatus(f,t)!==!1&&(b=this.prefixes.add["grid-row-align"],b&&b.prefixes))return b.process(f,t)}else if(f.prop==="justify-self"){if(this.gridStatus(f,t)!==!1&&(b=this.prefixes.add["grid-column-align"],b&&b.prefixes))return b.process(f,t)}else if(f.prop==="place-self"){if(b=this.prefixes.add["place-self"],b&&b.prefixes&&this.gridStatus(f,t)!==!1)return b.process(f,t)}else if(b=this.prefixes.add[f.prop],b&&b.prefixes)return b.process(f,t)}),this.gridStatus(e,t)&&tA(e,this.disabled),e.walkDecls(f=>{if(this.disabledValue(f,t))return;let d=this.prefixes.unprefixed(f.prop),p=this.prefixes.values("add",d);if(Array.isArray(p))for(let m of p)m.process&&m.process(f,t);eA.save(this.prefixes,f)})}remove(e,t){let r=this.prefixes.remove["@resolution"];e.walkAtRules((n,a)=>{this.prefixes.remove[`@${n.name}`]?this.disabled(n,t)||n.parent.removeChild(a):n.name==="media"&&n.params.includes("-resolution")&&r&&r.clean(n)});for(let n of this.prefixes.remove.selectors)e.walkRules((a,s)=>{n.check(a)&&(this.disabled(a,t)||a.parent.removeChild(s))});return e.walkDecls((n,a)=>{if(this.disabled(n,t))return;let s=n.parent,o=this.prefixes.unprefixed(n.prop);if((n.prop==="transition"||n.prop==="transition-property")&&this.prefixes.transition.remove(n),this.prefixes.remove[n.prop]&&this.prefixes.remove[n.prop].remove){let u=this.prefixes.group(n).down(c=>this.prefixes.normalize(c.prop)===o);if(o==="flex-flow"&&(u=!0),n.prop==="-webkit-box-orient"){let c={"flex-direction":!0,"flex-flow":!0};if(!n.parent.some(f=>c[f.prop]))return}if(u&&!this.withHackValue(n)){n.raw("before").includes(` +`)&&this.reduceSpaces(n),s.removeChild(a);return}}for(let u of this.prefixes.values("remove",o)){if(!u.check||!u.check(n.value))continue;if(o=u.unprefixed,this.prefixes.group(n).down(f=>f.value.includes(o))){s.removeChild(a);return}}})}withHackValue(e){return e.prop==="-webkit-background-clip"&&e.value==="text"}disabledValue(e,t){return this.gridStatus(e,t)===!1&&e.type==="decl"&&e.prop==="display"&&e.value.includes("grid")||this.prefixes.options.flexbox===!1&&e.type==="decl"&&e.prop==="display"&&e.value.includes("flex")||e.type==="decl"&&e.prop==="content"?!0:this.disabled(e,t)}disabledDecl(e,t){if(this.gridStatus(e,t)===!1&&e.type==="decl"&&(e.prop.includes("grid")||e.prop==="justify-items"))return!0;if(this.prefixes.options.flexbox===!1&&e.type==="decl"){let r=["order","justify-content","align-items","align-content"];if(e.prop.includes("flex")||r.includes(e.prop))return!0}return this.disabled(e,t)}disabled(e,t){if(!e)return!1;if(e._autoprefixerDisabled!==void 0)return e._autoprefixerDisabled;if(e.parent){let n=e.prev();if(n&&n.type==="comment"&&nA.test(n.text))return e._autoprefixerDisabled=!0,e._autoprefixerSelfDisabled=!0,!0}let r=null;if(e.nodes){let n;e.each(a=>{a.type==="comment"&&/(!\s*)?autoprefixer:\s*(off|on)/i.test(a.text)&&(typeof n!="undefined"?t.warn("Second Autoprefixer control comment was ignored. Autoprefixer applies control comment to whole block, not to next rules.",{node:a}):n=/on/i.test(a.text))}),n!==void 0&&(r=!n)}if(!e.nodes||r===null)if(e.parent){let n=this.disabled(e.parent,t);e.parent._autoprefixerSelfDisabled===!0?r=!1:r=n}else r=!1;return e._autoprefixerDisabled=r,r}reduceSpaces(e){let t=!1;if(this.prefixes.group(e).up(()=>(t=!0,!0)),t)return;let r=e.raw("before").split(` +`),n=r[r.length-1].length,a=!1;this.prefixes.group(e).down(s=>{r=s.raw("before").split(` +`);let o=r.length-1;r[o].length>n&&(a===!1&&(a=r[o].length-n),r[o]=r[o].slice(0,-a),s.raws.before=r.join(` +`))})}displayType(e){for(let t of e.parent.nodes)if(t.prop==="display"){if(t.value.includes("flex"))return"flex";if(t.value.includes("grid"))return"grid"}return!1}gridStatus(e,t){if(!e)return!1;if(e._autoprefixerGridStatus!==void 0)return e._autoprefixerGridStatus;let r=null;if(e.nodes){let n;e.each(a=>{if(a.type==="comment"&&sA.test(a.text)){let s=/:\s*autoplace/i.test(a.text),o=/no-autoplace/i.test(a.text);typeof n!="undefined"?t.warn("Second Autoprefixer grid control comment was ignored. Autoprefixer applies control comments to the whole block, not to the next rules.",{node:a}):s?n="autoplace":o?n=!0:n=/on/i.test(a.text)}}),n!==void 0&&(r=n)}if(e.type==="atrule"&&e.name==="supports"){let n=e.params;n.includes("grid")&&n.includes("auto")&&(r=!1)}if(!e.nodes||r===null)if(e.parent){let n=this.gridStatus(e.parent,t);e.parent._autoprefixerSelfDisabled===!0?r=!1:r=n}else typeof this.prefixes.options.grid!="undefined"?r=this.prefixes.options.grid:typeof h.env.AUTOPREFIXER_GRID!="undefined"?h.env.AUTOPREFIXER_GRID==="autoplace"?r="autoplace":r=!0:r=!1;return e._autoprefixerGridStatus=r,r}};eg.exports=Zm});var rg=v((b4,tg)=>{l();tg.exports={A:{A:{"2":"K E F G A B JC"},B:{"1":"C L M H N D O P Q R S T U V W X Y Z a b c d e f g h i j n o p q r s t u v w x y z I"},C:{"1":"2 3 4 5 6 7 8 9 AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB VB WB XB YB ZB aB bB cB 0B dB 1B eB fB gB hB iB jB kB lB mB nB oB m pB qB rB sB tB P Q R 2B S T U V W X Y Z a b c d e f g h i j n o p q r s t u v w x y z I uB 3B 4B","2":"0 1 KC zB J K E F G A B C L M H N D O k l LC MC"},D:{"1":"8 9 AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB VB WB XB YB ZB aB bB cB 0B dB 1B eB fB gB hB iB jB kB lB mB nB oB m pB qB rB sB tB P Q R S T U V W X Y Z a b c d e f g h i j n o p q r s t u v w x y z I uB 3B 4B","2":"0 1 2 3 4 5 6 7 J K E F G A B C L M H N D O k l"},E:{"1":"G A B C L M H D RC 6B vB wB 7B SC TC 8B 9B xB AC yB BC CC DC EC FC GC UC","2":"0 J K E F NC 5B OC PC QC"},F:{"1":"1 2 3 4 5 6 7 8 9 H N D O k l AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB VB WB XB YB ZB aB bB cB dB eB fB gB hB iB jB kB lB mB nB oB m pB qB rB sB tB P Q R 2B S T U V W X Y Z a b c d e f g h i j wB","2":"G B C VC WC XC YC vB HC ZC"},G:{"1":"D fC gC hC iC jC kC lC mC nC oC pC qC rC sC tC 8B 9B xB AC yB BC CC DC EC FC GC","2":"F 5B aC IC bC cC dC eC"},H:{"1":"uC"},I:{"1":"I zC 0C","2":"zB J vC wC xC yC IC"},J:{"2":"E A"},K:{"1":"m","2":"A B C vB HC wB"},L:{"1":"I"},M:{"1":"uB"},N:{"2":"A B"},O:{"1":"xB"},P:{"1":"J k l 1C 2C 3C 4C 5C 6B 6C 7C 8C 9C AD yB BD CD DD"},Q:{"1":"7B"},R:{"1":"ED"},S:{"1":"FD GD"}},B:4,C:"CSS Feature Queries"}});var ag=v((v4,sg)=>{l();function ig(i){return i[i.length-1]}var ng={parse(i){let e=[""],t=[e];for(let r of i){if(r==="("){e=[""],ig(t).push(e),t.push(e);continue}if(r===")"){t.pop(),e=ig(t),e.push("");continue}e[e.length-1]+=r}return t[0]},stringify(i){let e="";for(let t of i){if(typeof t=="object"){e+=`(${ng.stringify(t)})`;continue}e+=t}return e}};sg.exports=ng});var cg=v((x4,fg)=>{l();var lA=rg(),{feature:uA}=($n(),Ln),{parse:fA}=ye(),cA=dt(),tl=ag(),pA=Se(),dA=ue(),og=uA(lA),lg=[];for(let i in og.stats){let e=og.stats[i];for(let t in e){let r=e[t];/y/.test(r)&&lg.push(i+" "+t)}}var ug=class{constructor(e,t){this.Prefixes=e,this.all=t}prefixer(){if(this.prefixerCache)return this.prefixerCache;let e=this.all.browsers.selected.filter(r=>lg.includes(r)),t=new cA(this.all.browsers.data,e,this.all.options);return this.prefixerCache=new this.Prefixes(this.all.data,t,this.all.options),this.prefixerCache}parse(e){let t=e.split(":"),r=t[0],n=t[1];return n||(n=""),[r.trim(),n.trim()]}virtual(e){let[t,r]=this.parse(e),n=fA("a{}").first;return n.append({prop:t,value:r,raws:{before:""}}),n}prefixed(e){let t=this.virtual(e);if(this.disabled(t.first))return t.nodes;let r={warn:()=>null},n=this.prefixer().add[t.first.prop];n&&n.process&&n.process(t.first,r);for(let a of t.nodes){for(let s of this.prefixer().values("add",t.first.prop))s.process(a);pA.save(this.all,a)}return t.nodes}isNot(e){return typeof e=="string"&&/not\s*/i.test(e)}isOr(e){return typeof e=="string"&&/\s*or\s*/i.test(e)}isProp(e){return typeof e=="object"&&e.length===1&&typeof e[0]=="string"}isHack(e,t){return!new RegExp(`(\\(|\\s)${dA.escapeRegexp(t)}:`).test(e)}toRemove(e,t){let[r,n]=this.parse(e),a=this.all.unprefixed(r),s=this.all.cleaner();if(s.remove[r]&&s.remove[r].remove&&!this.isHack(t,a))return!0;for(let o of s.values("remove",a))if(o.check(n))return!0;return!1}remove(e,t){let r=0;for(;rtypeof t!="object"?t:t.length===1&&typeof t[0]=="object"?this.cleanBrackets(t[0]):this.cleanBrackets(t))}convert(e){let t=[""];for(let r of e)t.push([`${r.prop}: ${r.value}`]),t.push(" or ");return t[t.length-1]="",t}normalize(e){if(typeof e!="object")return e;if(e=e.filter(t=>t!==""),typeof e[0]=="string"){let t=e[0].trim();if(t.includes(":")||t==="selector"||t==="not selector")return[tl.stringify(e)]}return e.map(t=>this.normalize(t))}add(e,t){return e.map(r=>{if(this.isProp(r)){let n=this.prefixed(r[0]);return n.length>1?this.convert(n):r}return typeof r=="object"?this.add(r,t):r})}process(e){let t=tl.parse(e.params);t=this.normalize(t),t=this.remove(t,e.params),t=this.add(t,e.params),t=this.cleanBrackets(t),e.params=tl.stringify(t)}disabled(e){if(!this.all.options.grid&&(e.prop==="display"&&e.value.includes("grid")||e.prop.includes("grid")||e.prop==="justify-items"))return!0;if(this.all.options.flexbox===!1){if(e.prop==="display"&&e.value.includes("flex"))return!0;let t=["order","justify-content","align-items","align-content"];if(e.prop.includes("flex")||t.includes(e.prop))return!0}return!1}};fg.exports=ug});var hg=v((k4,dg)=>{l();var pg=class{constructor(e,t){this.prefix=t,this.prefixed=e.prefixed(this.prefix),this.regexp=e.regexp(this.prefix),this.prefixeds=e.possible().map(r=>[e.prefixed(r),e.regexp(r)]),this.unprefixed=e.name,this.nameRegexp=e.regexp()}isHack(e){let t=e.parent.index(e)+1,r=e.parent.nodes;for(;t{l();var{list:hA}=ye(),mA=hg(),gA=Wt(),yA=dt(),wA=ue(),mg=class extends gA{constructor(e,t,r){super(e,t,r);this.regexpCache=new Map}check(e){return e.selector.includes(this.name)?!!e.selector.match(this.regexp()):!1}prefixed(e){return this.name.replace(/^(\W*)/,`$1${e}`)}regexp(e){if(!this.regexpCache.has(e)){let t=e?this.prefixed(e):this.name;this.regexpCache.set(e,new RegExp(`(^|[^:"'=])${wA.escapeRegexp(t)}`,"gi"))}return this.regexpCache.get(e)}possible(){return yA.prefixes()}prefixeds(e){if(e._autoprefixerPrefixeds){if(e._autoprefixerPrefixeds[this.name])return e._autoprefixerPrefixeds}else e._autoprefixerPrefixeds={};let t={};if(e.selector.includes(",")){let n=hA.comma(e.selector).filter(a=>a.includes(this.name));for(let a of this.possible())t[a]=n.map(s=>this.replace(s,a)).join(", ")}else for(let r of this.possible())t[r]=this.replace(e.selector,r);return e._autoprefixerPrefixeds[this.name]=t,e._autoprefixerPrefixeds}already(e,t,r){let n=e.parent.index(e)-1;for(;n>=0;){let a=e.parent.nodes[n];if(a.type!=="rule")return!1;let s=!1;for(let o in t[this.name]){let u=t[this.name][o];if(a.selector===u){if(r===o)return!0;s=!0;break}}if(!s)return!1;n-=1}return!1}replace(e,t){return e.replace(this.regexp(),`$1${this.prefixed(t)}`)}add(e,t){let r=this.prefixeds(e);if(this.already(e,r,t))return;let n=this.clone(e,{selector:r[this.name][t]});e.parent.insertBefore(e,n)}old(e){return new mA(this,e)}};gg.exports=mg});var bg=v((C4,wg)=>{l();var bA=Wt(),yg=class extends bA{add(e,t){let r=t+e.name;if(e.parent.some(s=>s.name===r&&s.params===e.params))return;let a=this.clone(e,{name:r});return e.parent.insertBefore(e,a)}process(e){let t=this.parentPrefix(e);for(let r of this.prefixes)(!t||t===r)&&this.add(e,r)}};wg.exports=yg});var xg=v((A4,vg)=>{l();var vA=Yt(),rl=class extends vA{prefixed(e){return e==="-webkit-"?":-webkit-full-screen":e==="-moz-"?":-moz-full-screen":`:${e}fullscreen`}};rl.names=[":fullscreen"];vg.exports=rl});var Sg=v((_4,kg)=>{l();var xA=Yt(),il=class extends xA{possible(){return super.possible().concat(["-moz- old","-ms- old"])}prefixed(e){return e==="-webkit-"?"::-webkit-input-placeholder":e==="-ms-"?"::-ms-input-placeholder":e==="-ms- old"?":-ms-input-placeholder":e==="-moz- old"?":-moz-placeholder":`::${e}placeholder`}};il.names=["::placeholder"];kg.exports=il});var Ag=v((O4,Cg)=>{l();var kA=Yt(),nl=class extends kA{prefixed(e){return e==="-ms-"?":-ms-input-placeholder":`:${e}placeholder-shown`}};nl.names=[":placeholder-shown"];Cg.exports=nl});var Og=v((E4,_g)=>{l();var SA=Yt(),CA=ue(),sl=class extends SA{constructor(e,t,r){super(e,t,r);this.prefixes&&(this.prefixes=CA.uniq(this.prefixes.map(n=>"-webkit-")))}prefixed(e){return e==="-webkit-"?"::-webkit-file-upload-button":`::${e}file-selector-button`}};sl.names=["::file-selector-button"];_g.exports=sl});var de=v((T4,Eg)=>{l();Eg.exports=function(i){let e;return i==="-webkit- 2009"||i==="-moz-"?e=2009:i==="-ms-"?e=2012:i==="-webkit-"&&(e="final"),i==="-webkit- 2009"&&(i="-webkit-"),[e,i]}});var Ig=v((P4,Dg)=>{l();var Tg=ye().list,Pg=de(),AA=M(),Qt=class extends AA{prefixed(e,t){let r;return[r,t]=Pg(t),r===2009?t+"box-flex":super.prefixed(e,t)}normalize(){return"flex"}set(e,t){let r=Pg(t)[0];if(r===2009)return e.value=Tg.space(e.value)[0],e.value=Qt.oldValues[e.value]||e.value,super.set(e,t);if(r===2012){let n=Tg.space(e.value);n.length===3&&n[2]==="0"&&(e.value=n.slice(0,2).concat("0px").join(" "))}return super.set(e,t)}};Qt.names=["flex","box-flex"];Qt.oldValues={auto:"1",none:"0"};Dg.exports=Qt});var Mg=v((D4,Rg)=>{l();var qg=de(),_A=M(),al=class extends _A{prefixed(e,t){let r;return[r,t]=qg(t),r===2009?t+"box-ordinal-group":r===2012?t+"flex-order":super.prefixed(e,t)}normalize(){return"order"}set(e,t){return qg(t)[0]===2009&&/\d/.test(e.value)?(e.value=(parseInt(e.value)+1).toString(),super.set(e,t)):super.set(e,t)}};al.names=["order","flex-order","box-ordinal-group"];Rg.exports=al});var Fg=v((I4,Bg)=>{l();var OA=M(),ol=class extends OA{check(e){let t=e.value;return!t.toLowerCase().includes("alpha(")&&!t.includes("DXImageTransform.Microsoft")&&!t.includes("data:image/svg+xml")}};ol.names=["filter"];Bg.exports=ol});var Lg=v((q4,Ng)=>{l();var EA=M(),ll=class extends EA{insert(e,t,r,n){if(t!=="-ms-")return super.insert(e,t,r);let a=this.clone(e),s=e.prop.replace(/end$/,"start"),o=t+e.prop.replace(/end$/,"span");if(!e.parent.some(u=>u.prop===o)){if(a.prop=o,e.value.includes("span"))a.value=e.value.replace(/span\s/i,"");else{let u;if(e.parent.walkDecls(s,c=>{u=c}),u){let c=Number(e.value)-Number(u.value)+"";a.value=c}else e.warn(n,`Can not prefix ${e.prop} (${s} is not found)`)}e.cloneBefore(a)}}};ll.names=["grid-row-end","grid-column-end"];Ng.exports=ll});var jg=v((R4,$g)=>{l();var TA=M(),ul=class extends TA{check(e){return!e.value.split(/\s+/).some(t=>{let r=t.toLowerCase();return r==="reverse"||r==="alternate-reverse"})}};ul.names=["animation","animation-direction"];$g.exports=ul});var Vg=v((M4,zg)=>{l();var PA=de(),DA=M(),fl=class extends DA{insert(e,t,r){let n;if([n,t]=PA(t),n!==2009)return super.insert(e,t,r);let a=e.value.split(/\s+/).filter(d=>d!=="wrap"&&d!=="nowrap"&&"wrap-reverse");if(a.length===0||e.parent.some(d=>d.prop===t+"box-orient"||d.prop===t+"box-direction"))return;let o=a[0],u=o.includes("row")?"horizontal":"vertical",c=o.includes("reverse")?"reverse":"normal",f=this.clone(e);return f.prop=t+"box-orient",f.value=u,this.needCascade(e)&&(f.raws.before=this.calcBefore(r,e,t)),e.parent.insertBefore(e,f),f=this.clone(e),f.prop=t+"box-direction",f.value=c,this.needCascade(e)&&(f.raws.before=this.calcBefore(r,e,t)),e.parent.insertBefore(e,f)}};fl.names=["flex-flow","box-direction","box-orient"];zg.exports=fl});var Wg=v((B4,Ug)=>{l();var IA=de(),qA=M(),cl=class extends qA{normalize(){return"flex"}prefixed(e,t){let r;return[r,t]=IA(t),r===2009?t+"box-flex":r===2012?t+"flex-positive":super.prefixed(e,t)}};cl.names=["flex-grow","flex-positive"];Ug.exports=cl});var Hg=v((F4,Gg)=>{l();var RA=de(),MA=M(),pl=class extends MA{set(e,t){if(RA(t)[0]!==2009)return super.set(e,t)}};pl.names=["flex-wrap"];Gg.exports=pl});var Qg=v((N4,Yg)=>{l();var BA=M(),Jt=mt(),dl=class extends BA{insert(e,t,r,n){if(t!=="-ms-")return super.insert(e,t,r);let a=Jt.parse(e),[s,o]=Jt.translate(a,0,2),[u,c]=Jt.translate(a,1,3);[["grid-row",s],["grid-row-span",o],["grid-column",u],["grid-column-span",c]].forEach(([f,d])=>{Jt.insertDecl(e,f,d)}),Jt.warnTemplateSelectorNotFound(e,n),Jt.warnIfGridRowColumnExists(e,n)}};dl.names=["grid-area"];Yg.exports=dl});var Xg=v((L4,Jg)=>{l();var FA=M(),ni=mt(),hl=class extends FA{insert(e,t,r){if(t!=="-ms-")return super.insert(e,t,r);if(e.parent.some(s=>s.prop==="-ms-grid-row-align"))return;let[[n,a]]=ni.parse(e);a?(ni.insertDecl(e,"grid-row-align",n),ni.insertDecl(e,"grid-column-align",a)):(ni.insertDecl(e,"grid-row-align",n),ni.insertDecl(e,"grid-column-align",n))}};hl.names=["place-self"];Jg.exports=hl});var Zg=v(($4,Kg)=>{l();var NA=M(),ml=class extends NA{check(e){let t=e.value;return!t.includes("/")||t.includes("span")}normalize(e){return e.replace("-start","")}prefixed(e,t){let r=super.prefixed(e,t);return t==="-ms-"&&(r=r.replace("-start","")),r}};ml.names=["grid-row-start","grid-column-start"];Kg.exports=ml});var ry=v((j4,ty)=>{l();var ey=de(),LA=M(),Xt=class extends LA{check(e){return e.parent&&!e.parent.some(t=>t.prop&&t.prop.startsWith("grid-"))}prefixed(e,t){let r;return[r,t]=ey(t),r===2012?t+"flex-item-align":super.prefixed(e,t)}normalize(){return"align-self"}set(e,t){let r=ey(t)[0];if(r===2012)return e.value=Xt.oldValues[e.value]||e.value,super.set(e,t);if(r==="final")return super.set(e,t)}};Xt.names=["align-self","flex-item-align"];Xt.oldValues={"flex-end":"end","flex-start":"start"};ty.exports=Xt});var ny=v((z4,iy)=>{l();var $A=M(),jA=ue(),gl=class extends $A{constructor(e,t,r){super(e,t,r);this.prefixes&&(this.prefixes=jA.uniq(this.prefixes.map(n=>n==="-ms-"?"-webkit-":n)))}};gl.names=["appearance"];iy.exports=gl});var oy=v((V4,ay)=>{l();var sy=de(),zA=M(),yl=class extends zA{normalize(){return"flex-basis"}prefixed(e,t){let r;return[r,t]=sy(t),r===2012?t+"flex-preferred-size":super.prefixed(e,t)}set(e,t){let r;if([r,t]=sy(t),r===2012||r==="final")return super.set(e,t)}};yl.names=["flex-basis","flex-preferred-size"];ay.exports=yl});var uy=v((U4,ly)=>{l();var VA=M(),wl=class extends VA{normalize(){return this.name.replace("box-image","border")}prefixed(e,t){let r=super.prefixed(e,t);return t==="-webkit-"&&(r=r.replace("border","box-image")),r}};wl.names=["mask-border","mask-border-source","mask-border-slice","mask-border-width","mask-border-outset","mask-border-repeat","mask-box-image","mask-box-image-source","mask-box-image-slice","mask-box-image-width","mask-box-image-outset","mask-box-image-repeat"];ly.exports=wl});var cy=v((W4,fy)=>{l();var UA=M(),Le=class extends UA{insert(e,t,r){let n=e.prop==="mask-composite",a;n?a=e.value.split(","):a=e.value.match(Le.regexp)||[],a=a.map(c=>c.trim()).filter(c=>c);let s=a.length,o;if(s&&(o=this.clone(e),o.value=a.map(c=>Le.oldValues[c]||c).join(", "),a.includes("intersect")&&(o.value+=", xor"),o.prop=t+"mask-composite"),n)return s?(this.needCascade(e)&&(o.raws.before=this.calcBefore(r,e,t)),e.parent.insertBefore(e,o)):void 0;let u=this.clone(e);return u.prop=t+u.prop,s&&(u.value=u.value.replace(Le.regexp,"")),this.needCascade(e)&&(u.raws.before=this.calcBefore(r,e,t)),e.parent.insertBefore(e,u),s?(this.needCascade(e)&&(o.raws.before=this.calcBefore(r,e,t)),e.parent.insertBefore(e,o)):e}};Le.names=["mask","mask-composite"];Le.oldValues={add:"source-over",subtract:"source-out",intersect:"source-in",exclude:"xor"};Le.regexp=new RegExp(`\\s+(${Object.keys(Le.oldValues).join("|")})\\b(?!\\))\\s*(?=[,])`,"ig");fy.exports=Le});var hy=v((G4,dy)=>{l();var py=de(),WA=M(),Kt=class extends WA{prefixed(e,t){let r;return[r,t]=py(t),r===2009?t+"box-align":r===2012?t+"flex-align":super.prefixed(e,t)}normalize(){return"align-items"}set(e,t){let r=py(t)[0];return(r===2009||r===2012)&&(e.value=Kt.oldValues[e.value]||e.value),super.set(e,t)}};Kt.names=["align-items","flex-align","box-align"];Kt.oldValues={"flex-end":"end","flex-start":"start"};dy.exports=Kt});var gy=v((H4,my)=>{l();var GA=M(),bl=class extends GA{set(e,t){return t==="-ms-"&&e.value==="contain"&&(e.value="element"),super.set(e,t)}insert(e,t,r){if(!(e.value==="all"&&t==="-ms-"))return super.insert(e,t,r)}};bl.names=["user-select"];my.exports=bl});var by=v((Y4,wy)=>{l();var yy=de(),HA=M(),vl=class extends HA{normalize(){return"flex-shrink"}prefixed(e,t){let r;return[r,t]=yy(t),r===2012?t+"flex-negative":super.prefixed(e,t)}set(e,t){let r;if([r,t]=yy(t),r===2012||r==="final")return super.set(e,t)}};vl.names=["flex-shrink","flex-negative"];wy.exports=vl});var xy=v((Q4,vy)=>{l();var YA=M(),xl=class extends YA{prefixed(e,t){return`${t}column-${e}`}normalize(e){return e.includes("inside")?"break-inside":e.includes("before")?"break-before":"break-after"}set(e,t){return(e.prop==="break-inside"&&e.value==="avoid-column"||e.value==="avoid-page")&&(e.value="avoid"),super.set(e,t)}insert(e,t,r){if(e.prop!=="break-inside")return super.insert(e,t,r);if(!(/region/i.test(e.value)||/page/i.test(e.value)))return super.insert(e,t,r)}};xl.names=["break-inside","page-break-inside","column-break-inside","break-before","page-break-before","column-break-before","break-after","page-break-after","column-break-after"];vy.exports=xl});var Sy=v((J4,ky)=>{l();var QA=M(),kl=class extends QA{prefixed(e,t){return t+"print-color-adjust"}normalize(){return"color-adjust"}};kl.names=["color-adjust","print-color-adjust"];ky.exports=kl});var Ay=v((X4,Cy)=>{l();var JA=M(),Zt=class extends JA{insert(e,t,r){if(t==="-ms-"){let n=this.set(this.clone(e),t);this.needCascade(e)&&(n.raws.before=this.calcBefore(r,e,t));let a="ltr";return e.parent.nodes.forEach(s=>{s.prop==="direction"&&(s.value==="rtl"||s.value==="ltr")&&(a=s.value)}),n.value=Zt.msValues[a][e.value]||e.value,e.parent.insertBefore(e,n)}return super.insert(e,t,r)}};Zt.names=["writing-mode"];Zt.msValues={ltr:{"horizontal-tb":"lr-tb","vertical-rl":"tb-rl","vertical-lr":"tb-lr"},rtl:{"horizontal-tb":"rl-tb","vertical-rl":"bt-rl","vertical-lr":"bt-lr"}};Cy.exports=Zt});var Oy=v((K4,_y)=>{l();var XA=M(),Sl=class extends XA{set(e,t){return e.value=e.value.replace(/\s+fill(\s)/,"$1"),super.set(e,t)}};Sl.names=["border-image"];_y.exports=Sl});var Py=v((Z4,Ty)=>{l();var Ey=de(),KA=M(),er=class extends KA{prefixed(e,t){let r;return[r,t]=Ey(t),r===2012?t+"flex-line-pack":super.prefixed(e,t)}normalize(){return"align-content"}set(e,t){let r=Ey(t)[0];if(r===2012)return e.value=er.oldValues[e.value]||e.value,super.set(e,t);if(r==="final")return super.set(e,t)}};er.names=["align-content","flex-line-pack"];er.oldValues={"flex-end":"end","flex-start":"start","space-between":"justify","space-around":"distribute"};Ty.exports=er});var Iy=v((eI,Dy)=>{l();var ZA=M(),Ce=class extends ZA{prefixed(e,t){return t==="-moz-"?t+(Ce.toMozilla[e]||e):super.prefixed(e,t)}normalize(e){return Ce.toNormal[e]||e}};Ce.names=["border-radius"];Ce.toMozilla={};Ce.toNormal={};for(let i of["top","bottom"])for(let e of["left","right"]){let t=`border-${i}-${e}-radius`,r=`border-radius-${i}${e}`;Ce.names.push(t),Ce.names.push(r),Ce.toMozilla[t]=r,Ce.toNormal[r]=t}Dy.exports=Ce});var Ry=v((tI,qy)=>{l();var e_=M(),Cl=class extends e_{prefixed(e,t){return e.includes("-start")?t+e.replace("-block-start","-before"):t+e.replace("-block-end","-after")}normalize(e){return e.includes("-before")?e.replace("-before","-block-start"):e.replace("-after","-block-end")}};Cl.names=["border-block-start","border-block-end","margin-block-start","margin-block-end","padding-block-start","padding-block-end","border-before","border-after","margin-before","margin-after","padding-before","padding-after"];qy.exports=Cl});var By=v((rI,My)=>{l();var t_=M(),{parseTemplate:r_,warnMissedAreas:i_,getGridGap:n_,warnGridGap:s_,inheritGridGap:a_}=mt(),Al=class extends t_{insert(e,t,r,n){if(t!=="-ms-")return super.insert(e,t,r);if(e.parent.some(m=>m.prop==="-ms-grid-rows"))return;let a=n_(e),s=a_(e,a),{rows:o,columns:u,areas:c}=r_({decl:e,gap:s||a}),f=Object.keys(c).length>0,d=Boolean(o),p=Boolean(u);return s_({gap:a,hasColumns:p,decl:e,result:n}),i_(c,e,n),(d&&p||f)&&e.cloneBefore({prop:"-ms-grid-rows",value:o,raws:{}}),p&&e.cloneBefore({prop:"-ms-grid-columns",value:u,raws:{}}),e}};Al.names=["grid-template"];My.exports=Al});var Ny=v((iI,Fy)=>{l();var o_=M(),_l=class extends o_{prefixed(e,t){return t+e.replace("-inline","")}normalize(e){return e.replace(/(margin|padding|border)-(start|end)/,"$1-inline-$2")}};_l.names=["border-inline-start","border-inline-end","margin-inline-start","margin-inline-end","padding-inline-start","padding-inline-end","border-start","border-end","margin-start","margin-end","padding-start","padding-end"];Fy.exports=_l});var $y=v((nI,Ly)=>{l();var l_=M(),Ol=class extends l_{check(e){return!e.value.includes("flex-")&&e.value!=="baseline"}prefixed(e,t){return t+"grid-row-align"}normalize(){return"align-self"}};Ol.names=["grid-row-align"];Ly.exports=Ol});var zy=v((sI,jy)=>{l();var u_=M(),tr=class extends u_{keyframeParents(e){let{parent:t}=e;for(;t;){if(t.type==="atrule"&&t.name==="keyframes")return!0;({parent:t}=t)}return!1}contain3d(e){if(e.prop==="transform-origin")return!1;for(let t of tr.functions3d)if(e.value.includes(`${t}(`))return!0;return!1}set(e,t){return e=super.set(e,t),t==="-ms-"&&(e.value=e.value.replace(/rotatez/gi,"rotate")),e}insert(e,t,r){if(t==="-ms-"){if(!this.contain3d(e)&&!this.keyframeParents(e))return super.insert(e,t,r)}else if(t==="-o-"){if(!this.contain3d(e))return super.insert(e,t,r)}else return super.insert(e,t,r)}};tr.names=["transform","transform-origin"];tr.functions3d=["matrix3d","translate3d","translateZ","scale3d","scaleZ","rotate3d","rotateX","rotateY","perspective"];jy.exports=tr});var Wy=v((aI,Uy)=>{l();var Vy=de(),f_=M(),El=class extends f_{normalize(){return"flex-direction"}insert(e,t,r){let n;if([n,t]=Vy(t),n!==2009)return super.insert(e,t,r);if(e.parent.some(f=>f.prop===t+"box-orient"||f.prop===t+"box-direction"))return;let s=e.value,o,u;s==="inherit"||s==="initial"||s==="unset"?(o=s,u=s):(o=s.includes("row")?"horizontal":"vertical",u=s.includes("reverse")?"reverse":"normal");let c=this.clone(e);return c.prop=t+"box-orient",c.value=o,this.needCascade(e)&&(c.raws.before=this.calcBefore(r,e,t)),e.parent.insertBefore(e,c),c=this.clone(e),c.prop=t+"box-direction",c.value=u,this.needCascade(e)&&(c.raws.before=this.calcBefore(r,e,t)),e.parent.insertBefore(e,c)}old(e,t){let r;return[r,t]=Vy(t),r===2009?[t+"box-orient",t+"box-direction"]:super.old(e,t)}};El.names=["flex-direction","box-direction","box-orient"];Uy.exports=El});var Hy=v((oI,Gy)=>{l();var c_=M(),Tl=class extends c_{check(e){return e.value==="pixelated"}prefixed(e,t){return t==="-ms-"?"-ms-interpolation-mode":super.prefixed(e,t)}set(e,t){return t!=="-ms-"?super.set(e,t):(e.prop="-ms-interpolation-mode",e.value="nearest-neighbor",e)}normalize(){return"image-rendering"}process(e,t){return super.process(e,t)}};Tl.names=["image-rendering","interpolation-mode"];Gy.exports=Tl});var Qy=v((lI,Yy)=>{l();var p_=M(),d_=ue(),Pl=class extends p_{constructor(e,t,r){super(e,t,r);this.prefixes&&(this.prefixes=d_.uniq(this.prefixes.map(n=>n==="-ms-"?"-webkit-":n)))}};Pl.names=["backdrop-filter"];Yy.exports=Pl});var Xy=v((uI,Jy)=>{l();var h_=M(),m_=ue(),Dl=class extends h_{constructor(e,t,r){super(e,t,r);this.prefixes&&(this.prefixes=m_.uniq(this.prefixes.map(n=>n==="-ms-"?"-webkit-":n)))}check(e){return e.value.toLowerCase()==="text"}};Dl.names=["background-clip"];Jy.exports=Dl});var Zy=v((fI,Ky)=>{l();var g_=M(),y_=["none","underline","overline","line-through","blink","inherit","initial","unset"],Il=class extends g_{check(e){return e.value.split(/\s+/).some(t=>!y_.includes(t))}};Il.names=["text-decoration"];Ky.exports=Il});var rw=v((cI,tw)=>{l();var ew=de(),w_=M(),rr=class extends w_{prefixed(e,t){let r;return[r,t]=ew(t),r===2009?t+"box-pack":r===2012?t+"flex-pack":super.prefixed(e,t)}normalize(){return"justify-content"}set(e,t){let r=ew(t)[0];if(r===2009||r===2012){let n=rr.oldValues[e.value]||e.value;if(e.value=n,r!==2009||n!=="distribute")return super.set(e,t)}else if(r==="final")return super.set(e,t)}};rr.names=["justify-content","flex-pack","box-pack"];rr.oldValues={"flex-end":"end","flex-start":"start","space-between":"justify","space-around":"distribute"};tw.exports=rr});var nw=v((pI,iw)=>{l();var b_=M(),ql=class extends b_{set(e,t){let r=e.value.toLowerCase();return t==="-webkit-"&&!r.includes(" ")&&r!=="contain"&&r!=="cover"&&(e.value=e.value+" "+e.value),super.set(e,t)}};ql.names=["background-size"];iw.exports=ql});var aw=v((dI,sw)=>{l();var v_=M(),Rl=mt(),Ml=class extends v_{insert(e,t,r){if(t!=="-ms-")return super.insert(e,t,r);let n=Rl.parse(e),[a,s]=Rl.translate(n,0,1);n[0]&&n[0].includes("span")&&(s=n[0].join("").replace(/\D/g,"")),[[e.prop,a],[`${e.prop}-span`,s]].forEach(([u,c])=>{Rl.insertDecl(e,u,c)})}};Ml.names=["grid-row","grid-column"];sw.exports=Ml});var uw=v((hI,lw)=>{l();var x_=M(),{prefixTrackProp:ow,prefixTrackValue:k_,autoplaceGridItems:S_,getGridGap:C_,inheritGridGap:A_}=mt(),__=el(),Bl=class extends x_{prefixed(e,t){return t==="-ms-"?ow({prop:e,prefix:t}):super.prefixed(e,t)}normalize(e){return e.replace(/^grid-(rows|columns)/,"grid-template-$1")}insert(e,t,r,n){if(t!=="-ms-")return super.insert(e,t,r);let{parent:a,prop:s,value:o}=e,u=s.includes("rows"),c=s.includes("columns"),f=a.some(k=>k.prop==="grid-template"||k.prop==="grid-template-areas");if(f&&u)return!1;let d=new __({options:{}}),p=d.gridStatus(a,n),m=C_(e);m=A_(e,m)||m;let b=u?m.row:m.column;(p==="no-autoplace"||p===!0)&&!f&&(b=null);let x=k_({value:o,gap:b});e.cloneBefore({prop:ow({prop:s,prefix:t}),value:x});let y=a.nodes.find(k=>k.prop==="grid-auto-flow"),w="row";if(y&&!d.disabled(y,n)&&(w=y.value.trim()),p==="autoplace"){let k=a.nodes.find(_=>_.prop==="grid-template-rows");if(!k&&f)return;if(!k&&!f){e.warn(n,"Autoplacement does not work without grid-template-rows property");return}!a.nodes.find(_=>_.prop==="grid-template-columns")&&!f&&e.warn(n,"Autoplacement does not work without grid-template-columns property"),c&&!f&&S_(e,n,m,w)}}};Bl.names=["grid-template-rows","grid-template-columns","grid-rows","grid-columns"];lw.exports=Bl});var cw=v((mI,fw)=>{l();var O_=M(),Fl=class extends O_{check(e){return!e.value.includes("flex-")&&e.value!=="baseline"}prefixed(e,t){return t+"grid-column-align"}normalize(){return"justify-self"}};Fl.names=["grid-column-align"];fw.exports=Fl});var dw=v((gI,pw)=>{l();var E_=M(),Nl=class extends E_{prefixed(e,t){return t+"scroll-chaining"}normalize(){return"overscroll-behavior"}set(e,t){return e.value==="auto"?e.value="chained":(e.value==="none"||e.value==="contain")&&(e.value="none"),super.set(e,t)}};Nl.names=["overscroll-behavior","scroll-chaining"];pw.exports=Nl});var gw=v((yI,mw)=>{l();var T_=M(),{parseGridAreas:P_,warnMissedAreas:D_,prefixTrackProp:I_,prefixTrackValue:hw,getGridGap:q_,warnGridGap:R_,inheritGridGap:M_}=mt();function B_(i){return i.trim().slice(1,-1).split(/["']\s*["']?/g)}var Ll=class extends T_{insert(e,t,r,n){if(t!=="-ms-")return super.insert(e,t,r);let a=!1,s=!1,o=e.parent,u=q_(e);u=M_(e,u)||u,o.walkDecls(/-ms-grid-rows/,d=>d.remove()),o.walkDecls(/grid-template-(rows|columns)/,d=>{if(d.prop==="grid-template-rows"){s=!0;let{prop:p,value:m}=d;d.cloneBefore({prop:I_({prop:p,prefix:t}),value:hw({value:m,gap:u.row})})}else a=!0});let c=B_(e.value);a&&!s&&u.row&&c.length>1&&e.cloneBefore({prop:"-ms-grid-rows",value:hw({value:`repeat(${c.length}, auto)`,gap:u.row}),raws:{}}),R_({gap:u,hasColumns:a,decl:e,result:n});let f=P_({rows:c,gap:u});return D_(f,e,n),e}};Ll.names=["grid-template-areas"];mw.exports=Ll});var ww=v((wI,yw)=>{l();var F_=M(),$l=class extends F_{set(e,t){return t==="-webkit-"&&(e.value=e.value.replace(/\s*(right|left)\s*/i,"")),super.set(e,t)}};$l.names=["text-emphasis-position"];yw.exports=$l});var vw=v((bI,bw)=>{l();var N_=M(),jl=class extends N_{set(e,t){return e.prop==="text-decoration-skip-ink"&&e.value==="auto"?(e.prop=t+"text-decoration-skip",e.value="ink",e):super.set(e,t)}};jl.names=["text-decoration-skip-ink","text-decoration-skip"];bw.exports=jl});var _w=v((vI,Aw)=>{l();"use strict";Aw.exports={wrap:xw,limit:kw,validate:Sw,test:zl,curry:L_,name:Cw};function xw(i,e,t){var r=e-i;return((t-i)%r+r)%r+i}function kw(i,e,t){return Math.max(i,Math.min(e,t))}function Sw(i,e,t,r,n){if(!zl(i,e,t,r,n))throw new Error(t+" is outside of range ["+i+","+e+")");return t}function zl(i,e,t,r,n){return!(te||n&&t===e||r&&t===i)}function Cw(i,e,t,r){return(t?"(":"[")+i+","+e+(r?")":"]")}function L_(i,e,t,r){var n=Cw.bind(null,i,e,t,r);return{wrap:xw.bind(null,i,e),limit:kw.bind(null,i,e),validate:function(a){return Sw(i,e,a,t,r)},test:function(a){return zl(i,e,a,t,r)},toString:n,name:n}}});var Tw=v((xI,Ew)=>{l();var Vl=Gn(),$_=_w(),j_=Ht(),z_=Se(),V_=ue(),Ow=/top|left|right|bottom/gi,Qe=class extends z_{replace(e,t){let r=Vl(e);for(let n of r.nodes)if(n.type==="function"&&n.value===this.name)if(n.nodes=this.newDirection(n.nodes),n.nodes=this.normalize(n.nodes),t==="-webkit- old"){if(!this.oldWebkit(n))return!1}else n.nodes=this.convertDirection(n.nodes),n.value=t+n.value;return r.toString()}replaceFirst(e,...t){return t.map(n=>n===" "?{type:"space",value:n}:{type:"word",value:n}).concat(e.slice(1))}normalizeUnit(e,t){return`${parseFloat(e)/t*360}deg`}normalize(e){if(!e[0])return e;if(/-?\d+(.\d+)?grad/.test(e[0].value))e[0].value=this.normalizeUnit(e[0].value,400);else if(/-?\d+(.\d+)?rad/.test(e[0].value))e[0].value=this.normalizeUnit(e[0].value,2*Math.PI);else if(/-?\d+(.\d+)?turn/.test(e[0].value))e[0].value=this.normalizeUnit(e[0].value,1);else if(e[0].value.includes("deg")){let t=parseFloat(e[0].value);t=$_.wrap(0,360,t),e[0].value=`${t}deg`}return e[0].value==="0deg"?e=this.replaceFirst(e,"to"," ","top"):e[0].value==="90deg"?e=this.replaceFirst(e,"to"," ","right"):e[0].value==="180deg"?e=this.replaceFirst(e,"to"," ","bottom"):e[0].value==="270deg"&&(e=this.replaceFirst(e,"to"," ","left")),e}newDirection(e){if(e[0].value==="to"||(Ow.lastIndex=0,!Ow.test(e[0].value)))return e;e.unshift({type:"word",value:"to"},{type:"space",value:" "});for(let t=2;t0&&(e[0].value==="to"?this.fixDirection(e):e[0].value.includes("deg")?this.fixAngle(e):this.isRadial(e)&&this.fixRadial(e)),e}fixDirection(e){e.splice(0,2);for(let t of e){if(t.type==="div")break;t.type==="word"&&(t.value=this.revertDirection(t.value))}}fixAngle(e){let t=e[0].value;t=parseFloat(t),t=Math.abs(450-t)%360,t=this.roundFloat(t,3),e[0].value=`${t}deg`}fixRadial(e){let t=[],r=[],n,a,s,o,u;for(o=0;o{l();var U_=Ht(),W_=Se();function Pw(i){return new RegExp(`(^|[\\s,(])(${i}($|[\\s),]))`,"gi")}var Ul=class extends W_{regexp(){return this.regexpCache||(this.regexpCache=Pw(this.name)),this.regexpCache}isStretch(){return this.name==="stretch"||this.name==="fill"||this.name==="fill-available"}replace(e,t){return t==="-moz-"&&this.isStretch()?e.replace(this.regexp(),"$1-moz-available$3"):t==="-webkit-"&&this.isStretch()?e.replace(this.regexp(),"$1-webkit-fill-available$3"):super.replace(e,t)}old(e){let t=e+this.name;return this.isStretch()&&(e==="-moz-"?t="-moz-available":e==="-webkit-"&&(t="-webkit-fill-available")),new U_(this.name,t,t,Pw(t))}add(e,t){if(!(e.prop.includes("grid")&&t!=="-webkit-"))return super.add(e,t)}};Ul.names=["max-content","min-content","fit-content","fill","fill-available","stretch"];Dw.exports=Ul});var Mw=v((SI,Rw)=>{l();var qw=Ht(),G_=Se(),Wl=class extends G_{replace(e,t){return t==="-webkit-"?e.replace(this.regexp(),"$1-webkit-optimize-contrast"):t==="-moz-"?e.replace(this.regexp(),"$1-moz-crisp-edges"):super.replace(e,t)}old(e){return e==="-webkit-"?new qw(this.name,"-webkit-optimize-contrast"):e==="-moz-"?new qw(this.name,"-moz-crisp-edges"):super.old(e)}};Wl.names=["pixelated"];Rw.exports=Wl});var Fw=v((CI,Bw)=>{l();var H_=Se(),Gl=class extends H_{replace(e,t){let r=super.replace(e,t);return t==="-webkit-"&&(r=r.replace(/("[^"]+"|'[^']+')(\s+\d+\w)/gi,"url($1)$2")),r}};Gl.names=["image-set"];Bw.exports=Gl});var Lw=v((AI,Nw)=>{l();var Y_=ye().list,Q_=Se(),Hl=class extends Q_{replace(e,t){return Y_.space(e).map(r=>{if(r.slice(0,+this.name.length+1)!==this.name+"(")return r;let n=r.lastIndexOf(")"),a=r.slice(n+1),s=r.slice(this.name.length+1,n);if(t==="-webkit-"){let o=s.match(/\d*.?\d+%?/);o?(s=s.slice(o[0].length).trim(),s+=`, ${o[0]}`):s+=", 0.5"}return t+this.name+"("+s+")"+a}).join(" ")}};Hl.names=["cross-fade"];Nw.exports=Hl});var jw=v((_I,$w)=>{l();var J_=de(),X_=Ht(),K_=Se(),Yl=class extends K_{constructor(e,t){super(e,t);e==="display-flex"&&(this.name="flex")}check(e){return e.prop==="display"&&e.value===this.name}prefixed(e){let t,r;return[t,e]=J_(e),t===2009?this.name==="flex"?r="box":r="inline-box":t===2012?this.name==="flex"?r="flexbox":r="inline-flexbox":t==="final"&&(r=this.name),e+r}replace(e,t){return this.prefixed(t)}old(e){let t=this.prefixed(e);if(!!t)return new X_(this.name,t)}};Yl.names=["display-flex","inline-flex"];$w.exports=Yl});var Vw=v((OI,zw)=>{l();var Z_=Se(),Ql=class extends Z_{constructor(e,t){super(e,t);e==="display-grid"&&(this.name="grid")}check(e){return e.prop==="display"&&e.value===this.name}};Ql.names=["display-grid","inline-grid"];zw.exports=Ql});var Ww=v((EI,Uw)=>{l();var e5=Se(),Jl=class extends e5{constructor(e,t){super(e,t);e==="filter-function"&&(this.name="filter")}};Jl.names=["filter","filter-function"];Uw.exports=Jl});var Qw=v((TI,Yw)=>{l();var Gw=ii(),B=M(),Hw=Em(),t5=Gm(),r5=el(),i5=cg(),Xl=dt(),ir=Yt(),n5=bg(),$e=Se(),nr=ue(),s5=xg(),a5=Sg(),o5=Ag(),l5=Og(),u5=Ig(),f5=Mg(),c5=Fg(),p5=Lg(),d5=jg(),h5=Vg(),m5=Wg(),g5=Hg(),y5=Qg(),w5=Xg(),b5=Zg(),v5=ry(),x5=ny(),k5=oy(),S5=uy(),C5=cy(),A5=hy(),_5=gy(),O5=by(),E5=xy(),T5=Sy(),P5=Ay(),D5=Oy(),I5=Py(),q5=Iy(),R5=Ry(),M5=By(),B5=Ny(),F5=$y(),N5=zy(),L5=Wy(),$5=Hy(),j5=Qy(),z5=Xy(),V5=Zy(),U5=rw(),W5=nw(),G5=aw(),H5=uw(),Y5=cw(),Q5=dw(),J5=gw(),X5=ww(),K5=vw(),Z5=Tw(),eO=Iw(),tO=Mw(),rO=Fw(),iO=Lw(),nO=jw(),sO=Vw(),aO=Ww();ir.hack(s5);ir.hack(a5);ir.hack(o5);ir.hack(l5);B.hack(u5);B.hack(f5);B.hack(c5);B.hack(p5);B.hack(d5);B.hack(h5);B.hack(m5);B.hack(g5);B.hack(y5);B.hack(w5);B.hack(b5);B.hack(v5);B.hack(x5);B.hack(k5);B.hack(S5);B.hack(C5);B.hack(A5);B.hack(_5);B.hack(O5);B.hack(E5);B.hack(T5);B.hack(P5);B.hack(D5);B.hack(I5);B.hack(q5);B.hack(R5);B.hack(M5);B.hack(B5);B.hack(F5);B.hack(N5);B.hack(L5);B.hack($5);B.hack(j5);B.hack(z5);B.hack(V5);B.hack(U5);B.hack(W5);B.hack(G5);B.hack(H5);B.hack(Y5);B.hack(Q5);B.hack(J5);B.hack(X5);B.hack(K5);$e.hack(Z5);$e.hack(eO);$e.hack(tO);$e.hack(rO);$e.hack(iO);$e.hack(nO);$e.hack(sO);$e.hack(aO);var Kl=new Map,si=class{constructor(e,t,r={}){this.data=e,this.browsers=t,this.options=r,[this.add,this.remove]=this.preprocess(this.select(this.data)),this.transition=new t5(this),this.processor=new r5(this)}cleaner(){if(this.cleanerCache)return this.cleanerCache;if(this.browsers.selected.length){let e=new Xl(this.browsers.data,[]);this.cleanerCache=new si(this.data,e,this.options)}else return this;return this.cleanerCache}select(e){let t={add:{},remove:{}};for(let r in e){let n=e[r],a=n.browsers.map(u=>{let c=u.split(" ");return{browser:`${c[0]} ${c[1]}`,note:c[2]}}),s=a.filter(u=>u.note).map(u=>`${this.browsers.prefix(u.browser)} ${u.note}`);s=nr.uniq(s),a=a.filter(u=>this.browsers.isSelected(u.browser)).map(u=>{let c=this.browsers.prefix(u.browser);return u.note?`${c} ${u.note}`:c}),a=this.sort(nr.uniq(a)),this.options.flexbox==="no-2009"&&(a=a.filter(u=>!u.includes("2009")));let o=n.browsers.map(u=>this.browsers.prefix(u));n.mistakes&&(o=o.concat(n.mistakes)),o=o.concat(s),o=nr.uniq(o),a.length?(t.add[r]=a,a.length!a.includes(u)))):t.remove[r]=o}return t}sort(e){return e.sort((t,r)=>{let n=nr.removeNote(t).length,a=nr.removeNote(r).length;return n===a?r.length-t.length:a-n})}preprocess(e){let t={selectors:[],"@supports":new i5(si,this)};for(let n in e.add){let a=e.add[n];if(n==="@keyframes"||n==="@viewport")t[n]=new n5(n,a,this);else if(n==="@resolution")t[n]=new Hw(n,a,this);else if(this.data[n].selector)t.selectors.push(ir.load(n,a,this));else{let s=this.data[n].props;if(s){let o=$e.load(n,a,this);for(let u of s)t[u]||(t[u]={values:[]}),t[u].values.push(o)}else{let o=t[n]&&t[n].values||[];t[n]=B.load(n,a,this),t[n].values=o}}}let r={selectors:[]};for(let n in e.remove){let a=e.remove[n];if(this.data[n].selector){let s=ir.load(n,a);for(let o of a)r.selectors.push(s.old(o))}else if(n==="@keyframes"||n==="@viewport")for(let s of a){let o=`@${s}${n.slice(1)}`;r[o]={remove:!0}}else if(n==="@resolution")r[n]=new Hw(n,a,this);else{let s=this.data[n].props;if(s){let o=$e.load(n,[],this);for(let u of a){let c=o.old(u);if(c)for(let f of s)r[f]||(r[f]={}),r[f].values||(r[f].values=[]),r[f].values.push(c)}}else for(let o of a){let u=this.decl(n).old(n,o);if(n==="align-self"){let c=t[n]&&t[n].prefixes;if(c){if(o==="-webkit- 2009"&&c.includes("-webkit-"))continue;if(o==="-webkit-"&&c.includes("-webkit- 2009"))continue}}for(let c of u)r[c]||(r[c]={}),r[c].remove=!0}}}return[t,r]}decl(e){return Kl.has(e)||Kl.set(e,B.load(e)),Kl.get(e)}unprefixed(e){let t=this.normalize(Gw.unprefixed(e));return t==="flex-direction"&&(t="flex-flow"),t}normalize(e){return this.decl(e).normalize(e)}prefixed(e,t){return e=Gw.unprefixed(e),this.decl(e).prefixed(e,t)}values(e,t){let r=this[e],n=r["*"]&&r["*"].values,a=r[t]&&r[t].values;return n&&a?nr.uniq(n.concat(a)):n||a||[]}group(e){let t=e.parent,r=t.index(e),{length:n}=t.nodes,a=this.unprefixed(e.prop),s=(o,u)=>{for(r+=o;r>=0&&r{l();Jw.exports={"backdrop-filter":{feature:"css-backdrop-filter",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5","safari 16.5"]},element:{props:["background","background-image","border-image","mask","list-style","list-style-image","content","mask-image"],feature:"css-element-function",browsers:["firefox 114"]},"user-select":{mistakes:["-khtml-"],feature:"user-select-none",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5","safari 16.5"]},"background-clip":{feature:"background-clip-text",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},hyphens:{feature:"css-hyphens",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5","safari 16.5"]},fill:{props:["width","min-width","max-width","height","min-height","max-height","inline-size","min-inline-size","max-inline-size","block-size","min-block-size","max-block-size","grid","grid-template","grid-template-rows","grid-template-columns","grid-auto-columns","grid-auto-rows"],feature:"intrinsic-width",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"fill-available":{props:["width","min-width","max-width","height","min-height","max-height","inline-size","min-inline-size","max-inline-size","block-size","min-block-size","max-block-size","grid","grid-template","grid-template-rows","grid-template-columns","grid-auto-columns","grid-auto-rows"],feature:"intrinsic-width",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},stretch:{props:["width","min-width","max-width","height","min-height","max-height","inline-size","min-inline-size","max-inline-size","block-size","min-block-size","max-block-size","grid","grid-template","grid-template-rows","grid-template-columns","grid-auto-columns","grid-auto-rows"],feature:"intrinsic-width",browsers:["firefox 114"]},"fit-content":{props:["width","min-width","max-width","height","min-height","max-height","inline-size","min-inline-size","max-inline-size","block-size","min-block-size","max-block-size","grid","grid-template","grid-template-rows","grid-template-columns","grid-auto-columns","grid-auto-rows"],feature:"intrinsic-width",browsers:["firefox 114"]},"text-decoration-style":{feature:"text-decoration",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5"]},"text-decoration-color":{feature:"text-decoration",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5"]},"text-decoration-line":{feature:"text-decoration",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5"]},"text-decoration":{feature:"text-decoration",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5"]},"text-decoration-skip":{feature:"text-decoration",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5"]},"text-decoration-skip-ink":{feature:"text-decoration",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5"]},"text-size-adjust":{feature:"text-size-adjust",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5"]},"mask-clip":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-composite":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-image":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-origin":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-repeat":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-border-repeat":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-border-source":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},mask:{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-position":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-size":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-border":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-border-outset":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-border-width":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-border-slice":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"clip-path":{feature:"css-clip-path",browsers:["samsung 21"]},"box-decoration-break":{feature:"css-boxdecorationbreak",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5","opera 99","safari 16.5","samsung 21"]},appearance:{feature:"css-appearance",browsers:["samsung 21"]},"image-set":{props:["background","background-image","border-image","cursor","mask","mask-image","list-style","list-style-image","content"],feature:"css-image-set",browsers:["and_uc 15.5","chrome 109","samsung 21"]},"cross-fade":{props:["background","background-image","border-image","mask","list-style","list-style-image","content","mask-image"],feature:"css-cross-fade",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},isolate:{props:["unicode-bidi"],feature:"css-unicode-bidi",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5","safari 16.5"]},"color-adjust":{feature:"css-color-adjust",browsers:["chrome 109","chrome 113","chrome 114","edge 114","opera 99"]}}});var Zw=v((DI,Kw)=>{l();Kw.exports={}});var ib=v((II,rb)=>{l();var oO=zo(),{agents:lO}=($n(),Ln),Zl=hm(),uO=dt(),fO=Qw(),cO=Xw(),pO=Zw(),eb={browsers:lO,prefixes:cO},tb=` + Replace Autoprefixer \`browsers\` option to Browserslist config. + Use \`browserslist\` key in \`package.json\` or \`.browserslistrc\` file. + + Using \`browsers\` option can cause errors. Browserslist config can + be used for Babel, Autoprefixer, postcss-normalize and other tools. + + If you really need to use option, rename it to \`overrideBrowserslist\`. + + Learn more at: + https://github.com/browserslist/browserslist#readme + https://twitter.com/browserslist + +`;function dO(i){return Object.prototype.toString.apply(i)==="[object Object]"}var eu=new Map;function hO(i,e){e.browsers.selected.length!==0&&(e.add.selectors.length>0||Object.keys(e.add).length>2||i.warn(`Autoprefixer target browsers do not need any prefixes.You do not need Autoprefixer anymore. +Check your Browserslist config to be sure that your targets are set up correctly. + + Learn more at: + https://github.com/postcss/autoprefixer#readme + https://github.com/browserslist/browserslist#readme + +`))}rb.exports=sr;function sr(...i){let e;if(i.length===1&&dO(i[0])?(e=i[0],i=void 0):i.length===0||i.length===1&&!i[0]?i=void 0:i.length<=2&&(Array.isArray(i[0])||!i[0])?(e=i[1],i=i[0]):typeof i[i.length-1]=="object"&&(e=i.pop()),e||(e={}),e.browser)throw new Error("Change `browser` option to `overrideBrowserslist` in Autoprefixer");if(e.browserslist)throw new Error("Change `browserslist` option to `overrideBrowserslist` in Autoprefixer");e.overrideBrowserslist?i=e.overrideBrowserslist:e.browsers&&(typeof console!="undefined"&&console.warn&&(Zl.red?console.warn(Zl.red(tb.replace(/`[^`]+`/g,n=>Zl.yellow(n.slice(1,-1))))):console.warn(tb)),i=e.browsers);let t={ignoreUnknownVersions:e.ignoreUnknownVersions,stats:e.stats,env:e.env};function r(n){let a=eb,s=new uO(a.browsers,i,n,t),o=s.selected.join(", ")+JSON.stringify(e);return eu.has(o)||eu.set(o,new fO(a.prefixes,s,e)),eu.get(o)}return{postcssPlugin:"autoprefixer",prepare(n){let a=r({from:n.opts.from,env:e.env});return{OnceExit(s){hO(n,a),e.remove!==!1&&a.processor.remove(s,n),e.add!==!1&&a.processor.add(s,n)}}},info(n){return n=n||{},n.from=n.from||h.cwd(),pO(r(n))},options:e,browsers:i}}sr.postcss=!0;sr.data=eb;sr.defaults=oO.defaults;sr.info=()=>sr().info()});var nb={};_e(nb,{default:()=>mO});var mO,sb=C(()=>{l();mO=[]});var ob={};_e(ob,{default:()=>gO});var ab,gO,lb=C(()=>{l();hi();ab=X(bi()),gO=Ze(ab.default.theme)});var fb={};_e(fb,{default:()=>yO});var ub,yO,cb=C(()=>{l();hi();ub=X(bi()),yO=Ze(ub.default)});l();"use strict";var wO=Je(pm()),bO=Je(ye()),vO=Je(ib()),xO=Je((sb(),nb)),kO=Je((lb(),ob)),SO=Je((cb(),fb)),CO=Je((Zn(),bu)),AO=Je((mo(),ho)),_O=Je((hs(),Ku));function Je(i){return i&&i.__esModule?i:{default:i}}console.warn("cdn.tailwindcss.com should not be used in production. To use Tailwind CSS in production, install it as a PostCSS plugin or use the Tailwind CLI: https://tailwindcss.com/docs/installation");var Hn="tailwind",tu="text/tailwindcss",pb="/template.html",St,db=!0,hb=0,ru=new Set,iu,mb="",gb=(i=!1)=>({get(e,t){return(!i||t==="config")&&typeof e[t]=="object"&&e[t]!==null?new Proxy(e[t],gb()):e[t]},set(e,t,r){return e[t]=r,(!i||t==="config")&&nu(!0),!0}});window[Hn]=new Proxy({config:{},defaultTheme:kO.default,defaultConfig:SO.default,colors:CO.default,plugin:AO.default,resolveConfig:_O.default},gb(!0));function yb(i){iu.observe(i,{attributes:!0,attributeFilter:["type"],characterData:!0,subtree:!0,childList:!0})}new MutationObserver(async i=>{let e=!1;if(!iu){iu=new MutationObserver(async()=>await nu(!0));for(let t of document.querySelectorAll(`style[type="${tu}"]`))yb(t)}for(let t of i)for(let r of t.addedNodes)r.nodeType===1&&r.tagName==="STYLE"&&r.getAttribute("type")===tu&&(yb(r),e=!0);await nu(e)}).observe(document.documentElement,{attributes:!0,attributeFilter:["class"],childList:!0,subtree:!0});async function nu(i=!1){i&&(hb++,ru.clear());let e="";for(let r of document.querySelectorAll(`style[type="${tu}"]`))e+=r.textContent;let t=new Set;for(let r of document.querySelectorAll("[class]"))for(let n of r.classList)ru.has(n)||t.add(n);if(document.body&&(db||t.size>0||e!==mb||!St||!St.isConnected)){for(let n of t)ru.add(n);db=!1,mb=e,self[pb]=Array.from(t).join(" ");let{css:r}=await(0,bO.default)([(0,wO.default)({...window[Hn].config,_hash:hb,content:{files:[pb],extract:{html:n=>n.split(" ")}},plugins:[...xO.default,...Array.isArray(window[Hn].config.plugins)?window[Hn].config.plugins:[]]}),(0,vO.default)({remove:!1})]).process(`@tailwind base;@tailwind components;@tailwind utilities;${e}`);(!St||!St.isConnected)&&(St=document.createElement("style"),document.head.append(St)),St.textContent=r}}})(); +/*! https://mths.be/cssesc v3.0.0 by @mathias */ diff --git a/public/styles/app.css b/public/styles/app.css deleted file mode 100644 index 8d80352e..00000000 --- a/public/styles/app.css +++ /dev/null @@ -1,1311 +0,0 @@ -:root { - --bg01: #111810; - --bg02: #10240C; - - --fg03: #007C00; - --fg02: #00C000; - --fg01: #3CF800; - --fg-highlight: #FCFF2F; - - /* Greens: - Fallout 2 character select screen: #5BF523 - Fallout Tactics custom campaign: #4AFC24 - - Oranges: - Fallout Tactics custom campaign: #FCFF2F - */ - - --bg02-half-transparent: rgba(16,36,12,0.5); - --bg01-abovehalf-transparent: rgba(17,24,16,0.625); - --fg01-half-transparent: rgba(60,248,0,0.5); - --fg01-fully-transparent: rgba(60,248,0,0); - --fg03-half-transparent: rgba(0,124,0,0.5); - --fg-highlight-transparent: rgba(252,253,125,0.25); - --fg-highlight-fully-transparent: rgba(252,253,125,0); - - /* filters for the logo calculated with https://codepen.io/sosuke/pen/Pjoqqp */ - --filter-fg02: invert(42%) sepia(85%) saturate(1707%) hue-rotate(88deg) brightness(102%) contrast(112%); - --filter-fg01: invert(71%) sepia(54%) saturate(3327%) hue-rotate(60deg) brightness(106%) contrast(118%) drop-shadow(0px 0px 8px var(--fg03)); -} - -/* Final choice: -PixelOperator/16px for body -PixelOperatorHB/16px for bold -PixelOperatorHBSC/16px for extra bold / login form / buttons etc? -PixelOperatorMonoHB/16px for code listing -*/ - -@font-face { - font-family: "PixelOperator"; - font-weight: 400; - src: url("../fonts/PixelOperator.ttf") format('truetype'); -} -@font-face { - font-family: "PixelOperator"; - font-weight: 700; - src: url("../fonts/PixelOperatorHB.ttf") format('truetype'); -} -@font-face { - font-family: "PixelOperator"; - font-weight: 900; - src: url("../fonts/PixelOperatorHBSC.ttf") format('truetype'); -} -@font-face { - font-family: "PixelOperatorMono"; - src: url("../fonts/PixelOperatorMonoHB.ttf") format('truetype'); -} - - - -html { - width: 100%; - height: 100%; -} - -body { - display: flex; - color: var(--fg02); - margin: 0; - position: relative; - min-height: 100%; -} - -* { - font-family: "PixelOperator"; - line-height: 17px; - font-size: 16px; - font-weight: normal; - - font-smooth: never; - -webkit-font-smoothing: none; - -moz-osx-font-smoothing: none; - /* -webkit-font-smoothing: antialiased; */ -} - -body:after { - position: absolute; - content: ''; - left: 0; - right: 0; - top: 0; - bottom: 0; - z-index: 1; - border-style: solid; - border-width: 128px; - border-color: transparent; - border-image: url('../images/border-image.png') 50% repeat; - box-sizing: border-box; - pointer-events: none; -} - -p { - max-width: 60ch; -} - -button, input, textarea { - border: none; - background: transparent; - color: var(--fg02); - padding: 0; - margin: 0; -} -button:disabled { - color: var(--fg03); -} -input:focus, textarea:focus { - outline: none; -} - -button { - text-transform: uppercase; - cursor: pointer; -} - -.has-tooltip { - text-decoration: underline; - text-decoration-style: dashed; - text-decoration-color: var(--fg03); -} - -button:hover, -button:active { - color: var(--fg01); - outline-color: var(--fg01); -} - -::placeholder { - color: var(--fg03); -} - -ul { - margin: 0; -} - -#app { - display: flex; - flex: 1; - flex-direction: row; - background-color: var(--bg01); -} - -#left-nav { - background-color: var(--bg02); - min-width: 190px; - width: 190px; - display: flex; - flex-direction: column; - align-items: flex-start; - padding-bottom: 40px; - padding-left: 40px; - padding-right: 40px; -} - -#left-nav-content { - padding-left: 27px; -} - -#logo-wrapper { - display: flex; - flex-direction: column; - align-items: flex-end; - margin-top: 26px; -} - -#logo { - width: 190px; - height: 36px; - filter: var(--filter-fg02); -} - -#version { - color: var(--fg03); -} - -#app.player #logo, -#app.admin #logo { - filter: var(--filter-fg01); - animation: flicker 2s linear 1; -} - -/* Safari hack courtesy https://browserstrangeness.github.io/ - -Disable the flicker animation in Safari, since it behaves very weird and -doesn't look as nice as in Chrome/Firefox. -*/ -_::-webkit-full-page-media, _:future, :root #app.player #logo, -_::-webkit-full-page-media, _:future, :root #app.admin #logo { - animation: none; -} - -@keyframes flicker { - 0%, 19%, 26%, 46%, 65%, 82%, 86%, 87%, 90%, 95% { - filter: var(--filter-fg02); - } - 20%, 25%, 47%, 64%, 83%, 85%, 88%, 89%, 96%, 100% { - filter: var(--filter-fg01); - } -} - -#login-form { - margin-top: 40px; - width: 20ch; -} - -#login-form input { - color: var(--fg01); - width: 18ch; - margin: 0; - padding: 0; - font-weight: 900; -} - -#login-form input:focus { - background-color: var(--bg01); -} - -#admin-hiscores-content #ladder-table { - margin-top: 16px; -} -/* select+option taken mainly from https://codepen.io/5t3ph/pen/MWyyYNz */ -.login-world-select-label { - margin-top: 20px; -} -.login-world-select-wrapper { - display: grid; - grid-template-areas: "select"; - align-items: center; - position: relative; - width: 20ch; - border-radius: 4px; - cursor: pointer; - background-color: var(--fg02); - margin-top: 8px; -} -.login-world-select-wrapper::after { - grid-area: select; - content: "^"; - justify-self: end; - transform: translateY(-2px) rotate(180deg); - color: #000000; /* we can't affect color, so we give up and make the -arrow have the same color */ - padding-left: 8px; - padding-right: 8px; -} -.login-world-select { - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - background-color: transparent; - border: none; - margin: 0; - padding: 4px 32px 4px 8px; - width: 100%; - font-size: inherit; - cursor: inherit; - line-height: inherit; - z-index: 1; - outline: none; - grid-area: select; -} -.login-world-select::-ms-expand { - display: none; -} -.login-world-select:focus + .login-world-select-focus { - position: absolute; - top: -1px; - left: -1px; - right: -1px; - bottom: -1px; - border: 2px solid var(--fg01); - border-radius: inherit; -} - -#login-form-buttons { - margin-top: 1em; - display: flex; - justify-content: space-between; -} - -#alert-message { - margin-top: 40px; - color: var(--fg-highlight); -} - -#logged-out-links, -#logged-in-links { - margin-top: 40px; -} - -#common-links { - margin-top: 1em; -} - -#logged-out-links, -#logged-in-links, -#common-links { - padding-left: 24px; -} - -.link { - color: var(--fg03); - cursor: pointer; - text-decoration: none; - display: block; - text-align: left; -} - -.link-label { - color: var(--fg01); - text-transform: uppercase; - width: 9ch; - min-width: 9ch; - display: inline-block; - margin: 0 1ch; - white-space: pre; -} - -.link[target="_blank"] .link-right-bracket::before { - content: "-> "; - color: var(--fg03); - margin-left: -2ch; -} - -.link.active .link-label, -.link:hover, -.link:hover .link-label { - color: var(--fg-highlight); -} - -.link.dimmed:not(:hover):not(.active) .link-label { - color: var(--fg03); -} - -.link:disabled .link-left-bracket, -.link:disabled .link-right-bracket, -.link:disabled .link-label { - color: var(--fg03); - -} - -#player-info { - margin-top: 40px; - padding-left: 16px; - display: grid; - grid-template-columns: min-content min-content; - grid-auto-rows: auto; -} - -.player-stat-label { - grid-column: 1; - text-align: right; - color: var(--fg03); - margin-right: 1ch; -} - -.player-stat-value { - grid-column: 2; - color: var(--fg02); -} - -.emphasized { - color: var(--fg01); -} - -.slightly-emphasized { - color: var(--fg02); -} - -.deemphasized { - color: var(--fg03); -} - -#loading-nav { - margin-top: 40px; -} - -.loading-cursor { - display: inline-block; - animation: cursor-blink 1.5s linear infinite; - width: 1ch; - height: 1em; - margin-bottom: -2px; - margin-left: 2px; -} - -@keyframes cursor-blink { - 0%, 10%, 90%, 100% { - background: var(--fg02); - } - 30%, 70% { - background: transparent; - } -} - -#admin-worlds-list table { - white-space: nowrap; -} -#admin-worlds-list button+button { - margin-left: 1ch; -} - -#content { - padding: 32px 40px 40px; - display: flex; - flex-direction: column; - flex: 1; - align-items: flex-start; -} - -#page-title { - font-size: 32px; - margin: 0 0 40px; - font-weight: 900; -} - -table { - text-align: left; - border-collapse: collapse; -} - -table tbody td { - border-left: 1px solid var(--fg03-half-transparent); - padding: 4px 8px; -} - -table thead { - color: var(--fg03); - border-bottom: 3px solid var(--fg03-half-transparent); -} - -table thead th { - border-left: 3px solid var(--fg03-half-transparent); - padding: 4px 8px; - font-weight: normal; -} - -table tbody td:first-child, -table thead th:first-child { - border-left: none; -} - -table tbody tr:hover td { - background: var(--bg02); -} - -#ladder-table tbody tr.is-player { - color: var(--fg01); -} - -#ladder-table tbody tr.is-player td { - background: var(--bg02); -} - -#ladder-table tbody .ladder-rank, -#ladder-table tbody .ladder-lvl, -#ladder-table tbody .ladder-wins, -#ladder-table tbody .ladder-losses { - text-align: right; -} - -#ladder-table tbody .ladder-fight { - cursor: pointer; - background: var(--bg02); - color: var(--fg01); -} - -#ladder-table tbody .ladder-fight:hover { - color: var(--fg-highlight); -} - -#ladder-table tbody tr.is-player .ladder-fight { - color: var(--fg03); -} - -#messages-table tbody .messages-unread { - text-align: right; -} - -#messages-table tbody tr.is-unread { - color: var(--fg01); -} - -#messages-table tbody .messages-remove:hover { - color: var(--fg-highlight); -} - -#messages-empty-note { - margin-top: 40px; -} - -#message-summary { - margin: 0; - color: var(--fg01); - font-weight: 700; -} - -#message-date { - color: var(--fg03); -} - -#message-content { - max-width: 60ch; -} - -.news-item:not(:first-of-type) { - margin-top: 60px; -} - - -.news-item-title { - margin: 0; - color: var(--fg01); - font-weight: 700; -} - -.news-item-date { - color: var(--fg03); -} - -.news-item-text { - max-width: 60ch; -} - - -.news-item-text pre { - padding-left: 32px; -} -.news-item-text pre code { - color: var(--fg01); -} - -.news-item-text a { - color: var(--fg-highlight); - position: relative; - text-decoration: none; -} - -.news-item-text a:after { - position: absolute; - content: ''; - background: var(--fg-highlight-transparent); - left: -3px; - right: -3px; - bottom: -2px; - height: 4px; - transition: bottom 0.25s ease, height 0.25s ease; -} - -.news-item-text a:hover:after { - bottom: 0px; - height: 100%; -} - -.news-item-text strong { - font-weight: normal; - color: var(--fg-highlight); -} - -.news-item-text li:not(first-child) { - margin-top: 1em; -} - -.character-special-attribute-value { - padding-left: 2ch; - width: 2ch; - text-align: right; -} -.character-special-attribute-value.out-of-range { - color: var(--fg-highlight); -} - -.character-special-attribute-dec button, -.character-special-attribute-inc button { - border: none; - background: transparent; - color: var(--fg01); -} - -.character-special-attribute-dec button:not(:disabled):hover, -.character-special-attribute-inc button:not(:disabled):hover { - color: var(--fg-highlight); - background: var(--bg02); -} - -.character-special-attribute-dec { - padding-right: 20px; -} - -.character-special-attribute-inc { - padding-left: 20px; -} - -#character-stats-list { - margin-top: 40px; -} - -#fight-back-button { - margin-top: 40px; -} - -#message-back-button { - margin-top: 40px; -} - -#create-char-button { - margin-top: 40px; -} - -#next-tick, -#server-tick { - color: var(--fg03); - height: 1em; - padding-left: 10px; -} - -#next-tick { - margin-top: 20px; -} - -#server-tick { - margin-top: 10px; -} - -#map { - position: relative; - width: calc(var(--map-columns) * var(--map-cell-size)); - height: calc(var(--map-rows) * var(--map-cell-size)); - background-color: black; - background-image: url('../images/map_whole.png'); - background-position: 0 0; - background-repeat: no-repeat; - user-select: none; -} -#map.admin-map { - margin-top: 1em; -} - -#admin-last-ten-msgs-table td { - white-space: nowrap; - padding-right: 2ch; -} - -#map-cost-info { - transform: translate( - calc(var(--map-cell-size) * (0.5 + var(--tile-coord-x)) - 50%), - calc(var(--map-cell-size) * var(--tile-coord-y) - 100% - 10px) - ); - width: min-content; - white-space: nowrap; - padding: 20px; - background-color: var(--bg01); - color: var(--bad-path-color, var(--fg02)); - position: relative; - z-index: 3; -} - -#map-mouse-layer { - left: 0; - top: 0; - right: 0; - bottom: 0; - position: absolute; -} - -#map-mouse-layer.too-distant, -#map-mouse-layer.not-all-passable { - --bad-path-color: var(--fg-highlight); -} - -#map-tiles { - display: grid; - grid-template-columns: repeat(var(--map-columns), var(--map-cell-size)); - grid-template-rows: repeat(var(--map-rows), var(--map-cell-size)); -} - -#map-mouse-event-catcher { - z-index: 4; - left: 0; - top: 0; - right: 0; - bottom: 0; - position: absolute; -} - -.tile { - position: absolute; - left: 0; - top: 0; - width: var(--map-cell-size); - height: var(--map-cell-size); - transform: translate( - calc(var(--map-cell-size) * var(--tile-coord-x)), - calc(var(--map-cell-size) * var(--tile-coord-y)) - ); -} - -#map-path-tiles { - left: 0; - top: 0; - right: 0; - bottom: 0; - position: absolute; -} - -.map-path-tile { - background: var(--bad-path-color,var(--fg03)); - opacity: 0.5; - pointer-events: none; - z-index: 1; -} - -#map-mouse-tile { - background: var(--bad-path-color,var(--fg03)); - opacity: 0.75; - pointer-events: none; - z-index: 1; -} - -#map-locations { - position: absolute; - left: 0; - top: 0; - right: 0; - bottom: 0; - background-color: rgba(0,0,0,0.25); -} - -.map-location { - color: var(--fg01); - opacity: 0.5; -} -.map-location.has-vendor { opacity: 1; } -.map-location.is-current { opacity: 1; } -.map-location:hover { opacity: 1; } - -.map-location.small { - --location-border-width: 1px; - --location-size: 11px; - --location-name-top: 68%; -} - -.map-location.middle { - --location-border-width: 1px; - --location-size: 23px; - --location-name-top: 75%; -} - -.map-location.large { - --location-border-width: 2px; - --location-size: 45px; - --location-name-top: 100%; -} - -.map-location:before { - position: absolute; - top: 50%; - left: 50%; - content: ''; - display: block; - width: var(--location-size); - height: var(--location-size); - border: var(--location-border-width) solid var(--fg01); - border-radius: 50%; - background: radial-gradient(circle, - var(--fg01-fully-transparent) 0%, - var(--fg01-half-transparent) 100%); - transform: translate(-50%, -50%); -} - -.map-location:after { - content: attr(data-location-name); - display: block; - top: var(--location-name-top); - left: 50%; - transform: translate(-50%, 0); - text-align: center; - position: absolute; - white-space: nowrap; - background-color: rgba(0,0,0,0.25); - padding: 0 4px; - line-height: 13px; - text-shadow: 2px 0 2px #000, 0 2px 2px #000, -2px 0 2px #000, 0 -2px 2px #000; -} - - -.map-marker { - position: absolute; - left: 0; - top: 0; - transform: translate( - calc(var(--map-cell-size) * (0.5 + var(--player-coord-x)) - 50%), - calc(var(--map-cell-size) * (0.5 + var(--player-coord-y)) - 50%) - ); - z-index: 2; -} - -.fight-log-action strong { - color: var(--fg-highlight); -} - -.fight-info { - margin-top: 40px; -} - -#import-textarea { - border: none; - background-color: var(--bg02); - width: 80ch; - height: 20em; - margin-bottom: 1em; -} - -#town-store-grid { - margin-top: 40px; - align-self: stretch; - display: grid; - grid-template-columns: repeat(4, 1fr); - grid-template-areas: - "player-name player-name vendor-name vendor-name" - "player-kept-caps player-traded-caps vendor-traded-caps vendor-kept-caps" - "player-kept-items player-traded-items vendor-traded-items vendor-kept-items" - "barter-reset-btn player-traded-value vendor-traded-value barter-confirm-btn"; -} - -#town-store-reset-btn { - grid-area: barter-reset-btn; -} -#town-store-confirm-btn { - grid-area: barter-confirm-btn; -} -#town-store-player-name { - grid-area: player-name; - padding: 8px; -} -#town-store-vendor-name { - grid-area: vendor-name; - text-align: right; - padding: 8px; -} -#town-store-player-name, -#town-store-vendor-name { - border-bottom: 2px solid var(--bg02); -} -#town-store-player-traded-value { - grid-area: player-traded-value; - color: var(--fg01); - text-align: center; -} -#town-store-vendor-traded-value { - grid-area: vendor-traded-value; - color: var(--fg01); - text-align: center; -} -.town-store-transfer-btn { - padding: 2px 4px; - margin: 0 4px; - background: var(--bg02); - color: var(--fg02); -} -.town-store-transfer-btn:disabled { - color: var(--fg03); - opacity: 0.5; - pointer-events: none; -} -.town-store-transfer-btn:not(:disabled):hover { - background: var(--fg03); - color: var(--fg01); -} -.town-store-transfer-btn.hidden { - display: none; -} - -.town-store-item { - display: flex; - align-items: center; -} - -.town-store-item-label { - flex: 1; -} - -.player-traded-caps .town-store-item-label, -.vendor-kept-caps .town-store-item-label, -.vendor-kept-item .town-store-item-label, -.player-traded-item .town-store-item-label { - margin-left: 4px; -} - -.town-store-item, -#town-store-player-traded-value, -#town-store-vendor-traded-value { - padding: 8px; -} - -#town-store-player-traded-bg { - grid-area: 2 / 2 / 5 / 3; - background-color: var(--bg02-half-transparent); - border-right: 1px solid var(--bg02); -} -#town-store-vendor-traded-bg { - grid-area: 2 / 3 / 5 / 4; - background-color: var(--bg02-half-transparent); - border-left: 1px solid var(--bg02); -} - -.town-store-item.player-kept-caps { grid-area: player-kept-caps; } -.town-store-item.player-traded-caps { grid-area: player-traded-caps; } -.town-store-item.vendor-kept-caps { grid-area: vendor-kept-caps; } -.town-store-item.vendor-traded-caps { grid-area: vendor-traded-caps; } - -.town-store-caps { - padding-top: 4px; - padding-bottom: 8px; -} -.town-store-caps[data-caps="0"] { - color: var(--fg03); -} - -#town-store-player-kept-items { grid-area: player-kept-items; } -#town-store-player-traded-items { grid-area: player-traded-items; } -#town-store-vendor-kept-items { grid-area: vendor-kept-items; } -#town-store-vendor-traded-items { grid-area: vendor-traded-items; } - -#town-store-player-traded-value { grid-area: player-traded-value; } -#town-store-vendor-traded-value { grid-area: vendor-traded-value; } - -#town-store-barter-message { - margin-top: 40px; - color: var(--fg-highlight); -} - -.town-store-transfer-n-area { - display: flex; -} -.town-store-transfer-n-area .after-hover { display: none; } -.town-store-transfer-n-area:hover .after-hover { display: block; } -.town-store-transfer-n-area .before-hover { display: block; } -.town-store-transfer-n-area:hover .before-hover { display: none; } -.town-store-transfer-n-input { - width: 5.5ch; - background-color: var(--bg02); - padding-left: 6px; -} - -.character-skills-skill { - display: flex; - flex-direction: row; - justify-content: space-between; -} -.character-skills-skill:hover, -.character-skills-skill:hover .character-skill-tag-btn, -.character-skills-skill:hover .character-skill-inc-btn { - color: var(--fg01); -} -.character-skills-skill.is-taggable { - cursor: pointer; -} -.character-skills-skill.not-useful { - opacity: 0.5; -} -.character-skills-skill.is-tagged, -.character-skills-skill.is-tagged .character-skill-tag-btn , -.character-skills-skill.is-tagged .character-skill-inc-btn { - color: var(--fg-highlight); -} -.character-skill-tag-btn { - white-space: pre; - margin-right: 1ch; -} -.character-skill-inc-btn { - white-space: pre; - margin-left: 1ch; -} -#character-skills.cannot-inc .character-skill-inc-btn { - opacity: 0.5; -} -.character-skill-value { - display: flex; -} -.character-skill-percent { - padding-left: 2ch; - width: 4ch; - text-align: right; -} -#character-skills-list { - width: max-content; - padding: 0; -} - -.new-character-traits-trait { - display: flex; - flex-direction: row; - justify-content: flex-start; - cursor: pointer; -} -.new-character-traits-trait:hover, -.new-character-traits-trait:hover .new-character-trait-tag-btn { - color: var(--fg01); -} -.new-character-traits-trait.is-toggled, -.new-character-traits-trait.is-toggled .new-character-trait-tag-btn { - color: var(--fg-highlight); -} -.new-character-trait-tag-btn { - white-space: pre; - margin-right: 1ch; -} -#new-character-traits-list { - width: max-content; - padding: 0; - display: grid; - grid-template-columns: repeat(2, 1fr); -} - -#new-character-grid, -#character-grid { - display: grid; - grid-template-columns: repeat(3, 1fr); - grid-gap: 20px; -} - -#new-character-traits, -#character-traits, -#character-perks { - margin-top: 40px; -} - -#new-character-notes p { - max-width: none; - color: var(--fg03); -} - -#new-character-create-btn { - margin-top: 40px; -} - -.new-character-section-title, -.character-section-title { - color: var(--fg03); - margin-top: 0; -} -.new-character-section-available-number, -.character-section-available-number { - color: var(--fg-highlight); -} - -#new-character-special p, -#new-character-traits p, -#new-character-skills p { - color: var(--fg03); -} - -#new-character-error { - color: var(--fg-highlight); - margin-top: 20px; -} - -#new-character-help, -#character-help { - margin-top: 20px; -} - -.inventory-item button { - margin-right: 1ch; -} -.inventory-item button:last-child { - margin-right: 2ch; -} -.inventory-item-use-btn:disabled { - color: var(--fg03); -} -.inventory-equipment-unequip-btn { - margin-left: 1ch; -} - -.character-choose-perk-item { - cursor: pointer; -} - -.character-choose-perk-item:hover { - color: var(--fg-highlight); -} - -#character-choose-perk { - flex: 1; - display: flex; - flex-direction: column; - align-self: stretch; -} - -#character-choose-perk-columns { - flex: 1; - display: grid; - grid-template-columns: repeat(2, 1fr); -} - -.hovered-item-title { - margin-top: 0; - color: var(--fg-highlight); -} - -#about-content strong { - color: var(--fg-highlight); -} - -#about-content p { - margin-top: 0; -} - -#fight-stats-table th, -#fight-stats-table td { - text-align: right; -} - -.fight-strategy-grid { - display: grid; - grid-template-areas: - "examples info" - "textarea info"; - --textarea-margin-top: 16px; - --textarea-padding: 16px; - --textarea-line-height: 18px; -} -.fight-strategy-examples { - grid-area: examples; -} -.fight-strategy-example { - text-transform: none; -} -.fight-strategy-example:before { - content: '['; -} -.fight-strategy-example:after { - content: ']'; -} -.fight-strategy-textarea { - background-color: var(--bg02); - grid-area: textarea; - width: 70ch; - height: 25em; - margin-top: var(--textarea-margin-top); - margin-bottom: 16px; - padding: var(--textarea-padding); - border-radius: 4px; - font-size: 16px; - line-height: var(--textarea-line-height); - white-space: pre; - font-family: "PixelOperatorMono"; -} -.fight-strategy-hovered-error { - pointer-events: none; - user-select: none; - border-bottom: 2px; - width: 3ch; - height: 1em; - background-color: var(--fg-highlight-transparent); - margin-left: -2px; - padding-left: 2px; - border-left: 2px solid var(--fg-highlight); - background: var(--fg-highlight); - background: linear-gradient(90deg, var(--fg-highlight-transparent) 0%, var(--fg-highlight-fully-transparent) 100%); - grid-area: textarea; - font-size: 16px; - line-height: var(--textarea-line-height); - transform: translate( - calc((var(--error-col) - 1) * 1ch + var(--textarea-padding)), - calc((var(--error-row) - 1) * var(--textarea-line-height) + var(--textarea-padding) + var(--textarea-margin-top)) - ); - -} -.fight-strategy-info { - grid-area: info; - margin-left: 16px; -} -.fight-strategy-info-paragraph { - margin-top: 16px; -} -.fight-strategy-info-link { - color: var(--fg01); -} -.fight-strategy-info-link:hover { - color: var(--fg-highlight); -} -.fight-strategy-help-btn { - margin-left: 1ch; -} - -.fight-strategy-reset-btn { - margin-left: 1ch; -} -.fight-strategy-dead-ends { - margin: 0; - padding: 0; - list-style: none; -} -.fight-strategy-dead-end:hover { - color: var(--fg01); -} -.fight-strategy-warnings { - margin: 0; - padding: 0; - list-style: none; -} -.fight-strategy-warning:hover { - color: var(--fg01); -} -.fight-strategy-syntax-help { -} -.fight-strategy-syntax-help-reference { - color: var(--fg-highlight); - font-family: "PixelOperatorMono"; -} -.fight-strategy-syntax-help-grid { - display: grid; - grid-template-areas: 'cheatsheet hover'; -} -.fight-strategy-syntax-help-cheatsheet { - grid-area: cheatsheet; - font-family: "PixelOperatorMono"; -} -.fight-strategy-syntax-help-hover { - grid-area: hover; - margin-left: 2ch; -} -.fight-strategy-syntax-help-hover-description { - white-space: pre-wrap; -} -#admin-new-world-form { - margin-top: 1em; - display: flex; - flex-direction: column; - align-items: flex-start; -} -#admin-new-world-form label input[type="checkbox"] { - margin-right: 1ch; -} -.quests { - list-style: none; -} -.quest { - padding-left: 16px; -} -.quest:before { - content: '[+]'; - padding-right: 8px; - color: var(--fg02); -} -.quest:not(.expanded) { - cursor: pointer; -} -.quest:not(.expanded):hover, -.quest:not(.expanded):hover:before { - color: var(--fg01); -} -.quest.expanded:before { - content: '[-]'; -} -.quest-inner { - display: inline-block; - vertical-align: top; -} -.quest.expanded:not(:last-child) { - margin-bottom: 20px; -} -.quest-players { - color: var(--fg03); -} -.quest-number { - color: var(--fg02); -} -.quest-name { - cursor: pointer; -} -.quest-name:hover { - color: var(--fg01); -} -.quest-progressbar { - color: var(--fg03); - margin-top: 20px; -} -.quest-progressbar-text { - margin-left: 1ch; -} -.quest-toggle-btn { - margin-left: 1ch; -} -.quest-toggle-btn:hover { - color: var(--fg-highlight); -} -.quest-requirements-title { - margin-top: 20px; -} -.quest-requirements-list { - padding-inline-start: 4ch; -} -.quest-requirements-none { - margin-left: 4ch; - color: var(--fg03); -} -.quest-xp-per-tick { - color: var(--fg03); -} diff --git a/public/styles/defaults.css b/public/styles/defaults.css new file mode 100644 index 00000000..83d05b73 --- /dev/null +++ b/public/styles/defaults.css @@ -0,0 +1,116 @@ +:root { + --green-900: #111810; + --green-800: #10240C; + + --green-300: #007C00; + --green-200: #00C000; + --green-100: #3CF800; + + + --orange: #FCFF2F; + --red: #FC0001; + + --green-800-half-transparent: rgba(16, 36, 12, 0.5); + --green-300-half-transparent: rgba(0, 124, 0, 0.5); + + --green-100-half-transparent: rgba(60, 248, 0, 0.5); + --green-100-fully-transparent: rgba(60, 248, 0, 0); + + --orange-transparent: rgba(252, 253, 125, 0.25); + --orange-fully-transparent: rgba(252, 253, 125, 0); + --black-transparent: rgba(0, 0, 0, 0.25); + /* + Greens: + Fallout 2 character select screen: #5BF523 + Fallout Tactics custom campaign: #4AFC24 + + Oranges: + Fallout Tactics custom campaign: #FCFF2F + */ +} + +body { + background-color: var(--green-900); + color: var(--green-200); + display: flex; + height: 100vh; + width: 100vw; +} + +* { + font-family: "PixelOperator"; + line-height: 17px; + font-size: 16px; + font-weight: normal; + + font-smooth: never; + -webkit-font-smoothing: none; + -moz-osx-font-smoothing: none; + + text-wrap: pretty; +} + +/* VIGNETTE CORNERS */ +body:after { + position: fixed; + content: ''; + left: 0; + right: 0; + top: 0; + bottom: 0; + z-index: 1; + border-style: solid; + border-width: 128px; + border-color: transparent; + border-image: url('../images/border-image.webp') 50% repeat; + box-sizing: border-box; + pointer-events: none; +} + +::placeholder { + color: var(--green-300) !important; +} + +/* To remove this style we'd have to use Dillon's Markdown package. Too lazy right now */ +strong { + font-weight: 400 !important; + color: var(--orange) !important; +} + +/* Tables */ +table { + text-align: left; + border-collapse: collapse; +} + +thead { + border-bottom: 3px solid var(--green-300-half-transparent); + color: var(--green-300); +} + +th { + padding-left: 8px; + padding-right: 8px; + padding-top: 4px; + padding-bottom: 4px; + font-weight: 400; +} + +th:not(:first-child) { + border-left: 3px solid var(--green-300-half-transparent); +} + +td { + padding-left: 8px; + padding-right: 8px; + padding-top: 2px; + padding-bottom: 2px; +} + +td:not(:first-child) { + border-left: 1px solid var(--green-300-half-transparent); +} + +tr:hover td { + background-color: var(--green-800); +} \ No newline at end of file diff --git a/public/styles/fonts.css b/public/styles/fonts.css new file mode 100644 index 00000000..14c39c47 --- /dev/null +++ b/public/styles/fonts.css @@ -0,0 +1,22 @@ +@font-face { + font-family: "PixelOperator"; + font-weight: 400; + src: url("../fonts/PixelOperator.ttf") format('truetype'); +} + +@font-face { + font-family: "PixelOperator"; + font-weight: 700; + src: url("../fonts/PixelOperatorHB.ttf") format('truetype'); +} + +@font-face { + font-family: "PixelOperator"; + font-weight: 900; + src: url("../fonts/PixelOperatorHBSC.ttf") format('truetype'); +} + +@font-face { + font-family: "PixelOperatorMono"; + src: url("../fonts/PixelOperatorMonoHB.ttf") format('truetype'); +} \ No newline at end of file diff --git a/public/styles/links.css b/public/styles/links.css new file mode 100644 index 00000000..52222160 --- /dev/null +++ b/public/styles/links.css @@ -0,0 +1,39 @@ +.link { + color: var(--green-300); + cursor: pointer; + text-decoration: none; + display: block; + text-align: left; +} + +.link-label { + color: var(--green-100); + text-transform: uppercase; + width: 9ch; + min-width: 9ch; + display: inline-block; + margin: 0 1ch; + white-space: pre; +} + +.link[target="_blank"] .link-right-bracket::before { + content: "-> "; + color: var(--green-300); + margin-left: -2ch; +} + +.link.active .link-label, +.link:hover, +.link:hover .link-label { + color: var(--orange); +} + +.link.dimmed:not(:hover):not(.active) .link-label { + color: var(--green-300); +} + +.link:disabled .link-left-bracket, +.link:disabled .link-right-bracket, +.link:disabled .link-label { + color: var(--green-300); +} \ No newline at end of file diff --git a/public/styles/loading-cursor.css b/public/styles/loading-cursor.css new file mode 100644 index 00000000..482d9d57 --- /dev/null +++ b/public/styles/loading-cursor.css @@ -0,0 +1,18 @@ +.loading-cursor { + animation: cursor-blink 1.5s linear infinite; +} + +@keyframes cursor-blink { + + 0%, + 10%, + 90%, + 100% { + background: var(--green-200); + } + + 30%, + 70% { + background: transparent; + } +} \ No newline at end of file diff --git a/public/styles/logo-filter.css b/public/styles/logo-filter.css new file mode 100644 index 00000000..4b17663a --- /dev/null +++ b/public/styles/logo-filter.css @@ -0,0 +1,54 @@ +:root { + /* Calculated with https://codepen.io/sosuke/pen/Pjoqqp */ + --filter-logo-inactive: invert(42%) sepia(85%) saturate(1707%) hue-rotate(88deg) brightness(102%) contrast(112%); + --filter-logo-active: invert(71%) sepia(54%) saturate(3327%) hue-rotate(60deg) brightness(106%) contrast(118%) drop-shadow(0px 0px 8px var(--green-300)); +} + +/* Safari hack courtesy https://browserstrangeness.github.io/ + +Disable the flicker animation in Safari, since it behaves very weird and +doesn't look as nice as in Chrome/Firefox. +*/ +_::-webkit-full-page-media, +_:future, +:root .filter-logo-active { + animation: none; +} + +@keyframes flicker { + + 0%, + 19%, + 26%, + 46%, + 65%, + 82%, + 86%, + 87%, + 90%, + 95% { + filter: var(--filter-logo-inactive); + } + + 20%, + 25%, + 47%, + 64%, + 83%, + 85%, + 88%, + 89%, + 96%, + 100% { + filter: var(--filter-logo-active); + } +} + +.filter-logo-inactive { + filter: var(--filter-logo-inactive); +} + +.filter-logo-active { + filter: var(--filter-logo-active); + animation: flicker 2s linear 1; +} \ No newline at end of file diff --git a/public/styles/select.css b/public/styles/select.css new file mode 100644 index 00000000..1b451f84 --- /dev/null +++ b/public/styles/select.css @@ -0,0 +1,20 @@ +/* select+option taken mainly from https://codepen.io/5t3ph/pen/MWyyYNz */ +.select-wrapper { + grid-template-areas: "select"; +} + +.select-wrapper::after { + grid-area: select; + content: "^" !important; +} + +.select { + grid-area: select; + font-size: inherit; + cursor: inherit; + line-height: inherit; +} + +.select::-ms-expand { + display: none; +} \ No newline at end of file diff --git a/public/styles/town-store.css b/public/styles/town-store.css new file mode 100644 index 00000000..f920b82b --- /dev/null +++ b/public/styles/town-store.css @@ -0,0 +1,7 @@ +.town-store-grid { + grid-template-areas: + "player-name player-name vendor-name vendor-name" + "player-kept-caps player-traded-caps vendor-traded-caps vendor-kept-caps" + "player-kept-items player-traded-items vendor-traded-items vendor-kept-items" + "barter-reset-btn player-traded-value vendor-traded-value barter-confirm-btn"; +} \ No newline at end of file diff --git a/src/Admin.elm b/src/Admin.elm index 58a4fc65..a5cf9722 100644 --- a/src/Admin.elm +++ b/src/Admin.elm @@ -4,6 +4,7 @@ module Admin exposing , encodeToBackendMsg ) +import BiDict import Data.Auth as Auth import Data.Barter as Barter import Data.FightStrategy as FightStrategy @@ -44,11 +45,12 @@ backendModelDecoderV1 seed = JD.map (\world -> { worlds = Dict.singleton Logic.mainWorldName world - , loggedInPlayers = Dict.empty + , loggedInPlayers = BiDict.empty , time = Time.millisToPosix 0 , adminLoggedIn = Nothing , lastTenToBackendMsgs = Queue.empty , randomSeed = seed + , playerDataCache = Dict.empty } ) World.decoder @@ -60,11 +62,12 @@ backendModelDecoderV2 seed = JD.map (\worlds -> { worlds = worlds - , loggedInPlayers = Dict.empty + , loggedInPlayers = BiDict.empty , time = Time.millisToPosix 0 , adminLoggedIn = Nothing , lastTenToBackendMsgs = Queue.empty , randomSeed = seed + , playerDataCache = Dict.empty } ) (JD.field "worlds" (Dict.decoder JD.string World.decoder)) diff --git a/src/Backend.elm b/src/Backend.elm index 89ad10bd..90f5deb4 100644 --- a/src/Backend.elm +++ b/src/Backend.elm @@ -3,6 +3,7 @@ module Backend exposing (..) import Admin import AssocList as Dict_ import AssocSet as Set_ +import BiDict import Cmd.Extra as Cmd import Data.Auth as Auth exposing @@ -52,6 +53,7 @@ import Http import Json.Decode as JD import Json.Encode as JE import Lamdera exposing (ClientId, SessionId) +import Lamdera.Hash import List.Extra as List import Logic import Queue @@ -81,10 +83,11 @@ init : ( Model, Cmd BackendMsg ) init = ( { worlds = Dict.singleton Logic.mainWorldName (World.init { fast = False }) , time = Time.millisToPosix 0 - , loggedInPlayers = Dict.empty + , loggedInPlayers = BiDict.empty , adminLoggedIn = Nothing , lastTenToBackendMsgs = Queue.empty , randomSeed = Random.initialSeed 0 + , playerDataCache = Dict.empty } , Task.perform FirstTick Time.now ) @@ -138,13 +141,13 @@ getAdminData model = getLoggedInPlayers : Model -> Dict World.Name (List PlayerName) getLoggedInPlayers model = model.loggedInPlayers - |> Dict.values - |> List.gatherEqualsBy .worldName + |> BiDict.values + |> List.gatherEqualsBy Tuple.first |> List.map - (\( first, rest ) -> - ( first.worldName + (\( ( worldName, _ ) as first, rest ) -> + ( worldName , (first :: rest) - |> List.map .playerName + |> List.map Tuple.second ) ) |> Dict.fromList @@ -305,7 +308,7 @@ update msg model = ) Disconnected _ clientId -> - ( { model | loggedInPlayers = Dict.remove clientId model.loggedInPlayers } + ( { model | loggedInPlayers = BiDict.remove clientId model.loggedInPlayers } , Cmd.none ) @@ -389,17 +392,38 @@ update msg model = ) |> Cmd.andThen (\m -> - ( m - , model.loggedInPlayers - |> Dict.toList - |> List.filter (\( _, r ) -> r.worldName == worldName) - |> List.filterMap - (\( clientId, { playerName } ) -> - getPlayerData worldName playerName m - |> Maybe.map (Lamdera.sendToFrontend clientId << CurrentPlayer) + model.loggedInPlayers + |> BiDict.toReverseList + |> List.filter (\( ( wn, _ ), _ ) -> wn == worldName) + |> List.foldl + (\( ( wn, pn ), clientIds ) accOuter -> + case getPlayerData wn pn m of + Nothing -> + accOuter + + Just playerData_ -> + let + newHash : Int + newHash = + Lamdera.Hash.hash + Types.w3_encode_PlayerData_ + playerData_ + in + clientIds + |> Set.toList + |> List.foldl + (\clientId accInner -> + if Lamdera.Hash.hasChanged newHash clientId model.playerDataCache then + accInner + |> Tuple.mapFirst (saveToPlayerDataCache clientId newHash) + |> Cmd.withCmd (Lamdera.sendToFrontend clientId (CurrentPlayer playerData_)) + + else + accInner + ) + accOuter ) - |> Cmd.batch - ) + ( m, Cmd.none ) ) in ( newModel, Cmd.batch [ cmd, newCmd ] ) @@ -413,6 +437,11 @@ update msg model = ( model, Cmd.none ) +saveToPlayerDataCache : ClientId -> Int -> Model -> Model +saveToPlayerDataCache clientId newHash model = + { model | playerDataCache = Dict.insert clientId newHash model.playerDataCache } + + processGameTick : World.Name -> Model -> ( Model, Cmd BackendMsg ) processGameTick worldName model = -- TODO refresh the affected users that are logged-in? @@ -480,9 +509,9 @@ withLoggedInPlayer_ : -> (ClientId -> World -> World.Name -> Player SPlayer -> Model -> ( Model, Cmd BackendMsg )) -> ( Model, Cmd BackendMsg ) withLoggedInPlayer_ model clientId fn = - Dict.get clientId model.loggedInPlayers + BiDict.get clientId model.loggedInPlayers |> Maybe.andThen - (\{ worldName, playerName } -> + (\( worldName, playerName ) -> Dict.get worldName model.worlds |> Maybe.map (\world -> ( world, worldName, playerName )) ) @@ -518,9 +547,10 @@ logAndUpdateFromFrontend_ : SessionId -> ClientId -> ToBackend -> Model -> ( Mod logAndUpdateFromFrontend_ sessionId clientId msg model = let logMsgCmd = - Dict.get clientId model.loggedInPlayers + -- TODO rethink this, something something Event Sourcing? Or maybe indeed just log all *Msgs somewhere and build tooling on being able to play it back + BiDict.get clientId model.loggedInPlayers |> Maybe.map - (\{ playerName, worldName } -> + (\( worldName, playerName ) -> Http.request { method = "POST" , url = "https://janiczek-nuashworld.builtwithdark.com/log-backend" @@ -541,15 +571,9 @@ logAndUpdateFromFrontend_ sessionId clientId msg model = ) |> Maybe.withDefault Cmd.none - playerName_ = - Dict.get clientId model.loggedInPlayers - |> Maybe.map .playerName - |> Maybe.withDefault "anonymous" - - worldName_ = - Dict.get clientId model.loggedInPlayers - |> Maybe.map .worldName - |> Maybe.withDefault "-" + ( worldName_, playerName_ ) = + BiDict.get clientId model.loggedInPlayers + |> Maybe.withDefault ( "-", "anonymous" ) modelWithLoggedMsg = if isAdminMsg msg then @@ -623,9 +647,9 @@ updateFromFrontend sessionId clientId msg model = (ClientId -> World -> World.Name -> SPlayer -> Model -> ( Model, Cmd BackendMsg )) -> ( Model, Cmd BackendMsg ) withLoggedInCreatedPlayer fn = - Dict.get clientId model.loggedInPlayers + BiDict.get clientId model.loggedInPlayers |> Maybe.andThen - (\{ worldName, playerName } -> + (\( worldName, playerName ) -> Dict.get worldName model.worlds |> Maybe.andThen (\world -> @@ -703,11 +727,12 @@ updateFromFrontend sessionId clientId msg model = |> Maybe.map (\data -> let - ( loggedOutPlayers, otherPlayers ) = - -- We log this clientId in, but we log their other browser out. - Dict.partition - (\_ names -> names.worldName == auth.worldName && names.playerName == auth.name) - model.loggedInPlayers + names = + ( auth.worldName, auth.name ) + + clientIdsToLogout : Set ClientId + clientIdsToLogout = + BiDict.getReverse names model.loggedInPlayers loggedOutData = getWorlds model @@ -715,20 +740,18 @@ updateFromFrontend sessionId clientId msg model = newModel = { model | loggedInPlayers = - Dict.insert - clientId - { worldName = auth.worldName - , playerName = auth.name - } - otherPlayers + model.loggedInPlayers + |> -- TODO: BiDict.removeReverse would be nice + BiDict.filter (\_ names_ -> names_ /= names) + |> BiDict.insert clientId names } in ( newModel , Cmd.batch <| (Lamdera.sendToFrontend clientId <| YoureLoggedIn data) :: refreshAdminLoggedInPlayers newModel - :: (loggedOutPlayers - |> Dict.keys + :: (clientIdsToLogout + |> Set.toList |> List.map (\cId -> Lamdera.sendToFrontend cId <| YoureLoggedOut loggedOutData) ) ) @@ -777,13 +800,7 @@ updateFromFrontend sessionId clientId msg model = newModel = { model - | loggedInPlayers = - Dict.insert - clientId - { worldName = auth.worldName - , playerName = auth.name - } - model.loggedInPlayers + | loggedInPlayers = BiDict.insert clientId ( auth.worldName, auth.name ) model.loggedInPlayers , worlds = model.worlds |> Dict.insert auth.worldName newWorld } @@ -807,7 +824,7 @@ updateFromFrontend sessionId clientId msg model = { model | adminLoggedIn = Nothing } else - { model | loggedInPlayers = Dict.remove clientId model.loggedInPlayers } + { model | loggedInPlayers = BiDict.remove clientId model.loggedInPlayers } world = getWorlds newModel @@ -860,16 +877,24 @@ updateFromFrontend sessionId clientId msg model = ) else - case Dict.get clientId model.loggedInPlayers of + case BiDict.get clientId model.loggedInPlayers of Nothing -> loggedOut () - Just { worldName, playerName } -> + Just (( worldName, playerName ) as worldAndPlayer) -> + let + clientIds : Set ClientId + clientIds = + BiDict.getReverse worldAndPlayer model.loggedInPlayers + in getPlayerData worldName playerName model |> Maybe.map (\data -> ( model - , Lamdera.sendToFrontend clientId <| CurrentPlayer data + , clientIds + |> Set.toList + |> List.map (\cId -> Lamdera.sendToFrontend cId <| CurrentPlayer data) + |> Cmd.batch ) ) |> Maybe.withDefault (loggedOut ()) diff --git a/src/Calculator/BarterPrice.elm b/src/Calculator/BarterPrice.elm index 000172b3..611c4fa9 100644 --- a/src/Calculator/BarterPrice.elm +++ b/src/Calculator/BarterPrice.elm @@ -139,7 +139,9 @@ view model = , H.text "Do you have the Master Trader perk?" ] , H.div [ HA.id "final-price" ] - [ H.strong [] [ H.text "Final price: " ] + [ H.span + [ HA.class "text-orange" ] + [ H.text "Final price: " ] , H.text <| case maybePrice of Nothing -> diff --git a/src/Cmd/Extra.elm b/src/Cmd/Extra.elm index 6b578739..44e43228 100644 --- a/src/Cmd/Extra.elm +++ b/src/Cmd/Extra.elm @@ -1,4 +1,4 @@ -module Cmd.Extra exposing (andThen) +module Cmd.Extra exposing (andThen, withCmd) andThen : (model -> ( model, Cmd msg )) -> ( model, Cmd msg ) -> ( model, Cmd msg ) @@ -10,3 +10,10 @@ andThen fn ( model, oldCmd ) = ( newModel , Cmd.batch [ oldCmd, newCmd ] ) + + +withCmd : Cmd msg -> ( model, Cmd msg ) -> ( model, Cmd msg ) +withCmd newCmd ( model, oldCmd ) = + ( model + , Cmd.batch [ newCmd, oldCmd ] + ) diff --git a/src/Data/Auth.elm b/src/Data/Auth.elm index c452777e..b76b291c 100644 --- a/src/Data/Auth.elm +++ b/src/Data/Auth.elm @@ -210,6 +210,14 @@ selectDefaultWorld worlds auth = { auth | worldName = worlds + |> List.sortBy + (\world -> + if world.name == Logic.mainWorldName then + 0 + + else + 1 + ) |> List.head |> Maybe.map .name |> Maybe.withDefault auth.worldName diff --git a/src/Data/Fight.elm b/src/Data/Fight.elm index dec1fa1d..7ec0fc94 100644 --- a/src/Data/Fight.elm +++ b/src/Data/Fight.elm @@ -12,6 +12,7 @@ module Data.Fight exposing , isAttack , isCriticalAttack , isMiss + , isNPC , isPlayer , opponentName , opponentXp @@ -566,6 +567,16 @@ isPlayer opponentType = True +isNPC : OpponentType -> Bool +isNPC opponentType = + case opponentType of + Npc _ -> + True + + Player _ -> + False + + attackDamage : Action -> Int attackDamage action = case action of diff --git a/src/Data/Fight/Generator.elm b/src/Data/Fight/Generator.elm index cf70f1d7..f246e5da 100644 --- a/src/Data/Fight/Generator.elm +++ b/src/Data/Fight/Generator.elm @@ -1045,6 +1045,9 @@ evalCondition state condition = OpponentIsPlayer -> Fight.isPlayer state.them.type_ + OpponentIsNPC -> + Fight.isNPC state.them.type_ + Operator { op, value, number_ } -> operatorFn op diff --git a/src/Data/Fight/View.elm b/src/Data/Fight/View.elm index 396b93e0..e49f068c 100644 --- a/src/Data/Fight/View.elm +++ b/src/Data/Fight/View.elm @@ -159,7 +159,7 @@ view perceptionLevel fight yourName = Fight.Npc enemyType -> Enemy.aimedShotName enemyType aimedShot in - H.div [ HA.class "fight-info" ] + H.div [ HA.class "flex flex-col gap-4" ] [ fight.log |> List.Extra.groupWhile (\( a, _ ) ( b, _ ) -> a == b) |> List.map @@ -169,147 +169,187 @@ view perceptionLevel fight yourName = names_ = getNames who - name : String -> String - name n = - -- This is then picked up by the CSS - "**" ++ n ++ "**" + highlight : String -> Html msg + highlight n = + H.span + [ HA.class "text-orange" ] + [ H.text n ] other : Who other = Fight.theOther who in H.li [] - [ H.text <| names_.subject.namePossCap ++ " turn" + [ H.span + [ HA.class "text-green-300" ] + [ H.text <| names_.subject.namePossCap ++ " turn" ] , (first :: rest) |> List.map (\( currentActionWho, action ) -> let - action_ : String + action_ : Html msg action_ = case action of Fight.Start { distanceHexes } -> if Perception.atLeast Perception.Great perceptionLevel then - names_.subject.verbPresent "initiate" - ++ " the fight from " - ++ String.fromInt distanceHexes - ++ " hexes away." + H.span [] + [ H.text <| + names_.subject.verbPresent "initiate" + ++ " the fight from " + , highlight <| String.fromInt distanceHexes + , H.text " hexes away." + ] else - names_.subject.verbPresent "initiate" - ++ " the fight." + H.text <| + names_.subject.verbPresent "initiate" + ++ " the fight." Fight.ComeCloser { hexes, remainingDistanceHexes } -> if Perception.atLeast Perception.Great perceptionLevel then - names_.subject.verbPresent "come" - ++ " closer " - ++ String.fromInt hexes - ++ " hexes. Remaining distance: " - ++ String.fromInt remainingDistanceHexes - ++ " hexes." + H.span [] + [ H.text <| + names_.subject.verbPresent "come" + ++ " closer " + , highlight <| String.fromInt hexes + , H.text " hexes. Remaining distance: " + , highlight <| String.fromInt remainingDistanceHexes + , H.text " hexes." + ] else - names_.subject.verbPresent "come" - ++ " closer." + H.text <| + names_.subject.verbPresent "come" + ++ " closer." Fight.Attack { damage, remainingHp, shotType, isCritical } -> - (case shotType of - NormalShot -> - "" - - AimedShot aimed -> - names_.subject.verbPresent "aim" - ++ " for " - ++ aimedShotName other aimed - ++ " and " - ) - ++ (if isCritical then - "critically " - - else - "" - ) - ++ names_.subject.verbPresent "attack" - ++ " " - ++ name names_.object.name - ++ " for " - ++ String.fromInt damage - ++ " damage." - ++ (if currentActionWho /= you || Perception.atLeast Perception.Great perceptionLevel then - " Remaining HP: " - ++ String.fromInt remainingHp - ++ "." - - else - "" - ) + H.span [] + [ H.text <| + (case shotType of + NormalShot -> + "" + + AimedShot aimed -> + names_.subject.verbPresent "aim" + ++ " for " + ++ aimedShotName other aimed + ++ " and " + ) + ++ (if isCritical then + "critically " + + else + "" + ) + ++ names_.subject.verbPresent "attack" + ++ " " + , highlight names_.object.name + , H.text " for " + , highlight <| String.fromInt damage + , H.text " damage." + , if currentActionWho /= you || Perception.atLeast Perception.Great perceptionLevel then + H.span [] + [ H.text " Remaining HP: " + , highlight <| String.fromInt remainingHp + , H.text "." + ] + + else + H.text "" + ] Fight.Miss { shotType } -> - (case shotType of - NormalShot -> - "" - - AimedShot aimed -> - names_.subject.verbPresent "aim" - ++ " for " - ++ aimedShotName other aimed - ++ " and " - ) - ++ names_.subject.verbPresent "attack" - ++ " " - ++ name names_.object.name - ++ " but " - ++ names_.subject.verbPresent "miss" - ++ "." + H.span [] + [ H.text <| + (case shotType of + NormalShot -> + "" + + AimedShot aimed -> + names_.subject.verbPresent "aim" + ++ " for " + ++ aimedShotName other aimed + ++ " and " + ) + ++ names_.subject.verbPresent "attack" + ++ " " + , highlight names_.object.name + , H.text <| + " but " + ++ names_.subject.verbPresent "miss" + ++ "." + ] Fight.Heal r -> - names_.subject.verbPresent "heal" - ++ " with " - ++ Item.name r.itemKind - ++ " for " - ++ String.fromInt r.healedHp - ++ " HP." - ++ (if currentActionWho == you || Perception.atLeast Perception.Great perceptionLevel then - " Current HP: " - ++ String.fromInt r.newHp - ++ "." - - else - "" - ) + H.text <| + names_.subject.verbPresent "heal" + ++ " with " + ++ Item.name r.itemKind + ++ " for " + ++ String.fromInt r.healedHp + ++ " HP." + ++ (if currentActionWho == you || Perception.atLeast Perception.Great perceptionLevel then + " Current HP: " + ++ String.fromInt r.newHp + ++ "." + + else + "" + ) in - H.li [] - [ Markdown.toHtml [ HA.class "fight-log-action" ] <| - name names_.subject.nameCap - ++ " " - ++ action_ + H.li + [ HA.class "ps-[2ch]" ] + [ highlight names_.subject.nameCap + , H.text " " + , action_ ] ) |> H.ul [] ] ) - |> H.ul [] + |> H.ul [ HA.class "flex flex-col gap-4" ] , H.div [] - [ H.text <| - "Result: " - ++ (case fight.result of - Fight.AttackerWon { xpGained, capsGained, itemsGained } -> - if youAreAttacker then - "You won! You gained " - ++ String.fromInt xpGained - ++ " XP and looted " - ++ String.fromInt capsGained - ++ " caps." - ++ (if List.isEmpty itemsGained then - "" - - else - " You also looted " - ++ viewLoot itemsGained - ++ "." - ) - - else - "You lost! Your attacker gained " + [ H.span + [ HA.class "text-green-300" ] + [ H.text "Result: " ] + , H.span [ HA.class "text-green-100" ] + [ H.text <| + case fight.result of + Fight.AttackerWon { xpGained, capsGained, itemsGained } -> + if youAreAttacker then + "You won! You gained " + ++ String.fromInt xpGained + ++ " XP and looted " + ++ String.fromInt capsGained + ++ " caps." + ++ (if List.isEmpty itemsGained then + "" + + else + " You also looted " + ++ viewLoot itemsGained + ++ "." + ) + + else + "You lost! Your attacker gained " + ++ String.fromInt xpGained + ++ " XP and looted " + ++ String.fromInt capsGained + ++ " caps." + ++ (if List.isEmpty itemsGained then + "" + + else + " They also looted " + ++ viewLoot itemsGained + ++ "." + ) + + Fight.TargetWon { xpGained, capsGained, itemsGained } -> + if youAreAttacker then + if Fight.isPlayer fight.target then + "You lost! Your target gained " ++ String.fromInt xpGained ++ " XP and looted " ++ String.fromInt capsGained @@ -323,59 +363,42 @@ view perceptionLevel fight yourName = ++ "." ) - Fight.TargetWon { xpGained, capsGained, itemsGained } -> - if youAreAttacker then - if Fight.isPlayer fight.target then - "You lost! Your target gained " - ++ String.fromInt xpGained - ++ " XP and looted " - ++ String.fromInt capsGained - ++ " caps." - ++ (if List.isEmpty itemsGained then - "" - - else - " They also looted " - ++ viewLoot itemsGained - ++ "." - ) - - else - "You lost!" - - else - "You won! You gained " - ++ String.fromInt xpGained - ++ " XP and looted " - ++ String.fromInt capsGained - ++ " caps." - ++ (if List.isEmpty itemsGained then - "" - - else - " You also looted " - ++ viewLoot itemsGained - ++ "." - ) - - Fight.TargetAlreadyDead -> - if youAreAttacker then - "You wanted to fight them but then realized they're already dead. You feel slightly dumb. (Higher Perception will help you see more info about your opponents.)" - else - attackerName ++ " wanted to fight you but due to their low Perception didn't realize you're already dead. Ashamed, they quickly ran away and will deny this ever happened." - - Fight.BothDead -> - "You both end up dead." - - Fight.NobodyDead -> - "You both get out of the fight alive." - - Fight.NobodyDeadGivenUp -> - "You're both so exhausted by this long fight that you agree to finish this some other time." - ) + "You lost!" + + else + "You won! You gained " + ++ String.fromInt xpGained + ++ " XP and looted " + ++ String.fromInt capsGained + ++ " caps." + ++ (if List.isEmpty itemsGained then + "" + + else + " You also looted " + ++ viewLoot itemsGained + ++ "." + ) + + Fight.TargetAlreadyDead -> + if youAreAttacker then + "You wanted to fight them but then realized they're already dead. You feel slightly dumb. (Higher Perception will help you see more info about your opponents.)" + + else + attackerName ++ " wanted to fight you but due to their low Perception didn't realize you're already dead. Ashamed, they quickly ran away and will deny this ever happened." + + Fight.BothDead -> + "You both end up dead." + + Fight.NobodyDead -> + "You both get out of the fight alive." + + Fight.NobodyDeadGivenUp -> + "You're both so exhausted by this long fight that you agree to finish this some other time." + ] ] - , H.p [] [ H.text "Stats:" ] + , H.span [ HA.class "text-green-300" ] [ H.text "Stats:" ] , let ( yourActions, theirActions ) = List.partition (\( who, _ ) -> who == you) fight.log @@ -455,40 +478,46 @@ view perceptionLevel fight yourName = else (String.fromFloat <| (\x -> x / 100) <| toFloat <| round <| pct * 10000) ++ "%" + + th attrs children = + H.th (HA.class "text-right" :: attrs) children + + td attrs children = + H.td (HA.class "text-right" :: attrs) children in - H.table [ HA.id "fight-stats-table" ] + H.table [ HA.class "w-max" ] [ H.thead [] [ H.tr [] - [ H.td [] [] - , H.th [] [ H.text "You" ] - , H.th [] [ H.text yourOpponentName ] + [ td [] [] + , th [] [ H.text "You" ] + , th [] [ H.text yourOpponentName ] ] ] , H.tbody [] [ H.tr [] - [ H.td [] [ H.text "Total damage" ] - , H.td [] [ H.text <| String.fromInt yourTotalDamage ] - , H.td [] [ H.text <| String.fromInt theirTotalDamage ] + [ td [] [ H.text "Total damage" ] + , td [] [ H.text <| String.fromInt yourTotalDamage ] + , td [] [ H.text <| String.fromInt theirTotalDamage ] ] , H.tr [] - [ H.td [] [ H.text "Hit rate" ] - , H.td [] [ H.text <| formatPercentage yourHitRate ] - , H.td [] [ H.text <| formatPercentage theirHitRate ] + [ td [] [ H.text "Hit rate" ] + , td [] [ H.text <| formatPercentage yourHitRate ] + , td [] [ H.text <| formatPercentage theirHitRate ] ] , H.tr [] - [ H.td [] [ H.text "Critical hit rate" ] - , H.td [] [ H.text <| formatPercentage yourCritRate ] - , H.td [] [ H.text <| formatPercentage theirCritRate ] + [ td [] [ H.text "Critical hit rate" ] + , td [] [ H.text <| formatPercentage yourCritRate ] + , td [] [ H.text <| formatPercentage theirCritRate ] ] , H.tr [] - [ H.td [] [ H.text "Average damage" ] - , H.td [] [ H.text <| formatFloat yourAvgDamage ] - , H.td [] [ H.text <| formatFloat theirAvgDamage ] + [ td [] [ H.text "Average damage" ] + , td [] [ H.text <| formatFloat yourAvgDamage ] + , td [] [ H.text <| formatFloat theirAvgDamage ] ] , H.tr [] - [ H.td [] [ H.text "Max hit" ] - , H.td [] [ H.text <| String.fromInt yourMaxHit ] - , H.td [] [ H.text <| String.fromInt theirMaxHit ] + [ td [] [ H.text "Max hit" ] + , td [] [ H.text <| String.fromInt yourMaxHit ] + , td [] [ H.text <| String.fromInt theirMaxHit ] ] ] ] diff --git a/src/Data/FightStrategy.elm b/src/Data/FightStrategy.elm index 35c0786c..4597130c 100644 --- a/src/Data/FightStrategy.elm +++ b/src/Data/FightStrategy.elm @@ -47,6 +47,7 @@ type Condition | And Condition Condition | Operator OperatorData | OpponentIsPlayer + | OpponentIsNPC type alias OperatorData = @@ -130,6 +131,9 @@ conditionToString condition = OpponentIsPlayer -> "opponent is player" + OpponentIsNPC -> + "opponent is NPC" + Operator { op, value, number_ } -> valueToString value ++ " " @@ -290,6 +294,11 @@ encodeCondition condition = [ ( "type", JE.string "OpponentIsPlayer" ) ] + OpponentIsNPC -> + JE.object + [ ( "type", JE.string "OpponentIsNPC" ) + ] + Operator { op, value, number_ } -> JE.object [ ( "type", JE.string "Operator" ) @@ -400,6 +409,9 @@ conditionDecoder = "OpponentIsPlayer" -> JD.succeed OpponentIsPlayer + "OpponentIsNPC" -> + JD.succeed OpponentIsNPC + "Operator" -> JD.succeed OperatorData |> JD.andMap (JD.field "value" valueDecoder) @@ -576,6 +588,9 @@ extractItems strategy = OpponentIsPlayer -> [] + OpponentIsNPC -> + [] + Operator { value } -> fromValue value in diff --git a/src/Data/FightStrategy/Help.elm b/src/Data/FightStrategy/Help.elm index 1a6bcbd9..e32964cd 100644 --- a/src/Data/FightStrategy/Help.elm +++ b/src/Data/FightStrategy/Help.elm @@ -18,28 +18,29 @@ help = - if [CONDITION] then [STRATEGY] else [STRATEGY] -[COMMAND] [VALUE] - - attack randomly - my HP - - attack ([SHOT TYPE]) - my AP - - heal ([ITEM]) - number of available [ITEM] - - move forward - number of used [ITEM] - - do whatever - opponent's level - - chance to hit ([SHOT TYPE]) - - distance +[COMMAND] [VALUE] + - attack randomly - my HP + - attack ([SHOT TYPE]) - my AP + - heal ([ITEM]) - number of available [ITEM] + - move forward - number of used [ITEM] + - do whatever - opponent's level + - chance to hit ([SHOT TYPE]) + - distance [CONDITION] - opponent is player - - [VALUE] [OPERATOR] [NUMBER] [SHOT TYPE] - - ([CONDITION] or [CONDITION]) - unaimed - - ([CONDITION] and [CONDITION]) - head - - eyes + - opponent is NPC [SHOT TYPE] + - [VALUE] [OPERATOR] [NUMBER] - unaimed + - ([CONDITION] or [CONDITION]) - head + - ([CONDITION] and [CONDITION]) - eyes - torso -[OPERATOR] - groin - - < - left arm - - <= - right arm - - == - left leg - - != - right leg - - >= - - > + - groin +[OPERATOR] - left arm + - < (less than) - right arm + - <= (less than or equal) - left leg + - == (equals) - right leg + - != (doesn't equal) + - >= (greater than or equal) + - > (greater than) """ |> P.run parser |> Result.withDefault [ Text "BUG: couldn't parse the syntax help!" ] @@ -148,7 +149,7 @@ referenceDescription : Reference -> String referenceDescription ref = case ref of Strategy -> - """The main building block of your strategy. + """The entrypoint to your fight strategy. Examples: - do whatever @@ -157,7 +158,7 @@ Examples: else do whatever""" Command -> - """The result of applying your strategy to your current situation. + """The end result of applying your strategy to your current situation. Examples: - heal (Stimpak) @@ -198,9 +199,7 @@ Example usage: - number of available Stimpak""" Operator -> - """The != operator means 'is not equal to'. - -Example usage: + """Example usage: - distance > 0 - my HP <= 80 - my AP == 3 diff --git a/src/Data/FightStrategy/Parser.elm b/src/Data/FightStrategy/Parser.elm index 828b28d9..a5e36d2d 100644 --- a/src/Data/FightStrategy/Parser.elm +++ b/src/Data/FightStrategy/Parser.elm @@ -123,6 +123,7 @@ condition = P.oneOf [ binary , P.map (\_ -> OpponentIsPlayer) (P.keyword "opponent is player") + , P.map (\_ -> OpponentIsNPC) (P.keyword "opponent is NPC") , operatorCondition ] diff --git a/src/Data/Special/Perception.elm b/src/Data/Special/Perception.elm index 1c51a490..33991360 100644 --- a/src/Data/Special/Perception.elm +++ b/src/Data/Special/Perception.elm @@ -95,10 +95,12 @@ healthPerceptionTooltip level_ = "You see everybody's exact HP and max HP." Great -> - "You see others' HP in range of (Unhurt, Slightly Wounded, Wounded, Severely Wounded, Almost Dead, Dead)." + """You see others' HP in range of (Unhurt, Slightly Wounded, + Wounded, Severely Wounded, Almost Dead, Dead).""" Good -> - "You see others' HP in range of (Unhurt, Wounded, Severely Wounded, Almost Dead, Dead)." + """You see others' HP in range of (Unhurt, Wounded, Severely + Wounded, Almost Dead, Dead).""" Bad -> "You see others' HP in range of (Alive, Dead)." @@ -112,15 +114,22 @@ mapMovementTooltip level_ = let terrainAwareOptimalMovement : String terrainAwareOptimalMovement = - "When planning longer route on the map you always go in the most efficient line, taking into consideration the terrain like mountains etc. You also see the AP cost of your route." + """When planning longer route on the map you always go in the most + efficient line, taking into consideration the terrain like mountains + etc. You also see the AP cost of your route and are able to see + which areas are more dangerous than others.""" okayMovement : String okayMovement = - "When planning longer route on the map you always go in a mostly efficient straight line but ignore terrain like mountains etc. You also see the AP cost of your route." + """When planning longer route on the map you always go in a mostly + efficient straight line but ignore terrain like mountains etc. You + also see the AP cost of your route.""" inefficientMovement : String inefficientMovement = - "When planning longer route on the map you always go in a (not very efficient) straight line but ignore terrain like mountains etc." + """When planning longer route on the map you always go in a (not + very efficient) straight line but ignore terrain like mountains + etc.""" in case level_ of Perfect -> diff --git a/src/Data/Version.elm b/src/Data/Version.elm index d1c63853..bdb90322 100644 --- a/src/Data/Version.elm +++ b/src/Data/Version.elm @@ -3,4 +3,4 @@ module Data.Version exposing (version) version : String version = - "2021.11.30::001" + "2024.09.22::001" diff --git a/src/Evergreen/Migrate/V100.elm b/src/Evergreen/Migrate/V100.elm deleted file mode 100644 index 332f066e..00000000 --- a/src/Evergreen/Migrate/V100.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.Migrate.V100 exposing (..) - -import Evergreen.V100.Types as New -import Evergreen.V97.Types as Old -import Lamdera.Migrations exposing (..) - - -frontendModel : Old.FrontendModel -> ModelMigration New.FrontendModel New.FrontendMsg -frontendModel old = - ModelUnchanged - - -backendModel : Old.BackendModel -> ModelMigration New.BackendModel New.BackendMsg -backendModel old = - ModelUnchanged - - -frontendMsg : Old.FrontendMsg -> MsgMigration New.FrontendMsg New.FrontendMsg -frontendMsg old = - MsgUnchanged - - -toBackend : Old.ToBackend -> MsgMigration New.ToBackend New.BackendMsg -toBackend old = - MsgUnchanged - - -backendMsg : Old.BackendMsg -> MsgMigration New.BackendMsg New.BackendMsg -backendMsg old = - MsgUnchanged - - -toFrontend : Old.ToFrontend -> MsgMigration New.ToFrontend New.FrontendMsg -toFrontend old = - MsgUnchanged diff --git a/src/Evergreen/Migrate/V77.elm b/src/Evergreen/Migrate/V77.elm deleted file mode 100644 index d348b54e..00000000 --- a/src/Evergreen/Migrate/V77.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.Migrate.V77 exposing (..) - -import Evergreen.V75.Types as Old -import Evergreen.V77.Types as New -import Lamdera.Migrations exposing (..) - - -frontendModel : Old.FrontendModel -> ModelMigration New.FrontendModel New.FrontendMsg -frontendModel old = - ModelUnchanged - - -backendModel : Old.BackendModel -> ModelMigration New.BackendModel New.BackendMsg -backendModel old = - ModelUnchanged - - -frontendMsg : Old.FrontendMsg -> MsgMigration New.FrontendMsg New.FrontendMsg -frontendMsg old = - MsgUnchanged - - -toBackend : Old.ToBackend -> MsgMigration New.ToBackend New.BackendMsg -toBackend old = - MsgUnchanged - - -backendMsg : Old.BackendMsg -> MsgMigration New.BackendMsg New.BackendMsg -backendMsg old = - MsgUnchanged - - -toFrontend : Old.ToFrontend -> MsgMigration New.ToFrontend New.FrontendMsg -toFrontend old = - MsgUnchanged diff --git a/src/Evergreen/Migrate/V78.elm b/src/Evergreen/Migrate/V78.elm deleted file mode 100644 index 97f8eb26..00000000 --- a/src/Evergreen/Migrate/V78.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.Migrate.V78 exposing (..) - -import Evergreen.V77.Types as Old -import Evergreen.V78.Types as New -import Lamdera.Migrations exposing (..) - - -frontendModel : Old.FrontendModel -> ModelMigration New.FrontendModel New.FrontendMsg -frontendModel old = - ModelUnchanged - - -backendModel : Old.BackendModel -> ModelMigration New.BackendModel New.BackendMsg -backendModel old = - ModelUnchanged - - -frontendMsg : Old.FrontendMsg -> MsgMigration New.FrontendMsg New.FrontendMsg -frontendMsg old = - MsgUnchanged - - -toBackend : Old.ToBackend -> MsgMigration New.ToBackend New.BackendMsg -toBackend old = - MsgUnchanged - - -backendMsg : Old.BackendMsg -> MsgMigration New.BackendMsg New.BackendMsg -backendMsg old = - MsgUnchanged - - -toFrontend : Old.ToFrontend -> MsgMigration New.ToFrontend New.FrontendMsg -toFrontend old = - MsgUnchanged diff --git a/src/Evergreen/Migrate/V79.elm b/src/Evergreen/Migrate/V79.elm deleted file mode 100644 index e7ba5ce0..00000000 --- a/src/Evergreen/Migrate/V79.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.Migrate.V79 exposing (..) - -import Evergreen.V78.Types as Old -import Evergreen.V79.Types as New -import Lamdera.Migrations exposing (..) - - -frontendModel : Old.FrontendModel -> ModelMigration New.FrontendModel New.FrontendMsg -frontendModel old = - ModelUnchanged - - -backendModel : Old.BackendModel -> ModelMigration New.BackendModel New.BackendMsg -backendModel old = - ModelUnchanged - - -frontendMsg : Old.FrontendMsg -> MsgMigration New.FrontendMsg New.FrontendMsg -frontendMsg old = - MsgUnchanged - - -toBackend : Old.ToBackend -> MsgMigration New.ToBackend New.BackendMsg -toBackend old = - MsgUnchanged - - -backendMsg : Old.BackendMsg -> MsgMigration New.BackendMsg New.BackendMsg -backendMsg old = - MsgUnchanged - - -toFrontend : Old.ToFrontend -> MsgMigration New.ToFrontend New.FrontendMsg -toFrontend old = - MsgUnchanged diff --git a/src/Evergreen/Migrate/V81.elm b/src/Evergreen/Migrate/V81.elm deleted file mode 100644 index b04c2c9b..00000000 --- a/src/Evergreen/Migrate/V81.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.Migrate.V81 exposing (..) - -import Evergreen.V79.Types as Old -import Evergreen.V81.Types as New -import Lamdera.Migrations exposing (..) - - -frontendModel : Old.FrontendModel -> ModelMigration New.FrontendModel New.FrontendMsg -frontendModel old = - ModelUnchanged - - -backendModel : Old.BackendModel -> ModelMigration New.BackendModel New.BackendMsg -backendModel old = - ModelUnchanged - - -frontendMsg : Old.FrontendMsg -> MsgMigration New.FrontendMsg New.FrontendMsg -frontendMsg old = - MsgUnchanged - - -toBackend : Old.ToBackend -> MsgMigration New.ToBackend New.BackendMsg -toBackend old = - MsgUnchanged - - -backendMsg : Old.BackendMsg -> MsgMigration New.BackendMsg New.BackendMsg -backendMsg old = - MsgUnchanged - - -toFrontend : Old.ToFrontend -> MsgMigration New.ToFrontend New.FrontendMsg -toFrontend old = - MsgUnchanged diff --git a/src/Evergreen/Migrate/V83.elm b/src/Evergreen/Migrate/V83.elm deleted file mode 100644 index b92934cb..00000000 --- a/src/Evergreen/Migrate/V83.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.Migrate.V83 exposing (..) - -import Evergreen.V81.Types as Old -import Evergreen.V83.Types as New -import Lamdera.Migrations exposing (..) - - -frontendModel : Old.FrontendModel -> ModelMigration New.FrontendModel New.FrontendMsg -frontendModel old = - ModelUnchanged - - -backendModel : Old.BackendModel -> ModelMigration New.BackendModel New.BackendMsg -backendModel old = - ModelUnchanged - - -frontendMsg : Old.FrontendMsg -> MsgMigration New.FrontendMsg New.FrontendMsg -frontendMsg old = - MsgUnchanged - - -toBackend : Old.ToBackend -> MsgMigration New.ToBackend New.BackendMsg -toBackend old = - MsgUnchanged - - -backendMsg : Old.BackendMsg -> MsgMigration New.BackendMsg New.BackendMsg -backendMsg old = - MsgUnchanged - - -toFrontend : Old.ToFrontend -> MsgMigration New.ToFrontend New.FrontendMsg -toFrontend old = - MsgUnchanged diff --git a/src/Evergreen/Migrate/V85.elm b/src/Evergreen/Migrate/V85.elm deleted file mode 100644 index e56b7f82..00000000 --- a/src/Evergreen/Migrate/V85.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.Migrate.V85 exposing (..) - -import Evergreen.V83.Types as Old -import Evergreen.V85.Types as New -import Lamdera.Migrations exposing (..) - - -frontendModel : Old.FrontendModel -> ModelMigration New.FrontendModel New.FrontendMsg -frontendModel old = - ModelUnchanged - - -backendModel : Old.BackendModel -> ModelMigration New.BackendModel New.BackendMsg -backendModel old = - ModelUnchanged - - -frontendMsg : Old.FrontendMsg -> MsgMigration New.FrontendMsg New.FrontendMsg -frontendMsg old = - MsgUnchanged - - -toBackend : Old.ToBackend -> MsgMigration New.ToBackend New.BackendMsg -toBackend old = - MsgUnchanged - - -backendMsg : Old.BackendMsg -> MsgMigration New.BackendMsg New.BackendMsg -backendMsg old = - MsgUnchanged - - -toFrontend : Old.ToFrontend -> MsgMigration New.ToFrontend New.FrontendMsg -toFrontend old = - MsgUnchanged diff --git a/src/Evergreen/Migrate/V87.elm b/src/Evergreen/Migrate/V87.elm deleted file mode 100644 index b7b1cf77..00000000 --- a/src/Evergreen/Migrate/V87.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.Migrate.V87 exposing (..) - -import Evergreen.V85.Types as Old -import Evergreen.V87.Types as New -import Lamdera.Migrations exposing (..) - - -frontendModel : Old.FrontendModel -> ModelMigration New.FrontendModel New.FrontendMsg -frontendModel old = - ModelUnchanged - - -backendModel : Old.BackendModel -> ModelMigration New.BackendModel New.BackendMsg -backendModel old = - ModelUnchanged - - -frontendMsg : Old.FrontendMsg -> MsgMigration New.FrontendMsg New.FrontendMsg -frontendMsg old = - MsgUnchanged - - -toBackend : Old.ToBackend -> MsgMigration New.ToBackend New.BackendMsg -toBackend old = - MsgUnchanged - - -backendMsg : Old.BackendMsg -> MsgMigration New.BackendMsg New.BackendMsg -backendMsg old = - MsgUnchanged - - -toFrontend : Old.ToFrontend -> MsgMigration New.ToFrontend New.FrontendMsg -toFrontend old = - MsgUnchanged diff --git a/src/Evergreen/Migrate/V88.elm b/src/Evergreen/Migrate/V88.elm deleted file mode 100644 index 7564025f..00000000 --- a/src/Evergreen/Migrate/V88.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.Migrate.V88 exposing (..) - -import Evergreen.V87.Types as Old -import Evergreen.V88.Types as New -import Lamdera.Migrations exposing (..) - - -frontendModel : Old.FrontendModel -> ModelMigration New.FrontendModel New.FrontendMsg -frontendModel old = - ModelUnchanged - - -backendModel : Old.BackendModel -> ModelMigration New.BackendModel New.BackendMsg -backendModel old = - ModelUnchanged - - -frontendMsg : Old.FrontendMsg -> MsgMigration New.FrontendMsg New.FrontendMsg -frontendMsg old = - MsgUnchanged - - -toBackend : Old.ToBackend -> MsgMigration New.ToBackend New.BackendMsg -toBackend old = - MsgUnchanged - - -backendMsg : Old.BackendMsg -> MsgMigration New.BackendMsg New.BackendMsg -backendMsg old = - MsgUnchanged - - -toFrontend : Old.ToFrontend -> MsgMigration New.ToFrontend New.FrontendMsg -toFrontend old = - MsgUnchanged diff --git a/src/Evergreen/Migrate/V89.elm b/src/Evergreen/Migrate/V89.elm deleted file mode 100644 index 8b95ce06..00000000 --- a/src/Evergreen/Migrate/V89.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.Migrate.V89 exposing (..) - -import Evergreen.V88.Types as Old -import Evergreen.V89.Types as New -import Lamdera.Migrations exposing (..) - - -frontendModel : Old.FrontendModel -> ModelMigration New.FrontendModel New.FrontendMsg -frontendModel old = - ModelUnchanged - - -backendModel : Old.BackendModel -> ModelMigration New.BackendModel New.BackendMsg -backendModel old = - ModelUnchanged - - -frontendMsg : Old.FrontendMsg -> MsgMigration New.FrontendMsg New.FrontendMsg -frontendMsg old = - MsgUnchanged - - -toBackend : Old.ToBackend -> MsgMigration New.ToBackend New.BackendMsg -toBackend old = - MsgUnchanged - - -backendMsg : Old.BackendMsg -> MsgMigration New.BackendMsg New.BackendMsg -backendMsg old = - MsgUnchanged - - -toFrontend : Old.ToFrontend -> MsgMigration New.ToFrontend New.FrontendMsg -toFrontend old = - MsgUnchanged diff --git a/src/Evergreen/Migrate/V96.elm b/src/Evergreen/Migrate/V96.elm deleted file mode 100644 index cb88724e..00000000 --- a/src/Evergreen/Migrate/V96.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.Migrate.V96 exposing (..) - -import Evergreen.V89.Types as Old -import Evergreen.V96.Types as New -import Lamdera.Migrations exposing (..) - - -frontendModel : Old.FrontendModel -> ModelMigration New.FrontendModel New.FrontendMsg -frontendModel old = - ModelUnchanged - - -backendModel : Old.BackendModel -> ModelMigration New.BackendModel New.BackendMsg -backendModel old = - ModelUnchanged - - -frontendMsg : Old.FrontendMsg -> MsgMigration New.FrontendMsg New.FrontendMsg -frontendMsg old = - MsgUnchanged - - -toBackend : Old.ToBackend -> MsgMigration New.ToBackend New.BackendMsg -toBackend old = - MsgUnchanged - - -backendMsg : Old.BackendMsg -> MsgMigration New.BackendMsg New.BackendMsg -backendMsg old = - MsgUnchanged - - -toFrontend : Old.ToFrontend -> MsgMigration New.ToFrontend New.FrontendMsg -toFrontend old = - MsgUnchanged diff --git a/src/Evergreen/Migrate/V97.elm b/src/Evergreen/Migrate/V97.elm deleted file mode 100644 index 779aa866..00000000 --- a/src/Evergreen/Migrate/V97.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.Migrate.V97 exposing (..) - -import Evergreen.V96.Types as Old -import Evergreen.V97.Types as New -import Lamdera.Migrations exposing (..) - - -frontendModel : Old.FrontendModel -> ModelMigration New.FrontendModel New.FrontendMsg -frontendModel old = - ModelUnchanged - - -backendModel : Old.BackendModel -> ModelMigration New.BackendModel New.BackendMsg -backendModel old = - ModelUnchanged - - -frontendMsg : Old.FrontendMsg -> MsgMigration New.FrontendMsg New.FrontendMsg -frontendMsg old = - MsgUnchanged - - -toBackend : Old.ToBackend -> MsgMigration New.ToBackend New.BackendMsg -toBackend old = - MsgUnchanged - - -backendMsg : Old.BackendMsg -> MsgMigration New.BackendMsg New.BackendMsg -backendMsg old = - MsgUnchanged - - -toFrontend : Old.ToFrontend -> MsgMigration New.ToFrontend New.FrontendMsg -toFrontend old = - MsgUnchanged diff --git a/src/Evergreen/V100/Data/Auth.elm b/src/Evergreen/V100/Data/Auth.elm deleted file mode 100644 index fd088a61..00000000 --- a/src/Evergreen/V100/Data/Auth.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V100.Data.Auth exposing (..) - - -type Plaintext - = Plaintext - - -type Password a - = Password String - - -type alias Auth a = - { name : String - , password : Password a - } - - -type Verified - = Verified - - -type Hashed - = Hashed diff --git a/src/Evergreen/V100/Data/Barter.elm b/src/Evergreen/V100/Data/Barter.elm deleted file mode 100644 index ff398bdf..00000000 --- a/src/Evergreen/V100/Data/Barter.elm +++ /dev/null @@ -1,33 +0,0 @@ -module Evergreen.V100.Data.Barter exposing (..) - -import AssocList -import Dict -import Evergreen.V100.Data.Item - - -type Message - = BarterIsEmpty - | PlayerOfferNotValuableEnough - | YouGaveStuffForFree - - -type TransferNPosition - = PlayerKeptItem Evergreen.V100.Data.Item.Id - | VendorKeptItem Evergreen.V100.Data.Item.Id - | PlayerTradedItem Evergreen.V100.Data.Item.Id - | VendorTradedItem Evergreen.V100.Data.Item.Id - | PlayerKeptCaps - | VendorKeptCaps - | PlayerTradedCaps - | VendorTradedCaps - - -type alias State = - { playerItems : Dict.Dict Evergreen.V100.Data.Item.Id Int - , vendorItems : Dict.Dict Evergreen.V100.Data.Item.Id Int - , playerCaps : Int - , vendorCaps : Int - , lastMessage : Maybe Message - , transferNInputs : AssocList.Dict TransferNPosition String - , transferNHover : Maybe TransferNPosition - } diff --git a/src/Evergreen/V100/Data/Enemy.elm b/src/Evergreen/V100/Data/Enemy.elm deleted file mode 100644 index 6977529e..00000000 --- a/src/Evergreen/V100/Data/Enemy.elm +++ /dev/null @@ -1,14 +0,0 @@ -module Evergreen.V100.Data.Enemy exposing (..) - - -type Type - = Brahmin - | AngryBrahmin - | WeakBrahmin - | WildBrahmin - | GiantAnt - | ToughGiantAnt - | BlackRadscorpion - | LesserBlackRadscorpion - | LesserRadscorpion - | Radscorpion diff --git a/src/Evergreen/V100/Data/Fight.elm b/src/Evergreen/V100/Data/Fight.elm deleted file mode 100644 index d22241a7..00000000 --- a/src/Evergreen/V100/Data/Fight.elm +++ /dev/null @@ -1,99 +0,0 @@ -module Evergreen.V100.Data.Fight exposing (..) - -import AssocList -import AssocSet -import Dict -import Evergreen.V100.Data.Enemy -import Evergreen.V100.Data.Fight.ShotType -import Evergreen.V100.Data.FightStrategy -import Evergreen.V100.Data.Item -import Evergreen.V100.Data.Perk -import Evergreen.V100.Data.Player.PlayerName -import Evergreen.V100.Data.Skill -import Evergreen.V100.Data.Special -import Evergreen.V100.Data.Trait -import Evergreen.V100.Logic - - -type alias PlayerOpponent = - { name : Evergreen.V100.Data.Player.PlayerName.PlayerName - , xp : Int - } - - -type OpponentType - = Npc Evergreen.V100.Data.Enemy.Type - | Player PlayerOpponent - - -type Who - = Attacker - | Target - - -type Action - = Start - { distanceHexes : Int - } - | ComeCloser - { hexes : Int - , remainingDistanceHexes : Int - } - | Attack - { damage : Int - , shotType : Evergreen.V100.Data.Fight.ShotType.ShotType - , remainingHp : Int - , isCritical : Bool - } - | Miss - { shotType : Evergreen.V100.Data.Fight.ShotType.ShotType - } - | Heal - { itemKind : Evergreen.V100.Data.Item.Kind - , healedHp : Int - , newHp : Int - } - - -type Result - = AttackerWon - { xpGained : Int - , capsGained : Int - , itemsGained : List Evergreen.V100.Data.Item.Item - } - | TargetWon - { xpGained : Int - , capsGained : Int - , itemsGained : List Evergreen.V100.Data.Item.Item - } - | TargetAlreadyDead - | BothDead - | NobodyDead - - -type alias Info = - { attacker : OpponentType - , target : OpponentType - , log : List ( Who, Action ) - , result : Result - } - - -type alias Opponent = - { type_ : OpponentType - , hp : Int - , maxHp : Int - , maxAp : Int - , sequence : Int - , traits : AssocSet.Set Evergreen.V100.Data.Trait.Trait - , perks : AssocList.Dict Evergreen.V100.Data.Perk.Perk Int - , caps : Int - , items : Dict.Dict Evergreen.V100.Data.Item.Id Evergreen.V100.Data.Item.Item - , drops : List Evergreen.V100.Data.Item.Item - , equippedArmor : Maybe Evergreen.V100.Data.Item.Kind - , naturalArmorClass : Int - , attackStats : Evergreen.V100.Logic.AttackStats - , addedSkillPercentages : AssocList.Dict Evergreen.V100.Data.Skill.Skill Int - , special : Evergreen.V100.Data.Special.Special - , fightStrategy : Evergreen.V100.Data.FightStrategy.FightStrategy - } diff --git a/src/Evergreen/V100/Data/Fight/Generator.elm b/src/Evergreen/V100/Data/Fight/Generator.elm deleted file mode 100644 index 9334c999..00000000 --- a/src/Evergreen/V100/Data/Fight/Generator.elm +++ /dev/null @@ -1,13 +0,0 @@ -module Evergreen.V100.Data.Fight.Generator exposing (..) - -import Evergreen.V100.Data.Fight -import Evergreen.V100.Data.Message - - -type alias Fight = - { finalAttacker : Evergreen.V100.Data.Fight.Opponent - , finalTarget : Evergreen.V100.Data.Fight.Opponent - , fightInfo : Evergreen.V100.Data.Fight.Info - , messageForTarget : Evergreen.V100.Data.Message.Message - , messageForAttacker : Evergreen.V100.Data.Message.Message - } diff --git a/src/Evergreen/V100/Data/Fight/ShotType.elm b/src/Evergreen/V100/Data/Fight/ShotType.elm deleted file mode 100644 index c292ed0f..00000000 --- a/src/Evergreen/V100/Data/Fight/ShotType.elm +++ /dev/null @@ -1,17 +0,0 @@ -module Evergreen.V100.Data.Fight.ShotType exposing (..) - - -type AimedShot - = Head - | Torso - | Eyes - | Groin - | LeftArm - | RightArm - | LeftLeg - | RightLeg - - -type ShotType - = NormalShot - | AimedShot AimedShot diff --git a/src/Evergreen/V100/Data/FightStrategy.elm b/src/Evergreen/V100/Data/FightStrategy.elm deleted file mode 100644 index 8f74be3f..00000000 --- a/src/Evergreen/V100/Data/FightStrategy.elm +++ /dev/null @@ -1,57 +0,0 @@ -module Evergreen.V100.Data.FightStrategy exposing (..) - -import Evergreen.V100.Data.Fight.ShotType -import Evergreen.V100.Data.Item - - -type Operator - = LT_ - | LTE - | EQ_ - | NE - | GTE - | GT_ - - -type Value - = MyHP - | MyAP - | MyItemCount Evergreen.V100.Data.Item.Kind - | ItemsUsed Evergreen.V100.Data.Item.Kind - | TheirLevel - | ChanceToHit Evergreen.V100.Data.Fight.ShotType.ShotType - | Distance - - -type alias OperatorData = - { op : Operator - , value : Value - , number_ : Float - } - - -type Condition - = Or Condition Condition - | And Condition Condition - | Not Condition - | Operator OperatorData - - -type alias IfData = - { condition : Condition - , then_ : FightStrategy - , else_ : FightStrategy - } - - -type Command - = Attack Evergreen.V100.Data.Fight.ShotType.ShotType - | AttackRandomly - | Heal Evergreen.V100.Data.Item.Kind - | MoveForward - | DoWhatever - - -type FightStrategy - = If IfData - | Command Command diff --git a/src/Evergreen/V100/Data/HealthStatus.elm b/src/Evergreen/V100/Data/HealthStatus.elm deleted file mode 100644 index 70d3c111..00000000 --- a/src/Evergreen/V100/Data/HealthStatus.elm +++ /dev/null @@ -1,16 +0,0 @@ -module Evergreen.V100.Data.HealthStatus exposing (..) - - -type HealthStatus - = ExactHp - { current : Int - , max : Int - } - | Unhurt - | SlightlyWounded - | Wounded - | SeverelyWounded - | AlmostDead - | Dead - | Alive - | Unknown diff --git a/src/Evergreen/V100/Data/Item.elm b/src/Evergreen/V100/Data/Item.elm deleted file mode 100644 index 45605d12..00000000 --- a/src/Evergreen/V100/Data/Item.elm +++ /dev/null @@ -1,27 +0,0 @@ -module Evergreen.V100.Data.Item exposing (..) - - -type alias Id = - Int - - -type Kind - = Fruit - | HealingPowder - | Stimpak - | BigBookOfScience - | DeansElectronics - | FirstAidBook - | GunsAndBullets - | ScoutHandbook - | Robes - | LeatherJacket - | LeatherArmor - | MetalArmor - - -type alias Item = - { id : Id - , kind : Kind - , count : Int - } diff --git a/src/Evergreen/V100/Data/Map.elm b/src/Evergreen/V100/Data/Map.elm deleted file mode 100644 index 4b895632..00000000 --- a/src/Evergreen/V100/Data/Map.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V100.Data.Map exposing (..) - - -type alias TileNum = - Int - - -type alias TileCoords = - ( Int, Int ) diff --git a/src/Evergreen/V100/Data/Message.elm b/src/Evergreen/V100/Data/Message.elm deleted file mode 100644 index 4715ad90..00000000 --- a/src/Evergreen/V100/Data/Message.elm +++ /dev/null @@ -1,27 +0,0 @@ -module Evergreen.V100.Data.Message exposing (..) - -import Evergreen.V100.Data.Fight -import Evergreen.V100.Data.Player.PlayerName -import Time - - -type Type - = Welcome - | YouAdvancedLevel - { newLevel : Int - } - | YouWereAttacked - { attacker : Evergreen.V100.Data.Player.PlayerName.PlayerName - , fightInfo : Evergreen.V100.Data.Fight.Info - } - | YouAttacked - { target : Evergreen.V100.Data.Player.PlayerName.PlayerName - , fightInfo : Evergreen.V100.Data.Fight.Info - } - - -type alias Message = - { type_ : Type - , hasBeenRead : Bool - , date : Time.Posix - } diff --git a/src/Evergreen/V100/Data/NewChar.elm b/src/Evergreen/V100/Data/NewChar.elm deleted file mode 100644 index 1e7575a1..00000000 --- a/src/Evergreen/V100/Data/NewChar.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V100.Data.NewChar exposing (..) - -import AssocSet -import Evergreen.V100.Data.Skill -import Evergreen.V100.Data.Special -import Evergreen.V100.Data.Trait - - -type CreationError - = DoesNotHaveThreeTaggedSkills - | HasSpecialPointsLeft - | UsedMoreSpecialPointsThanAvailable - | HasSpecialOutOfRange - | HasMoreThanTwoTraits - - -type alias NewChar = - { baseSpecial : Evergreen.V100.Data.Special.Special - , availableSpecial : Int - , taggedSkills : AssocSet.Set Evergreen.V100.Data.Skill.Skill - , traits : AssocSet.Set Evergreen.V100.Data.Trait.Trait - , error : Maybe CreationError - } diff --git a/src/Evergreen/V100/Data/Perk.elm b/src/Evergreen/V100/Data/Perk.elm deleted file mode 100644 index e8a81b8d..00000000 --- a/src/Evergreen/V100/Data/Perk.elm +++ /dev/null @@ -1,45 +0,0 @@ -module Evergreen.V100.Data.Perk exposing (..) - - -type Perk - = BonusHthDamage - | Awareness - | CautiousNature - | Comprehension - | EarlierSequence - | FasterHealing - | HereAndNow - | Survivalist - | SwiftLearner - | Thief - | Toughness - | AdrenalineRush - | Educated - | FortuneFinder - | Gambler - | MoreCriticals - | Negotiator - | Pathfinder - | Ranger - | Salesman - | BetterCriticals - | Dodger - | Speaker - | ActionBoy - | GainStrength - | GainPerception - | GainEndurance - | GainCharisma - | GainIntelligence - | GainAgility - | GainLuck - | HthEvade - | Lifegiver - | LivingAnatomy - | MasterThief - | MasterTrader - | Medic - | MrFixit - | Tag - | BonusHthAttacks - | Slayer diff --git a/src/Evergreen/V100/Data/Player.elm b/src/Evergreen/V100/Data/Player.elm deleted file mode 100644 index f7486290..00000000 --- a/src/Evergreen/V100/Data/Player.elm +++ /dev/null @@ -1,80 +0,0 @@ -module Evergreen.V100.Data.Player exposing (..) - -import AssocList -import AssocSet -import Dict -import Evergreen.V100.Data.Auth -import Evergreen.V100.Data.FightStrategy -import Evergreen.V100.Data.HealthStatus -import Evergreen.V100.Data.Item -import Evergreen.V100.Data.Map -import Evergreen.V100.Data.Message -import Evergreen.V100.Data.Perk -import Evergreen.V100.Data.Player.PlayerName -import Evergreen.V100.Data.Skill -import Evergreen.V100.Data.Special -import Evergreen.V100.Data.Trait -import Evergreen.V100.Data.Xp - - -type alias COtherPlayer = - { level : Evergreen.V100.Data.Xp.Level - , name : Evergreen.V100.Data.Player.PlayerName.PlayerName - , wins : Int - , losses : Int - , healthStatus : Evergreen.V100.Data.HealthStatus.HealthStatus - } - - -type alias CPlayer = - { hp : Int - , maxHp : Int - , xp : Evergreen.V100.Data.Xp.Xp - , name : Evergreen.V100.Data.Player.PlayerName.PlayerName - , special : Evergreen.V100.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V100.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V100.Data.Perk.Perk Int - , messages : List Evergreen.V100.Data.Message.Message - , items : Dict.Dict Evergreen.V100.Data.Item.Id Evergreen.V100.Data.Item.Item - , traits : AssocSet.Set Evergreen.V100.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V100.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V100.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - , equippedArmor : Maybe Evergreen.V100.Data.Item.Item - , fightStrategy : Evergreen.V100.Data.FightStrategy.FightStrategy - } - - -type Player a - = NeedsCharCreated (Evergreen.V100.Data.Auth.Auth Evergreen.V100.Data.Auth.Verified) - | Player a - - -type alias SPlayer = - { name : Evergreen.V100.Data.Player.PlayerName.PlayerName - , password : Evergreen.V100.Data.Auth.Password Evergreen.V100.Data.Auth.Verified - , hp : Int - , maxHp : Int - , xp : Int - , special : Evergreen.V100.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V100.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V100.Data.Perk.Perk Int - , messages : List Evergreen.V100.Data.Message.Message - , items : Dict.Dict Evergreen.V100.Data.Item.Id Evergreen.V100.Data.Item.Item - , traits : AssocSet.Set Evergreen.V100.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V100.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V100.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - , equippedArmor : Maybe Evergreen.V100.Data.Item.Item - , fightStrategy : Evergreen.V100.Data.FightStrategy.FightStrategy - } diff --git a/src/Evergreen/V100/Data/Player/PlayerName.elm b/src/Evergreen/V100/Data/Player/PlayerName.elm deleted file mode 100644 index 6529089a..00000000 --- a/src/Evergreen/V100/Data/Player/PlayerName.elm +++ /dev/null @@ -1,5 +0,0 @@ -module Evergreen.V100.Data.Player.PlayerName exposing (..) - - -type alias PlayerName = - String diff --git a/src/Evergreen/V100/Data/Skill.elm b/src/Evergreen/V100/Data/Skill.elm deleted file mode 100644 index c88c1c3a..00000000 --- a/src/Evergreen/V100/Data/Skill.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V100.Data.Skill exposing (..) - - -type Skill - = SmallGuns - | BigGuns - | EnergyWeapons - | Unarmed - | MeleeWeapons - | Throwing - | FirstAid - | Doctor - | Sneak - | Lockpick - | Steal - | Traps - | Science - | Repair - | Speech - | Barter - | Gambling - | Outdoorsman diff --git a/src/Evergreen/V100/Data/Special.elm b/src/Evergreen/V100/Data/Special.elm deleted file mode 100644 index 72dd141d..00000000 --- a/src/Evergreen/V100/Data/Special.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V100.Data.Special exposing (..) - - -type alias Special = - { strength : Int - , perception : Int - , endurance : Int - , charisma : Int - , intelligence : Int - , agility : Int - , luck : Int - } - - -type Type - = Strength - | Perception - | Endurance - | Charisma - | Intelligence - | Agility - | Luck diff --git a/src/Evergreen/V100/Data/Trait.elm b/src/Evergreen/V100/Data/Trait.elm deleted file mode 100644 index e94910a9..00000000 --- a/src/Evergreen/V100/Data/Trait.elm +++ /dev/null @@ -1,11 +0,0 @@ -module Evergreen.V100.Data.Trait exposing (..) - - -type Trait - = Kamikaze - | Bruiser - | Gifted - | SmallFrame - | Skilled - | HeavyHanded - | Finesse diff --git a/src/Evergreen/V100/Data/Vendor.elm b/src/Evergreen/V100/Data/Vendor.elm deleted file mode 100644 index f2188b5c..00000000 --- a/src/Evergreen/V100/Data/Vendor.elm +++ /dev/null @@ -1,20 +0,0 @@ -module Evergreen.V100.Data.Vendor exposing (..) - -import Dict -import Evergreen.V100.Data.Item - - -type Name - = ArroyoHakunin - | KlamathMaidaBuckner - | DenFlick - | ModocJo - | VaultCityHappyHarry - - -type alias Vendor = - { name : Name - , items : Dict.Dict Evergreen.V100.Data.Item.Id Evergreen.V100.Data.Item.Item - , caps : Int - , barterSkill : Int - } diff --git a/src/Evergreen/V100/Data/World.elm b/src/Evergreen/V100/Data/World.elm deleted file mode 100644 index 784c963e..00000000 --- a/src/Evergreen/V100/Data/World.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.V100.Data.World exposing (..) - -import AssocList -import Evergreen.V100.Data.Auth -import Evergreen.V100.Data.Player -import Evergreen.V100.Data.Player.PlayerName -import Evergreen.V100.Data.Vendor -import Time - - -type alias WorldLoggedOutData = - { players : List Evergreen.V100.Data.Player.COtherPlayer - } - - -type alias WorldLoggedInData = - { player : Evergreen.V100.Data.Player.Player Evergreen.V100.Data.Player.CPlayer - , otherPlayers : List Evergreen.V100.Data.Player.COtherPlayer - , playerRank : Int - , vendors : AssocList.Dict Evergreen.V100.Data.Vendor.Name Evergreen.V100.Data.Vendor.Vendor - } - - -type alias AdminData = - { players : List (Evergreen.V100.Data.Player.Player Evergreen.V100.Data.Player.SPlayer) - , loggedInPlayers : List Evergreen.V100.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - } - - -type World - = WorldNotInitialized (Evergreen.V100.Data.Auth.Auth Evergreen.V100.Data.Auth.Plaintext) - | WorldLoggedOut (Evergreen.V100.Data.Auth.Auth Evergreen.V100.Data.Auth.Plaintext) WorldLoggedOutData - | WorldLoggedIn WorldLoggedInData - | WorldAdmin AdminData diff --git a/src/Evergreen/V100/Data/Xp.elm b/src/Evergreen/V100/Data/Xp.elm deleted file mode 100644 index 1dfa3294..00000000 --- a/src/Evergreen/V100/Data/Xp.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V100.Data.Xp exposing (..) - - -type alias Level = - Int - - -type alias Xp = - Int diff --git a/src/Evergreen/V100/Frontend/HoveredItem.elm b/src/Evergreen/V100/Frontend/HoveredItem.elm deleted file mode 100644 index 14bed1d7..00000000 --- a/src/Evergreen/V100/Frontend/HoveredItem.elm +++ /dev/null @@ -1,13 +0,0 @@ -module Evergreen.V100.Frontend.HoveredItem exposing (..) - -import Evergreen.V100.Data.Perk -import Evergreen.V100.Data.Skill -import Evergreen.V100.Data.Special -import Evergreen.V100.Data.Trait - - -type HoveredItem - = HoveredPerk Evergreen.V100.Data.Perk.Perk - | HoveredTrait Evergreen.V100.Data.Trait.Trait - | HoveredSpecial Evergreen.V100.Data.Special.Type - | HoveredSkill Evergreen.V100.Data.Skill.Skill diff --git a/src/Evergreen/V100/Frontend/Route.elm b/src/Evergreen/V100/Frontend/Route.elm deleted file mode 100644 index 2153d480..00000000 --- a/src/Evergreen/V100/Frontend/Route.elm +++ /dev/null @@ -1,32 +0,0 @@ -module Evergreen.V100.Frontend.Route exposing (..) - -import Evergreen.V100.Data.Barter -import Evergreen.V100.Data.Fight -import Evergreen.V100.Data.Message - - -type TownRoute - = MainSquare - | Store - { barter : Evergreen.V100.Data.Barter.State - } - - -type AdminRoute - = LoggedIn - - -type Route - = Character - | Inventory - | Map - | Ladder - | Town TownRoute - | About - | News - | Fight Evergreen.V100.Data.Fight.Info - | Messages - | Message Evergreen.V100.Data.Message.Message - | CharCreation - | Admin AdminRoute - | Settings diff --git a/src/Evergreen/V100/Logic.elm b/src/Evergreen/V100/Logic.elm deleted file mode 100644 index 21c367ae..00000000 --- a/src/Evergreen/V100/Logic.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V100.Logic exposing (..) - - -type alias AttackStats = - { minDamage : Int - , maxDamage : Int - , criticalChanceBonus : Int - } diff --git a/src/Evergreen/V100/Types.elm b/src/Evergreen/V100/Types.elm deleted file mode 100644 index e30db5ac..00000000 --- a/src/Evergreen/V100/Types.elm +++ /dev/null @@ -1,167 +0,0 @@ -module Evergreen.V100.Types exposing (..) - -import AssocList -import Browser -import Browser.Navigation -import Dict -import Evergreen.V100.Data.Auth -import Evergreen.V100.Data.Barter -import Evergreen.V100.Data.Fight -import Evergreen.V100.Data.Fight.Generator -import Evergreen.V100.Data.FightStrategy -import Evergreen.V100.Data.Item -import Evergreen.V100.Data.Map -import Evergreen.V100.Data.Message -import Evergreen.V100.Data.NewChar -import Evergreen.V100.Data.Perk -import Evergreen.V100.Data.Player -import Evergreen.V100.Data.Player.PlayerName -import Evergreen.V100.Data.Skill -import Evergreen.V100.Data.Special -import Evergreen.V100.Data.Trait -import Evergreen.V100.Data.Vendor -import Evergreen.V100.Data.World -import Evergreen.V100.Frontend.HoveredItem -import Evergreen.V100.Frontend.Route -import File exposing (File) -import Lamdera -import Set -import Time -import Url - - -type alias FrontendModel = - { key : Browser.Navigation.Key - , time : Time.Posix - , zone : Time.Zone - , route : Evergreen.V100.Frontend.Route.Route - , world : Evergreen.V100.Data.World.World - , newChar : Evergreen.V100.Data.NewChar.NewChar - , alertMessage : Maybe String - , mapMouseCoords : Maybe ( Evergreen.V100.Data.Map.TileCoords, Set.Set Evergreen.V100.Data.Map.TileCoords ) - , hoveredItem : Maybe Evergreen.V100.Frontend.HoveredItem.HoveredItem - } - - -type alias BackendModel = - { players : Dict.Dict Evergreen.V100.Data.Player.PlayerName.PlayerName (Evergreen.V100.Data.Player.Player Evergreen.V100.Data.Player.SPlayer) - , loggedInPlayers : Dict.Dict Lamdera.ClientId Evergreen.V100.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - , adminLoggedIn : Maybe ( Lamdera.ClientId, Lamdera.SessionId ) - , time : Time.Posix - , vendors : AssocList.Dict Evergreen.V100.Data.Vendor.Name Evergreen.V100.Data.Vendor.Vendor - , lastItemId : Int - } - - -type BarterMsg - = AddPlayerItem Evergreen.V100.Data.Item.Id Int - | AddVendorItem Evergreen.V100.Data.Item.Id Int - | AddPlayerCaps Int - | AddVendorCaps Int - | RemovePlayerItem Evergreen.V100.Data.Item.Id Int - | RemoveVendorItem Evergreen.V100.Data.Item.Id Int - | RemovePlayerCaps Int - | RemoveVendorCaps Int - | ResetBarter - | ConfirmBarter - | SetTransferNInput Evergreen.V100.Data.Barter.TransferNPosition String - | SetTransferNHover Evergreen.V100.Data.Barter.TransferNPosition - | UnsetTransferNHover - - -type FrontendMsg - = UrlClicked Browser.UrlRequest - | UrlChanged Url.Url - | GoToRoute Evergreen.V100.Frontend.Route.Route - | Logout - | Login - | Register - | GotZone Time.Zone - | GotTime Time.Posix - | AskToFight Evergreen.V100.Data.Player.PlayerName.PlayerName - | AskToHeal - | AskToUseItem Evergreen.V100.Data.Item.Id - | AskToWander - | AskToChoosePerk Evergreen.V100.Data.Perk.Perk - | AskToEquipItem Evergreen.V100.Data.Item.Id - | AskToUnequipArmor - | AskToSetFightStrategy Evergreen.V100.Data.FightStrategy.FightStrategy - | AskForExport - | ImportButtonClicked - | ImportFileSelected File - | AskToImport String - | Refresh - | AskToTagSkill Evergreen.V100.Data.Skill.Skill - | AskToUseSkillPoints Evergreen.V100.Data.Skill.Skill - | SetAuthName String - | SetAuthPassword String - | CreateChar - | NewCharIncSpecial Evergreen.V100.Data.Special.Type - | NewCharDecSpecial Evergreen.V100.Data.Special.Type - | NewCharToggleTaggedSkill Evergreen.V100.Data.Skill.Skill - | NewCharToggleTrait Evergreen.V100.Data.Trait.Trait - | MapMouseAtCoords Evergreen.V100.Data.Map.TileCoords - | MapMouseOut - | MapMouseClick - | OpenMessage Evergreen.V100.Data.Message.Message - | AskToRemoveMessage Evergreen.V100.Data.Message.Message - | BarterMsg BarterMsg - | HoverItem Evergreen.V100.Frontend.HoveredItem.HoveredItem - | StopHoveringItem - - -type AdminToBackend - = ExportJson - | ImportJson String - - -type ToBackend - = LogMeIn (Evergreen.V100.Data.Auth.Auth Evergreen.V100.Data.Auth.Hashed) - | RegisterMe (Evergreen.V100.Data.Auth.Auth Evergreen.V100.Data.Auth.Hashed) - | CreateNewChar Evergreen.V100.Data.NewChar.NewChar - | LogMeOut - | Fight Evergreen.V100.Data.Player.PlayerName.PlayerName - | HealMe - | UseItem Evergreen.V100.Data.Item.Id - | Wander - | EquipItem Evergreen.V100.Data.Item.Id - | SetFightStrategy Evergreen.V100.Data.FightStrategy.FightStrategy - | UnequipArmor - | RefreshPlease - | TagSkill Evergreen.V100.Data.Skill.Skill - | UseSkillPoints Evergreen.V100.Data.Skill.Skill - | ChoosePerk Evergreen.V100.Data.Perk.Perk - | MoveTo Evergreen.V100.Data.Map.TileCoords (Set.Set Evergreen.V100.Data.Map.TileCoords) - | MessageWasRead Evergreen.V100.Data.Message.Message - | RemoveMessage Evergreen.V100.Data.Message.Message - | Barter Evergreen.V100.Data.Barter.State - | AdminToBackend AdminToBackend - - -type BackendMsg - = Connected Lamdera.SessionId Lamdera.ClientId - | Disconnected Lamdera.SessionId Lamdera.ClientId - | GeneratedFight Lamdera.ClientId Evergreen.V100.Data.Player.SPlayer ( Evergreen.V100.Data.Fight.Generator.Fight, Int ) - | GeneratedNewVendorsStock ( AssocList.Dict Evergreen.V100.Data.Vendor.Name Evergreen.V100.Data.Vendor.Vendor, Int ) - | Tick Time.Posix - | CreateNewCharWithTime Lamdera.ClientId Evergreen.V100.Data.NewChar.NewChar Time.Posix - | LoggedToBackendMsg - - -type ToFrontend - = YourCurrentWorld Evergreen.V100.Data.World.WorldLoggedInData - | InitWorld Evergreen.V100.Data.World.WorldLoggedOutData - | RefreshedLoggedOut Evergreen.V100.Data.World.WorldLoggedOutData - | CurrentAdminData Evergreen.V100.Data.World.AdminData - | YourFightResult ( Evergreen.V100.Data.Fight.Info, Evergreen.V100.Data.World.WorldLoggedInData ) - | YoureLoggedIn Evergreen.V100.Data.World.WorldLoggedInData - | YoureRegistered Evergreen.V100.Data.World.WorldLoggedInData - | CharCreationError Evergreen.V100.Data.NewChar.CreationError - | YouHaveCreatedChar Evergreen.V100.Data.World.WorldLoggedInData - | YoureLoggedOut Evergreen.V100.Data.World.WorldLoggedOutData - | AlertMessage String - | YoureLoggedInAsAdmin Evergreen.V100.Data.World.AdminData - | JsonExportDone String - | BarterDone ( Evergreen.V100.Data.World.WorldLoggedInData, Maybe Evergreen.V100.Data.Barter.Message ) - | BarterMessage Evergreen.V100.Data.Barter.Message diff --git a/src/Evergreen/V75/Data/Auth.elm b/src/Evergreen/V75/Data/Auth.elm deleted file mode 100644 index afa53874..00000000 --- a/src/Evergreen/V75/Data/Auth.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V75.Data.Auth exposing (..) - - -type Plaintext - = Plaintext - - -type Password a - = Password String - - -type alias Auth a = - { name : String - , password : Password a - } - - -type Verified - = Verified - - -type Hashed - = Hashed diff --git a/src/Evergreen/V75/Data/Barter.elm b/src/Evergreen/V75/Data/Barter.elm deleted file mode 100644 index c6a4950b..00000000 --- a/src/Evergreen/V75/Data/Barter.elm +++ /dev/null @@ -1,33 +0,0 @@ -module Evergreen.V75.Data.Barter exposing (..) - -import AssocList -import Dict -import Evergreen.V75.Data.Item - - -type Message - = BarterIsEmpty - | PlayerOfferNotValuableEnough - | YouGaveStuffForFree - - -type TransferNPosition - = PlayerKeptItem Evergreen.V75.Data.Item.Id - | VendorKeptItem Evergreen.V75.Data.Item.Id - | PlayerTradedItem Evergreen.V75.Data.Item.Id - | VendorTradedItem Evergreen.V75.Data.Item.Id - | PlayerKeptCaps - | VendorKeptCaps - | PlayerTradedCaps - | VendorTradedCaps - - -type alias State = - { playerItems : Dict.Dict Evergreen.V75.Data.Item.Id Int - , vendorItems : Dict.Dict Evergreen.V75.Data.Item.Id Int - , playerCaps : Int - , vendorCaps : Int - , lastMessage : Maybe Message - , transferNInputs : AssocList.Dict TransferNPosition String - , transferNHover : Maybe TransferNPosition - } diff --git a/src/Evergreen/V75/Data/Enemy.elm b/src/Evergreen/V75/Data/Enemy.elm deleted file mode 100644 index 9f01ee28..00000000 --- a/src/Evergreen/V75/Data/Enemy.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V75.Data.Enemy exposing (..) - - -type Type - = GiantAnt - | ToughGiantAnt - | LesserRadscorpion - | Radscorpion diff --git a/src/Evergreen/V75/Data/Fight.elm b/src/Evergreen/V75/Data/Fight.elm deleted file mode 100644 index e5b759d7..00000000 --- a/src/Evergreen/V75/Data/Fight.elm +++ /dev/null @@ -1,78 +0,0 @@ -module Evergreen.V75.Data.Fight exposing (..) - -import AssocList -import AssocSet -import Evergreen.V75.Data.Enemy -import Evergreen.V75.Data.Fight.ShotType -import Evergreen.V75.Data.Perk -import Evergreen.V75.Data.Player.PlayerName -import Evergreen.V75.Data.Skill -import Evergreen.V75.Data.Special -import Evergreen.V75.Data.Trait -import Evergreen.V75.Logic - - -type OpponentType - = Npc Evergreen.V75.Data.Enemy.Type - | Player Evergreen.V75.Data.Player.PlayerName.PlayerName - - -type Who - = Attacker - | Target - - -type FightAction - = Start - { distanceHexes : Int - } - | ComeCloser - { hexes : Int - , remainingDistanceHexes : Int - } - | Attack - { damage : Int - , shotType : Evergreen.V75.Data.Fight.ShotType.ShotType - , remainingHp : Int - } - | Miss - { shotType : Evergreen.V75.Data.Fight.ShotType.ShotType - } - - -type FightResult - = AttackerWon - { xpGained : Int - , capsGained : Int - } - | TargetWon - { xpGained : Int - , capsGained : Int - } - | TargetAlreadyDead - | BothDead - | NobodyDead - - -type alias FightInfo = - { attacker : OpponentType - , target : OpponentType - , log : List ( Who, FightAction ) - , result : FightResult - } - - -type alias Opponent = - { type_ : OpponentType - , hp : Int - , maxHp : Int - , maxAp : Int - , sequence : Int - , traits : AssocSet.Set Evergreen.V75.Data.Trait.Trait - , perks : AssocList.Dict Evergreen.V75.Data.Perk.Perk Int - , caps : Int - , armorClass : Int - , attackStats : Evergreen.V75.Logic.AttackStats - , addedSkillPercentages : AssocList.Dict Evergreen.V75.Data.Skill.Skill Int - , baseSpecial : Evergreen.V75.Data.Special.Special - } diff --git a/src/Evergreen/V75/Data/Fight/Generator.elm b/src/Evergreen/V75/Data/Fight/Generator.elm deleted file mode 100644 index 42270c5c..00000000 --- a/src/Evergreen/V75/Data/Fight/Generator.elm +++ /dev/null @@ -1,12 +0,0 @@ -module Evergreen.V75.Data.Fight.Generator exposing (..) - -import Evergreen.V75.Data.Fight -import Evergreen.V75.Data.Message - - -type alias Fight = - { finalAttacker : Evergreen.V75.Data.Fight.Opponent - , finalTarget : Evergreen.V75.Data.Fight.Opponent - , fightInfo : Evergreen.V75.Data.Fight.FightInfo - , messageForTarget : Evergreen.V75.Data.Message.Message - } diff --git a/src/Evergreen/V75/Data/Fight/ShotType.elm b/src/Evergreen/V75/Data/Fight/ShotType.elm deleted file mode 100644 index 455f4f5b..00000000 --- a/src/Evergreen/V75/Data/Fight/ShotType.elm +++ /dev/null @@ -1,17 +0,0 @@ -module Evergreen.V75.Data.Fight.ShotType exposing (..) - - -type AimedShot - = Head - | Torso - | Eyes - | Groin - | LeftArm - | RightArm - | LeftLeg - | RightLeg - - -type ShotType - = NormalShot - | AimedShot AimedShot diff --git a/src/Evergreen/V75/Data/HealthStatus.elm b/src/Evergreen/V75/Data/HealthStatus.elm deleted file mode 100644 index 9f1c6588..00000000 --- a/src/Evergreen/V75/Data/HealthStatus.elm +++ /dev/null @@ -1,16 +0,0 @@ -module Evergreen.V75.Data.HealthStatus exposing (..) - - -type HealthStatus - = ExactHp - { current : Int - , max : Int - } - | Unhurt - | SlightlyWounded - | Wounded - | SeverelyWounded - | AlmostDead - | Dead - | Alive - | Unknown diff --git a/src/Evergreen/V75/Data/Item.elm b/src/Evergreen/V75/Data/Item.elm deleted file mode 100644 index d93b8b09..00000000 --- a/src/Evergreen/V75/Data/Item.elm +++ /dev/null @@ -1,21 +0,0 @@ -module Evergreen.V75.Data.Item exposing (..) - - -type alias Id = - Int - - -type Kind - = Stimpak - | BigBookOfScience - | DeansElectronics - | FirstAidBook - | GunsAndBullets - | ScoutHandbook - - -type alias Item = - { id : Id - , kind : Kind - , count : Int - } diff --git a/src/Evergreen/V75/Data/Map.elm b/src/Evergreen/V75/Data/Map.elm deleted file mode 100644 index 3cd524a0..00000000 --- a/src/Evergreen/V75/Data/Map.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V75.Data.Map exposing (..) - - -type alias TileNum = - Int - - -type alias TileCoords = - ( Int, Int ) diff --git a/src/Evergreen/V75/Data/Message.elm b/src/Evergreen/V75/Data/Message.elm deleted file mode 100644 index 3b719a9c..00000000 --- a/src/Evergreen/V75/Data/Message.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V75.Data.Message exposing (..) - -import Evergreen.V75.Data.Fight -import Evergreen.V75.Data.Player.PlayerName -import Time - - -type Type - = Welcome - | YouAdvancedLevel - { newLevel : Int - } - | YouWereAttacked - { attacker : Evergreen.V75.Data.Player.PlayerName.PlayerName - , fightInfo : Evergreen.V75.Data.Fight.FightInfo - } - - -type alias Message = - { type_ : Type - , hasBeenRead : Bool - , date : Time.Posix - } diff --git a/src/Evergreen/V75/Data/NewChar.elm b/src/Evergreen/V75/Data/NewChar.elm deleted file mode 100644 index 7dbe52e5..00000000 --- a/src/Evergreen/V75/Data/NewChar.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V75.Data.NewChar exposing (..) - -import AssocSet -import Evergreen.V75.Data.Skill -import Evergreen.V75.Data.Special -import Evergreen.V75.Data.Trait - - -type CreationError - = DoesNotHaveThreeTaggedSkills - | HasSpecialPointsLeft - | UsedMoreSpecialPointsThanAvailable - | HasSpecialOutOfRange - | HasMoreThanTwoTraits - - -type alias NewChar = - { baseSpecial : Evergreen.V75.Data.Special.Special - , availableSpecial : Int - , taggedSkills : AssocSet.Set Evergreen.V75.Data.Skill.Skill - , traits : AssocSet.Set Evergreen.V75.Data.Trait.Trait - , error : Maybe CreationError - } diff --git a/src/Evergreen/V75/Data/Perk.elm b/src/Evergreen/V75/Data/Perk.elm deleted file mode 100644 index 588fd3b5..00000000 --- a/src/Evergreen/V75/Data/Perk.elm +++ /dev/null @@ -1,12 +0,0 @@ -module Evergreen.V75.Data.Perk exposing (..) - - -type Perk - = EarlierSequence - | Tag - | Educated - | BonusHthDamage - | MasterTrader - | Awareness - | CautiousNature - | Comprehension diff --git a/src/Evergreen/V75/Data/Player.elm b/src/Evergreen/V75/Data/Player.elm deleted file mode 100644 index 6a1e8d2d..00000000 --- a/src/Evergreen/V75/Data/Player.elm +++ /dev/null @@ -1,75 +0,0 @@ -module Evergreen.V75.Data.Player exposing (..) - -import AssocList -import AssocSet -import Dict -import Evergreen.V75.Data.Auth -import Evergreen.V75.Data.HealthStatus -import Evergreen.V75.Data.Item -import Evergreen.V75.Data.Map -import Evergreen.V75.Data.Message -import Evergreen.V75.Data.Perk -import Evergreen.V75.Data.Player.PlayerName -import Evergreen.V75.Data.Skill -import Evergreen.V75.Data.Special -import Evergreen.V75.Data.Trait -import Evergreen.V75.Data.Xp - - -type alias COtherPlayer = - { level : Evergreen.V75.Data.Xp.Level - , name : Evergreen.V75.Data.Player.PlayerName.PlayerName - , wins : Int - , losses : Int - , healthStatus : Evergreen.V75.Data.HealthStatus.HealthStatus - } - - -type alias CPlayer = - { hp : Int - , maxHp : Int - , xp : Evergreen.V75.Data.Xp.Xp - , name : Evergreen.V75.Data.Player.PlayerName.PlayerName - , baseSpecial : Evergreen.V75.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V75.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V75.Data.Perk.Perk Int - , messages : List Evergreen.V75.Data.Message.Message - , items : Dict.Dict Evergreen.V75.Data.Item.Id Evergreen.V75.Data.Item.Item - , traits : AssocSet.Set Evergreen.V75.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V75.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V75.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - } - - -type Player a - = NeedsCharCreated (Evergreen.V75.Data.Auth.Auth Evergreen.V75.Data.Auth.Verified) - | Player a - - -type alias SPlayer = - { name : Evergreen.V75.Data.Player.PlayerName.PlayerName - , password : Evergreen.V75.Data.Auth.Password Evergreen.V75.Data.Auth.Verified - , hp : Int - , maxHp : Int - , xp : Int - , baseSpecial : Evergreen.V75.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V75.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V75.Data.Perk.Perk Int - , messages : List Evergreen.V75.Data.Message.Message - , items : Dict.Dict Evergreen.V75.Data.Item.Id Evergreen.V75.Data.Item.Item - , traits : AssocSet.Set Evergreen.V75.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V75.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V75.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - } diff --git a/src/Evergreen/V75/Data/Player/PlayerName.elm b/src/Evergreen/V75/Data/Player/PlayerName.elm deleted file mode 100644 index 31b80ce9..00000000 --- a/src/Evergreen/V75/Data/Player/PlayerName.elm +++ /dev/null @@ -1,5 +0,0 @@ -module Evergreen.V75.Data.Player.PlayerName exposing (..) - - -type alias PlayerName = - String diff --git a/src/Evergreen/V75/Data/Skill.elm b/src/Evergreen/V75/Data/Skill.elm deleted file mode 100644 index 3e30a885..00000000 --- a/src/Evergreen/V75/Data/Skill.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V75.Data.Skill exposing (..) - - -type Skill - = SmallGuns - | BigGuns - | EnergyWeapons - | Unarmed - | MeleeWeapons - | Throwing - | FirstAid - | Doctor - | Sneak - | Lockpick - | Steal - | Traps - | Science - | Repair - | Speech - | Barter - | Gambling - | Outdoorsman diff --git a/src/Evergreen/V75/Data/Special.elm b/src/Evergreen/V75/Data/Special.elm deleted file mode 100644 index 35bb92e5..00000000 --- a/src/Evergreen/V75/Data/Special.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V75.Data.Special exposing (..) - - -type alias Special = - { strength : Int - , perception : Int - , endurance : Int - , charisma : Int - , intelligence : Int - , agility : Int - , luck : Int - } - - -type SpecialType - = Strength - | Perception - | Endurance - | Charisma - | Intelligence - | Agility - | Luck diff --git a/src/Evergreen/V75/Data/Trait.elm b/src/Evergreen/V75/Data/Trait.elm deleted file mode 100644 index 4e7b22f5..00000000 --- a/src/Evergreen/V75/Data/Trait.elm +++ /dev/null @@ -1,10 +0,0 @@ -module Evergreen.V75.Data.Trait exposing (..) - - -type Trait - = Kamikaze - | Bruiser - | Gifted - | SmallFrame - | Skilled - | HeavyHanded diff --git a/src/Evergreen/V75/Data/Vendor.elm b/src/Evergreen/V75/Data/Vendor.elm deleted file mode 100644 index 363ef284..00000000 --- a/src/Evergreen/V75/Data/Vendor.elm +++ /dev/null @@ -1,17 +0,0 @@ -module Evergreen.V75.Data.Vendor exposing (..) - -import Dict -import Evergreen.V75.Data.Item - - -type Name - = KlamathMaidaBuckner - | DenFlick - - -type alias Vendor = - { name : Name - , items : Dict.Dict Evergreen.V75.Data.Item.Id Evergreen.V75.Data.Item.Item - , caps : Int - , barterSkill : Int - } diff --git a/src/Evergreen/V75/Data/World.elm b/src/Evergreen/V75/Data/World.elm deleted file mode 100644 index 64da069f..00000000 --- a/src/Evergreen/V75/Data/World.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.V75.Data.World exposing (..) - -import AssocList -import Evergreen.V75.Data.Auth -import Evergreen.V75.Data.Player -import Evergreen.V75.Data.Player.PlayerName -import Evergreen.V75.Data.Vendor -import Time - - -type alias WorldLoggedOutData = - { players : List Evergreen.V75.Data.Player.COtherPlayer - } - - -type alias WorldLoggedInData = - { player : Evergreen.V75.Data.Player.Player Evergreen.V75.Data.Player.CPlayer - , otherPlayers : List Evergreen.V75.Data.Player.COtherPlayer - , playerRank : Int - , vendors : AssocList.Dict Evergreen.V75.Data.Vendor.Name Evergreen.V75.Data.Vendor.Vendor - } - - -type alias AdminData = - { players : List (Evergreen.V75.Data.Player.Player Evergreen.V75.Data.Player.SPlayer) - , loggedInPlayers : List Evergreen.V75.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - } - - -type World - = WorldNotInitialized (Evergreen.V75.Data.Auth.Auth Evergreen.V75.Data.Auth.Plaintext) - | WorldLoggedOut (Evergreen.V75.Data.Auth.Auth Evergreen.V75.Data.Auth.Plaintext) WorldLoggedOutData - | WorldLoggedIn WorldLoggedInData - | WorldAdmin AdminData diff --git a/src/Evergreen/V75/Data/Xp.elm b/src/Evergreen/V75/Data/Xp.elm deleted file mode 100644 index 7314db8a..00000000 --- a/src/Evergreen/V75/Data/Xp.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V75.Data.Xp exposing (..) - - -type alias Level = - Int - - -type alias Xp = - Int diff --git a/src/Evergreen/V75/Frontend/Route.elm b/src/Evergreen/V75/Frontend/Route.elm deleted file mode 100644 index 99287107..00000000 --- a/src/Evergreen/V75/Frontend/Route.elm +++ /dev/null @@ -1,32 +0,0 @@ -module Evergreen.V75.Frontend.Route exposing (..) - -import Evergreen.V75.Data.Barter -import Evergreen.V75.Data.Fight -import Evergreen.V75.Data.Message - - -type TownRoute - = MainSquare - | Store - { barter : Evergreen.V75.Data.Barter.State - } - - -type AdminRoute - = Players - | LoggedIn - - -type Route - = Character - | Inventory - | Map - | Ladder - | Town TownRoute - | About - | News - | Fight Evergreen.V75.Data.Fight.FightInfo - | Messages - | Message Evergreen.V75.Data.Message.Message - | CharCreation - | Admin AdminRoute diff --git a/src/Evergreen/V75/Logic.elm b/src/Evergreen/V75/Logic.elm deleted file mode 100644 index 42b8b981..00000000 --- a/src/Evergreen/V75/Logic.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V75.Logic exposing (..) - - -type alias AttackStats = - { minDamage : Int - , maxDamage : Int - , criticalChanceBonus : Int - } diff --git a/src/Evergreen/V75/Types.elm b/src/Evergreen/V75/Types.elm deleted file mode 100644 index 95ed7e58..00000000 --- a/src/Evergreen/V75/Types.elm +++ /dev/null @@ -1,156 +0,0 @@ -module Evergreen.V75.Types exposing (..) - -import AssocList -import Browser -import Browser.Navigation -import Dict -import Evergreen.V75.Data.Auth -import Evergreen.V75.Data.Barter -import Evergreen.V75.Data.Fight -import Evergreen.V75.Data.Fight.Generator -import Evergreen.V75.Data.Item -import Evergreen.V75.Data.Map -import Evergreen.V75.Data.Message -import Evergreen.V75.Data.NewChar -import Evergreen.V75.Data.Perk -import Evergreen.V75.Data.Player -import Evergreen.V75.Data.Player.PlayerName -import Evergreen.V75.Data.Skill -import Evergreen.V75.Data.Special -import Evergreen.V75.Data.Trait -import Evergreen.V75.Data.Vendor -import Evergreen.V75.Data.World -import Evergreen.V75.Frontend.Route -import File exposing (File) -import Lamdera -import Set -import Time -import Url - - -type alias FrontendModel = - { key : Browser.Navigation.Key - , time : Time.Posix - , zone : Time.Zone - , route : Evergreen.V75.Frontend.Route.Route - , world : Evergreen.V75.Data.World.World - , newChar : Evergreen.V75.Data.NewChar.NewChar - , alertMessage : Maybe String - , mapMouseCoords : Maybe ( Evergreen.V75.Data.Map.TileCoords, Set.Set Evergreen.V75.Data.Map.TileCoords ) - } - - -type alias BackendModel = - { players : Dict.Dict Evergreen.V75.Data.Player.PlayerName.PlayerName (Evergreen.V75.Data.Player.Player Evergreen.V75.Data.Player.SPlayer) - , loggedInPlayers : Dict.Dict Lamdera.ClientId Evergreen.V75.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - , adminLoggedIn : Maybe ( Lamdera.ClientId, Lamdera.SessionId ) - , time : Time.Posix - , vendors : AssocList.Dict Evergreen.V75.Data.Vendor.Name Evergreen.V75.Data.Vendor.Vendor - , lastItemId : Int - } - - -type BarterMsg - = AddPlayerItem Evergreen.V75.Data.Item.Id Int - | AddVendorItem Evergreen.V75.Data.Item.Id Int - | AddPlayerCaps Int - | AddVendorCaps Int - | RemovePlayerItem Evergreen.V75.Data.Item.Id Int - | RemoveVendorItem Evergreen.V75.Data.Item.Id Int - | RemovePlayerCaps Int - | RemoveVendorCaps Int - | ResetBarter - | ConfirmBarter - | SetTransferNInput Evergreen.V75.Data.Barter.TransferNPosition String - | SetTransferNHover Evergreen.V75.Data.Barter.TransferNPosition - | UnsetTransferNHover - - -type FrontendMsg - = UrlClicked Browser.UrlRequest - | UrlChanged Url.Url - | GoToRoute Evergreen.V75.Frontend.Route.Route - | Logout - | Login - | Register - | GotZone Time.Zone - | GotTime Time.Posix - | AskToFight Evergreen.V75.Data.Player.PlayerName.PlayerName - | AskToHeal - | AskToUseItem Evergreen.V75.Data.Item.Id - | AskToWander - | AskToChoosePerk Evergreen.V75.Data.Perk.Perk - | AskForExport - | ImportButtonClicked - | ImportFileSelected File - | AskToImport String - | Refresh - | AskToTagSkill Evergreen.V75.Data.Skill.Skill - | AskToUseSkillPoints Evergreen.V75.Data.Skill.Skill - | SetAuthName String - | SetAuthPassword String - | CreateChar - | NewCharIncSpecial Evergreen.V75.Data.Special.SpecialType - | NewCharDecSpecial Evergreen.V75.Data.Special.SpecialType - | NewCharToggleTaggedSkill Evergreen.V75.Data.Skill.Skill - | NewCharToggleTrait Evergreen.V75.Data.Trait.Trait - | MapMouseAtCoords Evergreen.V75.Data.Map.TileCoords - | MapMouseOut - | MapMouseClick - | OpenMessage Evergreen.V75.Data.Message.Message - | AskToRemoveMessage Evergreen.V75.Data.Message.Message - | BarterMsg BarterMsg - - -type AdminToBackend - = ExportJson - | ImportJson String - - -type ToBackend - = LogMeIn (Evergreen.V75.Data.Auth.Auth Evergreen.V75.Data.Auth.Hashed) - | RegisterMe (Evergreen.V75.Data.Auth.Auth Evergreen.V75.Data.Auth.Hashed) - | CreateNewChar Evergreen.V75.Data.NewChar.NewChar - | LogMeOut - | Fight Evergreen.V75.Data.Player.PlayerName.PlayerName - | HealMe - | UseItem Evergreen.V75.Data.Item.Id - | Wander - | RefreshPlease - | TagSkill Evergreen.V75.Data.Skill.Skill - | UseSkillPoints Evergreen.V75.Data.Skill.Skill - | ChoosePerk Evergreen.V75.Data.Perk.Perk - | MoveTo Evergreen.V75.Data.Map.TileCoords (Set.Set Evergreen.V75.Data.Map.TileCoords) - | MessageWasRead Evergreen.V75.Data.Message.Message - | RemoveMessage Evergreen.V75.Data.Message.Message - | Barter Evergreen.V75.Data.Barter.State - | AdminToBackend AdminToBackend - - -type BackendMsg - = Connected Lamdera.SessionId Lamdera.ClientId - | Disconnected Lamdera.SessionId Lamdera.ClientId - | GeneratedFight Lamdera.ClientId Evergreen.V75.Data.Player.SPlayer Evergreen.V75.Data.Fight.Generator.Fight - | GeneratedNewVendorsStock ( AssocList.Dict Evergreen.V75.Data.Vendor.Name Evergreen.V75.Data.Vendor.Vendor, Int ) - | Tick Time.Posix - | CreateNewCharWithTime Lamdera.ClientId Evergreen.V75.Data.NewChar.NewChar Time.Posix - | LoggedToBackendMsg - - -type ToFrontend - = YourCurrentWorld Evergreen.V75.Data.World.WorldLoggedInData - | InitWorld Evergreen.V75.Data.World.WorldLoggedOutData - | RefreshedLoggedOut Evergreen.V75.Data.World.WorldLoggedOutData - | CurrentAdminData Evergreen.V75.Data.World.AdminData - | YourFightResult ( Evergreen.V75.Data.Fight.FightInfo, Evergreen.V75.Data.World.WorldLoggedInData ) - | YoureLoggedIn Evergreen.V75.Data.World.WorldLoggedInData - | YoureRegistered Evergreen.V75.Data.World.WorldLoggedInData - | CharCreationError Evergreen.V75.Data.NewChar.CreationError - | YouHaveCreatedChar Evergreen.V75.Data.World.WorldLoggedInData - | YoureLoggedOut Evergreen.V75.Data.World.WorldLoggedOutData - | AlertMessage String - | YoureLoggedInAsAdmin Evergreen.V75.Data.World.AdminData - | JsonExportDone String - | BarterDone ( Evergreen.V75.Data.World.WorldLoggedInData, Maybe Evergreen.V75.Data.Barter.Message ) - | BarterMessage Evergreen.V75.Data.Barter.Message diff --git a/src/Evergreen/V77/Data/Auth.elm b/src/Evergreen/V77/Data/Auth.elm deleted file mode 100644 index 37461670..00000000 --- a/src/Evergreen/V77/Data/Auth.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V77.Data.Auth exposing (..) - - -type Plaintext - = Plaintext - - -type Password a - = Password String - - -type alias Auth a = - { name : String - , password : Password a - } - - -type Verified - = Verified - - -type Hashed - = Hashed diff --git a/src/Evergreen/V77/Data/Barter.elm b/src/Evergreen/V77/Data/Barter.elm deleted file mode 100644 index 0dded15d..00000000 --- a/src/Evergreen/V77/Data/Barter.elm +++ /dev/null @@ -1,33 +0,0 @@ -module Evergreen.V77.Data.Barter exposing (..) - -import AssocList -import Dict -import Evergreen.V77.Data.Item - - -type Message - = BarterIsEmpty - | PlayerOfferNotValuableEnough - | YouGaveStuffForFree - - -type TransferNPosition - = PlayerKeptItem Evergreen.V77.Data.Item.Id - | VendorKeptItem Evergreen.V77.Data.Item.Id - | PlayerTradedItem Evergreen.V77.Data.Item.Id - | VendorTradedItem Evergreen.V77.Data.Item.Id - | PlayerKeptCaps - | VendorKeptCaps - | PlayerTradedCaps - | VendorTradedCaps - - -type alias State = - { playerItems : Dict.Dict Evergreen.V77.Data.Item.Id Int - , vendorItems : Dict.Dict Evergreen.V77.Data.Item.Id Int - , playerCaps : Int - , vendorCaps : Int - , lastMessage : Maybe Message - , transferNInputs : AssocList.Dict TransferNPosition String - , transferNHover : Maybe TransferNPosition - } diff --git a/src/Evergreen/V77/Data/Enemy.elm b/src/Evergreen/V77/Data/Enemy.elm deleted file mode 100644 index 09c2e146..00000000 --- a/src/Evergreen/V77/Data/Enemy.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V77.Data.Enemy exposing (..) - - -type Type - = GiantAnt - | ToughGiantAnt - | LesserRadscorpion - | Radscorpion diff --git a/src/Evergreen/V77/Data/Fight.elm b/src/Evergreen/V77/Data/Fight.elm deleted file mode 100644 index a5e6b6ab..00000000 --- a/src/Evergreen/V77/Data/Fight.elm +++ /dev/null @@ -1,78 +0,0 @@ -module Evergreen.V77.Data.Fight exposing (..) - -import AssocList -import AssocSet -import Evergreen.V77.Data.Enemy -import Evergreen.V77.Data.Fight.ShotType -import Evergreen.V77.Data.Perk -import Evergreen.V77.Data.Player.PlayerName -import Evergreen.V77.Data.Skill -import Evergreen.V77.Data.Special -import Evergreen.V77.Data.Trait -import Evergreen.V77.Logic - - -type OpponentType - = Npc Evergreen.V77.Data.Enemy.Type - | Player Evergreen.V77.Data.Player.PlayerName.PlayerName - - -type Who - = Attacker - | Target - - -type FightAction - = Start - { distanceHexes : Int - } - | ComeCloser - { hexes : Int - , remainingDistanceHexes : Int - } - | Attack - { damage : Int - , shotType : Evergreen.V77.Data.Fight.ShotType.ShotType - , remainingHp : Int - } - | Miss - { shotType : Evergreen.V77.Data.Fight.ShotType.ShotType - } - - -type FightResult - = AttackerWon - { xpGained : Int - , capsGained : Int - } - | TargetWon - { xpGained : Int - , capsGained : Int - } - | TargetAlreadyDead - | BothDead - | NobodyDead - - -type alias FightInfo = - { attacker : OpponentType - , target : OpponentType - , log : List ( Who, FightAction ) - , result : FightResult - } - - -type alias Opponent = - { type_ : OpponentType - , hp : Int - , maxHp : Int - , maxAp : Int - , sequence : Int - , traits : AssocSet.Set Evergreen.V77.Data.Trait.Trait - , perks : AssocList.Dict Evergreen.V77.Data.Perk.Perk Int - , caps : Int - , armorClass : Int - , attackStats : Evergreen.V77.Logic.AttackStats - , addedSkillPercentages : AssocList.Dict Evergreen.V77.Data.Skill.Skill Int - , baseSpecial : Evergreen.V77.Data.Special.Special - } diff --git a/src/Evergreen/V77/Data/Fight/Generator.elm b/src/Evergreen/V77/Data/Fight/Generator.elm deleted file mode 100644 index a701908f..00000000 --- a/src/Evergreen/V77/Data/Fight/Generator.elm +++ /dev/null @@ -1,12 +0,0 @@ -module Evergreen.V77.Data.Fight.Generator exposing (..) - -import Evergreen.V77.Data.Fight -import Evergreen.V77.Data.Message - - -type alias Fight = - { finalAttacker : Evergreen.V77.Data.Fight.Opponent - , finalTarget : Evergreen.V77.Data.Fight.Opponent - , fightInfo : Evergreen.V77.Data.Fight.FightInfo - , messageForTarget : Evergreen.V77.Data.Message.Message - } diff --git a/src/Evergreen/V77/Data/Fight/ShotType.elm b/src/Evergreen/V77/Data/Fight/ShotType.elm deleted file mode 100644 index e943cec4..00000000 --- a/src/Evergreen/V77/Data/Fight/ShotType.elm +++ /dev/null @@ -1,17 +0,0 @@ -module Evergreen.V77.Data.Fight.ShotType exposing (..) - - -type AimedShot - = Head - | Torso - | Eyes - | Groin - | LeftArm - | RightArm - | LeftLeg - | RightLeg - - -type ShotType - = NormalShot - | AimedShot AimedShot diff --git a/src/Evergreen/V77/Data/HealthStatus.elm b/src/Evergreen/V77/Data/HealthStatus.elm deleted file mode 100644 index 4a4e107e..00000000 --- a/src/Evergreen/V77/Data/HealthStatus.elm +++ /dev/null @@ -1,16 +0,0 @@ -module Evergreen.V77.Data.HealthStatus exposing (..) - - -type HealthStatus - = ExactHp - { current : Int - , max : Int - } - | Unhurt - | SlightlyWounded - | Wounded - | SeverelyWounded - | AlmostDead - | Dead - | Alive - | Unknown diff --git a/src/Evergreen/V77/Data/Item.elm b/src/Evergreen/V77/Data/Item.elm deleted file mode 100644 index 3dd88ea9..00000000 --- a/src/Evergreen/V77/Data/Item.elm +++ /dev/null @@ -1,21 +0,0 @@ -module Evergreen.V77.Data.Item exposing (..) - - -type alias Id = - Int - - -type Kind - = Stimpak - | BigBookOfScience - | DeansElectronics - | FirstAidBook - | GunsAndBullets - | ScoutHandbook - - -type alias Item = - { id : Id - , kind : Kind - , count : Int - } diff --git a/src/Evergreen/V77/Data/Map.elm b/src/Evergreen/V77/Data/Map.elm deleted file mode 100644 index 6727ec74..00000000 --- a/src/Evergreen/V77/Data/Map.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V77.Data.Map exposing (..) - - -type alias TileNum = - Int - - -type alias TileCoords = - ( Int, Int ) diff --git a/src/Evergreen/V77/Data/Message.elm b/src/Evergreen/V77/Data/Message.elm deleted file mode 100644 index 5bb4a683..00000000 --- a/src/Evergreen/V77/Data/Message.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V77.Data.Message exposing (..) - -import Evergreen.V77.Data.Fight -import Evergreen.V77.Data.Player.PlayerName -import Time - - -type Type - = Welcome - | YouAdvancedLevel - { newLevel : Int - } - | YouWereAttacked - { attacker : Evergreen.V77.Data.Player.PlayerName.PlayerName - , fightInfo : Evergreen.V77.Data.Fight.FightInfo - } - - -type alias Message = - { type_ : Type - , hasBeenRead : Bool - , date : Time.Posix - } diff --git a/src/Evergreen/V77/Data/NewChar.elm b/src/Evergreen/V77/Data/NewChar.elm deleted file mode 100644 index 41f799f2..00000000 --- a/src/Evergreen/V77/Data/NewChar.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V77.Data.NewChar exposing (..) - -import AssocSet -import Evergreen.V77.Data.Skill -import Evergreen.V77.Data.Special -import Evergreen.V77.Data.Trait - - -type CreationError - = DoesNotHaveThreeTaggedSkills - | HasSpecialPointsLeft - | UsedMoreSpecialPointsThanAvailable - | HasSpecialOutOfRange - | HasMoreThanTwoTraits - - -type alias NewChar = - { baseSpecial : Evergreen.V77.Data.Special.Special - , availableSpecial : Int - , taggedSkills : AssocSet.Set Evergreen.V77.Data.Skill.Skill - , traits : AssocSet.Set Evergreen.V77.Data.Trait.Trait - , error : Maybe CreationError - } diff --git a/src/Evergreen/V77/Data/Perk.elm b/src/Evergreen/V77/Data/Perk.elm deleted file mode 100644 index e1352649..00000000 --- a/src/Evergreen/V77/Data/Perk.elm +++ /dev/null @@ -1,13 +0,0 @@ -module Evergreen.V77.Data.Perk exposing (..) - - -type Perk - = BonusHthDamage - | MasterTrader - | Awareness - | CautiousNature - | Comprehension - | EarlierSequence - | FasterHealing - | Educated - | Tag diff --git a/src/Evergreen/V77/Data/Player.elm b/src/Evergreen/V77/Data/Player.elm deleted file mode 100644 index b453011b..00000000 --- a/src/Evergreen/V77/Data/Player.elm +++ /dev/null @@ -1,75 +0,0 @@ -module Evergreen.V77.Data.Player exposing (..) - -import AssocList -import AssocSet -import Dict -import Evergreen.V77.Data.Auth -import Evergreen.V77.Data.HealthStatus -import Evergreen.V77.Data.Item -import Evergreen.V77.Data.Map -import Evergreen.V77.Data.Message -import Evergreen.V77.Data.Perk -import Evergreen.V77.Data.Player.PlayerName -import Evergreen.V77.Data.Skill -import Evergreen.V77.Data.Special -import Evergreen.V77.Data.Trait -import Evergreen.V77.Data.Xp - - -type alias COtherPlayer = - { level : Evergreen.V77.Data.Xp.Level - , name : Evergreen.V77.Data.Player.PlayerName.PlayerName - , wins : Int - , losses : Int - , healthStatus : Evergreen.V77.Data.HealthStatus.HealthStatus - } - - -type alias CPlayer = - { hp : Int - , maxHp : Int - , xp : Evergreen.V77.Data.Xp.Xp - , name : Evergreen.V77.Data.Player.PlayerName.PlayerName - , baseSpecial : Evergreen.V77.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V77.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V77.Data.Perk.Perk Int - , messages : List Evergreen.V77.Data.Message.Message - , items : Dict.Dict Evergreen.V77.Data.Item.Id Evergreen.V77.Data.Item.Item - , traits : AssocSet.Set Evergreen.V77.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V77.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V77.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - } - - -type Player a - = NeedsCharCreated (Evergreen.V77.Data.Auth.Auth Evergreen.V77.Data.Auth.Verified) - | Player a - - -type alias SPlayer = - { name : Evergreen.V77.Data.Player.PlayerName.PlayerName - , password : Evergreen.V77.Data.Auth.Password Evergreen.V77.Data.Auth.Verified - , hp : Int - , maxHp : Int - , xp : Int - , baseSpecial : Evergreen.V77.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V77.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V77.Data.Perk.Perk Int - , messages : List Evergreen.V77.Data.Message.Message - , items : Dict.Dict Evergreen.V77.Data.Item.Id Evergreen.V77.Data.Item.Item - , traits : AssocSet.Set Evergreen.V77.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V77.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V77.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - } diff --git a/src/Evergreen/V77/Data/Player/PlayerName.elm b/src/Evergreen/V77/Data/Player/PlayerName.elm deleted file mode 100644 index 3ae101cb..00000000 --- a/src/Evergreen/V77/Data/Player/PlayerName.elm +++ /dev/null @@ -1,5 +0,0 @@ -module Evergreen.V77.Data.Player.PlayerName exposing (..) - - -type alias PlayerName = - String diff --git a/src/Evergreen/V77/Data/Skill.elm b/src/Evergreen/V77/Data/Skill.elm deleted file mode 100644 index 38b082f2..00000000 --- a/src/Evergreen/V77/Data/Skill.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V77.Data.Skill exposing (..) - - -type Skill - = SmallGuns - | BigGuns - | EnergyWeapons - | Unarmed - | MeleeWeapons - | Throwing - | FirstAid - | Doctor - | Sneak - | Lockpick - | Steal - | Traps - | Science - | Repair - | Speech - | Barter - | Gambling - | Outdoorsman diff --git a/src/Evergreen/V77/Data/Special.elm b/src/Evergreen/V77/Data/Special.elm deleted file mode 100644 index 9f802407..00000000 --- a/src/Evergreen/V77/Data/Special.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V77.Data.Special exposing (..) - - -type alias Special = - { strength : Int - , perception : Int - , endurance : Int - , charisma : Int - , intelligence : Int - , agility : Int - , luck : Int - } - - -type SpecialType - = Strength - | Perception - | Endurance - | Charisma - | Intelligence - | Agility - | Luck diff --git a/src/Evergreen/V77/Data/Trait.elm b/src/Evergreen/V77/Data/Trait.elm deleted file mode 100644 index 74a650f5..00000000 --- a/src/Evergreen/V77/Data/Trait.elm +++ /dev/null @@ -1,10 +0,0 @@ -module Evergreen.V77.Data.Trait exposing (..) - - -type Trait - = Kamikaze - | Bruiser - | Gifted - | SmallFrame - | Skilled - | HeavyHanded diff --git a/src/Evergreen/V77/Data/Vendor.elm b/src/Evergreen/V77/Data/Vendor.elm deleted file mode 100644 index 90ef9e80..00000000 --- a/src/Evergreen/V77/Data/Vendor.elm +++ /dev/null @@ -1,17 +0,0 @@ -module Evergreen.V77.Data.Vendor exposing (..) - -import Dict -import Evergreen.V77.Data.Item - - -type Name - = KlamathMaidaBuckner - | DenFlick - - -type alias Vendor = - { name : Name - , items : Dict.Dict Evergreen.V77.Data.Item.Id Evergreen.V77.Data.Item.Item - , caps : Int - , barterSkill : Int - } diff --git a/src/Evergreen/V77/Data/World.elm b/src/Evergreen/V77/Data/World.elm deleted file mode 100644 index 13da1b0f..00000000 --- a/src/Evergreen/V77/Data/World.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.V77.Data.World exposing (..) - -import AssocList -import Evergreen.V77.Data.Auth -import Evergreen.V77.Data.Player -import Evergreen.V77.Data.Player.PlayerName -import Evergreen.V77.Data.Vendor -import Time - - -type alias WorldLoggedOutData = - { players : List Evergreen.V77.Data.Player.COtherPlayer - } - - -type alias WorldLoggedInData = - { player : Evergreen.V77.Data.Player.Player Evergreen.V77.Data.Player.CPlayer - , otherPlayers : List Evergreen.V77.Data.Player.COtherPlayer - , playerRank : Int - , vendors : AssocList.Dict Evergreen.V77.Data.Vendor.Name Evergreen.V77.Data.Vendor.Vendor - } - - -type alias AdminData = - { players : List (Evergreen.V77.Data.Player.Player Evergreen.V77.Data.Player.SPlayer) - , loggedInPlayers : List Evergreen.V77.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - } - - -type World - = WorldNotInitialized (Evergreen.V77.Data.Auth.Auth Evergreen.V77.Data.Auth.Plaintext) - | WorldLoggedOut (Evergreen.V77.Data.Auth.Auth Evergreen.V77.Data.Auth.Plaintext) WorldLoggedOutData - | WorldLoggedIn WorldLoggedInData - | WorldAdmin AdminData diff --git a/src/Evergreen/V77/Data/Xp.elm b/src/Evergreen/V77/Data/Xp.elm deleted file mode 100644 index 1b7aa596..00000000 --- a/src/Evergreen/V77/Data/Xp.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V77.Data.Xp exposing (..) - - -type alias Level = - Int - - -type alias Xp = - Int diff --git a/src/Evergreen/V77/Frontend/Route.elm b/src/Evergreen/V77/Frontend/Route.elm deleted file mode 100644 index 46439fdd..00000000 --- a/src/Evergreen/V77/Frontend/Route.elm +++ /dev/null @@ -1,32 +0,0 @@ -module Evergreen.V77.Frontend.Route exposing (..) - -import Evergreen.V77.Data.Barter -import Evergreen.V77.Data.Fight -import Evergreen.V77.Data.Message - - -type TownRoute - = MainSquare - | Store - { barter : Evergreen.V77.Data.Barter.State - } - - -type AdminRoute - = Players - | LoggedIn - - -type Route - = Character - | Inventory - | Map - | Ladder - | Town TownRoute - | About - | News - | Fight Evergreen.V77.Data.Fight.FightInfo - | Messages - | Message Evergreen.V77.Data.Message.Message - | CharCreation - | Admin AdminRoute diff --git a/src/Evergreen/V77/Logic.elm b/src/Evergreen/V77/Logic.elm deleted file mode 100644 index 1cab94c2..00000000 --- a/src/Evergreen/V77/Logic.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V77.Logic exposing (..) - - -type alias AttackStats = - { minDamage : Int - , maxDamage : Int - , criticalChanceBonus : Int - } diff --git a/src/Evergreen/V77/Types.elm b/src/Evergreen/V77/Types.elm deleted file mode 100644 index b19138c9..00000000 --- a/src/Evergreen/V77/Types.elm +++ /dev/null @@ -1,156 +0,0 @@ -module Evergreen.V77.Types exposing (..) - -import AssocList -import Browser -import Browser.Navigation -import Dict -import Evergreen.V77.Data.Auth -import Evergreen.V77.Data.Barter -import Evergreen.V77.Data.Fight -import Evergreen.V77.Data.Fight.Generator -import Evergreen.V77.Data.Item -import Evergreen.V77.Data.Map -import Evergreen.V77.Data.Message -import Evergreen.V77.Data.NewChar -import Evergreen.V77.Data.Perk -import Evergreen.V77.Data.Player -import Evergreen.V77.Data.Player.PlayerName -import Evergreen.V77.Data.Skill -import Evergreen.V77.Data.Special -import Evergreen.V77.Data.Trait -import Evergreen.V77.Data.Vendor -import Evergreen.V77.Data.World -import Evergreen.V77.Frontend.Route -import File exposing (File) -import Lamdera -import Set -import Time -import Url - - -type alias FrontendModel = - { key : Browser.Navigation.Key - , time : Time.Posix - , zone : Time.Zone - , route : Evergreen.V77.Frontend.Route.Route - , world : Evergreen.V77.Data.World.World - , newChar : Evergreen.V77.Data.NewChar.NewChar - , alertMessage : Maybe String - , mapMouseCoords : Maybe ( Evergreen.V77.Data.Map.TileCoords, Set.Set Evergreen.V77.Data.Map.TileCoords ) - } - - -type alias BackendModel = - { players : Dict.Dict Evergreen.V77.Data.Player.PlayerName.PlayerName (Evergreen.V77.Data.Player.Player Evergreen.V77.Data.Player.SPlayer) - , loggedInPlayers : Dict.Dict Lamdera.ClientId Evergreen.V77.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - , adminLoggedIn : Maybe ( Lamdera.ClientId, Lamdera.SessionId ) - , time : Time.Posix - , vendors : AssocList.Dict Evergreen.V77.Data.Vendor.Name Evergreen.V77.Data.Vendor.Vendor - , lastItemId : Int - } - - -type BarterMsg - = AddPlayerItem Evergreen.V77.Data.Item.Id Int - | AddVendorItem Evergreen.V77.Data.Item.Id Int - | AddPlayerCaps Int - | AddVendorCaps Int - | RemovePlayerItem Evergreen.V77.Data.Item.Id Int - | RemoveVendorItem Evergreen.V77.Data.Item.Id Int - | RemovePlayerCaps Int - | RemoveVendorCaps Int - | ResetBarter - | ConfirmBarter - | SetTransferNInput Evergreen.V77.Data.Barter.TransferNPosition String - | SetTransferNHover Evergreen.V77.Data.Barter.TransferNPosition - | UnsetTransferNHover - - -type FrontendMsg - = UrlClicked Browser.UrlRequest - | UrlChanged Url.Url - | GoToRoute Evergreen.V77.Frontend.Route.Route - | Logout - | Login - | Register - | GotZone Time.Zone - | GotTime Time.Posix - | AskToFight Evergreen.V77.Data.Player.PlayerName.PlayerName - | AskToHeal - | AskToUseItem Evergreen.V77.Data.Item.Id - | AskToWander - | AskToChoosePerk Evergreen.V77.Data.Perk.Perk - | AskForExport - | ImportButtonClicked - | ImportFileSelected File - | AskToImport String - | Refresh - | AskToTagSkill Evergreen.V77.Data.Skill.Skill - | AskToUseSkillPoints Evergreen.V77.Data.Skill.Skill - | SetAuthName String - | SetAuthPassword String - | CreateChar - | NewCharIncSpecial Evergreen.V77.Data.Special.SpecialType - | NewCharDecSpecial Evergreen.V77.Data.Special.SpecialType - | NewCharToggleTaggedSkill Evergreen.V77.Data.Skill.Skill - | NewCharToggleTrait Evergreen.V77.Data.Trait.Trait - | MapMouseAtCoords Evergreen.V77.Data.Map.TileCoords - | MapMouseOut - | MapMouseClick - | OpenMessage Evergreen.V77.Data.Message.Message - | AskToRemoveMessage Evergreen.V77.Data.Message.Message - | BarterMsg BarterMsg - - -type AdminToBackend - = ExportJson - | ImportJson String - - -type ToBackend - = LogMeIn (Evergreen.V77.Data.Auth.Auth Evergreen.V77.Data.Auth.Hashed) - | RegisterMe (Evergreen.V77.Data.Auth.Auth Evergreen.V77.Data.Auth.Hashed) - | CreateNewChar Evergreen.V77.Data.NewChar.NewChar - | LogMeOut - | Fight Evergreen.V77.Data.Player.PlayerName.PlayerName - | HealMe - | UseItem Evergreen.V77.Data.Item.Id - | Wander - | RefreshPlease - | TagSkill Evergreen.V77.Data.Skill.Skill - | UseSkillPoints Evergreen.V77.Data.Skill.Skill - | ChoosePerk Evergreen.V77.Data.Perk.Perk - | MoveTo Evergreen.V77.Data.Map.TileCoords (Set.Set Evergreen.V77.Data.Map.TileCoords) - | MessageWasRead Evergreen.V77.Data.Message.Message - | RemoveMessage Evergreen.V77.Data.Message.Message - | Barter Evergreen.V77.Data.Barter.State - | AdminToBackend AdminToBackend - - -type BackendMsg - = Connected Lamdera.SessionId Lamdera.ClientId - | Disconnected Lamdera.SessionId Lamdera.ClientId - | GeneratedFight Lamdera.ClientId Evergreen.V77.Data.Player.SPlayer Evergreen.V77.Data.Fight.Generator.Fight - | GeneratedNewVendorsStock ( AssocList.Dict Evergreen.V77.Data.Vendor.Name Evergreen.V77.Data.Vendor.Vendor, Int ) - | Tick Time.Posix - | CreateNewCharWithTime Lamdera.ClientId Evergreen.V77.Data.NewChar.NewChar Time.Posix - | LoggedToBackendMsg - - -type ToFrontend - = YourCurrentWorld Evergreen.V77.Data.World.WorldLoggedInData - | InitWorld Evergreen.V77.Data.World.WorldLoggedOutData - | RefreshedLoggedOut Evergreen.V77.Data.World.WorldLoggedOutData - | CurrentAdminData Evergreen.V77.Data.World.AdminData - | YourFightResult ( Evergreen.V77.Data.Fight.FightInfo, Evergreen.V77.Data.World.WorldLoggedInData ) - | YoureLoggedIn Evergreen.V77.Data.World.WorldLoggedInData - | YoureRegistered Evergreen.V77.Data.World.WorldLoggedInData - | CharCreationError Evergreen.V77.Data.NewChar.CreationError - | YouHaveCreatedChar Evergreen.V77.Data.World.WorldLoggedInData - | YoureLoggedOut Evergreen.V77.Data.World.WorldLoggedOutData - | AlertMessage String - | YoureLoggedInAsAdmin Evergreen.V77.Data.World.AdminData - | JsonExportDone String - | BarterDone ( Evergreen.V77.Data.World.WorldLoggedInData, Maybe Evergreen.V77.Data.Barter.Message ) - | BarterMessage Evergreen.V77.Data.Barter.Message diff --git a/src/Evergreen/V78/Data/Auth.elm b/src/Evergreen/V78/Data/Auth.elm deleted file mode 100644 index 1d888c86..00000000 --- a/src/Evergreen/V78/Data/Auth.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V78.Data.Auth exposing (..) - - -type Plaintext - = Plaintext - - -type Password a - = Password String - - -type alias Auth a = - { name : String - , password : Password a - } - - -type Verified - = Verified - - -type Hashed - = Hashed diff --git a/src/Evergreen/V78/Data/Barter.elm b/src/Evergreen/V78/Data/Barter.elm deleted file mode 100644 index a2de5bc6..00000000 --- a/src/Evergreen/V78/Data/Barter.elm +++ /dev/null @@ -1,33 +0,0 @@ -module Evergreen.V78.Data.Barter exposing (..) - -import AssocList -import Dict -import Evergreen.V78.Data.Item - - -type Message - = BarterIsEmpty - | PlayerOfferNotValuableEnough - | YouGaveStuffForFree - - -type TransferNPosition - = PlayerKeptItem Evergreen.V78.Data.Item.Id - | VendorKeptItem Evergreen.V78.Data.Item.Id - | PlayerTradedItem Evergreen.V78.Data.Item.Id - | VendorTradedItem Evergreen.V78.Data.Item.Id - | PlayerKeptCaps - | VendorKeptCaps - | PlayerTradedCaps - | VendorTradedCaps - - -type alias State = - { playerItems : Dict.Dict Evergreen.V78.Data.Item.Id Int - , vendorItems : Dict.Dict Evergreen.V78.Data.Item.Id Int - , playerCaps : Int - , vendorCaps : Int - , lastMessage : Maybe Message - , transferNInputs : AssocList.Dict TransferNPosition String - , transferNHover : Maybe TransferNPosition - } diff --git a/src/Evergreen/V78/Data/Enemy.elm b/src/Evergreen/V78/Data/Enemy.elm deleted file mode 100644 index b27d27db..00000000 --- a/src/Evergreen/V78/Data/Enemy.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V78.Data.Enemy exposing (..) - - -type Type - = GiantAnt - | ToughGiantAnt - | LesserRadscorpion - | Radscorpion diff --git a/src/Evergreen/V78/Data/Fight.elm b/src/Evergreen/V78/Data/Fight.elm deleted file mode 100644 index 8930889c..00000000 --- a/src/Evergreen/V78/Data/Fight.elm +++ /dev/null @@ -1,78 +0,0 @@ -module Evergreen.V78.Data.Fight exposing (..) - -import AssocList -import AssocSet -import Evergreen.V78.Data.Enemy -import Evergreen.V78.Data.Fight.ShotType -import Evergreen.V78.Data.Perk -import Evergreen.V78.Data.Player.PlayerName -import Evergreen.V78.Data.Skill -import Evergreen.V78.Data.Special -import Evergreen.V78.Data.Trait -import Evergreen.V78.Logic - - -type OpponentType - = Npc Evergreen.V78.Data.Enemy.Type - | Player Evergreen.V78.Data.Player.PlayerName.PlayerName - - -type Who - = Attacker - | Target - - -type FightAction - = Start - { distanceHexes : Int - } - | ComeCloser - { hexes : Int - , remainingDistanceHexes : Int - } - | Attack - { damage : Int - , shotType : Evergreen.V78.Data.Fight.ShotType.ShotType - , remainingHp : Int - } - | Miss - { shotType : Evergreen.V78.Data.Fight.ShotType.ShotType - } - - -type FightResult - = AttackerWon - { xpGained : Int - , capsGained : Int - } - | TargetWon - { xpGained : Int - , capsGained : Int - } - | TargetAlreadyDead - | BothDead - | NobodyDead - - -type alias FightInfo = - { attacker : OpponentType - , target : OpponentType - , log : List ( Who, FightAction ) - , result : FightResult - } - - -type alias Opponent = - { type_ : OpponentType - , hp : Int - , maxHp : Int - , maxAp : Int - , sequence : Int - , traits : AssocSet.Set Evergreen.V78.Data.Trait.Trait - , perks : AssocList.Dict Evergreen.V78.Data.Perk.Perk Int - , caps : Int - , armorClass : Int - , attackStats : Evergreen.V78.Logic.AttackStats - , addedSkillPercentages : AssocList.Dict Evergreen.V78.Data.Skill.Skill Int - , baseSpecial : Evergreen.V78.Data.Special.Special - } diff --git a/src/Evergreen/V78/Data/Fight/Generator.elm b/src/Evergreen/V78/Data/Fight/Generator.elm deleted file mode 100644 index 846a7c72..00000000 --- a/src/Evergreen/V78/Data/Fight/Generator.elm +++ /dev/null @@ -1,12 +0,0 @@ -module Evergreen.V78.Data.Fight.Generator exposing (..) - -import Evergreen.V78.Data.Fight -import Evergreen.V78.Data.Message - - -type alias Fight = - { finalAttacker : Evergreen.V78.Data.Fight.Opponent - , finalTarget : Evergreen.V78.Data.Fight.Opponent - , fightInfo : Evergreen.V78.Data.Fight.FightInfo - , messageForTarget : Evergreen.V78.Data.Message.Message - } diff --git a/src/Evergreen/V78/Data/Fight/ShotType.elm b/src/Evergreen/V78/Data/Fight/ShotType.elm deleted file mode 100644 index 08f22020..00000000 --- a/src/Evergreen/V78/Data/Fight/ShotType.elm +++ /dev/null @@ -1,17 +0,0 @@ -module Evergreen.V78.Data.Fight.ShotType exposing (..) - - -type AimedShot - = Head - | Torso - | Eyes - | Groin - | LeftArm - | RightArm - | LeftLeg - | RightLeg - - -type ShotType - = NormalShot - | AimedShot AimedShot diff --git a/src/Evergreen/V78/Data/HealthStatus.elm b/src/Evergreen/V78/Data/HealthStatus.elm deleted file mode 100644 index 0e026f4b..00000000 --- a/src/Evergreen/V78/Data/HealthStatus.elm +++ /dev/null @@ -1,16 +0,0 @@ -module Evergreen.V78.Data.HealthStatus exposing (..) - - -type HealthStatus - = ExactHp - { current : Int - , max : Int - } - | Unhurt - | SlightlyWounded - | Wounded - | SeverelyWounded - | AlmostDead - | Dead - | Alive - | Unknown diff --git a/src/Evergreen/V78/Data/Item.elm b/src/Evergreen/V78/Data/Item.elm deleted file mode 100644 index b240df48..00000000 --- a/src/Evergreen/V78/Data/Item.elm +++ /dev/null @@ -1,21 +0,0 @@ -module Evergreen.V78.Data.Item exposing (..) - - -type alias Id = - Int - - -type Kind - = Stimpak - | BigBookOfScience - | DeansElectronics - | FirstAidBook - | GunsAndBullets - | ScoutHandbook - - -type alias Item = - { id : Id - , kind : Kind - , count : Int - } diff --git a/src/Evergreen/V78/Data/Map.elm b/src/Evergreen/V78/Data/Map.elm deleted file mode 100644 index 33847e3e..00000000 --- a/src/Evergreen/V78/Data/Map.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V78.Data.Map exposing (..) - - -type alias TileNum = - Int - - -type alias TileCoords = - ( Int, Int ) diff --git a/src/Evergreen/V78/Data/Message.elm b/src/Evergreen/V78/Data/Message.elm deleted file mode 100644 index 5e0df3e5..00000000 --- a/src/Evergreen/V78/Data/Message.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V78.Data.Message exposing (..) - -import Evergreen.V78.Data.Fight -import Evergreen.V78.Data.Player.PlayerName -import Time - - -type Type - = Welcome - | YouAdvancedLevel - { newLevel : Int - } - | YouWereAttacked - { attacker : Evergreen.V78.Data.Player.PlayerName.PlayerName - , fightInfo : Evergreen.V78.Data.Fight.FightInfo - } - - -type alias Message = - { type_ : Type - , hasBeenRead : Bool - , date : Time.Posix - } diff --git a/src/Evergreen/V78/Data/NewChar.elm b/src/Evergreen/V78/Data/NewChar.elm deleted file mode 100644 index dc972a17..00000000 --- a/src/Evergreen/V78/Data/NewChar.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V78.Data.NewChar exposing (..) - -import AssocSet -import Evergreen.V78.Data.Skill -import Evergreen.V78.Data.Special -import Evergreen.V78.Data.Trait - - -type CreationError - = DoesNotHaveThreeTaggedSkills - | HasSpecialPointsLeft - | UsedMoreSpecialPointsThanAvailable - | HasSpecialOutOfRange - | HasMoreThanTwoTraits - - -type alias NewChar = - { baseSpecial : Evergreen.V78.Data.Special.Special - , availableSpecial : Int - , taggedSkills : AssocSet.Set Evergreen.V78.Data.Skill.Skill - , traits : AssocSet.Set Evergreen.V78.Data.Trait.Trait - , error : Maybe CreationError - } diff --git a/src/Evergreen/V78/Data/Perk.elm b/src/Evergreen/V78/Data/Perk.elm deleted file mode 100644 index ec80ff6d..00000000 --- a/src/Evergreen/V78/Data/Perk.elm +++ /dev/null @@ -1,15 +0,0 @@ -module Evergreen.V78.Data.Perk exposing (..) - - -type Perk - = BonusHthDamage - | MasterTrader - | Awareness - | CautiousNature - | Comprehension - | EarlierSequence - | FasterHealing - | HereAndNow - | Survivalist - | Educated - | Tag diff --git a/src/Evergreen/V78/Data/Player.elm b/src/Evergreen/V78/Data/Player.elm deleted file mode 100644 index 4ceeceef..00000000 --- a/src/Evergreen/V78/Data/Player.elm +++ /dev/null @@ -1,75 +0,0 @@ -module Evergreen.V78.Data.Player exposing (..) - -import AssocList -import AssocSet -import Dict -import Evergreen.V78.Data.Auth -import Evergreen.V78.Data.HealthStatus -import Evergreen.V78.Data.Item -import Evergreen.V78.Data.Map -import Evergreen.V78.Data.Message -import Evergreen.V78.Data.Perk -import Evergreen.V78.Data.Player.PlayerName -import Evergreen.V78.Data.Skill -import Evergreen.V78.Data.Special -import Evergreen.V78.Data.Trait -import Evergreen.V78.Data.Xp - - -type alias COtherPlayer = - { level : Evergreen.V78.Data.Xp.Level - , name : Evergreen.V78.Data.Player.PlayerName.PlayerName - , wins : Int - , losses : Int - , healthStatus : Evergreen.V78.Data.HealthStatus.HealthStatus - } - - -type alias CPlayer = - { hp : Int - , maxHp : Int - , xp : Evergreen.V78.Data.Xp.Xp - , name : Evergreen.V78.Data.Player.PlayerName.PlayerName - , baseSpecial : Evergreen.V78.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V78.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V78.Data.Perk.Perk Int - , messages : List Evergreen.V78.Data.Message.Message - , items : Dict.Dict Evergreen.V78.Data.Item.Id Evergreen.V78.Data.Item.Item - , traits : AssocSet.Set Evergreen.V78.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V78.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V78.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - } - - -type Player a - = NeedsCharCreated (Evergreen.V78.Data.Auth.Auth Evergreen.V78.Data.Auth.Verified) - | Player a - - -type alias SPlayer = - { name : Evergreen.V78.Data.Player.PlayerName.PlayerName - , password : Evergreen.V78.Data.Auth.Password Evergreen.V78.Data.Auth.Verified - , hp : Int - , maxHp : Int - , xp : Int - , baseSpecial : Evergreen.V78.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V78.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V78.Data.Perk.Perk Int - , messages : List Evergreen.V78.Data.Message.Message - , items : Dict.Dict Evergreen.V78.Data.Item.Id Evergreen.V78.Data.Item.Item - , traits : AssocSet.Set Evergreen.V78.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V78.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V78.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - } diff --git a/src/Evergreen/V78/Data/Player/PlayerName.elm b/src/Evergreen/V78/Data/Player/PlayerName.elm deleted file mode 100644 index c542e358..00000000 --- a/src/Evergreen/V78/Data/Player/PlayerName.elm +++ /dev/null @@ -1,5 +0,0 @@ -module Evergreen.V78.Data.Player.PlayerName exposing (..) - - -type alias PlayerName = - String diff --git a/src/Evergreen/V78/Data/Skill.elm b/src/Evergreen/V78/Data/Skill.elm deleted file mode 100644 index 41d44e26..00000000 --- a/src/Evergreen/V78/Data/Skill.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V78.Data.Skill exposing (..) - - -type Skill - = SmallGuns - | BigGuns - | EnergyWeapons - | Unarmed - | MeleeWeapons - | Throwing - | FirstAid - | Doctor - | Sneak - | Lockpick - | Steal - | Traps - | Science - | Repair - | Speech - | Barter - | Gambling - | Outdoorsman diff --git a/src/Evergreen/V78/Data/Special.elm b/src/Evergreen/V78/Data/Special.elm deleted file mode 100644 index 7341108c..00000000 --- a/src/Evergreen/V78/Data/Special.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V78.Data.Special exposing (..) - - -type alias Special = - { strength : Int - , perception : Int - , endurance : Int - , charisma : Int - , intelligence : Int - , agility : Int - , luck : Int - } - - -type SpecialType - = Strength - | Perception - | Endurance - | Charisma - | Intelligence - | Agility - | Luck diff --git a/src/Evergreen/V78/Data/Trait.elm b/src/Evergreen/V78/Data/Trait.elm deleted file mode 100644 index 22293461..00000000 --- a/src/Evergreen/V78/Data/Trait.elm +++ /dev/null @@ -1,10 +0,0 @@ -module Evergreen.V78.Data.Trait exposing (..) - - -type Trait - = Kamikaze - | Bruiser - | Gifted - | SmallFrame - | Skilled - | HeavyHanded diff --git a/src/Evergreen/V78/Data/Vendor.elm b/src/Evergreen/V78/Data/Vendor.elm deleted file mode 100644 index 8df84da7..00000000 --- a/src/Evergreen/V78/Data/Vendor.elm +++ /dev/null @@ -1,17 +0,0 @@ -module Evergreen.V78.Data.Vendor exposing (..) - -import Dict -import Evergreen.V78.Data.Item - - -type Name - = KlamathMaidaBuckner - | DenFlick - - -type alias Vendor = - { name : Name - , items : Dict.Dict Evergreen.V78.Data.Item.Id Evergreen.V78.Data.Item.Item - , caps : Int - , barterSkill : Int - } diff --git a/src/Evergreen/V78/Data/World.elm b/src/Evergreen/V78/Data/World.elm deleted file mode 100644 index ef682238..00000000 --- a/src/Evergreen/V78/Data/World.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.V78.Data.World exposing (..) - -import AssocList -import Evergreen.V78.Data.Auth -import Evergreen.V78.Data.Player -import Evergreen.V78.Data.Player.PlayerName -import Evergreen.V78.Data.Vendor -import Time - - -type alias WorldLoggedOutData = - { players : List Evergreen.V78.Data.Player.COtherPlayer - } - - -type alias WorldLoggedInData = - { player : Evergreen.V78.Data.Player.Player Evergreen.V78.Data.Player.CPlayer - , otherPlayers : List Evergreen.V78.Data.Player.COtherPlayer - , playerRank : Int - , vendors : AssocList.Dict Evergreen.V78.Data.Vendor.Name Evergreen.V78.Data.Vendor.Vendor - } - - -type alias AdminData = - { players : List (Evergreen.V78.Data.Player.Player Evergreen.V78.Data.Player.SPlayer) - , loggedInPlayers : List Evergreen.V78.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - } - - -type World - = WorldNotInitialized (Evergreen.V78.Data.Auth.Auth Evergreen.V78.Data.Auth.Plaintext) - | WorldLoggedOut (Evergreen.V78.Data.Auth.Auth Evergreen.V78.Data.Auth.Plaintext) WorldLoggedOutData - | WorldLoggedIn WorldLoggedInData - | WorldAdmin AdminData diff --git a/src/Evergreen/V78/Data/Xp.elm b/src/Evergreen/V78/Data/Xp.elm deleted file mode 100644 index 8c67920d..00000000 --- a/src/Evergreen/V78/Data/Xp.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V78.Data.Xp exposing (..) - - -type alias Level = - Int - - -type alias Xp = - Int diff --git a/src/Evergreen/V78/Frontend/Route.elm b/src/Evergreen/V78/Frontend/Route.elm deleted file mode 100644 index eb28ef6c..00000000 --- a/src/Evergreen/V78/Frontend/Route.elm +++ /dev/null @@ -1,32 +0,0 @@ -module Evergreen.V78.Frontend.Route exposing (..) - -import Evergreen.V78.Data.Barter -import Evergreen.V78.Data.Fight -import Evergreen.V78.Data.Message - - -type TownRoute - = MainSquare - | Store - { barter : Evergreen.V78.Data.Barter.State - } - - -type AdminRoute - = Players - | LoggedIn - - -type Route - = Character - | Inventory - | Map - | Ladder - | Town TownRoute - | About - | News - | Fight Evergreen.V78.Data.Fight.FightInfo - | Messages - | Message Evergreen.V78.Data.Message.Message - | CharCreation - | Admin AdminRoute diff --git a/src/Evergreen/V78/Logic.elm b/src/Evergreen/V78/Logic.elm deleted file mode 100644 index ebb8ab7c..00000000 --- a/src/Evergreen/V78/Logic.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V78.Logic exposing (..) - - -type alias AttackStats = - { minDamage : Int - , maxDamage : Int - , criticalChanceBonus : Int - } diff --git a/src/Evergreen/V78/Types.elm b/src/Evergreen/V78/Types.elm deleted file mode 100644 index 37e3663c..00000000 --- a/src/Evergreen/V78/Types.elm +++ /dev/null @@ -1,156 +0,0 @@ -module Evergreen.V78.Types exposing (..) - -import AssocList -import Browser -import Browser.Navigation -import Dict -import Evergreen.V78.Data.Auth -import Evergreen.V78.Data.Barter -import Evergreen.V78.Data.Fight -import Evergreen.V78.Data.Fight.Generator -import Evergreen.V78.Data.Item -import Evergreen.V78.Data.Map -import Evergreen.V78.Data.Message -import Evergreen.V78.Data.NewChar -import Evergreen.V78.Data.Perk -import Evergreen.V78.Data.Player -import Evergreen.V78.Data.Player.PlayerName -import Evergreen.V78.Data.Skill -import Evergreen.V78.Data.Special -import Evergreen.V78.Data.Trait -import Evergreen.V78.Data.Vendor -import Evergreen.V78.Data.World -import Evergreen.V78.Frontend.Route -import File exposing (File) -import Lamdera -import Set -import Time -import Url - - -type alias FrontendModel = - { key : Browser.Navigation.Key - , time : Time.Posix - , zone : Time.Zone - , route : Evergreen.V78.Frontend.Route.Route - , world : Evergreen.V78.Data.World.World - , newChar : Evergreen.V78.Data.NewChar.NewChar - , alertMessage : Maybe String - , mapMouseCoords : Maybe ( Evergreen.V78.Data.Map.TileCoords, Set.Set Evergreen.V78.Data.Map.TileCoords ) - } - - -type alias BackendModel = - { players : Dict.Dict Evergreen.V78.Data.Player.PlayerName.PlayerName (Evergreen.V78.Data.Player.Player Evergreen.V78.Data.Player.SPlayer) - , loggedInPlayers : Dict.Dict Lamdera.ClientId Evergreen.V78.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - , adminLoggedIn : Maybe ( Lamdera.ClientId, Lamdera.SessionId ) - , time : Time.Posix - , vendors : AssocList.Dict Evergreen.V78.Data.Vendor.Name Evergreen.V78.Data.Vendor.Vendor - , lastItemId : Int - } - - -type BarterMsg - = AddPlayerItem Evergreen.V78.Data.Item.Id Int - | AddVendorItem Evergreen.V78.Data.Item.Id Int - | AddPlayerCaps Int - | AddVendorCaps Int - | RemovePlayerItem Evergreen.V78.Data.Item.Id Int - | RemoveVendorItem Evergreen.V78.Data.Item.Id Int - | RemovePlayerCaps Int - | RemoveVendorCaps Int - | ResetBarter - | ConfirmBarter - | SetTransferNInput Evergreen.V78.Data.Barter.TransferNPosition String - | SetTransferNHover Evergreen.V78.Data.Barter.TransferNPosition - | UnsetTransferNHover - - -type FrontendMsg - = UrlClicked Browser.UrlRequest - | UrlChanged Url.Url - | GoToRoute Evergreen.V78.Frontend.Route.Route - | Logout - | Login - | Register - | GotZone Time.Zone - | GotTime Time.Posix - | AskToFight Evergreen.V78.Data.Player.PlayerName.PlayerName - | AskToHeal - | AskToUseItem Evergreen.V78.Data.Item.Id - | AskToWander - | AskToChoosePerk Evergreen.V78.Data.Perk.Perk - | AskForExport - | ImportButtonClicked - | ImportFileSelected File - | AskToImport String - | Refresh - | AskToTagSkill Evergreen.V78.Data.Skill.Skill - | AskToUseSkillPoints Evergreen.V78.Data.Skill.Skill - | SetAuthName String - | SetAuthPassword String - | CreateChar - | NewCharIncSpecial Evergreen.V78.Data.Special.SpecialType - | NewCharDecSpecial Evergreen.V78.Data.Special.SpecialType - | NewCharToggleTaggedSkill Evergreen.V78.Data.Skill.Skill - | NewCharToggleTrait Evergreen.V78.Data.Trait.Trait - | MapMouseAtCoords Evergreen.V78.Data.Map.TileCoords - | MapMouseOut - | MapMouseClick - | OpenMessage Evergreen.V78.Data.Message.Message - | AskToRemoveMessage Evergreen.V78.Data.Message.Message - | BarterMsg BarterMsg - - -type AdminToBackend - = ExportJson - | ImportJson String - - -type ToBackend - = LogMeIn (Evergreen.V78.Data.Auth.Auth Evergreen.V78.Data.Auth.Hashed) - | RegisterMe (Evergreen.V78.Data.Auth.Auth Evergreen.V78.Data.Auth.Hashed) - | CreateNewChar Evergreen.V78.Data.NewChar.NewChar - | LogMeOut - | Fight Evergreen.V78.Data.Player.PlayerName.PlayerName - | HealMe - | UseItem Evergreen.V78.Data.Item.Id - | Wander - | RefreshPlease - | TagSkill Evergreen.V78.Data.Skill.Skill - | UseSkillPoints Evergreen.V78.Data.Skill.Skill - | ChoosePerk Evergreen.V78.Data.Perk.Perk - | MoveTo Evergreen.V78.Data.Map.TileCoords (Set.Set Evergreen.V78.Data.Map.TileCoords) - | MessageWasRead Evergreen.V78.Data.Message.Message - | RemoveMessage Evergreen.V78.Data.Message.Message - | Barter Evergreen.V78.Data.Barter.State - | AdminToBackend AdminToBackend - - -type BackendMsg - = Connected Lamdera.SessionId Lamdera.ClientId - | Disconnected Lamdera.SessionId Lamdera.ClientId - | GeneratedFight Lamdera.ClientId Evergreen.V78.Data.Player.SPlayer Evergreen.V78.Data.Fight.Generator.Fight - | GeneratedNewVendorsStock ( AssocList.Dict Evergreen.V78.Data.Vendor.Name Evergreen.V78.Data.Vendor.Vendor, Int ) - | Tick Time.Posix - | CreateNewCharWithTime Lamdera.ClientId Evergreen.V78.Data.NewChar.NewChar Time.Posix - | LoggedToBackendMsg - - -type ToFrontend - = YourCurrentWorld Evergreen.V78.Data.World.WorldLoggedInData - | InitWorld Evergreen.V78.Data.World.WorldLoggedOutData - | RefreshedLoggedOut Evergreen.V78.Data.World.WorldLoggedOutData - | CurrentAdminData Evergreen.V78.Data.World.AdminData - | YourFightResult ( Evergreen.V78.Data.Fight.FightInfo, Evergreen.V78.Data.World.WorldLoggedInData ) - | YoureLoggedIn Evergreen.V78.Data.World.WorldLoggedInData - | YoureRegistered Evergreen.V78.Data.World.WorldLoggedInData - | CharCreationError Evergreen.V78.Data.NewChar.CreationError - | YouHaveCreatedChar Evergreen.V78.Data.World.WorldLoggedInData - | YoureLoggedOut Evergreen.V78.Data.World.WorldLoggedOutData - | AlertMessage String - | YoureLoggedInAsAdmin Evergreen.V78.Data.World.AdminData - | JsonExportDone String - | BarterDone ( Evergreen.V78.Data.World.WorldLoggedInData, Maybe Evergreen.V78.Data.Barter.Message ) - | BarterMessage Evergreen.V78.Data.Barter.Message diff --git a/src/Evergreen/V79/Data/Auth.elm b/src/Evergreen/V79/Data/Auth.elm deleted file mode 100644 index 21d2670c..00000000 --- a/src/Evergreen/V79/Data/Auth.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V79.Data.Auth exposing (..) - - -type Plaintext - = Plaintext - - -type Password a - = Password String - - -type alias Auth a = - { name : String - , password : Password a - } - - -type Verified - = Verified - - -type Hashed - = Hashed diff --git a/src/Evergreen/V79/Data/Barter.elm b/src/Evergreen/V79/Data/Barter.elm deleted file mode 100644 index 9c77990e..00000000 --- a/src/Evergreen/V79/Data/Barter.elm +++ /dev/null @@ -1,33 +0,0 @@ -module Evergreen.V79.Data.Barter exposing (..) - -import AssocList -import Dict -import Evergreen.V79.Data.Item - - -type Message - = BarterIsEmpty - | PlayerOfferNotValuableEnough - | YouGaveStuffForFree - - -type TransferNPosition - = PlayerKeptItem Evergreen.V79.Data.Item.Id - | VendorKeptItem Evergreen.V79.Data.Item.Id - | PlayerTradedItem Evergreen.V79.Data.Item.Id - | VendorTradedItem Evergreen.V79.Data.Item.Id - | PlayerKeptCaps - | VendorKeptCaps - | PlayerTradedCaps - | VendorTradedCaps - - -type alias State = - { playerItems : Dict.Dict Evergreen.V79.Data.Item.Id Int - , vendorItems : Dict.Dict Evergreen.V79.Data.Item.Id Int - , playerCaps : Int - , vendorCaps : Int - , lastMessage : Maybe Message - , transferNInputs : AssocList.Dict TransferNPosition String - , transferNHover : Maybe TransferNPosition - } diff --git a/src/Evergreen/V79/Data/Enemy.elm b/src/Evergreen/V79/Data/Enemy.elm deleted file mode 100644 index 21a34ab4..00000000 --- a/src/Evergreen/V79/Data/Enemy.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V79.Data.Enemy exposing (..) - - -type Type - = GiantAnt - | ToughGiantAnt - | LesserRadscorpion - | Radscorpion diff --git a/src/Evergreen/V79/Data/Fight.elm b/src/Evergreen/V79/Data/Fight.elm deleted file mode 100644 index 037e4d4b..00000000 --- a/src/Evergreen/V79/Data/Fight.elm +++ /dev/null @@ -1,78 +0,0 @@ -module Evergreen.V79.Data.Fight exposing (..) - -import AssocList -import AssocSet -import Evergreen.V79.Data.Enemy -import Evergreen.V79.Data.Fight.ShotType -import Evergreen.V79.Data.Perk -import Evergreen.V79.Data.Player.PlayerName -import Evergreen.V79.Data.Skill -import Evergreen.V79.Data.Special -import Evergreen.V79.Data.Trait -import Evergreen.V79.Logic - - -type OpponentType - = Npc Evergreen.V79.Data.Enemy.Type - | Player Evergreen.V79.Data.Player.PlayerName.PlayerName - - -type Who - = Attacker - | Target - - -type FightAction - = Start - { distanceHexes : Int - } - | ComeCloser - { hexes : Int - , remainingDistanceHexes : Int - } - | Attack - { damage : Int - , shotType : Evergreen.V79.Data.Fight.ShotType.ShotType - , remainingHp : Int - } - | Miss - { shotType : Evergreen.V79.Data.Fight.ShotType.ShotType - } - - -type FightResult - = AttackerWon - { xpGained : Int - , capsGained : Int - } - | TargetWon - { xpGained : Int - , capsGained : Int - } - | TargetAlreadyDead - | BothDead - | NobodyDead - - -type alias FightInfo = - { attacker : OpponentType - , target : OpponentType - , log : List ( Who, FightAction ) - , result : FightResult - } - - -type alias Opponent = - { type_ : OpponentType - , hp : Int - , maxHp : Int - , maxAp : Int - , sequence : Int - , traits : AssocSet.Set Evergreen.V79.Data.Trait.Trait - , perks : AssocList.Dict Evergreen.V79.Data.Perk.Perk Int - , caps : Int - , armorClass : Int - , attackStats : Evergreen.V79.Logic.AttackStats - , addedSkillPercentages : AssocList.Dict Evergreen.V79.Data.Skill.Skill Int - , special : Evergreen.V79.Data.Special.Special - } diff --git a/src/Evergreen/V79/Data/Fight/Generator.elm b/src/Evergreen/V79/Data/Fight/Generator.elm deleted file mode 100644 index 08040bb8..00000000 --- a/src/Evergreen/V79/Data/Fight/Generator.elm +++ /dev/null @@ -1,12 +0,0 @@ -module Evergreen.V79.Data.Fight.Generator exposing (..) - -import Evergreen.V79.Data.Fight -import Evergreen.V79.Data.Message - - -type alias Fight = - { finalAttacker : Evergreen.V79.Data.Fight.Opponent - , finalTarget : Evergreen.V79.Data.Fight.Opponent - , fightInfo : Evergreen.V79.Data.Fight.FightInfo - , messageForTarget : Evergreen.V79.Data.Message.Message - } diff --git a/src/Evergreen/V79/Data/Fight/ShotType.elm b/src/Evergreen/V79/Data/Fight/ShotType.elm deleted file mode 100644 index 8f785b53..00000000 --- a/src/Evergreen/V79/Data/Fight/ShotType.elm +++ /dev/null @@ -1,17 +0,0 @@ -module Evergreen.V79.Data.Fight.ShotType exposing (..) - - -type AimedShot - = Head - | Torso - | Eyes - | Groin - | LeftArm - | RightArm - | LeftLeg - | RightLeg - - -type ShotType - = NormalShot - | AimedShot AimedShot diff --git a/src/Evergreen/V79/Data/HealthStatus.elm b/src/Evergreen/V79/Data/HealthStatus.elm deleted file mode 100644 index 0f648ea1..00000000 --- a/src/Evergreen/V79/Data/HealthStatus.elm +++ /dev/null @@ -1,16 +0,0 @@ -module Evergreen.V79.Data.HealthStatus exposing (..) - - -type HealthStatus - = ExactHp - { current : Int - , max : Int - } - | Unhurt - | SlightlyWounded - | Wounded - | SeverelyWounded - | AlmostDead - | Dead - | Alive - | Unknown diff --git a/src/Evergreen/V79/Data/Item.elm b/src/Evergreen/V79/Data/Item.elm deleted file mode 100644 index 1288aec3..00000000 --- a/src/Evergreen/V79/Data/Item.elm +++ /dev/null @@ -1,21 +0,0 @@ -module Evergreen.V79.Data.Item exposing (..) - - -type alias Id = - Int - - -type Kind - = Stimpak - | BigBookOfScience - | DeansElectronics - | FirstAidBook - | GunsAndBullets - | ScoutHandbook - - -type alias Item = - { id : Id - , kind : Kind - , count : Int - } diff --git a/src/Evergreen/V79/Data/Map.elm b/src/Evergreen/V79/Data/Map.elm deleted file mode 100644 index eb9ad4ff..00000000 --- a/src/Evergreen/V79/Data/Map.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V79.Data.Map exposing (..) - - -type alias TileNum = - Int - - -type alias TileCoords = - ( Int, Int ) diff --git a/src/Evergreen/V79/Data/Message.elm b/src/Evergreen/V79/Data/Message.elm deleted file mode 100644 index c0d19ffa..00000000 --- a/src/Evergreen/V79/Data/Message.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V79.Data.Message exposing (..) - -import Evergreen.V79.Data.Fight -import Evergreen.V79.Data.Player.PlayerName -import Time - - -type Type - = Welcome - | YouAdvancedLevel - { newLevel : Int - } - | YouWereAttacked - { attacker : Evergreen.V79.Data.Player.PlayerName.PlayerName - , fightInfo : Evergreen.V79.Data.Fight.FightInfo - } - - -type alias Message = - { type_ : Type - , hasBeenRead : Bool - , date : Time.Posix - } diff --git a/src/Evergreen/V79/Data/NewChar.elm b/src/Evergreen/V79/Data/NewChar.elm deleted file mode 100644 index f0e3454e..00000000 --- a/src/Evergreen/V79/Data/NewChar.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V79.Data.NewChar exposing (..) - -import AssocSet -import Evergreen.V79.Data.Skill -import Evergreen.V79.Data.Special -import Evergreen.V79.Data.Trait - - -type CreationError - = DoesNotHaveThreeTaggedSkills - | HasSpecialPointsLeft - | UsedMoreSpecialPointsThanAvailable - | HasSpecialOutOfRange - | HasMoreThanTwoTraits - - -type alias NewChar = - { baseSpecial : Evergreen.V79.Data.Special.Special - , availableSpecial : Int - , taggedSkills : AssocSet.Set Evergreen.V79.Data.Skill.Skill - , traits : AssocSet.Set Evergreen.V79.Data.Trait.Trait - , error : Maybe CreationError - } diff --git a/src/Evergreen/V79/Data/Perk.elm b/src/Evergreen/V79/Data/Perk.elm deleted file mode 100644 index f35e92d5..00000000 --- a/src/Evergreen/V79/Data/Perk.elm +++ /dev/null @@ -1,15 +0,0 @@ -module Evergreen.V79.Data.Perk exposing (..) - - -type Perk - = BonusHthDamage - | MasterTrader - | Awareness - | CautiousNature - | Comprehension - | EarlierSequence - | FasterHealing - | HereAndNow - | Survivalist - | Educated - | Tag diff --git a/src/Evergreen/V79/Data/Player.elm b/src/Evergreen/V79/Data/Player.elm deleted file mode 100644 index ba7106b8..00000000 --- a/src/Evergreen/V79/Data/Player.elm +++ /dev/null @@ -1,75 +0,0 @@ -module Evergreen.V79.Data.Player exposing (..) - -import AssocList -import AssocSet -import Dict -import Evergreen.V79.Data.Auth -import Evergreen.V79.Data.HealthStatus -import Evergreen.V79.Data.Item -import Evergreen.V79.Data.Map -import Evergreen.V79.Data.Message -import Evergreen.V79.Data.Perk -import Evergreen.V79.Data.Player.PlayerName -import Evergreen.V79.Data.Skill -import Evergreen.V79.Data.Special -import Evergreen.V79.Data.Trait -import Evergreen.V79.Data.Xp - - -type alias COtherPlayer = - { level : Evergreen.V79.Data.Xp.Level - , name : Evergreen.V79.Data.Player.PlayerName.PlayerName - , wins : Int - , losses : Int - , healthStatus : Evergreen.V79.Data.HealthStatus.HealthStatus - } - - -type alias CPlayer = - { hp : Int - , maxHp : Int - , xp : Evergreen.V79.Data.Xp.Xp - , name : Evergreen.V79.Data.Player.PlayerName.PlayerName - , special : Evergreen.V79.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V79.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V79.Data.Perk.Perk Int - , messages : List Evergreen.V79.Data.Message.Message - , items : Dict.Dict Evergreen.V79.Data.Item.Id Evergreen.V79.Data.Item.Item - , traits : AssocSet.Set Evergreen.V79.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V79.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V79.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - } - - -type Player a - = NeedsCharCreated (Evergreen.V79.Data.Auth.Auth Evergreen.V79.Data.Auth.Verified) - | Player a - - -type alias SPlayer = - { name : Evergreen.V79.Data.Player.PlayerName.PlayerName - , password : Evergreen.V79.Data.Auth.Password Evergreen.V79.Data.Auth.Verified - , hp : Int - , maxHp : Int - , xp : Int - , special : Evergreen.V79.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V79.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V79.Data.Perk.Perk Int - , messages : List Evergreen.V79.Data.Message.Message - , items : Dict.Dict Evergreen.V79.Data.Item.Id Evergreen.V79.Data.Item.Item - , traits : AssocSet.Set Evergreen.V79.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V79.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V79.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - } diff --git a/src/Evergreen/V79/Data/Player/PlayerName.elm b/src/Evergreen/V79/Data/Player/PlayerName.elm deleted file mode 100644 index 86a81386..00000000 --- a/src/Evergreen/V79/Data/Player/PlayerName.elm +++ /dev/null @@ -1,5 +0,0 @@ -module Evergreen.V79.Data.Player.PlayerName exposing (..) - - -type alias PlayerName = - String diff --git a/src/Evergreen/V79/Data/Skill.elm b/src/Evergreen/V79/Data/Skill.elm deleted file mode 100644 index a9fe157e..00000000 --- a/src/Evergreen/V79/Data/Skill.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V79.Data.Skill exposing (..) - - -type Skill - = SmallGuns - | BigGuns - | EnergyWeapons - | Unarmed - | MeleeWeapons - | Throwing - | FirstAid - | Doctor - | Sneak - | Lockpick - | Steal - | Traps - | Science - | Repair - | Speech - | Barter - | Gambling - | Outdoorsman diff --git a/src/Evergreen/V79/Data/Special.elm b/src/Evergreen/V79/Data/Special.elm deleted file mode 100644 index 10d28a31..00000000 --- a/src/Evergreen/V79/Data/Special.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V79.Data.Special exposing (..) - - -type alias Special = - { strength : Int - , perception : Int - , endurance : Int - , charisma : Int - , intelligence : Int - , agility : Int - , luck : Int - } - - -type SpecialType - = Strength - | Perception - | Endurance - | Charisma - | Intelligence - | Agility - | Luck diff --git a/src/Evergreen/V79/Data/Trait.elm b/src/Evergreen/V79/Data/Trait.elm deleted file mode 100644 index fcb6347d..00000000 --- a/src/Evergreen/V79/Data/Trait.elm +++ /dev/null @@ -1,10 +0,0 @@ -module Evergreen.V79.Data.Trait exposing (..) - - -type Trait - = Kamikaze - | Bruiser - | Gifted - | SmallFrame - | Skilled - | HeavyHanded diff --git a/src/Evergreen/V79/Data/Vendor.elm b/src/Evergreen/V79/Data/Vendor.elm deleted file mode 100644 index ea29df17..00000000 --- a/src/Evergreen/V79/Data/Vendor.elm +++ /dev/null @@ -1,17 +0,0 @@ -module Evergreen.V79.Data.Vendor exposing (..) - -import Dict -import Evergreen.V79.Data.Item - - -type Name - = KlamathMaidaBuckner - | DenFlick - - -type alias Vendor = - { name : Name - , items : Dict.Dict Evergreen.V79.Data.Item.Id Evergreen.V79.Data.Item.Item - , caps : Int - , barterSkill : Int - } diff --git a/src/Evergreen/V79/Data/World.elm b/src/Evergreen/V79/Data/World.elm deleted file mode 100644 index e896ba3e..00000000 --- a/src/Evergreen/V79/Data/World.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.V79.Data.World exposing (..) - -import AssocList -import Evergreen.V79.Data.Auth -import Evergreen.V79.Data.Player -import Evergreen.V79.Data.Player.PlayerName -import Evergreen.V79.Data.Vendor -import Time - - -type alias WorldLoggedOutData = - { players : List Evergreen.V79.Data.Player.COtherPlayer - } - - -type alias WorldLoggedInData = - { player : Evergreen.V79.Data.Player.Player Evergreen.V79.Data.Player.CPlayer - , otherPlayers : List Evergreen.V79.Data.Player.COtherPlayer - , playerRank : Int - , vendors : AssocList.Dict Evergreen.V79.Data.Vendor.Name Evergreen.V79.Data.Vendor.Vendor - } - - -type alias AdminData = - { players : List (Evergreen.V79.Data.Player.Player Evergreen.V79.Data.Player.SPlayer) - , loggedInPlayers : List Evergreen.V79.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - } - - -type World - = WorldNotInitialized (Evergreen.V79.Data.Auth.Auth Evergreen.V79.Data.Auth.Plaintext) - | WorldLoggedOut (Evergreen.V79.Data.Auth.Auth Evergreen.V79.Data.Auth.Plaintext) WorldLoggedOutData - | WorldLoggedIn WorldLoggedInData - | WorldAdmin AdminData diff --git a/src/Evergreen/V79/Data/Xp.elm b/src/Evergreen/V79/Data/Xp.elm deleted file mode 100644 index 0111bbe9..00000000 --- a/src/Evergreen/V79/Data/Xp.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V79.Data.Xp exposing (..) - - -type alias Level = - Int - - -type alias Xp = - Int diff --git a/src/Evergreen/V79/Frontend/Route.elm b/src/Evergreen/V79/Frontend/Route.elm deleted file mode 100644 index 7f2f9cc4..00000000 --- a/src/Evergreen/V79/Frontend/Route.elm +++ /dev/null @@ -1,32 +0,0 @@ -module Evergreen.V79.Frontend.Route exposing (..) - -import Evergreen.V79.Data.Barter -import Evergreen.V79.Data.Fight -import Evergreen.V79.Data.Message - - -type TownRoute - = MainSquare - | Store - { barter : Evergreen.V79.Data.Barter.State - } - - -type AdminRoute - = Players - | LoggedIn - - -type Route - = Character - | Inventory - | Map - | Ladder - | Town TownRoute - | About - | News - | Fight Evergreen.V79.Data.Fight.FightInfo - | Messages - | Message Evergreen.V79.Data.Message.Message - | CharCreation - | Admin AdminRoute diff --git a/src/Evergreen/V79/Logic.elm b/src/Evergreen/V79/Logic.elm deleted file mode 100644 index f4b5b023..00000000 --- a/src/Evergreen/V79/Logic.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V79.Logic exposing (..) - - -type alias AttackStats = - { minDamage : Int - , maxDamage : Int - , criticalChanceBonus : Int - } diff --git a/src/Evergreen/V79/Types.elm b/src/Evergreen/V79/Types.elm deleted file mode 100644 index 96830a1a..00000000 --- a/src/Evergreen/V79/Types.elm +++ /dev/null @@ -1,156 +0,0 @@ -module Evergreen.V79.Types exposing (..) - -import AssocList -import Browser -import Browser.Navigation -import Dict -import Evergreen.V79.Data.Auth -import Evergreen.V79.Data.Barter -import Evergreen.V79.Data.Fight -import Evergreen.V79.Data.Fight.Generator -import Evergreen.V79.Data.Item -import Evergreen.V79.Data.Map -import Evergreen.V79.Data.Message -import Evergreen.V79.Data.NewChar -import Evergreen.V79.Data.Perk -import Evergreen.V79.Data.Player -import Evergreen.V79.Data.Player.PlayerName -import Evergreen.V79.Data.Skill -import Evergreen.V79.Data.Special -import Evergreen.V79.Data.Trait -import Evergreen.V79.Data.Vendor -import Evergreen.V79.Data.World -import Evergreen.V79.Frontend.Route -import File exposing (File) -import Lamdera -import Set -import Time -import Url - - -type alias FrontendModel = - { key : Browser.Navigation.Key - , time : Time.Posix - , zone : Time.Zone - , route : Evergreen.V79.Frontend.Route.Route - , world : Evergreen.V79.Data.World.World - , newChar : Evergreen.V79.Data.NewChar.NewChar - , alertMessage : Maybe String - , mapMouseCoords : Maybe ( Evergreen.V79.Data.Map.TileCoords, Set.Set Evergreen.V79.Data.Map.TileCoords ) - } - - -type alias BackendModel = - { players : Dict.Dict Evergreen.V79.Data.Player.PlayerName.PlayerName (Evergreen.V79.Data.Player.Player Evergreen.V79.Data.Player.SPlayer) - , loggedInPlayers : Dict.Dict Lamdera.ClientId Evergreen.V79.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - , adminLoggedIn : Maybe ( Lamdera.ClientId, Lamdera.SessionId ) - , time : Time.Posix - , vendors : AssocList.Dict Evergreen.V79.Data.Vendor.Name Evergreen.V79.Data.Vendor.Vendor - , lastItemId : Int - } - - -type BarterMsg - = AddPlayerItem Evergreen.V79.Data.Item.Id Int - | AddVendorItem Evergreen.V79.Data.Item.Id Int - | AddPlayerCaps Int - | AddVendorCaps Int - | RemovePlayerItem Evergreen.V79.Data.Item.Id Int - | RemoveVendorItem Evergreen.V79.Data.Item.Id Int - | RemovePlayerCaps Int - | RemoveVendorCaps Int - | ResetBarter - | ConfirmBarter - | SetTransferNInput Evergreen.V79.Data.Barter.TransferNPosition String - | SetTransferNHover Evergreen.V79.Data.Barter.TransferNPosition - | UnsetTransferNHover - - -type FrontendMsg - = UrlClicked Browser.UrlRequest - | UrlChanged Url.Url - | GoToRoute Evergreen.V79.Frontend.Route.Route - | Logout - | Login - | Register - | GotZone Time.Zone - | GotTime Time.Posix - | AskToFight Evergreen.V79.Data.Player.PlayerName.PlayerName - | AskToHeal - | AskToUseItem Evergreen.V79.Data.Item.Id - | AskToWander - | AskToChoosePerk Evergreen.V79.Data.Perk.Perk - | AskForExport - | ImportButtonClicked - | ImportFileSelected File - | AskToImport String - | Refresh - | AskToTagSkill Evergreen.V79.Data.Skill.Skill - | AskToUseSkillPoints Evergreen.V79.Data.Skill.Skill - | SetAuthName String - | SetAuthPassword String - | CreateChar - | NewCharIncSpecial Evergreen.V79.Data.Special.SpecialType - | NewCharDecSpecial Evergreen.V79.Data.Special.SpecialType - | NewCharToggleTaggedSkill Evergreen.V79.Data.Skill.Skill - | NewCharToggleTrait Evergreen.V79.Data.Trait.Trait - | MapMouseAtCoords Evergreen.V79.Data.Map.TileCoords - | MapMouseOut - | MapMouseClick - | OpenMessage Evergreen.V79.Data.Message.Message - | AskToRemoveMessage Evergreen.V79.Data.Message.Message - | BarterMsg BarterMsg - - -type AdminToBackend - = ExportJson - | ImportJson String - - -type ToBackend - = LogMeIn (Evergreen.V79.Data.Auth.Auth Evergreen.V79.Data.Auth.Hashed) - | RegisterMe (Evergreen.V79.Data.Auth.Auth Evergreen.V79.Data.Auth.Hashed) - | CreateNewChar Evergreen.V79.Data.NewChar.NewChar - | LogMeOut - | Fight Evergreen.V79.Data.Player.PlayerName.PlayerName - | HealMe - | UseItem Evergreen.V79.Data.Item.Id - | Wander - | RefreshPlease - | TagSkill Evergreen.V79.Data.Skill.Skill - | UseSkillPoints Evergreen.V79.Data.Skill.Skill - | ChoosePerk Evergreen.V79.Data.Perk.Perk - | MoveTo Evergreen.V79.Data.Map.TileCoords (Set.Set Evergreen.V79.Data.Map.TileCoords) - | MessageWasRead Evergreen.V79.Data.Message.Message - | RemoveMessage Evergreen.V79.Data.Message.Message - | Barter Evergreen.V79.Data.Barter.State - | AdminToBackend AdminToBackend - - -type BackendMsg - = Connected Lamdera.SessionId Lamdera.ClientId - | Disconnected Lamdera.SessionId Lamdera.ClientId - | GeneratedFight Lamdera.ClientId Evergreen.V79.Data.Player.SPlayer Evergreen.V79.Data.Fight.Generator.Fight - | GeneratedNewVendorsStock ( AssocList.Dict Evergreen.V79.Data.Vendor.Name Evergreen.V79.Data.Vendor.Vendor, Int ) - | Tick Time.Posix - | CreateNewCharWithTime Lamdera.ClientId Evergreen.V79.Data.NewChar.NewChar Time.Posix - | LoggedToBackendMsg - - -type ToFrontend - = YourCurrentWorld Evergreen.V79.Data.World.WorldLoggedInData - | InitWorld Evergreen.V79.Data.World.WorldLoggedOutData - | RefreshedLoggedOut Evergreen.V79.Data.World.WorldLoggedOutData - | CurrentAdminData Evergreen.V79.Data.World.AdminData - | YourFightResult ( Evergreen.V79.Data.Fight.FightInfo, Evergreen.V79.Data.World.WorldLoggedInData ) - | YoureLoggedIn Evergreen.V79.Data.World.WorldLoggedInData - | YoureRegistered Evergreen.V79.Data.World.WorldLoggedInData - | CharCreationError Evergreen.V79.Data.NewChar.CreationError - | YouHaveCreatedChar Evergreen.V79.Data.World.WorldLoggedInData - | YoureLoggedOut Evergreen.V79.Data.World.WorldLoggedOutData - | AlertMessage String - | YoureLoggedInAsAdmin Evergreen.V79.Data.World.AdminData - | JsonExportDone String - | BarterDone ( Evergreen.V79.Data.World.WorldLoggedInData, Maybe Evergreen.V79.Data.Barter.Message ) - | BarterMessage Evergreen.V79.Data.Barter.Message diff --git a/src/Evergreen/V81/Data/Auth.elm b/src/Evergreen/V81/Data/Auth.elm deleted file mode 100644 index f2ace770..00000000 --- a/src/Evergreen/V81/Data/Auth.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V81.Data.Auth exposing (..) - - -type Plaintext - = Plaintext - - -type Password a - = Password String - - -type alias Auth a = - { name : String - , password : Password a - } - - -type Verified - = Verified - - -type Hashed - = Hashed diff --git a/src/Evergreen/V81/Data/Barter.elm b/src/Evergreen/V81/Data/Barter.elm deleted file mode 100644 index e468151d..00000000 --- a/src/Evergreen/V81/Data/Barter.elm +++ /dev/null @@ -1,33 +0,0 @@ -module Evergreen.V81.Data.Barter exposing (..) - -import AssocList -import Dict -import Evergreen.V81.Data.Item - - -type Message - = BarterIsEmpty - | PlayerOfferNotValuableEnough - | YouGaveStuffForFree - - -type TransferNPosition - = PlayerKeptItem Evergreen.V81.Data.Item.Id - | VendorKeptItem Evergreen.V81.Data.Item.Id - | PlayerTradedItem Evergreen.V81.Data.Item.Id - | VendorTradedItem Evergreen.V81.Data.Item.Id - | PlayerKeptCaps - | VendorKeptCaps - | PlayerTradedCaps - | VendorTradedCaps - - -type alias State = - { playerItems : Dict.Dict Evergreen.V81.Data.Item.Id Int - , vendorItems : Dict.Dict Evergreen.V81.Data.Item.Id Int - , playerCaps : Int - , vendorCaps : Int - , lastMessage : Maybe Message - , transferNInputs : AssocList.Dict TransferNPosition String - , transferNHover : Maybe TransferNPosition - } diff --git a/src/Evergreen/V81/Data/Enemy.elm b/src/Evergreen/V81/Data/Enemy.elm deleted file mode 100644 index 918e7299..00000000 --- a/src/Evergreen/V81/Data/Enemy.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V81.Data.Enemy exposing (..) - - -type Type - = GiantAnt - | ToughGiantAnt - | LesserRadscorpion - | Radscorpion diff --git a/src/Evergreen/V81/Data/Fight.elm b/src/Evergreen/V81/Data/Fight.elm deleted file mode 100644 index 62d81ad3..00000000 --- a/src/Evergreen/V81/Data/Fight.elm +++ /dev/null @@ -1,78 +0,0 @@ -module Evergreen.V81.Data.Fight exposing (..) - -import AssocList -import AssocSet -import Evergreen.V81.Data.Enemy -import Evergreen.V81.Data.Fight.ShotType -import Evergreen.V81.Data.Perk -import Evergreen.V81.Data.Player.PlayerName -import Evergreen.V81.Data.Skill -import Evergreen.V81.Data.Special -import Evergreen.V81.Data.Trait -import Evergreen.V81.Logic - - -type OpponentType - = Npc Evergreen.V81.Data.Enemy.Type - | Player Evergreen.V81.Data.Player.PlayerName.PlayerName - - -type Who - = Attacker - | Target - - -type FightAction - = Start - { distanceHexes : Int - } - | ComeCloser - { hexes : Int - , remainingDistanceHexes : Int - } - | Attack - { damage : Int - , shotType : Evergreen.V81.Data.Fight.ShotType.ShotType - , remainingHp : Int - } - | Miss - { shotType : Evergreen.V81.Data.Fight.ShotType.ShotType - } - - -type FightResult - = AttackerWon - { xpGained : Int - , capsGained : Int - } - | TargetWon - { xpGained : Int - , capsGained : Int - } - | TargetAlreadyDead - | BothDead - | NobodyDead - - -type alias FightInfo = - { attacker : OpponentType - , target : OpponentType - , log : List ( Who, FightAction ) - , result : FightResult - } - - -type alias Opponent = - { type_ : OpponentType - , hp : Int - , maxHp : Int - , maxAp : Int - , sequence : Int - , traits : AssocSet.Set Evergreen.V81.Data.Trait.Trait - , perks : AssocList.Dict Evergreen.V81.Data.Perk.Perk Int - , caps : Int - , armorClass : Int - , attackStats : Evergreen.V81.Logic.AttackStats - , addedSkillPercentages : AssocList.Dict Evergreen.V81.Data.Skill.Skill Int - , special : Evergreen.V81.Data.Special.Special - } diff --git a/src/Evergreen/V81/Data/Fight/Generator.elm b/src/Evergreen/V81/Data/Fight/Generator.elm deleted file mode 100644 index a5797728..00000000 --- a/src/Evergreen/V81/Data/Fight/Generator.elm +++ /dev/null @@ -1,12 +0,0 @@ -module Evergreen.V81.Data.Fight.Generator exposing (..) - -import Evergreen.V81.Data.Fight -import Evergreen.V81.Data.Message - - -type alias Fight = - { finalAttacker : Evergreen.V81.Data.Fight.Opponent - , finalTarget : Evergreen.V81.Data.Fight.Opponent - , fightInfo : Evergreen.V81.Data.Fight.FightInfo - , messageForTarget : Evergreen.V81.Data.Message.Message - } diff --git a/src/Evergreen/V81/Data/Fight/ShotType.elm b/src/Evergreen/V81/Data/Fight/ShotType.elm deleted file mode 100644 index 75722126..00000000 --- a/src/Evergreen/V81/Data/Fight/ShotType.elm +++ /dev/null @@ -1,17 +0,0 @@ -module Evergreen.V81.Data.Fight.ShotType exposing (..) - - -type AimedShot - = Head - | Torso - | Eyes - | Groin - | LeftArm - | RightArm - | LeftLeg - | RightLeg - - -type ShotType - = NormalShot - | AimedShot AimedShot diff --git a/src/Evergreen/V81/Data/HealthStatus.elm b/src/Evergreen/V81/Data/HealthStatus.elm deleted file mode 100644 index cec4786e..00000000 --- a/src/Evergreen/V81/Data/HealthStatus.elm +++ /dev/null @@ -1,16 +0,0 @@ -module Evergreen.V81.Data.HealthStatus exposing (..) - - -type HealthStatus - = ExactHp - { current : Int - , max : Int - } - | Unhurt - | SlightlyWounded - | Wounded - | SeverelyWounded - | AlmostDead - | Dead - | Alive - | Unknown diff --git a/src/Evergreen/V81/Data/Item.elm b/src/Evergreen/V81/Data/Item.elm deleted file mode 100644 index 3010fcbd..00000000 --- a/src/Evergreen/V81/Data/Item.elm +++ /dev/null @@ -1,21 +0,0 @@ -module Evergreen.V81.Data.Item exposing (..) - - -type alias Id = - Int - - -type Kind - = Stimpak - | BigBookOfScience - | DeansElectronics - | FirstAidBook - | GunsAndBullets - | ScoutHandbook - - -type alias Item = - { id : Id - , kind : Kind - , count : Int - } diff --git a/src/Evergreen/V81/Data/Map.elm b/src/Evergreen/V81/Data/Map.elm deleted file mode 100644 index c4b39914..00000000 --- a/src/Evergreen/V81/Data/Map.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V81.Data.Map exposing (..) - - -type alias TileNum = - Int - - -type alias TileCoords = - ( Int, Int ) diff --git a/src/Evergreen/V81/Data/Message.elm b/src/Evergreen/V81/Data/Message.elm deleted file mode 100644 index 5022dfc7..00000000 --- a/src/Evergreen/V81/Data/Message.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V81.Data.Message exposing (..) - -import Evergreen.V81.Data.Fight -import Evergreen.V81.Data.Player.PlayerName -import Time - - -type Type - = Welcome - | YouAdvancedLevel - { newLevel : Int - } - | YouWereAttacked - { attacker : Evergreen.V81.Data.Player.PlayerName.PlayerName - , fightInfo : Evergreen.V81.Data.Fight.FightInfo - } - - -type alias Message = - { type_ : Type - , hasBeenRead : Bool - , date : Time.Posix - } diff --git a/src/Evergreen/V81/Data/NewChar.elm b/src/Evergreen/V81/Data/NewChar.elm deleted file mode 100644 index d3a9079d..00000000 --- a/src/Evergreen/V81/Data/NewChar.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V81.Data.NewChar exposing (..) - -import AssocSet -import Evergreen.V81.Data.Skill -import Evergreen.V81.Data.Special -import Evergreen.V81.Data.Trait - - -type CreationError - = DoesNotHaveThreeTaggedSkills - | HasSpecialPointsLeft - | UsedMoreSpecialPointsThanAvailable - | HasSpecialOutOfRange - | HasMoreThanTwoTraits - - -type alias NewChar = - { baseSpecial : Evergreen.V81.Data.Special.Special - , availableSpecial : Int - , taggedSkills : AssocSet.Set Evergreen.V81.Data.Skill.Skill - , traits : AssocSet.Set Evergreen.V81.Data.Trait.Trait - , error : Maybe CreationError - } diff --git a/src/Evergreen/V81/Data/Perk.elm b/src/Evergreen/V81/Data/Perk.elm deleted file mode 100644 index bbc9aac9..00000000 --- a/src/Evergreen/V81/Data/Perk.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V81.Data.Perk exposing (..) - - -type Perk - = BonusHthDamage - | MasterTrader - | Awareness - | CautiousNature - | Comprehension - | EarlierSequence - | FasterHealing - | HereAndNow - | Survivalist - | Educated - | Tag - | GainStrength - | GainPerception - | GainEndurance - | GainCharisma - | GainIntelligence - | GainAgility - | GainLuck diff --git a/src/Evergreen/V81/Data/Player.elm b/src/Evergreen/V81/Data/Player.elm deleted file mode 100644 index 11d5a825..00000000 --- a/src/Evergreen/V81/Data/Player.elm +++ /dev/null @@ -1,75 +0,0 @@ -module Evergreen.V81.Data.Player exposing (..) - -import AssocList -import AssocSet -import Dict -import Evergreen.V81.Data.Auth -import Evergreen.V81.Data.HealthStatus -import Evergreen.V81.Data.Item -import Evergreen.V81.Data.Map -import Evergreen.V81.Data.Message -import Evergreen.V81.Data.Perk -import Evergreen.V81.Data.Player.PlayerName -import Evergreen.V81.Data.Skill -import Evergreen.V81.Data.Special -import Evergreen.V81.Data.Trait -import Evergreen.V81.Data.Xp - - -type alias COtherPlayer = - { level : Evergreen.V81.Data.Xp.Level - , name : Evergreen.V81.Data.Player.PlayerName.PlayerName - , wins : Int - , losses : Int - , healthStatus : Evergreen.V81.Data.HealthStatus.HealthStatus - } - - -type alias CPlayer = - { hp : Int - , maxHp : Int - , xp : Evergreen.V81.Data.Xp.Xp - , name : Evergreen.V81.Data.Player.PlayerName.PlayerName - , special : Evergreen.V81.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V81.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V81.Data.Perk.Perk Int - , messages : List Evergreen.V81.Data.Message.Message - , items : Dict.Dict Evergreen.V81.Data.Item.Id Evergreen.V81.Data.Item.Item - , traits : AssocSet.Set Evergreen.V81.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V81.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V81.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - } - - -type Player a - = NeedsCharCreated (Evergreen.V81.Data.Auth.Auth Evergreen.V81.Data.Auth.Verified) - | Player a - - -type alias SPlayer = - { name : Evergreen.V81.Data.Player.PlayerName.PlayerName - , password : Evergreen.V81.Data.Auth.Password Evergreen.V81.Data.Auth.Verified - , hp : Int - , maxHp : Int - , xp : Int - , special : Evergreen.V81.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V81.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V81.Data.Perk.Perk Int - , messages : List Evergreen.V81.Data.Message.Message - , items : Dict.Dict Evergreen.V81.Data.Item.Id Evergreen.V81.Data.Item.Item - , traits : AssocSet.Set Evergreen.V81.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V81.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V81.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - } diff --git a/src/Evergreen/V81/Data/Player/PlayerName.elm b/src/Evergreen/V81/Data/Player/PlayerName.elm deleted file mode 100644 index 01ff4e1d..00000000 --- a/src/Evergreen/V81/Data/Player/PlayerName.elm +++ /dev/null @@ -1,5 +0,0 @@ -module Evergreen.V81.Data.Player.PlayerName exposing (..) - - -type alias PlayerName = - String diff --git a/src/Evergreen/V81/Data/Skill.elm b/src/Evergreen/V81/Data/Skill.elm deleted file mode 100644 index 16264332..00000000 --- a/src/Evergreen/V81/Data/Skill.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V81.Data.Skill exposing (..) - - -type Skill - = SmallGuns - | BigGuns - | EnergyWeapons - | Unarmed - | MeleeWeapons - | Throwing - | FirstAid - | Doctor - | Sneak - | Lockpick - | Steal - | Traps - | Science - | Repair - | Speech - | Barter - | Gambling - | Outdoorsman diff --git a/src/Evergreen/V81/Data/Special.elm b/src/Evergreen/V81/Data/Special.elm deleted file mode 100644 index 84e2a4de..00000000 --- a/src/Evergreen/V81/Data/Special.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V81.Data.Special exposing (..) - - -type alias Special = - { strength : Int - , perception : Int - , endurance : Int - , charisma : Int - , intelligence : Int - , agility : Int - , luck : Int - } - - -type Type - = Strength - | Perception - | Endurance - | Charisma - | Intelligence - | Agility - | Luck diff --git a/src/Evergreen/V81/Data/Trait.elm b/src/Evergreen/V81/Data/Trait.elm deleted file mode 100644 index 4dcedfd2..00000000 --- a/src/Evergreen/V81/Data/Trait.elm +++ /dev/null @@ -1,10 +0,0 @@ -module Evergreen.V81.Data.Trait exposing (..) - - -type Trait - = Kamikaze - | Bruiser - | Gifted - | SmallFrame - | Skilled - | HeavyHanded diff --git a/src/Evergreen/V81/Data/Vendor.elm b/src/Evergreen/V81/Data/Vendor.elm deleted file mode 100644 index 042b7f60..00000000 --- a/src/Evergreen/V81/Data/Vendor.elm +++ /dev/null @@ -1,17 +0,0 @@ -module Evergreen.V81.Data.Vendor exposing (..) - -import Dict -import Evergreen.V81.Data.Item - - -type Name - = KlamathMaidaBuckner - | DenFlick - - -type alias Vendor = - { name : Name - , items : Dict.Dict Evergreen.V81.Data.Item.Id Evergreen.V81.Data.Item.Item - , caps : Int - , barterSkill : Int - } diff --git a/src/Evergreen/V81/Data/World.elm b/src/Evergreen/V81/Data/World.elm deleted file mode 100644 index 27e270b9..00000000 --- a/src/Evergreen/V81/Data/World.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.V81.Data.World exposing (..) - -import AssocList -import Evergreen.V81.Data.Auth -import Evergreen.V81.Data.Player -import Evergreen.V81.Data.Player.PlayerName -import Evergreen.V81.Data.Vendor -import Time - - -type alias WorldLoggedOutData = - { players : List Evergreen.V81.Data.Player.COtherPlayer - } - - -type alias WorldLoggedInData = - { player : Evergreen.V81.Data.Player.Player Evergreen.V81.Data.Player.CPlayer - , otherPlayers : List Evergreen.V81.Data.Player.COtherPlayer - , playerRank : Int - , vendors : AssocList.Dict Evergreen.V81.Data.Vendor.Name Evergreen.V81.Data.Vendor.Vendor - } - - -type alias AdminData = - { players : List (Evergreen.V81.Data.Player.Player Evergreen.V81.Data.Player.SPlayer) - , loggedInPlayers : List Evergreen.V81.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - } - - -type World - = WorldNotInitialized (Evergreen.V81.Data.Auth.Auth Evergreen.V81.Data.Auth.Plaintext) - | WorldLoggedOut (Evergreen.V81.Data.Auth.Auth Evergreen.V81.Data.Auth.Plaintext) WorldLoggedOutData - | WorldLoggedIn WorldLoggedInData - | WorldAdmin AdminData diff --git a/src/Evergreen/V81/Data/Xp.elm b/src/Evergreen/V81/Data/Xp.elm deleted file mode 100644 index 563fadb7..00000000 --- a/src/Evergreen/V81/Data/Xp.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V81.Data.Xp exposing (..) - - -type alias Level = - Int - - -type alias Xp = - Int diff --git a/src/Evergreen/V81/Frontend/Route.elm b/src/Evergreen/V81/Frontend/Route.elm deleted file mode 100644 index d166e76b..00000000 --- a/src/Evergreen/V81/Frontend/Route.elm +++ /dev/null @@ -1,32 +0,0 @@ -module Evergreen.V81.Frontend.Route exposing (..) - -import Evergreen.V81.Data.Barter -import Evergreen.V81.Data.Fight -import Evergreen.V81.Data.Message - - -type TownRoute - = MainSquare - | Store - { barter : Evergreen.V81.Data.Barter.State - } - - -type AdminRoute - = Players - | LoggedIn - - -type Route - = Character - | Inventory - | Map - | Ladder - | Town TownRoute - | About - | News - | Fight Evergreen.V81.Data.Fight.FightInfo - | Messages - | Message Evergreen.V81.Data.Message.Message - | CharCreation - | Admin AdminRoute diff --git a/src/Evergreen/V81/Logic.elm b/src/Evergreen/V81/Logic.elm deleted file mode 100644 index 8d8b5cd4..00000000 --- a/src/Evergreen/V81/Logic.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V81.Logic exposing (..) - - -type alias AttackStats = - { minDamage : Int - , maxDamage : Int - , criticalChanceBonus : Int - } diff --git a/src/Evergreen/V81/Types.elm b/src/Evergreen/V81/Types.elm deleted file mode 100644 index 95f6ce69..00000000 --- a/src/Evergreen/V81/Types.elm +++ /dev/null @@ -1,156 +0,0 @@ -module Evergreen.V81.Types exposing (..) - -import AssocList -import Browser -import Browser.Navigation -import Dict -import Evergreen.V81.Data.Auth -import Evergreen.V81.Data.Barter -import Evergreen.V81.Data.Fight -import Evergreen.V81.Data.Fight.Generator -import Evergreen.V81.Data.Item -import Evergreen.V81.Data.Map -import Evergreen.V81.Data.Message -import Evergreen.V81.Data.NewChar -import Evergreen.V81.Data.Perk -import Evergreen.V81.Data.Player -import Evergreen.V81.Data.Player.PlayerName -import Evergreen.V81.Data.Skill -import Evergreen.V81.Data.Special -import Evergreen.V81.Data.Trait -import Evergreen.V81.Data.Vendor -import Evergreen.V81.Data.World -import Evergreen.V81.Frontend.Route -import File exposing (File) -import Lamdera -import Set -import Time -import Url - - -type alias FrontendModel = - { key : Browser.Navigation.Key - , time : Time.Posix - , zone : Time.Zone - , route : Evergreen.V81.Frontend.Route.Route - , world : Evergreen.V81.Data.World.World - , newChar : Evergreen.V81.Data.NewChar.NewChar - , alertMessage : Maybe String - , mapMouseCoords : Maybe ( Evergreen.V81.Data.Map.TileCoords, Set.Set Evergreen.V81.Data.Map.TileCoords ) - } - - -type alias BackendModel = - { players : Dict.Dict Evergreen.V81.Data.Player.PlayerName.PlayerName (Evergreen.V81.Data.Player.Player Evergreen.V81.Data.Player.SPlayer) - , loggedInPlayers : Dict.Dict Lamdera.ClientId Evergreen.V81.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - , adminLoggedIn : Maybe ( Lamdera.ClientId, Lamdera.SessionId ) - , time : Time.Posix - , vendors : AssocList.Dict Evergreen.V81.Data.Vendor.Name Evergreen.V81.Data.Vendor.Vendor - , lastItemId : Int - } - - -type BarterMsg - = AddPlayerItem Evergreen.V81.Data.Item.Id Int - | AddVendorItem Evergreen.V81.Data.Item.Id Int - | AddPlayerCaps Int - | AddVendorCaps Int - | RemovePlayerItem Evergreen.V81.Data.Item.Id Int - | RemoveVendorItem Evergreen.V81.Data.Item.Id Int - | RemovePlayerCaps Int - | RemoveVendorCaps Int - | ResetBarter - | ConfirmBarter - | SetTransferNInput Evergreen.V81.Data.Barter.TransferNPosition String - | SetTransferNHover Evergreen.V81.Data.Barter.TransferNPosition - | UnsetTransferNHover - - -type FrontendMsg - = UrlClicked Browser.UrlRequest - | UrlChanged Url.Url - | GoToRoute Evergreen.V81.Frontend.Route.Route - | Logout - | Login - | Register - | GotZone Time.Zone - | GotTime Time.Posix - | AskToFight Evergreen.V81.Data.Player.PlayerName.PlayerName - | AskToHeal - | AskToUseItem Evergreen.V81.Data.Item.Id - | AskToWander - | AskToChoosePerk Evergreen.V81.Data.Perk.Perk - | AskForExport - | ImportButtonClicked - | ImportFileSelected File - | AskToImport String - | Refresh - | AskToTagSkill Evergreen.V81.Data.Skill.Skill - | AskToUseSkillPoints Evergreen.V81.Data.Skill.Skill - | SetAuthName String - | SetAuthPassword String - | CreateChar - | NewCharIncSpecial Evergreen.V81.Data.Special.Type - | NewCharDecSpecial Evergreen.V81.Data.Special.Type - | NewCharToggleTaggedSkill Evergreen.V81.Data.Skill.Skill - | NewCharToggleTrait Evergreen.V81.Data.Trait.Trait - | MapMouseAtCoords Evergreen.V81.Data.Map.TileCoords - | MapMouseOut - | MapMouseClick - | OpenMessage Evergreen.V81.Data.Message.Message - | AskToRemoveMessage Evergreen.V81.Data.Message.Message - | BarterMsg BarterMsg - - -type AdminToBackend - = ExportJson - | ImportJson String - - -type ToBackend - = LogMeIn (Evergreen.V81.Data.Auth.Auth Evergreen.V81.Data.Auth.Hashed) - | RegisterMe (Evergreen.V81.Data.Auth.Auth Evergreen.V81.Data.Auth.Hashed) - | CreateNewChar Evergreen.V81.Data.NewChar.NewChar - | LogMeOut - | Fight Evergreen.V81.Data.Player.PlayerName.PlayerName - | HealMe - | UseItem Evergreen.V81.Data.Item.Id - | Wander - | RefreshPlease - | TagSkill Evergreen.V81.Data.Skill.Skill - | UseSkillPoints Evergreen.V81.Data.Skill.Skill - | ChoosePerk Evergreen.V81.Data.Perk.Perk - | MoveTo Evergreen.V81.Data.Map.TileCoords (Set.Set Evergreen.V81.Data.Map.TileCoords) - | MessageWasRead Evergreen.V81.Data.Message.Message - | RemoveMessage Evergreen.V81.Data.Message.Message - | Barter Evergreen.V81.Data.Barter.State - | AdminToBackend AdminToBackend - - -type BackendMsg - = Connected Lamdera.SessionId Lamdera.ClientId - | Disconnected Lamdera.SessionId Lamdera.ClientId - | GeneratedFight Lamdera.ClientId Evergreen.V81.Data.Player.SPlayer Evergreen.V81.Data.Fight.Generator.Fight - | GeneratedNewVendorsStock ( AssocList.Dict Evergreen.V81.Data.Vendor.Name Evergreen.V81.Data.Vendor.Vendor, Int ) - | Tick Time.Posix - | CreateNewCharWithTime Lamdera.ClientId Evergreen.V81.Data.NewChar.NewChar Time.Posix - | LoggedToBackendMsg - - -type ToFrontend - = YourCurrentWorld Evergreen.V81.Data.World.WorldLoggedInData - | InitWorld Evergreen.V81.Data.World.WorldLoggedOutData - | RefreshedLoggedOut Evergreen.V81.Data.World.WorldLoggedOutData - | CurrentAdminData Evergreen.V81.Data.World.AdminData - | YourFightResult ( Evergreen.V81.Data.Fight.FightInfo, Evergreen.V81.Data.World.WorldLoggedInData ) - | YoureLoggedIn Evergreen.V81.Data.World.WorldLoggedInData - | YoureRegistered Evergreen.V81.Data.World.WorldLoggedInData - | CharCreationError Evergreen.V81.Data.NewChar.CreationError - | YouHaveCreatedChar Evergreen.V81.Data.World.WorldLoggedInData - | YoureLoggedOut Evergreen.V81.Data.World.WorldLoggedOutData - | AlertMessage String - | YoureLoggedInAsAdmin Evergreen.V81.Data.World.AdminData - | JsonExportDone String - | BarterDone ( Evergreen.V81.Data.World.WorldLoggedInData, Maybe Evergreen.V81.Data.Barter.Message ) - | BarterMessage Evergreen.V81.Data.Barter.Message diff --git a/src/Evergreen/V83/Data/Auth.elm b/src/Evergreen/V83/Data/Auth.elm deleted file mode 100644 index 920a4d42..00000000 --- a/src/Evergreen/V83/Data/Auth.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V83.Data.Auth exposing (..) - - -type Plaintext - = Plaintext - - -type Password a - = Password String - - -type alias Auth a = - { name : String - , password : Password a - } - - -type Verified - = Verified - - -type Hashed - = Hashed diff --git a/src/Evergreen/V83/Data/Barter.elm b/src/Evergreen/V83/Data/Barter.elm deleted file mode 100644 index f39d78b8..00000000 --- a/src/Evergreen/V83/Data/Barter.elm +++ /dev/null @@ -1,33 +0,0 @@ -module Evergreen.V83.Data.Barter exposing (..) - -import AssocList -import Dict -import Evergreen.V83.Data.Item - - -type Message - = BarterIsEmpty - | PlayerOfferNotValuableEnough - | YouGaveStuffForFree - - -type TransferNPosition - = PlayerKeptItem Evergreen.V83.Data.Item.Id - | VendorKeptItem Evergreen.V83.Data.Item.Id - | PlayerTradedItem Evergreen.V83.Data.Item.Id - | VendorTradedItem Evergreen.V83.Data.Item.Id - | PlayerKeptCaps - | VendorKeptCaps - | PlayerTradedCaps - | VendorTradedCaps - - -type alias State = - { playerItems : Dict.Dict Evergreen.V83.Data.Item.Id Int - , vendorItems : Dict.Dict Evergreen.V83.Data.Item.Id Int - , playerCaps : Int - , vendorCaps : Int - , lastMessage : Maybe Message - , transferNInputs : AssocList.Dict TransferNPosition String - , transferNHover : Maybe TransferNPosition - } diff --git a/src/Evergreen/V83/Data/Enemy.elm b/src/Evergreen/V83/Data/Enemy.elm deleted file mode 100644 index 16533f7e..00000000 --- a/src/Evergreen/V83/Data/Enemy.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V83.Data.Enemy exposing (..) - - -type Type - = GiantAnt - | ToughGiantAnt - | LesserRadscorpion - | Radscorpion diff --git a/src/Evergreen/V83/Data/Fight.elm b/src/Evergreen/V83/Data/Fight.elm deleted file mode 100644 index 3a0dacbb..00000000 --- a/src/Evergreen/V83/Data/Fight.elm +++ /dev/null @@ -1,80 +0,0 @@ -module Evergreen.V83.Data.Fight exposing (..) - -import AssocList -import AssocSet -import Evergreen.V83.Data.Enemy -import Evergreen.V83.Data.Fight.ShotType -import Evergreen.V83.Data.Item -import Evergreen.V83.Data.Perk -import Evergreen.V83.Data.Player.PlayerName -import Evergreen.V83.Data.Skill -import Evergreen.V83.Data.Special -import Evergreen.V83.Data.Trait -import Evergreen.V83.Logic - - -type OpponentType - = Npc Evergreen.V83.Data.Enemy.Type - | Player Evergreen.V83.Data.Player.PlayerName.PlayerName - - -type Who - = Attacker - | Target - - -type FightAction - = Start - { distanceHexes : Int - } - | ComeCloser - { hexes : Int - , remainingDistanceHexes : Int - } - | Attack - { damage : Int - , shotType : Evergreen.V83.Data.Fight.ShotType.ShotType - , remainingHp : Int - } - | Miss - { shotType : Evergreen.V83.Data.Fight.ShotType.ShotType - } - - -type FightResult - = AttackerWon - { xpGained : Int - , capsGained : Int - } - | TargetWon - { xpGained : Int - , capsGained : Int - } - | TargetAlreadyDead - | BothDead - | NobodyDead - - -type alias FightInfo = - { attacker : OpponentType - , target : OpponentType - , log : List ( Who, FightAction ) - , result : FightResult - } - - -type alias Opponent = - { type_ : OpponentType - , hp : Int - , maxHp : Int - , maxAp : Int - , sequence : Int - , traits : AssocSet.Set Evergreen.V83.Data.Trait.Trait - , perks : AssocList.Dict Evergreen.V83.Data.Perk.Perk Int - , caps : Int - , equippedArmor : Maybe Evergreen.V83.Data.Item.Kind - , naturalArmorClass : Int - , attackStats : Evergreen.V83.Logic.AttackStats - , addedSkillPercentages : AssocList.Dict Evergreen.V83.Data.Skill.Skill Int - , special : Evergreen.V83.Data.Special.Special - } diff --git a/src/Evergreen/V83/Data/Fight/Generator.elm b/src/Evergreen/V83/Data/Fight/Generator.elm deleted file mode 100644 index 635f3594..00000000 --- a/src/Evergreen/V83/Data/Fight/Generator.elm +++ /dev/null @@ -1,12 +0,0 @@ -module Evergreen.V83.Data.Fight.Generator exposing (..) - -import Evergreen.V83.Data.Fight -import Evergreen.V83.Data.Message - - -type alias Fight = - { finalAttacker : Evergreen.V83.Data.Fight.Opponent - , finalTarget : Evergreen.V83.Data.Fight.Opponent - , fightInfo : Evergreen.V83.Data.Fight.FightInfo - , messageForTarget : Evergreen.V83.Data.Message.Message - } diff --git a/src/Evergreen/V83/Data/Fight/ShotType.elm b/src/Evergreen/V83/Data/Fight/ShotType.elm deleted file mode 100644 index 7d6eb859..00000000 --- a/src/Evergreen/V83/Data/Fight/ShotType.elm +++ /dev/null @@ -1,17 +0,0 @@ -module Evergreen.V83.Data.Fight.ShotType exposing (..) - - -type AimedShot - = Head - | Torso - | Eyes - | Groin - | LeftArm - | RightArm - | LeftLeg - | RightLeg - - -type ShotType - = NormalShot - | AimedShot AimedShot diff --git a/src/Evergreen/V83/Data/HealthStatus.elm b/src/Evergreen/V83/Data/HealthStatus.elm deleted file mode 100644 index 0da41411..00000000 --- a/src/Evergreen/V83/Data/HealthStatus.elm +++ /dev/null @@ -1,16 +0,0 @@ -module Evergreen.V83.Data.HealthStatus exposing (..) - - -type HealthStatus - = ExactHp - { current : Int - , max : Int - } - | Unhurt - | SlightlyWounded - | Wounded - | SeverelyWounded - | AlmostDead - | Dead - | Alive - | Unknown diff --git a/src/Evergreen/V83/Data/Item.elm b/src/Evergreen/V83/Data/Item.elm deleted file mode 100644 index bdec673f..00000000 --- a/src/Evergreen/V83/Data/Item.elm +++ /dev/null @@ -1,26 +0,0 @@ -module Evergreen.V83.Data.Item exposing (..) - - -type alias Id = - Int - - -type Kind - = HealingPowder - | Stimpak - | BigBookOfScience - | DeansElectronics - | FirstAidBook - | GunsAndBullets - | ScoutHandbook - | Robes - | LeatherJacket - | LeatherArmor - | MetalArmor - - -type alias Item = - { id : Id - , kind : Kind - , count : Int - } diff --git a/src/Evergreen/V83/Data/Map.elm b/src/Evergreen/V83/Data/Map.elm deleted file mode 100644 index bbae59b0..00000000 --- a/src/Evergreen/V83/Data/Map.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V83.Data.Map exposing (..) - - -type alias TileNum = - Int - - -type alias TileCoords = - ( Int, Int ) diff --git a/src/Evergreen/V83/Data/Message.elm b/src/Evergreen/V83/Data/Message.elm deleted file mode 100644 index 052b481f..00000000 --- a/src/Evergreen/V83/Data/Message.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V83.Data.Message exposing (..) - -import Evergreen.V83.Data.Fight -import Evergreen.V83.Data.Player.PlayerName -import Time - - -type Type - = Welcome - | YouAdvancedLevel - { newLevel : Int - } - | YouWereAttacked - { attacker : Evergreen.V83.Data.Player.PlayerName.PlayerName - , fightInfo : Evergreen.V83.Data.Fight.FightInfo - } - - -type alias Message = - { type_ : Type - , hasBeenRead : Bool - , date : Time.Posix - } diff --git a/src/Evergreen/V83/Data/NewChar.elm b/src/Evergreen/V83/Data/NewChar.elm deleted file mode 100644 index 42d61db5..00000000 --- a/src/Evergreen/V83/Data/NewChar.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V83.Data.NewChar exposing (..) - -import AssocSet -import Evergreen.V83.Data.Skill -import Evergreen.V83.Data.Special -import Evergreen.V83.Data.Trait - - -type CreationError - = DoesNotHaveThreeTaggedSkills - | HasSpecialPointsLeft - | UsedMoreSpecialPointsThanAvailable - | HasSpecialOutOfRange - | HasMoreThanTwoTraits - - -type alias NewChar = - { baseSpecial : Evergreen.V83.Data.Special.Special - , availableSpecial : Int - , taggedSkills : AssocSet.Set Evergreen.V83.Data.Skill.Skill - , traits : AssocSet.Set Evergreen.V83.Data.Trait.Trait - , error : Maybe CreationError - } diff --git a/src/Evergreen/V83/Data/Perk.elm b/src/Evergreen/V83/Data/Perk.elm deleted file mode 100644 index 8d77f007..00000000 --- a/src/Evergreen/V83/Data/Perk.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V83.Data.Perk exposing (..) - - -type Perk - = BonusHthDamage - | MasterTrader - | Awareness - | CautiousNature - | Comprehension - | EarlierSequence - | FasterHealing - | HereAndNow - | Survivalist - | Educated - | Tag - | GainStrength - | GainPerception - | GainEndurance - | GainCharisma - | GainIntelligence - | GainAgility - | GainLuck diff --git a/src/Evergreen/V83/Data/Player.elm b/src/Evergreen/V83/Data/Player.elm deleted file mode 100644 index d58bc2e9..00000000 --- a/src/Evergreen/V83/Data/Player.elm +++ /dev/null @@ -1,77 +0,0 @@ -module Evergreen.V83.Data.Player exposing (..) - -import AssocList -import AssocSet -import Dict -import Evergreen.V83.Data.Auth -import Evergreen.V83.Data.HealthStatus -import Evergreen.V83.Data.Item -import Evergreen.V83.Data.Map -import Evergreen.V83.Data.Message -import Evergreen.V83.Data.Perk -import Evergreen.V83.Data.Player.PlayerName -import Evergreen.V83.Data.Skill -import Evergreen.V83.Data.Special -import Evergreen.V83.Data.Trait -import Evergreen.V83.Data.Xp - - -type alias COtherPlayer = - { level : Evergreen.V83.Data.Xp.Level - , name : Evergreen.V83.Data.Player.PlayerName.PlayerName - , wins : Int - , losses : Int - , healthStatus : Evergreen.V83.Data.HealthStatus.HealthStatus - } - - -type alias CPlayer = - { hp : Int - , maxHp : Int - , xp : Evergreen.V83.Data.Xp.Xp - , name : Evergreen.V83.Data.Player.PlayerName.PlayerName - , special : Evergreen.V83.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V83.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V83.Data.Perk.Perk Int - , messages : List Evergreen.V83.Data.Message.Message - , items : Dict.Dict Evergreen.V83.Data.Item.Id Evergreen.V83.Data.Item.Item - , traits : AssocSet.Set Evergreen.V83.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V83.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V83.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - , equippedArmor : Maybe Evergreen.V83.Data.Item.Item - } - - -type Player a - = NeedsCharCreated (Evergreen.V83.Data.Auth.Auth Evergreen.V83.Data.Auth.Verified) - | Player a - - -type alias SPlayer = - { name : Evergreen.V83.Data.Player.PlayerName.PlayerName - , password : Evergreen.V83.Data.Auth.Password Evergreen.V83.Data.Auth.Verified - , hp : Int - , maxHp : Int - , xp : Int - , special : Evergreen.V83.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V83.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V83.Data.Perk.Perk Int - , messages : List Evergreen.V83.Data.Message.Message - , items : Dict.Dict Evergreen.V83.Data.Item.Id Evergreen.V83.Data.Item.Item - , traits : AssocSet.Set Evergreen.V83.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V83.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V83.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - , equippedArmor : Maybe Evergreen.V83.Data.Item.Item - } diff --git a/src/Evergreen/V83/Data/Player/PlayerName.elm b/src/Evergreen/V83/Data/Player/PlayerName.elm deleted file mode 100644 index 700f65f1..00000000 --- a/src/Evergreen/V83/Data/Player/PlayerName.elm +++ /dev/null @@ -1,5 +0,0 @@ -module Evergreen.V83.Data.Player.PlayerName exposing (..) - - -type alias PlayerName = - String diff --git a/src/Evergreen/V83/Data/Skill.elm b/src/Evergreen/V83/Data/Skill.elm deleted file mode 100644 index 07dfe132..00000000 --- a/src/Evergreen/V83/Data/Skill.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V83.Data.Skill exposing (..) - - -type Skill - = SmallGuns - | BigGuns - | EnergyWeapons - | Unarmed - | MeleeWeapons - | Throwing - | FirstAid - | Doctor - | Sneak - | Lockpick - | Steal - | Traps - | Science - | Repair - | Speech - | Barter - | Gambling - | Outdoorsman diff --git a/src/Evergreen/V83/Data/Special.elm b/src/Evergreen/V83/Data/Special.elm deleted file mode 100644 index fc1c4bf6..00000000 --- a/src/Evergreen/V83/Data/Special.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V83.Data.Special exposing (..) - - -type alias Special = - { strength : Int - , perception : Int - , endurance : Int - , charisma : Int - , intelligence : Int - , agility : Int - , luck : Int - } - - -type Type - = Strength - | Perception - | Endurance - | Charisma - | Intelligence - | Agility - | Luck diff --git a/src/Evergreen/V83/Data/Trait.elm b/src/Evergreen/V83/Data/Trait.elm deleted file mode 100644 index 19b3fc5d..00000000 --- a/src/Evergreen/V83/Data/Trait.elm +++ /dev/null @@ -1,10 +0,0 @@ -module Evergreen.V83.Data.Trait exposing (..) - - -type Trait - = Kamikaze - | Bruiser - | Gifted - | SmallFrame - | Skilled - | HeavyHanded diff --git a/src/Evergreen/V83/Data/Vendor.elm b/src/Evergreen/V83/Data/Vendor.elm deleted file mode 100644 index 52b7764b..00000000 --- a/src/Evergreen/V83/Data/Vendor.elm +++ /dev/null @@ -1,20 +0,0 @@ -module Evergreen.V83.Data.Vendor exposing (..) - -import Dict -import Evergreen.V83.Data.Item - - -type Name - = ArroyoHakunin - | KlamathMaidaBuckner - | DenFlick - | ModocJo - | VaultCityHappyHarry - - -type alias Vendor = - { name : Name - , items : Dict.Dict Evergreen.V83.Data.Item.Id Evergreen.V83.Data.Item.Item - , caps : Int - , barterSkill : Int - } diff --git a/src/Evergreen/V83/Data/World.elm b/src/Evergreen/V83/Data/World.elm deleted file mode 100644 index c42f8f11..00000000 --- a/src/Evergreen/V83/Data/World.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.V83.Data.World exposing (..) - -import AssocList -import Evergreen.V83.Data.Auth -import Evergreen.V83.Data.Player -import Evergreen.V83.Data.Player.PlayerName -import Evergreen.V83.Data.Vendor -import Time - - -type alias WorldLoggedOutData = - { players : List Evergreen.V83.Data.Player.COtherPlayer - } - - -type alias WorldLoggedInData = - { player : Evergreen.V83.Data.Player.Player Evergreen.V83.Data.Player.CPlayer - , otherPlayers : List Evergreen.V83.Data.Player.COtherPlayer - , playerRank : Int - , vendors : AssocList.Dict Evergreen.V83.Data.Vendor.Name Evergreen.V83.Data.Vendor.Vendor - } - - -type alias AdminData = - { players : List (Evergreen.V83.Data.Player.Player Evergreen.V83.Data.Player.SPlayer) - , loggedInPlayers : List Evergreen.V83.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - } - - -type World - = WorldNotInitialized (Evergreen.V83.Data.Auth.Auth Evergreen.V83.Data.Auth.Plaintext) - | WorldLoggedOut (Evergreen.V83.Data.Auth.Auth Evergreen.V83.Data.Auth.Plaintext) WorldLoggedOutData - | WorldLoggedIn WorldLoggedInData - | WorldAdmin AdminData diff --git a/src/Evergreen/V83/Data/Xp.elm b/src/Evergreen/V83/Data/Xp.elm deleted file mode 100644 index 924449ab..00000000 --- a/src/Evergreen/V83/Data/Xp.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V83.Data.Xp exposing (..) - - -type alias Level = - Int - - -type alias Xp = - Int diff --git a/src/Evergreen/V83/Frontend/Route.elm b/src/Evergreen/V83/Frontend/Route.elm deleted file mode 100644 index 35c178a7..00000000 --- a/src/Evergreen/V83/Frontend/Route.elm +++ /dev/null @@ -1,32 +0,0 @@ -module Evergreen.V83.Frontend.Route exposing (..) - -import Evergreen.V83.Data.Barter -import Evergreen.V83.Data.Fight -import Evergreen.V83.Data.Message - - -type TownRoute - = MainSquare - | Store - { barter : Evergreen.V83.Data.Barter.State - } - - -type AdminRoute - = Players - | LoggedIn - - -type Route - = Character - | Inventory - | Map - | Ladder - | Town TownRoute - | About - | News - | Fight Evergreen.V83.Data.Fight.FightInfo - | Messages - | Message Evergreen.V83.Data.Message.Message - | CharCreation - | Admin AdminRoute diff --git a/src/Evergreen/V83/Logic.elm b/src/Evergreen/V83/Logic.elm deleted file mode 100644 index acad87be..00000000 --- a/src/Evergreen/V83/Logic.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V83.Logic exposing (..) - - -type alias AttackStats = - { minDamage : Int - , maxDamage : Int - , criticalChanceBonus : Int - } diff --git a/src/Evergreen/V83/Types.elm b/src/Evergreen/V83/Types.elm deleted file mode 100644 index df72e3bd..00000000 --- a/src/Evergreen/V83/Types.elm +++ /dev/null @@ -1,160 +0,0 @@ -module Evergreen.V83.Types exposing (..) - -import AssocList -import Browser -import Browser.Navigation -import Dict -import Evergreen.V83.Data.Auth -import Evergreen.V83.Data.Barter -import Evergreen.V83.Data.Fight -import Evergreen.V83.Data.Fight.Generator -import Evergreen.V83.Data.Item -import Evergreen.V83.Data.Map -import Evergreen.V83.Data.Message -import Evergreen.V83.Data.NewChar -import Evergreen.V83.Data.Perk -import Evergreen.V83.Data.Player -import Evergreen.V83.Data.Player.PlayerName -import Evergreen.V83.Data.Skill -import Evergreen.V83.Data.Special -import Evergreen.V83.Data.Trait -import Evergreen.V83.Data.Vendor -import Evergreen.V83.Data.World -import Evergreen.V83.Frontend.Route -import File exposing (File) -import Lamdera -import Set -import Time -import Url - - -type alias FrontendModel = - { key : Browser.Navigation.Key - , time : Time.Posix - , zone : Time.Zone - , route : Evergreen.V83.Frontend.Route.Route - , world : Evergreen.V83.Data.World.World - , newChar : Evergreen.V83.Data.NewChar.NewChar - , alertMessage : Maybe String - , mapMouseCoords : Maybe ( Evergreen.V83.Data.Map.TileCoords, Set.Set Evergreen.V83.Data.Map.TileCoords ) - } - - -type alias BackendModel = - { players : Dict.Dict Evergreen.V83.Data.Player.PlayerName.PlayerName (Evergreen.V83.Data.Player.Player Evergreen.V83.Data.Player.SPlayer) - , loggedInPlayers : Dict.Dict Lamdera.ClientId Evergreen.V83.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - , adminLoggedIn : Maybe ( Lamdera.ClientId, Lamdera.SessionId ) - , time : Time.Posix - , vendors : AssocList.Dict Evergreen.V83.Data.Vendor.Name Evergreen.V83.Data.Vendor.Vendor - , lastItemId : Int - } - - -type BarterMsg - = AddPlayerItem Evergreen.V83.Data.Item.Id Int - | AddVendorItem Evergreen.V83.Data.Item.Id Int - | AddPlayerCaps Int - | AddVendorCaps Int - | RemovePlayerItem Evergreen.V83.Data.Item.Id Int - | RemoveVendorItem Evergreen.V83.Data.Item.Id Int - | RemovePlayerCaps Int - | RemoveVendorCaps Int - | ResetBarter - | ConfirmBarter - | SetTransferNInput Evergreen.V83.Data.Barter.TransferNPosition String - | SetTransferNHover Evergreen.V83.Data.Barter.TransferNPosition - | UnsetTransferNHover - - -type FrontendMsg - = UrlClicked Browser.UrlRequest - | UrlChanged Url.Url - | GoToRoute Evergreen.V83.Frontend.Route.Route - | Logout - | Login - | Register - | GotZone Time.Zone - | GotTime Time.Posix - | AskToFight Evergreen.V83.Data.Player.PlayerName.PlayerName - | AskToHeal - | AskToUseItem Evergreen.V83.Data.Item.Id - | AskToWander - | AskToChoosePerk Evergreen.V83.Data.Perk.Perk - | AskToEquipItem Evergreen.V83.Data.Item.Id - | AskToUnequipArmor - | AskForExport - | ImportButtonClicked - | ImportFileSelected File - | AskToImport String - | Refresh - | AskToTagSkill Evergreen.V83.Data.Skill.Skill - | AskToUseSkillPoints Evergreen.V83.Data.Skill.Skill - | SetAuthName String - | SetAuthPassword String - | CreateChar - | NewCharIncSpecial Evergreen.V83.Data.Special.Type - | NewCharDecSpecial Evergreen.V83.Data.Special.Type - | NewCharToggleTaggedSkill Evergreen.V83.Data.Skill.Skill - | NewCharToggleTrait Evergreen.V83.Data.Trait.Trait - | MapMouseAtCoords Evergreen.V83.Data.Map.TileCoords - | MapMouseOut - | MapMouseClick - | OpenMessage Evergreen.V83.Data.Message.Message - | AskToRemoveMessage Evergreen.V83.Data.Message.Message - | BarterMsg BarterMsg - - -type AdminToBackend - = ExportJson - | ImportJson String - - -type ToBackend - = LogMeIn (Evergreen.V83.Data.Auth.Auth Evergreen.V83.Data.Auth.Hashed) - | RegisterMe (Evergreen.V83.Data.Auth.Auth Evergreen.V83.Data.Auth.Hashed) - | CreateNewChar Evergreen.V83.Data.NewChar.NewChar - | LogMeOut - | Fight Evergreen.V83.Data.Player.PlayerName.PlayerName - | HealMe - | UseItem Evergreen.V83.Data.Item.Id - | Wander - | EquipItem Evergreen.V83.Data.Item.Id - | UnequipArmor - | RefreshPlease - | TagSkill Evergreen.V83.Data.Skill.Skill - | UseSkillPoints Evergreen.V83.Data.Skill.Skill - | ChoosePerk Evergreen.V83.Data.Perk.Perk - | MoveTo Evergreen.V83.Data.Map.TileCoords (Set.Set Evergreen.V83.Data.Map.TileCoords) - | MessageWasRead Evergreen.V83.Data.Message.Message - | RemoveMessage Evergreen.V83.Data.Message.Message - | Barter Evergreen.V83.Data.Barter.State - | AdminToBackend AdminToBackend - - -type BackendMsg - = Connected Lamdera.SessionId Lamdera.ClientId - | Disconnected Lamdera.SessionId Lamdera.ClientId - | GeneratedFight Lamdera.ClientId Evergreen.V83.Data.Player.SPlayer Evergreen.V83.Data.Fight.Generator.Fight - | GeneratedNewVendorsStock ( AssocList.Dict Evergreen.V83.Data.Vendor.Name Evergreen.V83.Data.Vendor.Vendor, Int ) - | Tick Time.Posix - | CreateNewCharWithTime Lamdera.ClientId Evergreen.V83.Data.NewChar.NewChar Time.Posix - | LoggedToBackendMsg - - -type ToFrontend - = YourCurrentWorld Evergreen.V83.Data.World.WorldLoggedInData - | InitWorld Evergreen.V83.Data.World.WorldLoggedOutData - | RefreshedLoggedOut Evergreen.V83.Data.World.WorldLoggedOutData - | CurrentAdminData Evergreen.V83.Data.World.AdminData - | YourFightResult ( Evergreen.V83.Data.Fight.FightInfo, Evergreen.V83.Data.World.WorldLoggedInData ) - | YoureLoggedIn Evergreen.V83.Data.World.WorldLoggedInData - | YoureRegistered Evergreen.V83.Data.World.WorldLoggedInData - | CharCreationError Evergreen.V83.Data.NewChar.CreationError - | YouHaveCreatedChar Evergreen.V83.Data.World.WorldLoggedInData - | YoureLoggedOut Evergreen.V83.Data.World.WorldLoggedOutData - | AlertMessage String - | YoureLoggedInAsAdmin Evergreen.V83.Data.World.AdminData - | JsonExportDone String - | BarterDone ( Evergreen.V83.Data.World.WorldLoggedInData, Maybe Evergreen.V83.Data.Barter.Message ) - | BarterMessage Evergreen.V83.Data.Barter.Message diff --git a/src/Evergreen/V85/Data/Auth.elm b/src/Evergreen/V85/Data/Auth.elm deleted file mode 100644 index 689504c9..00000000 --- a/src/Evergreen/V85/Data/Auth.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V85.Data.Auth exposing (..) - - -type Plaintext - = Plaintext - - -type Password a - = Password String - - -type alias Auth a = - { name : String - , password : Password a - } - - -type Verified - = Verified - - -type Hashed - = Hashed diff --git a/src/Evergreen/V85/Data/Barter.elm b/src/Evergreen/V85/Data/Barter.elm deleted file mode 100644 index 2b00257a..00000000 --- a/src/Evergreen/V85/Data/Barter.elm +++ /dev/null @@ -1,33 +0,0 @@ -module Evergreen.V85.Data.Barter exposing (..) - -import AssocList -import Dict -import Evergreen.V85.Data.Item - - -type Message - = BarterIsEmpty - | PlayerOfferNotValuableEnough - | YouGaveStuffForFree - - -type TransferNPosition - = PlayerKeptItem Evergreen.V85.Data.Item.Id - | VendorKeptItem Evergreen.V85.Data.Item.Id - | PlayerTradedItem Evergreen.V85.Data.Item.Id - | VendorTradedItem Evergreen.V85.Data.Item.Id - | PlayerKeptCaps - | VendorKeptCaps - | PlayerTradedCaps - | VendorTradedCaps - - -type alias State = - { playerItems : Dict.Dict Evergreen.V85.Data.Item.Id Int - , vendorItems : Dict.Dict Evergreen.V85.Data.Item.Id Int - , playerCaps : Int - , vendorCaps : Int - , lastMessage : Maybe Message - , transferNInputs : AssocList.Dict TransferNPosition String - , transferNHover : Maybe TransferNPosition - } diff --git a/src/Evergreen/V85/Data/Enemy.elm b/src/Evergreen/V85/Data/Enemy.elm deleted file mode 100644 index afd5af7a..00000000 --- a/src/Evergreen/V85/Data/Enemy.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V85.Data.Enemy exposing (..) - - -type Type - = GiantAnt - | ToughGiantAnt - | LesserRadscorpion - | Radscorpion diff --git a/src/Evergreen/V85/Data/Fight.elm b/src/Evergreen/V85/Data/Fight.elm deleted file mode 100644 index 73f4b8aa..00000000 --- a/src/Evergreen/V85/Data/Fight.elm +++ /dev/null @@ -1,81 +0,0 @@ -module Evergreen.V85.Data.Fight exposing (..) - -import AssocList -import AssocSet -import Evergreen.V85.Data.Enemy -import Evergreen.V85.Data.Fight.ShotType -import Evergreen.V85.Data.Item -import Evergreen.V85.Data.Perk -import Evergreen.V85.Data.Player.PlayerName -import Evergreen.V85.Data.Skill -import Evergreen.V85.Data.Special -import Evergreen.V85.Data.Trait -import Evergreen.V85.Logic - - -type OpponentType - = Npc Evergreen.V85.Data.Enemy.Type - | Player Evergreen.V85.Data.Player.PlayerName.PlayerName - - -type Who - = Attacker - | Target - - -type Action - = Start - { distanceHexes : Int - } - | ComeCloser - { hexes : Int - , remainingDistanceHexes : Int - } - | Attack - { damage : Int - , shotType : Evergreen.V85.Data.Fight.ShotType.ShotType - , remainingHp : Int - , isCritical : Bool - } - | Miss - { shotType : Evergreen.V85.Data.Fight.ShotType.ShotType - } - - -type Result - = AttackerWon - { xpGained : Int - , capsGained : Int - } - | TargetWon - { xpGained : Int - , capsGained : Int - } - | TargetAlreadyDead - | BothDead - | NobodyDead - - -type alias Info = - { attacker : OpponentType - , target : OpponentType - , log : List ( Who, Action ) - , result : Result - } - - -type alias Opponent = - { type_ : OpponentType - , hp : Int - , maxHp : Int - , maxAp : Int - , sequence : Int - , traits : AssocSet.Set Evergreen.V85.Data.Trait.Trait - , perks : AssocList.Dict Evergreen.V85.Data.Perk.Perk Int - , caps : Int - , equippedArmor : Maybe Evergreen.V85.Data.Item.Kind - , naturalArmorClass : Int - , attackStats : Evergreen.V85.Logic.AttackStats - , addedSkillPercentages : AssocList.Dict Evergreen.V85.Data.Skill.Skill Int - , special : Evergreen.V85.Data.Special.Special - } diff --git a/src/Evergreen/V85/Data/Fight/Generator.elm b/src/Evergreen/V85/Data/Fight/Generator.elm deleted file mode 100644 index 98acce20..00000000 --- a/src/Evergreen/V85/Data/Fight/Generator.elm +++ /dev/null @@ -1,12 +0,0 @@ -module Evergreen.V85.Data.Fight.Generator exposing (..) - -import Evergreen.V85.Data.Fight -import Evergreen.V85.Data.Message - - -type alias Fight = - { finalAttacker : Evergreen.V85.Data.Fight.Opponent - , finalTarget : Evergreen.V85.Data.Fight.Opponent - , fightInfo : Evergreen.V85.Data.Fight.Info - , messageForTarget : Evergreen.V85.Data.Message.Message - } diff --git a/src/Evergreen/V85/Data/Fight/ShotType.elm b/src/Evergreen/V85/Data/Fight/ShotType.elm deleted file mode 100644 index 4e4bf2a1..00000000 --- a/src/Evergreen/V85/Data/Fight/ShotType.elm +++ /dev/null @@ -1,17 +0,0 @@ -module Evergreen.V85.Data.Fight.ShotType exposing (..) - - -type AimedShot - = Head - | Torso - | Eyes - | Groin - | LeftArm - | RightArm - | LeftLeg - | RightLeg - - -type ShotType - = NormalShot - | AimedShot AimedShot diff --git a/src/Evergreen/V85/Data/HealthStatus.elm b/src/Evergreen/V85/Data/HealthStatus.elm deleted file mode 100644 index b57c0783..00000000 --- a/src/Evergreen/V85/Data/HealthStatus.elm +++ /dev/null @@ -1,16 +0,0 @@ -module Evergreen.V85.Data.HealthStatus exposing (..) - - -type HealthStatus - = ExactHp - { current : Int - , max : Int - } - | Unhurt - | SlightlyWounded - | Wounded - | SeverelyWounded - | AlmostDead - | Dead - | Alive - | Unknown diff --git a/src/Evergreen/V85/Data/Item.elm b/src/Evergreen/V85/Data/Item.elm deleted file mode 100644 index ce4e7c26..00000000 --- a/src/Evergreen/V85/Data/Item.elm +++ /dev/null @@ -1,26 +0,0 @@ -module Evergreen.V85.Data.Item exposing (..) - - -type alias Id = - Int - - -type Kind - = HealingPowder - | Stimpak - | BigBookOfScience - | DeansElectronics - | FirstAidBook - | GunsAndBullets - | ScoutHandbook - | Robes - | LeatherJacket - | LeatherArmor - | MetalArmor - - -type alias Item = - { id : Id - , kind : Kind - , count : Int - } diff --git a/src/Evergreen/V85/Data/Map.elm b/src/Evergreen/V85/Data/Map.elm deleted file mode 100644 index c874da98..00000000 --- a/src/Evergreen/V85/Data/Map.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V85.Data.Map exposing (..) - - -type alias TileNum = - Int - - -type alias TileCoords = - ( Int, Int ) diff --git a/src/Evergreen/V85/Data/Message.elm b/src/Evergreen/V85/Data/Message.elm deleted file mode 100644 index 53bd7c41..00000000 --- a/src/Evergreen/V85/Data/Message.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V85.Data.Message exposing (..) - -import Evergreen.V85.Data.Fight -import Evergreen.V85.Data.Player.PlayerName -import Time - - -type Type - = Welcome - | YouAdvancedLevel - { newLevel : Int - } - | YouWereAttacked - { attacker : Evergreen.V85.Data.Player.PlayerName.PlayerName - , fightInfo : Evergreen.V85.Data.Fight.Info - } - - -type alias Message = - { type_ : Type - , hasBeenRead : Bool - , date : Time.Posix - } diff --git a/src/Evergreen/V85/Data/NewChar.elm b/src/Evergreen/V85/Data/NewChar.elm deleted file mode 100644 index 27f3832e..00000000 --- a/src/Evergreen/V85/Data/NewChar.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V85.Data.NewChar exposing (..) - -import AssocSet -import Evergreen.V85.Data.Skill -import Evergreen.V85.Data.Special -import Evergreen.V85.Data.Trait - - -type CreationError - = DoesNotHaveThreeTaggedSkills - | HasSpecialPointsLeft - | UsedMoreSpecialPointsThanAvailable - | HasSpecialOutOfRange - | HasMoreThanTwoTraits - - -type alias NewChar = - { baseSpecial : Evergreen.V85.Data.Special.Special - , availableSpecial : Int - , taggedSkills : AssocSet.Set Evergreen.V85.Data.Skill.Skill - , traits : AssocSet.Set Evergreen.V85.Data.Trait.Trait - , error : Maybe CreationError - } diff --git a/src/Evergreen/V85/Data/Perk.elm b/src/Evergreen/V85/Data/Perk.elm deleted file mode 100644 index f4a92da8..00000000 --- a/src/Evergreen/V85/Data/Perk.elm +++ /dev/null @@ -1,25 +0,0 @@ -module Evergreen.V85.Data.Perk exposing (..) - - -type Perk - = BonusHthDamage - | MasterTrader - | Awareness - | CautiousNature - | Comprehension - | EarlierSequence - | FasterHealing - | HereAndNow - | Survivalist - | Educated - | MoreCriticals - | BetterCriticals - | Tag - | GainStrength - | GainPerception - | GainEndurance - | GainCharisma - | GainIntelligence - | GainAgility - | GainLuck - | Slayer diff --git a/src/Evergreen/V85/Data/Player.elm b/src/Evergreen/V85/Data/Player.elm deleted file mode 100644 index 4ad5e69b..00000000 --- a/src/Evergreen/V85/Data/Player.elm +++ /dev/null @@ -1,77 +0,0 @@ -module Evergreen.V85.Data.Player exposing (..) - -import AssocList -import AssocSet -import Dict -import Evergreen.V85.Data.Auth -import Evergreen.V85.Data.HealthStatus -import Evergreen.V85.Data.Item -import Evergreen.V85.Data.Map -import Evergreen.V85.Data.Message -import Evergreen.V85.Data.Perk -import Evergreen.V85.Data.Player.PlayerName -import Evergreen.V85.Data.Skill -import Evergreen.V85.Data.Special -import Evergreen.V85.Data.Trait -import Evergreen.V85.Data.Xp - - -type alias COtherPlayer = - { level : Evergreen.V85.Data.Xp.Level - , name : Evergreen.V85.Data.Player.PlayerName.PlayerName - , wins : Int - , losses : Int - , healthStatus : Evergreen.V85.Data.HealthStatus.HealthStatus - } - - -type alias CPlayer = - { hp : Int - , maxHp : Int - , xp : Evergreen.V85.Data.Xp.Xp - , name : Evergreen.V85.Data.Player.PlayerName.PlayerName - , special : Evergreen.V85.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V85.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V85.Data.Perk.Perk Int - , messages : List Evergreen.V85.Data.Message.Message - , items : Dict.Dict Evergreen.V85.Data.Item.Id Evergreen.V85.Data.Item.Item - , traits : AssocSet.Set Evergreen.V85.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V85.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V85.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - , equippedArmor : Maybe Evergreen.V85.Data.Item.Item - } - - -type Player a - = NeedsCharCreated (Evergreen.V85.Data.Auth.Auth Evergreen.V85.Data.Auth.Verified) - | Player a - - -type alias SPlayer = - { name : Evergreen.V85.Data.Player.PlayerName.PlayerName - , password : Evergreen.V85.Data.Auth.Password Evergreen.V85.Data.Auth.Verified - , hp : Int - , maxHp : Int - , xp : Int - , special : Evergreen.V85.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V85.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V85.Data.Perk.Perk Int - , messages : List Evergreen.V85.Data.Message.Message - , items : Dict.Dict Evergreen.V85.Data.Item.Id Evergreen.V85.Data.Item.Item - , traits : AssocSet.Set Evergreen.V85.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V85.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V85.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - , equippedArmor : Maybe Evergreen.V85.Data.Item.Item - } diff --git a/src/Evergreen/V85/Data/Player/PlayerName.elm b/src/Evergreen/V85/Data/Player/PlayerName.elm deleted file mode 100644 index e1367e48..00000000 --- a/src/Evergreen/V85/Data/Player/PlayerName.elm +++ /dev/null @@ -1,5 +0,0 @@ -module Evergreen.V85.Data.Player.PlayerName exposing (..) - - -type alias PlayerName = - String diff --git a/src/Evergreen/V85/Data/Skill.elm b/src/Evergreen/V85/Data/Skill.elm deleted file mode 100644 index faf4ce57..00000000 --- a/src/Evergreen/V85/Data/Skill.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V85.Data.Skill exposing (..) - - -type Skill - = SmallGuns - | BigGuns - | EnergyWeapons - | Unarmed - | MeleeWeapons - | Throwing - | FirstAid - | Doctor - | Sneak - | Lockpick - | Steal - | Traps - | Science - | Repair - | Speech - | Barter - | Gambling - | Outdoorsman diff --git a/src/Evergreen/V85/Data/Special.elm b/src/Evergreen/V85/Data/Special.elm deleted file mode 100644 index 619d394a..00000000 --- a/src/Evergreen/V85/Data/Special.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V85.Data.Special exposing (..) - - -type alias Special = - { strength : Int - , perception : Int - , endurance : Int - , charisma : Int - , intelligence : Int - , agility : Int - , luck : Int - } - - -type Type - = Strength - | Perception - | Endurance - | Charisma - | Intelligence - | Agility - | Luck diff --git a/src/Evergreen/V85/Data/Trait.elm b/src/Evergreen/V85/Data/Trait.elm deleted file mode 100644 index 57e8b256..00000000 --- a/src/Evergreen/V85/Data/Trait.elm +++ /dev/null @@ -1,11 +0,0 @@ -module Evergreen.V85.Data.Trait exposing (..) - - -type Trait - = Kamikaze - | Bruiser - | Gifted - | SmallFrame - | Skilled - | HeavyHanded - | Finesse diff --git a/src/Evergreen/V85/Data/Vendor.elm b/src/Evergreen/V85/Data/Vendor.elm deleted file mode 100644 index 830a1cec..00000000 --- a/src/Evergreen/V85/Data/Vendor.elm +++ /dev/null @@ -1,20 +0,0 @@ -module Evergreen.V85.Data.Vendor exposing (..) - -import Dict -import Evergreen.V85.Data.Item - - -type Name - = ArroyoHakunin - | KlamathMaidaBuckner - | DenFlick - | ModocJo - | VaultCityHappyHarry - - -type alias Vendor = - { name : Name - , items : Dict.Dict Evergreen.V85.Data.Item.Id Evergreen.V85.Data.Item.Item - , caps : Int - , barterSkill : Int - } diff --git a/src/Evergreen/V85/Data/World.elm b/src/Evergreen/V85/Data/World.elm deleted file mode 100644 index a9223d39..00000000 --- a/src/Evergreen/V85/Data/World.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.V85.Data.World exposing (..) - -import AssocList -import Evergreen.V85.Data.Auth -import Evergreen.V85.Data.Player -import Evergreen.V85.Data.Player.PlayerName -import Evergreen.V85.Data.Vendor -import Time - - -type alias WorldLoggedOutData = - { players : List Evergreen.V85.Data.Player.COtherPlayer - } - - -type alias WorldLoggedInData = - { player : Evergreen.V85.Data.Player.Player Evergreen.V85.Data.Player.CPlayer - , otherPlayers : List Evergreen.V85.Data.Player.COtherPlayer - , playerRank : Int - , vendors : AssocList.Dict Evergreen.V85.Data.Vendor.Name Evergreen.V85.Data.Vendor.Vendor - } - - -type alias AdminData = - { players : List (Evergreen.V85.Data.Player.Player Evergreen.V85.Data.Player.SPlayer) - , loggedInPlayers : List Evergreen.V85.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - } - - -type World - = WorldNotInitialized (Evergreen.V85.Data.Auth.Auth Evergreen.V85.Data.Auth.Plaintext) - | WorldLoggedOut (Evergreen.V85.Data.Auth.Auth Evergreen.V85.Data.Auth.Plaintext) WorldLoggedOutData - | WorldLoggedIn WorldLoggedInData - | WorldAdmin AdminData diff --git a/src/Evergreen/V85/Data/Xp.elm b/src/Evergreen/V85/Data/Xp.elm deleted file mode 100644 index ffb9124c..00000000 --- a/src/Evergreen/V85/Data/Xp.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V85.Data.Xp exposing (..) - - -type alias Level = - Int - - -type alias Xp = - Int diff --git a/src/Evergreen/V85/Frontend/Route.elm b/src/Evergreen/V85/Frontend/Route.elm deleted file mode 100644 index 1ef2e34a..00000000 --- a/src/Evergreen/V85/Frontend/Route.elm +++ /dev/null @@ -1,31 +0,0 @@ -module Evergreen.V85.Frontend.Route exposing (..) - -import Evergreen.V85.Data.Barter -import Evergreen.V85.Data.Fight -import Evergreen.V85.Data.Message - - -type TownRoute - = MainSquare - | Store - { barter : Evergreen.V85.Data.Barter.State - } - - -type AdminRoute - = LoggedIn - - -type Route - = Character - | Inventory - | Map - | Ladder - | Town TownRoute - | About - | News - | Fight Evergreen.V85.Data.Fight.Info - | Messages - | Message Evergreen.V85.Data.Message.Message - | CharCreation - | Admin AdminRoute diff --git a/src/Evergreen/V85/Logic.elm b/src/Evergreen/V85/Logic.elm deleted file mode 100644 index b17580c7..00000000 --- a/src/Evergreen/V85/Logic.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V85.Logic exposing (..) - - -type alias AttackStats = - { minDamage : Int - , maxDamage : Int - , criticalChanceBonus : Int - } diff --git a/src/Evergreen/V85/Types.elm b/src/Evergreen/V85/Types.elm deleted file mode 100644 index 9eba620f..00000000 --- a/src/Evergreen/V85/Types.elm +++ /dev/null @@ -1,160 +0,0 @@ -module Evergreen.V85.Types exposing (..) - -import AssocList -import Browser -import Browser.Navigation -import Dict -import Evergreen.V85.Data.Auth -import Evergreen.V85.Data.Barter -import Evergreen.V85.Data.Fight -import Evergreen.V85.Data.Fight.Generator -import Evergreen.V85.Data.Item -import Evergreen.V85.Data.Map -import Evergreen.V85.Data.Message -import Evergreen.V85.Data.NewChar -import Evergreen.V85.Data.Perk -import Evergreen.V85.Data.Player -import Evergreen.V85.Data.Player.PlayerName -import Evergreen.V85.Data.Skill -import Evergreen.V85.Data.Special -import Evergreen.V85.Data.Trait -import Evergreen.V85.Data.Vendor -import Evergreen.V85.Data.World -import Evergreen.V85.Frontend.Route -import File exposing (File) -import Lamdera -import Set -import Time -import Url - - -type alias FrontendModel = - { key : Browser.Navigation.Key - , time : Time.Posix - , zone : Time.Zone - , route : Evergreen.V85.Frontend.Route.Route - , world : Evergreen.V85.Data.World.World - , newChar : Evergreen.V85.Data.NewChar.NewChar - , alertMessage : Maybe String - , mapMouseCoords : Maybe ( Evergreen.V85.Data.Map.TileCoords, Set.Set Evergreen.V85.Data.Map.TileCoords ) - } - - -type alias BackendModel = - { players : Dict.Dict Evergreen.V85.Data.Player.PlayerName.PlayerName (Evergreen.V85.Data.Player.Player Evergreen.V85.Data.Player.SPlayer) - , loggedInPlayers : Dict.Dict Lamdera.ClientId Evergreen.V85.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - , adminLoggedIn : Maybe ( Lamdera.ClientId, Lamdera.SessionId ) - , time : Time.Posix - , vendors : AssocList.Dict Evergreen.V85.Data.Vendor.Name Evergreen.V85.Data.Vendor.Vendor - , lastItemId : Int - } - - -type BarterMsg - = AddPlayerItem Evergreen.V85.Data.Item.Id Int - | AddVendorItem Evergreen.V85.Data.Item.Id Int - | AddPlayerCaps Int - | AddVendorCaps Int - | RemovePlayerItem Evergreen.V85.Data.Item.Id Int - | RemoveVendorItem Evergreen.V85.Data.Item.Id Int - | RemovePlayerCaps Int - | RemoveVendorCaps Int - | ResetBarter - | ConfirmBarter - | SetTransferNInput Evergreen.V85.Data.Barter.TransferNPosition String - | SetTransferNHover Evergreen.V85.Data.Barter.TransferNPosition - | UnsetTransferNHover - - -type FrontendMsg - = UrlClicked Browser.UrlRequest - | UrlChanged Url.Url - | GoToRoute Evergreen.V85.Frontend.Route.Route - | Logout - | Login - | Register - | GotZone Time.Zone - | GotTime Time.Posix - | AskToFight Evergreen.V85.Data.Player.PlayerName.PlayerName - | AskToHeal - | AskToUseItem Evergreen.V85.Data.Item.Id - | AskToWander - | AskToChoosePerk Evergreen.V85.Data.Perk.Perk - | AskToEquipItem Evergreen.V85.Data.Item.Id - | AskToUnequipArmor - | AskForExport - | ImportButtonClicked - | ImportFileSelected File - | AskToImport String - | Refresh - | AskToTagSkill Evergreen.V85.Data.Skill.Skill - | AskToUseSkillPoints Evergreen.V85.Data.Skill.Skill - | SetAuthName String - | SetAuthPassword String - | CreateChar - | NewCharIncSpecial Evergreen.V85.Data.Special.Type - | NewCharDecSpecial Evergreen.V85.Data.Special.Type - | NewCharToggleTaggedSkill Evergreen.V85.Data.Skill.Skill - | NewCharToggleTrait Evergreen.V85.Data.Trait.Trait - | MapMouseAtCoords Evergreen.V85.Data.Map.TileCoords - | MapMouseOut - | MapMouseClick - | OpenMessage Evergreen.V85.Data.Message.Message - | AskToRemoveMessage Evergreen.V85.Data.Message.Message - | BarterMsg BarterMsg - - -type AdminToBackend - = ExportJson - | ImportJson String - - -type ToBackend - = LogMeIn (Evergreen.V85.Data.Auth.Auth Evergreen.V85.Data.Auth.Hashed) - | RegisterMe (Evergreen.V85.Data.Auth.Auth Evergreen.V85.Data.Auth.Hashed) - | CreateNewChar Evergreen.V85.Data.NewChar.NewChar - | LogMeOut - | Fight Evergreen.V85.Data.Player.PlayerName.PlayerName - | HealMe - | UseItem Evergreen.V85.Data.Item.Id - | Wander - | EquipItem Evergreen.V85.Data.Item.Id - | UnequipArmor - | RefreshPlease - | TagSkill Evergreen.V85.Data.Skill.Skill - | UseSkillPoints Evergreen.V85.Data.Skill.Skill - | ChoosePerk Evergreen.V85.Data.Perk.Perk - | MoveTo Evergreen.V85.Data.Map.TileCoords (Set.Set Evergreen.V85.Data.Map.TileCoords) - | MessageWasRead Evergreen.V85.Data.Message.Message - | RemoveMessage Evergreen.V85.Data.Message.Message - | Barter Evergreen.V85.Data.Barter.State - | AdminToBackend AdminToBackend - - -type BackendMsg - = Connected Lamdera.SessionId Lamdera.ClientId - | Disconnected Lamdera.SessionId Lamdera.ClientId - | GeneratedFight Lamdera.ClientId Evergreen.V85.Data.Player.SPlayer Evergreen.V85.Data.Fight.Generator.Fight - | GeneratedNewVendorsStock ( AssocList.Dict Evergreen.V85.Data.Vendor.Name Evergreen.V85.Data.Vendor.Vendor, Int ) - | Tick Time.Posix - | CreateNewCharWithTime Lamdera.ClientId Evergreen.V85.Data.NewChar.NewChar Time.Posix - | LoggedToBackendMsg - - -type ToFrontend - = YourCurrentWorld Evergreen.V85.Data.World.WorldLoggedInData - | InitWorld Evergreen.V85.Data.World.WorldLoggedOutData - | RefreshedLoggedOut Evergreen.V85.Data.World.WorldLoggedOutData - | CurrentAdminData Evergreen.V85.Data.World.AdminData - | YourFightResult ( Evergreen.V85.Data.Fight.Info, Evergreen.V85.Data.World.WorldLoggedInData ) - | YoureLoggedIn Evergreen.V85.Data.World.WorldLoggedInData - | YoureRegistered Evergreen.V85.Data.World.WorldLoggedInData - | CharCreationError Evergreen.V85.Data.NewChar.CreationError - | YouHaveCreatedChar Evergreen.V85.Data.World.WorldLoggedInData - | YoureLoggedOut Evergreen.V85.Data.World.WorldLoggedOutData - | AlertMessage String - | YoureLoggedInAsAdmin Evergreen.V85.Data.World.AdminData - | JsonExportDone String - | BarterDone ( Evergreen.V85.Data.World.WorldLoggedInData, Maybe Evergreen.V85.Data.Barter.Message ) - | BarterMessage Evergreen.V85.Data.Barter.Message diff --git a/src/Evergreen/V87/Data/Auth.elm b/src/Evergreen/V87/Data/Auth.elm deleted file mode 100644 index 16bd37c1..00000000 --- a/src/Evergreen/V87/Data/Auth.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V87.Data.Auth exposing (..) - - -type Plaintext - = Plaintext - - -type Password a - = Password String - - -type alias Auth a = - { name : String - , password : Password a - } - - -type Verified - = Verified - - -type Hashed - = Hashed diff --git a/src/Evergreen/V87/Data/Barter.elm b/src/Evergreen/V87/Data/Barter.elm deleted file mode 100644 index 9ab8d432..00000000 --- a/src/Evergreen/V87/Data/Barter.elm +++ /dev/null @@ -1,33 +0,0 @@ -module Evergreen.V87.Data.Barter exposing (..) - -import AssocList -import Dict -import Evergreen.V87.Data.Item - - -type Message - = BarterIsEmpty - | PlayerOfferNotValuableEnough - | YouGaveStuffForFree - - -type TransferNPosition - = PlayerKeptItem Evergreen.V87.Data.Item.Id - | VendorKeptItem Evergreen.V87.Data.Item.Id - | PlayerTradedItem Evergreen.V87.Data.Item.Id - | VendorTradedItem Evergreen.V87.Data.Item.Id - | PlayerKeptCaps - | VendorKeptCaps - | PlayerTradedCaps - | VendorTradedCaps - - -type alias State = - { playerItems : Dict.Dict Evergreen.V87.Data.Item.Id Int - , vendorItems : Dict.Dict Evergreen.V87.Data.Item.Id Int - , playerCaps : Int - , vendorCaps : Int - , lastMessage : Maybe Message - , transferNInputs : AssocList.Dict TransferNPosition String - , transferNHover : Maybe TransferNPosition - } diff --git a/src/Evergreen/V87/Data/Enemy.elm b/src/Evergreen/V87/Data/Enemy.elm deleted file mode 100644 index f294efbb..00000000 --- a/src/Evergreen/V87/Data/Enemy.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V87.Data.Enemy exposing (..) - - -type Type - = GiantAnt - | ToughGiantAnt - | LesserRadscorpion - | Radscorpion diff --git a/src/Evergreen/V87/Data/Fight.elm b/src/Evergreen/V87/Data/Fight.elm deleted file mode 100644 index 11231bc0..00000000 --- a/src/Evergreen/V87/Data/Fight.elm +++ /dev/null @@ -1,81 +0,0 @@ -module Evergreen.V87.Data.Fight exposing (..) - -import AssocList -import AssocSet -import Evergreen.V87.Data.Enemy -import Evergreen.V87.Data.Fight.ShotType -import Evergreen.V87.Data.Item -import Evergreen.V87.Data.Perk -import Evergreen.V87.Data.Player.PlayerName -import Evergreen.V87.Data.Skill -import Evergreen.V87.Data.Special -import Evergreen.V87.Data.Trait -import Evergreen.V87.Logic - - -type OpponentType - = Npc Evergreen.V87.Data.Enemy.Type - | Player Evergreen.V87.Data.Player.PlayerName.PlayerName - - -type Who - = Attacker - | Target - - -type Action - = Start - { distanceHexes : Int - } - | ComeCloser - { hexes : Int - , remainingDistanceHexes : Int - } - | Attack - { damage : Int - , shotType : Evergreen.V87.Data.Fight.ShotType.ShotType - , remainingHp : Int - , isCritical : Bool - } - | Miss - { shotType : Evergreen.V87.Data.Fight.ShotType.ShotType - } - - -type Result - = AttackerWon - { xpGained : Int - , capsGained : Int - } - | TargetWon - { xpGained : Int - , capsGained : Int - } - | TargetAlreadyDead - | BothDead - | NobodyDead - - -type alias Info = - { attacker : OpponentType - , target : OpponentType - , log : List ( Who, Action ) - , result : Result - } - - -type alias Opponent = - { type_ : OpponentType - , hp : Int - , maxHp : Int - , maxAp : Int - , sequence : Int - , traits : AssocSet.Set Evergreen.V87.Data.Trait.Trait - , perks : AssocList.Dict Evergreen.V87.Data.Perk.Perk Int - , caps : Int - , equippedArmor : Maybe Evergreen.V87.Data.Item.Kind - , naturalArmorClass : Int - , attackStats : Evergreen.V87.Logic.AttackStats - , addedSkillPercentages : AssocList.Dict Evergreen.V87.Data.Skill.Skill Int - , special : Evergreen.V87.Data.Special.Special - } diff --git a/src/Evergreen/V87/Data/Fight/Generator.elm b/src/Evergreen/V87/Data/Fight/Generator.elm deleted file mode 100644 index 68d0932a..00000000 --- a/src/Evergreen/V87/Data/Fight/Generator.elm +++ /dev/null @@ -1,12 +0,0 @@ -module Evergreen.V87.Data.Fight.Generator exposing (..) - -import Evergreen.V87.Data.Fight -import Evergreen.V87.Data.Message - - -type alias Fight = - { finalAttacker : Evergreen.V87.Data.Fight.Opponent - , finalTarget : Evergreen.V87.Data.Fight.Opponent - , fightInfo : Evergreen.V87.Data.Fight.Info - , messageForTarget : Evergreen.V87.Data.Message.Message - } diff --git a/src/Evergreen/V87/Data/Fight/ShotType.elm b/src/Evergreen/V87/Data/Fight/ShotType.elm deleted file mode 100644 index 672b0aee..00000000 --- a/src/Evergreen/V87/Data/Fight/ShotType.elm +++ /dev/null @@ -1,17 +0,0 @@ -module Evergreen.V87.Data.Fight.ShotType exposing (..) - - -type AimedShot - = Head - | Torso - | Eyes - | Groin - | LeftArm - | RightArm - | LeftLeg - | RightLeg - - -type ShotType - = NormalShot - | AimedShot AimedShot diff --git a/src/Evergreen/V87/Data/HealthStatus.elm b/src/Evergreen/V87/Data/HealthStatus.elm deleted file mode 100644 index d6c98af1..00000000 --- a/src/Evergreen/V87/Data/HealthStatus.elm +++ /dev/null @@ -1,16 +0,0 @@ -module Evergreen.V87.Data.HealthStatus exposing (..) - - -type HealthStatus - = ExactHp - { current : Int - , max : Int - } - | Unhurt - | SlightlyWounded - | Wounded - | SeverelyWounded - | AlmostDead - | Dead - | Alive - | Unknown diff --git a/src/Evergreen/V87/Data/Item.elm b/src/Evergreen/V87/Data/Item.elm deleted file mode 100644 index ed824a48..00000000 --- a/src/Evergreen/V87/Data/Item.elm +++ /dev/null @@ -1,26 +0,0 @@ -module Evergreen.V87.Data.Item exposing (..) - - -type alias Id = - Int - - -type Kind - = HealingPowder - | Stimpak - | BigBookOfScience - | DeansElectronics - | FirstAidBook - | GunsAndBullets - | ScoutHandbook - | Robes - | LeatherJacket - | LeatherArmor - | MetalArmor - - -type alias Item = - { id : Id - , kind : Kind - , count : Int - } diff --git a/src/Evergreen/V87/Data/Map.elm b/src/Evergreen/V87/Data/Map.elm deleted file mode 100644 index cfe63130..00000000 --- a/src/Evergreen/V87/Data/Map.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V87.Data.Map exposing (..) - - -type alias TileNum = - Int - - -type alias TileCoords = - ( Int, Int ) diff --git a/src/Evergreen/V87/Data/Message.elm b/src/Evergreen/V87/Data/Message.elm deleted file mode 100644 index d77aea33..00000000 --- a/src/Evergreen/V87/Data/Message.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V87.Data.Message exposing (..) - -import Evergreen.V87.Data.Fight -import Evergreen.V87.Data.Player.PlayerName -import Time - - -type Type - = Welcome - | YouAdvancedLevel - { newLevel : Int - } - | YouWereAttacked - { attacker : Evergreen.V87.Data.Player.PlayerName.PlayerName - , fightInfo : Evergreen.V87.Data.Fight.Info - } - - -type alias Message = - { type_ : Type - , hasBeenRead : Bool - , date : Time.Posix - } diff --git a/src/Evergreen/V87/Data/NewChar.elm b/src/Evergreen/V87/Data/NewChar.elm deleted file mode 100644 index 8167182b..00000000 --- a/src/Evergreen/V87/Data/NewChar.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V87.Data.NewChar exposing (..) - -import AssocSet -import Evergreen.V87.Data.Skill -import Evergreen.V87.Data.Special -import Evergreen.V87.Data.Trait - - -type CreationError - = DoesNotHaveThreeTaggedSkills - | HasSpecialPointsLeft - | UsedMoreSpecialPointsThanAvailable - | HasSpecialOutOfRange - | HasMoreThanTwoTraits - - -type alias NewChar = - { baseSpecial : Evergreen.V87.Data.Special.Special - , availableSpecial : Int - , taggedSkills : AssocSet.Set Evergreen.V87.Data.Skill.Skill - , traits : AssocSet.Set Evergreen.V87.Data.Trait.Trait - , error : Maybe CreationError - } diff --git a/src/Evergreen/V87/Data/Perk.elm b/src/Evergreen/V87/Data/Perk.elm deleted file mode 100644 index e632325b..00000000 --- a/src/Evergreen/V87/Data/Perk.elm +++ /dev/null @@ -1,45 +0,0 @@ -module Evergreen.V87.Data.Perk exposing (..) - - -type Perk - = BonusHthDamage - | Awareness - | CautiousNature - | Comprehension - | EarlierSequence - | FasterHealing - | HereAndNow - | Survivalist - | SwiftLearner - | Thief - | Toughness - | AdrenalineRush - | Educated - | FortuneFinder - | Gambler - | MoreCriticals - | Negotiator - | Pathfinder - | Ranger - | Salesman - | BetterCriticals - | Dodger - | Speaker - | ActionBoy - | GainStrength - | GainPerception - | GainEndurance - | GainCharisma - | GainIntelligence - | GainAgility - | GainLuck - | HthEvade - | Lifegiver - | LivingAnatomy - | MasterThief - | MasterTrader - | Medic - | MrFixit - | Tag - | BonusHthAttacks - | Slayer diff --git a/src/Evergreen/V87/Data/Player.elm b/src/Evergreen/V87/Data/Player.elm deleted file mode 100644 index 492c39de..00000000 --- a/src/Evergreen/V87/Data/Player.elm +++ /dev/null @@ -1,77 +0,0 @@ -module Evergreen.V87.Data.Player exposing (..) - -import AssocList -import AssocSet -import Dict -import Evergreen.V87.Data.Auth -import Evergreen.V87.Data.HealthStatus -import Evergreen.V87.Data.Item -import Evergreen.V87.Data.Map -import Evergreen.V87.Data.Message -import Evergreen.V87.Data.Perk -import Evergreen.V87.Data.Player.PlayerName -import Evergreen.V87.Data.Skill -import Evergreen.V87.Data.Special -import Evergreen.V87.Data.Trait -import Evergreen.V87.Data.Xp - - -type alias COtherPlayer = - { level : Evergreen.V87.Data.Xp.Level - , name : Evergreen.V87.Data.Player.PlayerName.PlayerName - , wins : Int - , losses : Int - , healthStatus : Evergreen.V87.Data.HealthStatus.HealthStatus - } - - -type alias CPlayer = - { hp : Int - , maxHp : Int - , xp : Evergreen.V87.Data.Xp.Xp - , name : Evergreen.V87.Data.Player.PlayerName.PlayerName - , special : Evergreen.V87.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V87.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V87.Data.Perk.Perk Int - , messages : List Evergreen.V87.Data.Message.Message - , items : Dict.Dict Evergreen.V87.Data.Item.Id Evergreen.V87.Data.Item.Item - , traits : AssocSet.Set Evergreen.V87.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V87.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V87.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - , equippedArmor : Maybe Evergreen.V87.Data.Item.Item - } - - -type Player a - = NeedsCharCreated (Evergreen.V87.Data.Auth.Auth Evergreen.V87.Data.Auth.Verified) - | Player a - - -type alias SPlayer = - { name : Evergreen.V87.Data.Player.PlayerName.PlayerName - , password : Evergreen.V87.Data.Auth.Password Evergreen.V87.Data.Auth.Verified - , hp : Int - , maxHp : Int - , xp : Int - , special : Evergreen.V87.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V87.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V87.Data.Perk.Perk Int - , messages : List Evergreen.V87.Data.Message.Message - , items : Dict.Dict Evergreen.V87.Data.Item.Id Evergreen.V87.Data.Item.Item - , traits : AssocSet.Set Evergreen.V87.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V87.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V87.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - , equippedArmor : Maybe Evergreen.V87.Data.Item.Item - } diff --git a/src/Evergreen/V87/Data/Player/PlayerName.elm b/src/Evergreen/V87/Data/Player/PlayerName.elm deleted file mode 100644 index c876b162..00000000 --- a/src/Evergreen/V87/Data/Player/PlayerName.elm +++ /dev/null @@ -1,5 +0,0 @@ -module Evergreen.V87.Data.Player.PlayerName exposing (..) - - -type alias PlayerName = - String diff --git a/src/Evergreen/V87/Data/Skill.elm b/src/Evergreen/V87/Data/Skill.elm deleted file mode 100644 index 35e3da74..00000000 --- a/src/Evergreen/V87/Data/Skill.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V87.Data.Skill exposing (..) - - -type Skill - = SmallGuns - | BigGuns - | EnergyWeapons - | Unarmed - | MeleeWeapons - | Throwing - | FirstAid - | Doctor - | Sneak - | Lockpick - | Steal - | Traps - | Science - | Repair - | Speech - | Barter - | Gambling - | Outdoorsman diff --git a/src/Evergreen/V87/Data/Special.elm b/src/Evergreen/V87/Data/Special.elm deleted file mode 100644 index 8b7d7f75..00000000 --- a/src/Evergreen/V87/Data/Special.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V87.Data.Special exposing (..) - - -type alias Special = - { strength : Int - , perception : Int - , endurance : Int - , charisma : Int - , intelligence : Int - , agility : Int - , luck : Int - } - - -type Type - = Strength - | Perception - | Endurance - | Charisma - | Intelligence - | Agility - | Luck diff --git a/src/Evergreen/V87/Data/Trait.elm b/src/Evergreen/V87/Data/Trait.elm deleted file mode 100644 index 2448cd20..00000000 --- a/src/Evergreen/V87/Data/Trait.elm +++ /dev/null @@ -1,11 +0,0 @@ -module Evergreen.V87.Data.Trait exposing (..) - - -type Trait - = Kamikaze - | Bruiser - | Gifted - | SmallFrame - | Skilled - | HeavyHanded - | Finesse diff --git a/src/Evergreen/V87/Data/Vendor.elm b/src/Evergreen/V87/Data/Vendor.elm deleted file mode 100644 index bb353e71..00000000 --- a/src/Evergreen/V87/Data/Vendor.elm +++ /dev/null @@ -1,20 +0,0 @@ -module Evergreen.V87.Data.Vendor exposing (..) - -import Dict -import Evergreen.V87.Data.Item - - -type Name - = ArroyoHakunin - | KlamathMaidaBuckner - | DenFlick - | ModocJo - | VaultCityHappyHarry - - -type alias Vendor = - { name : Name - , items : Dict.Dict Evergreen.V87.Data.Item.Id Evergreen.V87.Data.Item.Item - , caps : Int - , barterSkill : Int - } diff --git a/src/Evergreen/V87/Data/World.elm b/src/Evergreen/V87/Data/World.elm deleted file mode 100644 index 2f2492ba..00000000 --- a/src/Evergreen/V87/Data/World.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.V87.Data.World exposing (..) - -import AssocList -import Evergreen.V87.Data.Auth -import Evergreen.V87.Data.Player -import Evergreen.V87.Data.Player.PlayerName -import Evergreen.V87.Data.Vendor -import Time - - -type alias WorldLoggedOutData = - { players : List Evergreen.V87.Data.Player.COtherPlayer - } - - -type alias WorldLoggedInData = - { player : Evergreen.V87.Data.Player.Player Evergreen.V87.Data.Player.CPlayer - , otherPlayers : List Evergreen.V87.Data.Player.COtherPlayer - , playerRank : Int - , vendors : AssocList.Dict Evergreen.V87.Data.Vendor.Name Evergreen.V87.Data.Vendor.Vendor - } - - -type alias AdminData = - { players : List (Evergreen.V87.Data.Player.Player Evergreen.V87.Data.Player.SPlayer) - , loggedInPlayers : List Evergreen.V87.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - } - - -type World - = WorldNotInitialized (Evergreen.V87.Data.Auth.Auth Evergreen.V87.Data.Auth.Plaintext) - | WorldLoggedOut (Evergreen.V87.Data.Auth.Auth Evergreen.V87.Data.Auth.Plaintext) WorldLoggedOutData - | WorldLoggedIn WorldLoggedInData - | WorldAdmin AdminData diff --git a/src/Evergreen/V87/Data/Xp.elm b/src/Evergreen/V87/Data/Xp.elm deleted file mode 100644 index b931cc73..00000000 --- a/src/Evergreen/V87/Data/Xp.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V87.Data.Xp exposing (..) - - -type alias Level = - Int - - -type alias Xp = - Int diff --git a/src/Evergreen/V87/Frontend/Route.elm b/src/Evergreen/V87/Frontend/Route.elm deleted file mode 100644 index 58e8b751..00000000 --- a/src/Evergreen/V87/Frontend/Route.elm +++ /dev/null @@ -1,31 +0,0 @@ -module Evergreen.V87.Frontend.Route exposing (..) - -import Evergreen.V87.Data.Barter -import Evergreen.V87.Data.Fight -import Evergreen.V87.Data.Message - - -type TownRoute - = MainSquare - | Store - { barter : Evergreen.V87.Data.Barter.State - } - - -type AdminRoute - = LoggedIn - - -type Route - = Character - | Inventory - | Map - | Ladder - | Town TownRoute - | About - | News - | Fight Evergreen.V87.Data.Fight.Info - | Messages - | Message Evergreen.V87.Data.Message.Message - | CharCreation - | Admin AdminRoute diff --git a/src/Evergreen/V87/Logic.elm b/src/Evergreen/V87/Logic.elm deleted file mode 100644 index b53ce033..00000000 --- a/src/Evergreen/V87/Logic.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V87.Logic exposing (..) - - -type alias AttackStats = - { minDamage : Int - , maxDamage : Int - , criticalChanceBonus : Int - } diff --git a/src/Evergreen/V87/Types.elm b/src/Evergreen/V87/Types.elm deleted file mode 100644 index 29b17310..00000000 --- a/src/Evergreen/V87/Types.elm +++ /dev/null @@ -1,163 +0,0 @@ -module Evergreen.V87.Types exposing (..) - -import AssocList -import Browser -import Browser.Navigation -import Dict -import Evergreen.V87.Data.Auth -import Evergreen.V87.Data.Barter -import Evergreen.V87.Data.Fight -import Evergreen.V87.Data.Fight.Generator -import Evergreen.V87.Data.Item -import Evergreen.V87.Data.Map -import Evergreen.V87.Data.Message -import Evergreen.V87.Data.NewChar -import Evergreen.V87.Data.Perk -import Evergreen.V87.Data.Player -import Evergreen.V87.Data.Player.PlayerName -import Evergreen.V87.Data.Skill -import Evergreen.V87.Data.Special -import Evergreen.V87.Data.Trait -import Evergreen.V87.Data.Vendor -import Evergreen.V87.Data.World -import Evergreen.V87.Frontend.Route -import File exposing (File) -import Lamdera -import Set -import Time -import Url - - -type alias FrontendModel = - { key : Browser.Navigation.Key - , time : Time.Posix - , zone : Time.Zone - , route : Evergreen.V87.Frontend.Route.Route - , world : Evergreen.V87.Data.World.World - , newChar : Evergreen.V87.Data.NewChar.NewChar - , alertMessage : Maybe String - , mapMouseCoords : Maybe ( Evergreen.V87.Data.Map.TileCoords, Set.Set Evergreen.V87.Data.Map.TileCoords ) - , hoveredPerk : Maybe Evergreen.V87.Data.Perk.Perk - } - - -type alias BackendModel = - { players : Dict.Dict Evergreen.V87.Data.Player.PlayerName.PlayerName (Evergreen.V87.Data.Player.Player Evergreen.V87.Data.Player.SPlayer) - , loggedInPlayers : Dict.Dict Lamdera.ClientId Evergreen.V87.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - , adminLoggedIn : Maybe ( Lamdera.ClientId, Lamdera.SessionId ) - , time : Time.Posix - , vendors : AssocList.Dict Evergreen.V87.Data.Vendor.Name Evergreen.V87.Data.Vendor.Vendor - , lastItemId : Int - } - - -type BarterMsg - = AddPlayerItem Evergreen.V87.Data.Item.Id Int - | AddVendorItem Evergreen.V87.Data.Item.Id Int - | AddPlayerCaps Int - | AddVendorCaps Int - | RemovePlayerItem Evergreen.V87.Data.Item.Id Int - | RemoveVendorItem Evergreen.V87.Data.Item.Id Int - | RemovePlayerCaps Int - | RemoveVendorCaps Int - | ResetBarter - | ConfirmBarter - | SetTransferNInput Evergreen.V87.Data.Barter.TransferNPosition String - | SetTransferNHover Evergreen.V87.Data.Barter.TransferNPosition - | UnsetTransferNHover - - -type FrontendMsg - = UrlClicked Browser.UrlRequest - | UrlChanged Url.Url - | GoToRoute Evergreen.V87.Frontend.Route.Route - | Logout - | Login - | Register - | GotZone Time.Zone - | GotTime Time.Posix - | AskToFight Evergreen.V87.Data.Player.PlayerName.PlayerName - | AskToHeal - | AskToUseItem Evergreen.V87.Data.Item.Id - | AskToWander - | AskToChoosePerk Evergreen.V87.Data.Perk.Perk - | AskToEquipItem Evergreen.V87.Data.Item.Id - | AskToUnequipArmor - | AskForExport - | ImportButtonClicked - | ImportFileSelected File - | AskToImport String - | Refresh - | AskToTagSkill Evergreen.V87.Data.Skill.Skill - | AskToUseSkillPoints Evergreen.V87.Data.Skill.Skill - | SetAuthName String - | SetAuthPassword String - | CreateChar - | NewCharIncSpecial Evergreen.V87.Data.Special.Type - | NewCharDecSpecial Evergreen.V87.Data.Special.Type - | NewCharToggleTaggedSkill Evergreen.V87.Data.Skill.Skill - | NewCharToggleTrait Evergreen.V87.Data.Trait.Trait - | MapMouseAtCoords Evergreen.V87.Data.Map.TileCoords - | MapMouseOut - | MapMouseClick - | OpenMessage Evergreen.V87.Data.Message.Message - | AskToRemoveMessage Evergreen.V87.Data.Message.Message - | BarterMsg BarterMsg - | HoverPerk Evergreen.V87.Data.Perk.Perk - | StopHoveringPerk - - -type AdminToBackend - = ExportJson - | ImportJson String - - -type ToBackend - = LogMeIn (Evergreen.V87.Data.Auth.Auth Evergreen.V87.Data.Auth.Hashed) - | RegisterMe (Evergreen.V87.Data.Auth.Auth Evergreen.V87.Data.Auth.Hashed) - | CreateNewChar Evergreen.V87.Data.NewChar.NewChar - | LogMeOut - | Fight Evergreen.V87.Data.Player.PlayerName.PlayerName - | HealMe - | UseItem Evergreen.V87.Data.Item.Id - | Wander - | EquipItem Evergreen.V87.Data.Item.Id - | UnequipArmor - | RefreshPlease - | TagSkill Evergreen.V87.Data.Skill.Skill - | UseSkillPoints Evergreen.V87.Data.Skill.Skill - | ChoosePerk Evergreen.V87.Data.Perk.Perk - | MoveTo Evergreen.V87.Data.Map.TileCoords (Set.Set Evergreen.V87.Data.Map.TileCoords) - | MessageWasRead Evergreen.V87.Data.Message.Message - | RemoveMessage Evergreen.V87.Data.Message.Message - | Barter Evergreen.V87.Data.Barter.State - | AdminToBackend AdminToBackend - - -type BackendMsg - = Connected Lamdera.SessionId Lamdera.ClientId - | Disconnected Lamdera.SessionId Lamdera.ClientId - | GeneratedFight Lamdera.ClientId Evergreen.V87.Data.Player.SPlayer Evergreen.V87.Data.Fight.Generator.Fight - | GeneratedNewVendorsStock ( AssocList.Dict Evergreen.V87.Data.Vendor.Name Evergreen.V87.Data.Vendor.Vendor, Int ) - | Tick Time.Posix - | CreateNewCharWithTime Lamdera.ClientId Evergreen.V87.Data.NewChar.NewChar Time.Posix - | LoggedToBackendMsg - - -type ToFrontend - = YourCurrentWorld Evergreen.V87.Data.World.WorldLoggedInData - | InitWorld Evergreen.V87.Data.World.WorldLoggedOutData - | RefreshedLoggedOut Evergreen.V87.Data.World.WorldLoggedOutData - | CurrentAdminData Evergreen.V87.Data.World.AdminData - | YourFightResult ( Evergreen.V87.Data.Fight.Info, Evergreen.V87.Data.World.WorldLoggedInData ) - | YoureLoggedIn Evergreen.V87.Data.World.WorldLoggedInData - | YoureRegistered Evergreen.V87.Data.World.WorldLoggedInData - | CharCreationError Evergreen.V87.Data.NewChar.CreationError - | YouHaveCreatedChar Evergreen.V87.Data.World.WorldLoggedInData - | YoureLoggedOut Evergreen.V87.Data.World.WorldLoggedOutData - | AlertMessage String - | YoureLoggedInAsAdmin Evergreen.V87.Data.World.AdminData - | JsonExportDone String - | BarterDone ( Evergreen.V87.Data.World.WorldLoggedInData, Maybe Evergreen.V87.Data.Barter.Message ) - | BarterMessage Evergreen.V87.Data.Barter.Message diff --git a/src/Evergreen/V88/Data/Auth.elm b/src/Evergreen/V88/Data/Auth.elm deleted file mode 100644 index a67bc62e..00000000 --- a/src/Evergreen/V88/Data/Auth.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V88.Data.Auth exposing (..) - - -type Plaintext - = Plaintext - - -type Password a - = Password String - - -type alias Auth a = - { name : String - , password : Password a - } - - -type Verified - = Verified - - -type Hashed - = Hashed diff --git a/src/Evergreen/V88/Data/Barter.elm b/src/Evergreen/V88/Data/Barter.elm deleted file mode 100644 index 40f02082..00000000 --- a/src/Evergreen/V88/Data/Barter.elm +++ /dev/null @@ -1,33 +0,0 @@ -module Evergreen.V88.Data.Barter exposing (..) - -import AssocList -import Dict -import Evergreen.V88.Data.Item - - -type Message - = BarterIsEmpty - | PlayerOfferNotValuableEnough - | YouGaveStuffForFree - - -type TransferNPosition - = PlayerKeptItem Evergreen.V88.Data.Item.Id - | VendorKeptItem Evergreen.V88.Data.Item.Id - | PlayerTradedItem Evergreen.V88.Data.Item.Id - | VendorTradedItem Evergreen.V88.Data.Item.Id - | PlayerKeptCaps - | VendorKeptCaps - | PlayerTradedCaps - | VendorTradedCaps - - -type alias State = - { playerItems : Dict.Dict Evergreen.V88.Data.Item.Id Int - , vendorItems : Dict.Dict Evergreen.V88.Data.Item.Id Int - , playerCaps : Int - , vendorCaps : Int - , lastMessage : Maybe Message - , transferNInputs : AssocList.Dict TransferNPosition String - , transferNHover : Maybe TransferNPosition - } diff --git a/src/Evergreen/V88/Data/Enemy.elm b/src/Evergreen/V88/Data/Enemy.elm deleted file mode 100644 index b0109fc4..00000000 --- a/src/Evergreen/V88/Data/Enemy.elm +++ /dev/null @@ -1,14 +0,0 @@ -module Evergreen.V88.Data.Enemy exposing (..) - - -type Type - = Brahmin - | AngryBrahmin - | WeakBrahmin - | WildBrahmin - | GiantAnt - | ToughGiantAnt - | BlackRadscorpion - | LesserBlackRadscorpion - | LesserRadscorpion - | Radscorpion diff --git a/src/Evergreen/V88/Data/Fight.elm b/src/Evergreen/V88/Data/Fight.elm deleted file mode 100644 index 4e4c9f18..00000000 --- a/src/Evergreen/V88/Data/Fight.elm +++ /dev/null @@ -1,84 +0,0 @@ -module Evergreen.V88.Data.Fight exposing (..) - -import AssocList -import AssocSet -import Evergreen.V88.Data.Enemy -import Evergreen.V88.Data.Fight.ShotType -import Evergreen.V88.Data.Item -import Evergreen.V88.Data.Perk -import Evergreen.V88.Data.Player.PlayerName -import Evergreen.V88.Data.Skill -import Evergreen.V88.Data.Special -import Evergreen.V88.Data.Trait -import Evergreen.V88.Logic - - -type OpponentType - = Npc Evergreen.V88.Data.Enemy.Type - | Player Evergreen.V88.Data.Player.PlayerName.PlayerName - - -type Who - = Attacker - | Target - - -type Action - = Start - { distanceHexes : Int - } - | ComeCloser - { hexes : Int - , remainingDistanceHexes : Int - } - | Attack - { damage : Int - , shotType : Evergreen.V88.Data.Fight.ShotType.ShotType - , remainingHp : Int - , isCritical : Bool - } - | Miss - { shotType : Evergreen.V88.Data.Fight.ShotType.ShotType - } - - -type Result - = AttackerWon - { xpGained : Int - , capsGained : Int - , itemsGained : List Evergreen.V88.Data.Item.Item - } - | TargetWon - { xpGained : Int - , capsGained : Int - , itemsGained : List Evergreen.V88.Data.Item.Item - } - | TargetAlreadyDead - | BothDead - | NobodyDead - - -type alias Info = - { attacker : OpponentType - , target : OpponentType - , log : List ( Who, Action ) - , result : Result - } - - -type alias Opponent = - { type_ : OpponentType - , hp : Int - , maxHp : Int - , maxAp : Int - , sequence : Int - , traits : AssocSet.Set Evergreen.V88.Data.Trait.Trait - , perks : AssocList.Dict Evergreen.V88.Data.Perk.Perk Int - , caps : Int - , drops : List Evergreen.V88.Data.Item.Item - , equippedArmor : Maybe Evergreen.V88.Data.Item.Kind - , naturalArmorClass : Int - , attackStats : Evergreen.V88.Logic.AttackStats - , addedSkillPercentages : AssocList.Dict Evergreen.V88.Data.Skill.Skill Int - , special : Evergreen.V88.Data.Special.Special - } diff --git a/src/Evergreen/V88/Data/Fight/Generator.elm b/src/Evergreen/V88/Data/Fight/Generator.elm deleted file mode 100644 index fc336a97..00000000 --- a/src/Evergreen/V88/Data/Fight/Generator.elm +++ /dev/null @@ -1,12 +0,0 @@ -module Evergreen.V88.Data.Fight.Generator exposing (..) - -import Evergreen.V88.Data.Fight -import Evergreen.V88.Data.Message - - -type alias Fight = - { finalAttacker : Evergreen.V88.Data.Fight.Opponent - , finalTarget : Evergreen.V88.Data.Fight.Opponent - , fightInfo : Evergreen.V88.Data.Fight.Info - , messageForTarget : Evergreen.V88.Data.Message.Message - } diff --git a/src/Evergreen/V88/Data/Fight/ShotType.elm b/src/Evergreen/V88/Data/Fight/ShotType.elm deleted file mode 100644 index 76b79dc8e..00000000 --- a/src/Evergreen/V88/Data/Fight/ShotType.elm +++ /dev/null @@ -1,17 +0,0 @@ -module Evergreen.V88.Data.Fight.ShotType exposing (..) - - -type AimedShot - = Head - | Torso - | Eyes - | Groin - | LeftArm - | RightArm - | LeftLeg - | RightLeg - - -type ShotType - = NormalShot - | AimedShot AimedShot diff --git a/src/Evergreen/V88/Data/HealthStatus.elm b/src/Evergreen/V88/Data/HealthStatus.elm deleted file mode 100644 index af600994..00000000 --- a/src/Evergreen/V88/Data/HealthStatus.elm +++ /dev/null @@ -1,16 +0,0 @@ -module Evergreen.V88.Data.HealthStatus exposing (..) - - -type HealthStatus - = ExactHp - { current : Int - , max : Int - } - | Unhurt - | SlightlyWounded - | Wounded - | SeverelyWounded - | AlmostDead - | Dead - | Alive - | Unknown diff --git a/src/Evergreen/V88/Data/Item.elm b/src/Evergreen/V88/Data/Item.elm deleted file mode 100644 index 30258c24..00000000 --- a/src/Evergreen/V88/Data/Item.elm +++ /dev/null @@ -1,27 +0,0 @@ -module Evergreen.V88.Data.Item exposing (..) - - -type alias Id = - Int - - -type Kind - = Fruit - | HealingPowder - | Stimpak - | BigBookOfScience - | DeansElectronics - | FirstAidBook - | GunsAndBullets - | ScoutHandbook - | Robes - | LeatherJacket - | LeatherArmor - | MetalArmor - - -type alias Item = - { id : Id - , kind : Kind - , count : Int - } diff --git a/src/Evergreen/V88/Data/Map.elm b/src/Evergreen/V88/Data/Map.elm deleted file mode 100644 index 1324a31c..00000000 --- a/src/Evergreen/V88/Data/Map.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V88.Data.Map exposing (..) - - -type alias TileNum = - Int - - -type alias TileCoords = - ( Int, Int ) diff --git a/src/Evergreen/V88/Data/Message.elm b/src/Evergreen/V88/Data/Message.elm deleted file mode 100644 index a01e4634..00000000 --- a/src/Evergreen/V88/Data/Message.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V88.Data.Message exposing (..) - -import Evergreen.V88.Data.Fight -import Evergreen.V88.Data.Player.PlayerName -import Time - - -type Type - = Welcome - | YouAdvancedLevel - { newLevel : Int - } - | YouWereAttacked - { attacker : Evergreen.V88.Data.Player.PlayerName.PlayerName - , fightInfo : Evergreen.V88.Data.Fight.Info - } - - -type alias Message = - { type_ : Type - , hasBeenRead : Bool - , date : Time.Posix - } diff --git a/src/Evergreen/V88/Data/NewChar.elm b/src/Evergreen/V88/Data/NewChar.elm deleted file mode 100644 index b0f46b29..00000000 --- a/src/Evergreen/V88/Data/NewChar.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V88.Data.NewChar exposing (..) - -import AssocSet -import Evergreen.V88.Data.Skill -import Evergreen.V88.Data.Special -import Evergreen.V88.Data.Trait - - -type CreationError - = DoesNotHaveThreeTaggedSkills - | HasSpecialPointsLeft - | UsedMoreSpecialPointsThanAvailable - | HasSpecialOutOfRange - | HasMoreThanTwoTraits - - -type alias NewChar = - { baseSpecial : Evergreen.V88.Data.Special.Special - , availableSpecial : Int - , taggedSkills : AssocSet.Set Evergreen.V88.Data.Skill.Skill - , traits : AssocSet.Set Evergreen.V88.Data.Trait.Trait - , error : Maybe CreationError - } diff --git a/src/Evergreen/V88/Data/Perk.elm b/src/Evergreen/V88/Data/Perk.elm deleted file mode 100644 index 7b129b49..00000000 --- a/src/Evergreen/V88/Data/Perk.elm +++ /dev/null @@ -1,45 +0,0 @@ -module Evergreen.V88.Data.Perk exposing (..) - - -type Perk - = BonusHthDamage - | Awareness - | CautiousNature - | Comprehension - | EarlierSequence - | FasterHealing - | HereAndNow - | Survivalist - | SwiftLearner - | Thief - | Toughness - | AdrenalineRush - | Educated - | FortuneFinder - | Gambler - | MoreCriticals - | Negotiator - | Pathfinder - | Ranger - | Salesman - | BetterCriticals - | Dodger - | Speaker - | ActionBoy - | GainStrength - | GainPerception - | GainEndurance - | GainCharisma - | GainIntelligence - | GainAgility - | GainLuck - | HthEvade - | Lifegiver - | LivingAnatomy - | MasterThief - | MasterTrader - | Medic - | MrFixit - | Tag - | BonusHthAttacks - | Slayer diff --git a/src/Evergreen/V88/Data/Player.elm b/src/Evergreen/V88/Data/Player.elm deleted file mode 100644 index 5065ffd4..00000000 --- a/src/Evergreen/V88/Data/Player.elm +++ /dev/null @@ -1,77 +0,0 @@ -module Evergreen.V88.Data.Player exposing (..) - -import AssocList -import AssocSet -import Dict -import Evergreen.V88.Data.Auth -import Evergreen.V88.Data.HealthStatus -import Evergreen.V88.Data.Item -import Evergreen.V88.Data.Map -import Evergreen.V88.Data.Message -import Evergreen.V88.Data.Perk -import Evergreen.V88.Data.Player.PlayerName -import Evergreen.V88.Data.Skill -import Evergreen.V88.Data.Special -import Evergreen.V88.Data.Trait -import Evergreen.V88.Data.Xp - - -type alias COtherPlayer = - { level : Evergreen.V88.Data.Xp.Level - , name : Evergreen.V88.Data.Player.PlayerName.PlayerName - , wins : Int - , losses : Int - , healthStatus : Evergreen.V88.Data.HealthStatus.HealthStatus - } - - -type alias CPlayer = - { hp : Int - , maxHp : Int - , xp : Evergreen.V88.Data.Xp.Xp - , name : Evergreen.V88.Data.Player.PlayerName.PlayerName - , special : Evergreen.V88.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V88.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V88.Data.Perk.Perk Int - , messages : List Evergreen.V88.Data.Message.Message - , items : Dict.Dict Evergreen.V88.Data.Item.Id Evergreen.V88.Data.Item.Item - , traits : AssocSet.Set Evergreen.V88.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V88.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V88.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - , equippedArmor : Maybe Evergreen.V88.Data.Item.Item - } - - -type Player a - = NeedsCharCreated (Evergreen.V88.Data.Auth.Auth Evergreen.V88.Data.Auth.Verified) - | Player a - - -type alias SPlayer = - { name : Evergreen.V88.Data.Player.PlayerName.PlayerName - , password : Evergreen.V88.Data.Auth.Password Evergreen.V88.Data.Auth.Verified - , hp : Int - , maxHp : Int - , xp : Int - , special : Evergreen.V88.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V88.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V88.Data.Perk.Perk Int - , messages : List Evergreen.V88.Data.Message.Message - , items : Dict.Dict Evergreen.V88.Data.Item.Id Evergreen.V88.Data.Item.Item - , traits : AssocSet.Set Evergreen.V88.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V88.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V88.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - , equippedArmor : Maybe Evergreen.V88.Data.Item.Item - } diff --git a/src/Evergreen/V88/Data/Player/PlayerName.elm b/src/Evergreen/V88/Data/Player/PlayerName.elm deleted file mode 100644 index f1886f28..00000000 --- a/src/Evergreen/V88/Data/Player/PlayerName.elm +++ /dev/null @@ -1,5 +0,0 @@ -module Evergreen.V88.Data.Player.PlayerName exposing (..) - - -type alias PlayerName = - String diff --git a/src/Evergreen/V88/Data/Skill.elm b/src/Evergreen/V88/Data/Skill.elm deleted file mode 100644 index 3c3d82d9..00000000 --- a/src/Evergreen/V88/Data/Skill.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V88.Data.Skill exposing (..) - - -type Skill - = SmallGuns - | BigGuns - | EnergyWeapons - | Unarmed - | MeleeWeapons - | Throwing - | FirstAid - | Doctor - | Sneak - | Lockpick - | Steal - | Traps - | Science - | Repair - | Speech - | Barter - | Gambling - | Outdoorsman diff --git a/src/Evergreen/V88/Data/Special.elm b/src/Evergreen/V88/Data/Special.elm deleted file mode 100644 index 144abc91..00000000 --- a/src/Evergreen/V88/Data/Special.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V88.Data.Special exposing (..) - - -type alias Special = - { strength : Int - , perception : Int - , endurance : Int - , charisma : Int - , intelligence : Int - , agility : Int - , luck : Int - } - - -type Type - = Strength - | Perception - | Endurance - | Charisma - | Intelligence - | Agility - | Luck diff --git a/src/Evergreen/V88/Data/Trait.elm b/src/Evergreen/V88/Data/Trait.elm deleted file mode 100644 index ae7aad9e..00000000 --- a/src/Evergreen/V88/Data/Trait.elm +++ /dev/null @@ -1,11 +0,0 @@ -module Evergreen.V88.Data.Trait exposing (..) - - -type Trait - = Kamikaze - | Bruiser - | Gifted - | SmallFrame - | Skilled - | HeavyHanded - | Finesse diff --git a/src/Evergreen/V88/Data/Vendor.elm b/src/Evergreen/V88/Data/Vendor.elm deleted file mode 100644 index e5b1ed5b..00000000 --- a/src/Evergreen/V88/Data/Vendor.elm +++ /dev/null @@ -1,20 +0,0 @@ -module Evergreen.V88.Data.Vendor exposing (..) - -import Dict -import Evergreen.V88.Data.Item - - -type Name - = ArroyoHakunin - | KlamathMaidaBuckner - | DenFlick - | ModocJo - | VaultCityHappyHarry - - -type alias Vendor = - { name : Name - , items : Dict.Dict Evergreen.V88.Data.Item.Id Evergreen.V88.Data.Item.Item - , caps : Int - , barterSkill : Int - } diff --git a/src/Evergreen/V88/Data/World.elm b/src/Evergreen/V88/Data/World.elm deleted file mode 100644 index 8c6cb942..00000000 --- a/src/Evergreen/V88/Data/World.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.V88.Data.World exposing (..) - -import AssocList -import Evergreen.V88.Data.Auth -import Evergreen.V88.Data.Player -import Evergreen.V88.Data.Player.PlayerName -import Evergreen.V88.Data.Vendor -import Time - - -type alias WorldLoggedOutData = - { players : List Evergreen.V88.Data.Player.COtherPlayer - } - - -type alias WorldLoggedInData = - { player : Evergreen.V88.Data.Player.Player Evergreen.V88.Data.Player.CPlayer - , otherPlayers : List Evergreen.V88.Data.Player.COtherPlayer - , playerRank : Int - , vendors : AssocList.Dict Evergreen.V88.Data.Vendor.Name Evergreen.V88.Data.Vendor.Vendor - } - - -type alias AdminData = - { players : List (Evergreen.V88.Data.Player.Player Evergreen.V88.Data.Player.SPlayer) - , loggedInPlayers : List Evergreen.V88.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - } - - -type World - = WorldNotInitialized (Evergreen.V88.Data.Auth.Auth Evergreen.V88.Data.Auth.Plaintext) - | WorldLoggedOut (Evergreen.V88.Data.Auth.Auth Evergreen.V88.Data.Auth.Plaintext) WorldLoggedOutData - | WorldLoggedIn WorldLoggedInData - | WorldAdmin AdminData diff --git a/src/Evergreen/V88/Data/Xp.elm b/src/Evergreen/V88/Data/Xp.elm deleted file mode 100644 index be826deb..00000000 --- a/src/Evergreen/V88/Data/Xp.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V88.Data.Xp exposing (..) - - -type alias Level = - Int - - -type alias Xp = - Int diff --git a/src/Evergreen/V88/Frontend/Route.elm b/src/Evergreen/V88/Frontend/Route.elm deleted file mode 100644 index cdf041cb..00000000 --- a/src/Evergreen/V88/Frontend/Route.elm +++ /dev/null @@ -1,31 +0,0 @@ -module Evergreen.V88.Frontend.Route exposing (..) - -import Evergreen.V88.Data.Barter -import Evergreen.V88.Data.Fight -import Evergreen.V88.Data.Message - - -type TownRoute - = MainSquare - | Store - { barter : Evergreen.V88.Data.Barter.State - } - - -type AdminRoute - = LoggedIn - - -type Route - = Character - | Inventory - | Map - | Ladder - | Town TownRoute - | About - | News - | Fight Evergreen.V88.Data.Fight.Info - | Messages - | Message Evergreen.V88.Data.Message.Message - | CharCreation - | Admin AdminRoute diff --git a/src/Evergreen/V88/Logic.elm b/src/Evergreen/V88/Logic.elm deleted file mode 100644 index d017a918..00000000 --- a/src/Evergreen/V88/Logic.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V88.Logic exposing (..) - - -type alias AttackStats = - { minDamage : Int - , maxDamage : Int - , criticalChanceBonus : Int - } diff --git a/src/Evergreen/V88/Types.elm b/src/Evergreen/V88/Types.elm deleted file mode 100644 index 4d06a426..00000000 --- a/src/Evergreen/V88/Types.elm +++ /dev/null @@ -1,163 +0,0 @@ -module Evergreen.V88.Types exposing (..) - -import AssocList -import Browser -import Browser.Navigation -import Dict -import Evergreen.V88.Data.Auth -import Evergreen.V88.Data.Barter -import Evergreen.V88.Data.Fight -import Evergreen.V88.Data.Fight.Generator -import Evergreen.V88.Data.Item -import Evergreen.V88.Data.Map -import Evergreen.V88.Data.Message -import Evergreen.V88.Data.NewChar -import Evergreen.V88.Data.Perk -import Evergreen.V88.Data.Player -import Evergreen.V88.Data.Player.PlayerName -import Evergreen.V88.Data.Skill -import Evergreen.V88.Data.Special -import Evergreen.V88.Data.Trait -import Evergreen.V88.Data.Vendor -import Evergreen.V88.Data.World -import Evergreen.V88.Frontend.Route -import File exposing (File) -import Lamdera -import Set -import Time -import Url - - -type alias FrontendModel = - { key : Browser.Navigation.Key - , time : Time.Posix - , zone : Time.Zone - , route : Evergreen.V88.Frontend.Route.Route - , world : Evergreen.V88.Data.World.World - , newChar : Evergreen.V88.Data.NewChar.NewChar - , alertMessage : Maybe String - , mapMouseCoords : Maybe ( Evergreen.V88.Data.Map.TileCoords, Set.Set Evergreen.V88.Data.Map.TileCoords ) - , hoveredPerk : Maybe Evergreen.V88.Data.Perk.Perk - } - - -type alias BackendModel = - { players : Dict.Dict Evergreen.V88.Data.Player.PlayerName.PlayerName (Evergreen.V88.Data.Player.Player Evergreen.V88.Data.Player.SPlayer) - , loggedInPlayers : Dict.Dict Lamdera.ClientId Evergreen.V88.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - , adminLoggedIn : Maybe ( Lamdera.ClientId, Lamdera.SessionId ) - , time : Time.Posix - , vendors : AssocList.Dict Evergreen.V88.Data.Vendor.Name Evergreen.V88.Data.Vendor.Vendor - , lastItemId : Int - } - - -type BarterMsg - = AddPlayerItem Evergreen.V88.Data.Item.Id Int - | AddVendorItem Evergreen.V88.Data.Item.Id Int - | AddPlayerCaps Int - | AddVendorCaps Int - | RemovePlayerItem Evergreen.V88.Data.Item.Id Int - | RemoveVendorItem Evergreen.V88.Data.Item.Id Int - | RemovePlayerCaps Int - | RemoveVendorCaps Int - | ResetBarter - | ConfirmBarter - | SetTransferNInput Evergreen.V88.Data.Barter.TransferNPosition String - | SetTransferNHover Evergreen.V88.Data.Barter.TransferNPosition - | UnsetTransferNHover - - -type FrontendMsg - = UrlClicked Browser.UrlRequest - | UrlChanged Url.Url - | GoToRoute Evergreen.V88.Frontend.Route.Route - | Logout - | Login - | Register - | GotZone Time.Zone - | GotTime Time.Posix - | AskToFight Evergreen.V88.Data.Player.PlayerName.PlayerName - | AskToHeal - | AskToUseItem Evergreen.V88.Data.Item.Id - | AskToWander - | AskToChoosePerk Evergreen.V88.Data.Perk.Perk - | AskToEquipItem Evergreen.V88.Data.Item.Id - | AskToUnequipArmor - | AskForExport - | ImportButtonClicked - | ImportFileSelected File - | AskToImport String - | Refresh - | AskToTagSkill Evergreen.V88.Data.Skill.Skill - | AskToUseSkillPoints Evergreen.V88.Data.Skill.Skill - | SetAuthName String - | SetAuthPassword String - | CreateChar - | NewCharIncSpecial Evergreen.V88.Data.Special.Type - | NewCharDecSpecial Evergreen.V88.Data.Special.Type - | NewCharToggleTaggedSkill Evergreen.V88.Data.Skill.Skill - | NewCharToggleTrait Evergreen.V88.Data.Trait.Trait - | MapMouseAtCoords Evergreen.V88.Data.Map.TileCoords - | MapMouseOut - | MapMouseClick - | OpenMessage Evergreen.V88.Data.Message.Message - | AskToRemoveMessage Evergreen.V88.Data.Message.Message - | BarterMsg BarterMsg - | HoverPerk Evergreen.V88.Data.Perk.Perk - | StopHoveringPerk - - -type AdminToBackend - = ExportJson - | ImportJson String - - -type ToBackend - = LogMeIn (Evergreen.V88.Data.Auth.Auth Evergreen.V88.Data.Auth.Hashed) - | RegisterMe (Evergreen.V88.Data.Auth.Auth Evergreen.V88.Data.Auth.Hashed) - | CreateNewChar Evergreen.V88.Data.NewChar.NewChar - | LogMeOut - | Fight Evergreen.V88.Data.Player.PlayerName.PlayerName - | HealMe - | UseItem Evergreen.V88.Data.Item.Id - | Wander - | EquipItem Evergreen.V88.Data.Item.Id - | UnequipArmor - | RefreshPlease - | TagSkill Evergreen.V88.Data.Skill.Skill - | UseSkillPoints Evergreen.V88.Data.Skill.Skill - | ChoosePerk Evergreen.V88.Data.Perk.Perk - | MoveTo Evergreen.V88.Data.Map.TileCoords (Set.Set Evergreen.V88.Data.Map.TileCoords) - | MessageWasRead Evergreen.V88.Data.Message.Message - | RemoveMessage Evergreen.V88.Data.Message.Message - | Barter Evergreen.V88.Data.Barter.State - | AdminToBackend AdminToBackend - - -type BackendMsg - = Connected Lamdera.SessionId Lamdera.ClientId - | Disconnected Lamdera.SessionId Lamdera.ClientId - | GeneratedFight Lamdera.ClientId Evergreen.V88.Data.Player.SPlayer ( Evergreen.V88.Data.Fight.Generator.Fight, Int ) - | GeneratedNewVendorsStock ( AssocList.Dict Evergreen.V88.Data.Vendor.Name Evergreen.V88.Data.Vendor.Vendor, Int ) - | Tick Time.Posix - | CreateNewCharWithTime Lamdera.ClientId Evergreen.V88.Data.NewChar.NewChar Time.Posix - | LoggedToBackendMsg - - -type ToFrontend - = YourCurrentWorld Evergreen.V88.Data.World.WorldLoggedInData - | InitWorld Evergreen.V88.Data.World.WorldLoggedOutData - | RefreshedLoggedOut Evergreen.V88.Data.World.WorldLoggedOutData - | CurrentAdminData Evergreen.V88.Data.World.AdminData - | YourFightResult ( Evergreen.V88.Data.Fight.Info, Evergreen.V88.Data.World.WorldLoggedInData ) - | YoureLoggedIn Evergreen.V88.Data.World.WorldLoggedInData - | YoureRegistered Evergreen.V88.Data.World.WorldLoggedInData - | CharCreationError Evergreen.V88.Data.NewChar.CreationError - | YouHaveCreatedChar Evergreen.V88.Data.World.WorldLoggedInData - | YoureLoggedOut Evergreen.V88.Data.World.WorldLoggedOutData - | AlertMessage String - | YoureLoggedInAsAdmin Evergreen.V88.Data.World.AdminData - | JsonExportDone String - | BarterDone ( Evergreen.V88.Data.World.WorldLoggedInData, Maybe Evergreen.V88.Data.Barter.Message ) - | BarterMessage Evergreen.V88.Data.Barter.Message diff --git a/src/Evergreen/V89/Data/Auth.elm b/src/Evergreen/V89/Data/Auth.elm deleted file mode 100644 index b236dd4a..00000000 --- a/src/Evergreen/V89/Data/Auth.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V89.Data.Auth exposing (..) - - -type Plaintext - = Plaintext - - -type Password a - = Password String - - -type alias Auth a = - { name : String - , password : Password a - } - - -type Verified - = Verified - - -type Hashed - = Hashed diff --git a/src/Evergreen/V89/Data/Barter.elm b/src/Evergreen/V89/Data/Barter.elm deleted file mode 100644 index eaf90db7..00000000 --- a/src/Evergreen/V89/Data/Barter.elm +++ /dev/null @@ -1,33 +0,0 @@ -module Evergreen.V89.Data.Barter exposing (..) - -import AssocList -import Dict -import Evergreen.V89.Data.Item - - -type Message - = BarterIsEmpty - | PlayerOfferNotValuableEnough - | YouGaveStuffForFree - - -type TransferNPosition - = PlayerKeptItem Evergreen.V89.Data.Item.Id - | VendorKeptItem Evergreen.V89.Data.Item.Id - | PlayerTradedItem Evergreen.V89.Data.Item.Id - | VendorTradedItem Evergreen.V89.Data.Item.Id - | PlayerKeptCaps - | VendorKeptCaps - | PlayerTradedCaps - | VendorTradedCaps - - -type alias State = - { playerItems : Dict.Dict Evergreen.V89.Data.Item.Id Int - , vendorItems : Dict.Dict Evergreen.V89.Data.Item.Id Int - , playerCaps : Int - , vendorCaps : Int - , lastMessage : Maybe Message - , transferNInputs : AssocList.Dict TransferNPosition String - , transferNHover : Maybe TransferNPosition - } diff --git a/src/Evergreen/V89/Data/Enemy.elm b/src/Evergreen/V89/Data/Enemy.elm deleted file mode 100644 index bbce463f..00000000 --- a/src/Evergreen/V89/Data/Enemy.elm +++ /dev/null @@ -1,14 +0,0 @@ -module Evergreen.V89.Data.Enemy exposing (..) - - -type Type - = Brahmin - | AngryBrahmin - | WeakBrahmin - | WildBrahmin - | GiantAnt - | ToughGiantAnt - | BlackRadscorpion - | LesserBlackRadscorpion - | LesserRadscorpion - | Radscorpion diff --git a/src/Evergreen/V89/Data/Fight.elm b/src/Evergreen/V89/Data/Fight.elm deleted file mode 100644 index 813f4834..00000000 --- a/src/Evergreen/V89/Data/Fight.elm +++ /dev/null @@ -1,84 +0,0 @@ -module Evergreen.V89.Data.Fight exposing (..) - -import AssocList -import AssocSet -import Evergreen.V89.Data.Enemy -import Evergreen.V89.Data.Fight.ShotType -import Evergreen.V89.Data.Item -import Evergreen.V89.Data.Perk -import Evergreen.V89.Data.Player.PlayerName -import Evergreen.V89.Data.Skill -import Evergreen.V89.Data.Special -import Evergreen.V89.Data.Trait -import Evergreen.V89.Logic - - -type OpponentType - = Npc Evergreen.V89.Data.Enemy.Type - | Player Evergreen.V89.Data.Player.PlayerName.PlayerName - - -type Who - = Attacker - | Target - - -type Action - = Start - { distanceHexes : Int - } - | ComeCloser - { hexes : Int - , remainingDistanceHexes : Int - } - | Attack - { damage : Int - , shotType : Evergreen.V89.Data.Fight.ShotType.ShotType - , remainingHp : Int - , isCritical : Bool - } - | Miss - { shotType : Evergreen.V89.Data.Fight.ShotType.ShotType - } - - -type Result - = AttackerWon - { xpGained : Int - , capsGained : Int - , itemsGained : List Evergreen.V89.Data.Item.Item - } - | TargetWon - { xpGained : Int - , capsGained : Int - , itemsGained : List Evergreen.V89.Data.Item.Item - } - | TargetAlreadyDead - | BothDead - | NobodyDead - - -type alias Info = - { attacker : OpponentType - , target : OpponentType - , log : List ( Who, Action ) - , result : Result - } - - -type alias Opponent = - { type_ : OpponentType - , hp : Int - , maxHp : Int - , maxAp : Int - , sequence : Int - , traits : AssocSet.Set Evergreen.V89.Data.Trait.Trait - , perks : AssocList.Dict Evergreen.V89.Data.Perk.Perk Int - , caps : Int - , drops : List Evergreen.V89.Data.Item.Item - , equippedArmor : Maybe Evergreen.V89.Data.Item.Kind - , naturalArmorClass : Int - , attackStats : Evergreen.V89.Logic.AttackStats - , addedSkillPercentages : AssocList.Dict Evergreen.V89.Data.Skill.Skill Int - , special : Evergreen.V89.Data.Special.Special - } diff --git a/src/Evergreen/V89/Data/Fight/Generator.elm b/src/Evergreen/V89/Data/Fight/Generator.elm deleted file mode 100644 index 331040b6..00000000 --- a/src/Evergreen/V89/Data/Fight/Generator.elm +++ /dev/null @@ -1,12 +0,0 @@ -module Evergreen.V89.Data.Fight.Generator exposing (..) - -import Evergreen.V89.Data.Fight -import Evergreen.V89.Data.Message - - -type alias Fight = - { finalAttacker : Evergreen.V89.Data.Fight.Opponent - , finalTarget : Evergreen.V89.Data.Fight.Opponent - , fightInfo : Evergreen.V89.Data.Fight.Info - , messageForTarget : Evergreen.V89.Data.Message.Message - } diff --git a/src/Evergreen/V89/Data/Fight/ShotType.elm b/src/Evergreen/V89/Data/Fight/ShotType.elm deleted file mode 100644 index d7605f8e..00000000 --- a/src/Evergreen/V89/Data/Fight/ShotType.elm +++ /dev/null @@ -1,17 +0,0 @@ -module Evergreen.V89.Data.Fight.ShotType exposing (..) - - -type AimedShot - = Head - | Torso - | Eyes - | Groin - | LeftArm - | RightArm - | LeftLeg - | RightLeg - - -type ShotType - = NormalShot - | AimedShot AimedShot diff --git a/src/Evergreen/V89/Data/HealthStatus.elm b/src/Evergreen/V89/Data/HealthStatus.elm deleted file mode 100644 index 24315a9f..00000000 --- a/src/Evergreen/V89/Data/HealthStatus.elm +++ /dev/null @@ -1,16 +0,0 @@ -module Evergreen.V89.Data.HealthStatus exposing (..) - - -type HealthStatus - = ExactHp - { current : Int - , max : Int - } - | Unhurt - | SlightlyWounded - | Wounded - | SeverelyWounded - | AlmostDead - | Dead - | Alive - | Unknown diff --git a/src/Evergreen/V89/Data/Item.elm b/src/Evergreen/V89/Data/Item.elm deleted file mode 100644 index a93d8e59..00000000 --- a/src/Evergreen/V89/Data/Item.elm +++ /dev/null @@ -1,27 +0,0 @@ -module Evergreen.V89.Data.Item exposing (..) - - -type alias Id = - Int - - -type Kind - = Fruit - | HealingPowder - | Stimpak - | BigBookOfScience - | DeansElectronics - | FirstAidBook - | GunsAndBullets - | ScoutHandbook - | Robes - | LeatherJacket - | LeatherArmor - | MetalArmor - - -type alias Item = - { id : Id - , kind : Kind - , count : Int - } diff --git a/src/Evergreen/V89/Data/Map.elm b/src/Evergreen/V89/Data/Map.elm deleted file mode 100644 index a609d516..00000000 --- a/src/Evergreen/V89/Data/Map.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V89.Data.Map exposing (..) - - -type alias TileNum = - Int - - -type alias TileCoords = - ( Int, Int ) diff --git a/src/Evergreen/V89/Data/Message.elm b/src/Evergreen/V89/Data/Message.elm deleted file mode 100644 index 542279eb..00000000 --- a/src/Evergreen/V89/Data/Message.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V89.Data.Message exposing (..) - -import Evergreen.V89.Data.Fight -import Evergreen.V89.Data.Player.PlayerName -import Time - - -type Type - = Welcome - | YouAdvancedLevel - { newLevel : Int - } - | YouWereAttacked - { attacker : Evergreen.V89.Data.Player.PlayerName.PlayerName - , fightInfo : Evergreen.V89.Data.Fight.Info - } - - -type alias Message = - { type_ : Type - , hasBeenRead : Bool - , date : Time.Posix - } diff --git a/src/Evergreen/V89/Data/NewChar.elm b/src/Evergreen/V89/Data/NewChar.elm deleted file mode 100644 index eee9669a..00000000 --- a/src/Evergreen/V89/Data/NewChar.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V89.Data.NewChar exposing (..) - -import AssocSet -import Evergreen.V89.Data.Skill -import Evergreen.V89.Data.Special -import Evergreen.V89.Data.Trait - - -type CreationError - = DoesNotHaveThreeTaggedSkills - | HasSpecialPointsLeft - | UsedMoreSpecialPointsThanAvailable - | HasSpecialOutOfRange - | HasMoreThanTwoTraits - - -type alias NewChar = - { baseSpecial : Evergreen.V89.Data.Special.Special - , availableSpecial : Int - , taggedSkills : AssocSet.Set Evergreen.V89.Data.Skill.Skill - , traits : AssocSet.Set Evergreen.V89.Data.Trait.Trait - , error : Maybe CreationError - } diff --git a/src/Evergreen/V89/Data/Perk.elm b/src/Evergreen/V89/Data/Perk.elm deleted file mode 100644 index 3b74b8b1..00000000 --- a/src/Evergreen/V89/Data/Perk.elm +++ /dev/null @@ -1,45 +0,0 @@ -module Evergreen.V89.Data.Perk exposing (..) - - -type Perk - = BonusHthDamage - | Awareness - | CautiousNature - | Comprehension - | EarlierSequence - | FasterHealing - | HereAndNow - | Survivalist - | SwiftLearner - | Thief - | Toughness - | AdrenalineRush - | Educated - | FortuneFinder - | Gambler - | MoreCriticals - | Negotiator - | Pathfinder - | Ranger - | Salesman - | BetterCriticals - | Dodger - | Speaker - | ActionBoy - | GainStrength - | GainPerception - | GainEndurance - | GainCharisma - | GainIntelligence - | GainAgility - | GainLuck - | HthEvade - | Lifegiver - | LivingAnatomy - | MasterThief - | MasterTrader - | Medic - | MrFixit - | Tag - | BonusHthAttacks - | Slayer diff --git a/src/Evergreen/V89/Data/Player.elm b/src/Evergreen/V89/Data/Player.elm deleted file mode 100644 index a5b3fcc2..00000000 --- a/src/Evergreen/V89/Data/Player.elm +++ /dev/null @@ -1,77 +0,0 @@ -module Evergreen.V89.Data.Player exposing (..) - -import AssocList -import AssocSet -import Dict -import Evergreen.V89.Data.Auth -import Evergreen.V89.Data.HealthStatus -import Evergreen.V89.Data.Item -import Evergreen.V89.Data.Map -import Evergreen.V89.Data.Message -import Evergreen.V89.Data.Perk -import Evergreen.V89.Data.Player.PlayerName -import Evergreen.V89.Data.Skill -import Evergreen.V89.Data.Special -import Evergreen.V89.Data.Trait -import Evergreen.V89.Data.Xp - - -type alias COtherPlayer = - { level : Evergreen.V89.Data.Xp.Level - , name : Evergreen.V89.Data.Player.PlayerName.PlayerName - , wins : Int - , losses : Int - , healthStatus : Evergreen.V89.Data.HealthStatus.HealthStatus - } - - -type alias CPlayer = - { hp : Int - , maxHp : Int - , xp : Evergreen.V89.Data.Xp.Xp - , name : Evergreen.V89.Data.Player.PlayerName.PlayerName - , special : Evergreen.V89.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V89.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V89.Data.Perk.Perk Int - , messages : List Evergreen.V89.Data.Message.Message - , items : Dict.Dict Evergreen.V89.Data.Item.Id Evergreen.V89.Data.Item.Item - , traits : AssocSet.Set Evergreen.V89.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V89.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V89.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - , equippedArmor : Maybe Evergreen.V89.Data.Item.Item - } - - -type Player a - = NeedsCharCreated (Evergreen.V89.Data.Auth.Auth Evergreen.V89.Data.Auth.Verified) - | Player a - - -type alias SPlayer = - { name : Evergreen.V89.Data.Player.PlayerName.PlayerName - , password : Evergreen.V89.Data.Auth.Password Evergreen.V89.Data.Auth.Verified - , hp : Int - , maxHp : Int - , xp : Int - , special : Evergreen.V89.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V89.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V89.Data.Perk.Perk Int - , messages : List Evergreen.V89.Data.Message.Message - , items : Dict.Dict Evergreen.V89.Data.Item.Id Evergreen.V89.Data.Item.Item - , traits : AssocSet.Set Evergreen.V89.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V89.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V89.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - , equippedArmor : Maybe Evergreen.V89.Data.Item.Item - } diff --git a/src/Evergreen/V89/Data/Player/PlayerName.elm b/src/Evergreen/V89/Data/Player/PlayerName.elm deleted file mode 100644 index 85265ab7..00000000 --- a/src/Evergreen/V89/Data/Player/PlayerName.elm +++ /dev/null @@ -1,5 +0,0 @@ -module Evergreen.V89.Data.Player.PlayerName exposing (..) - - -type alias PlayerName = - String diff --git a/src/Evergreen/V89/Data/Skill.elm b/src/Evergreen/V89/Data/Skill.elm deleted file mode 100644 index 1cd43fc9..00000000 --- a/src/Evergreen/V89/Data/Skill.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V89.Data.Skill exposing (..) - - -type Skill - = SmallGuns - | BigGuns - | EnergyWeapons - | Unarmed - | MeleeWeapons - | Throwing - | FirstAid - | Doctor - | Sneak - | Lockpick - | Steal - | Traps - | Science - | Repair - | Speech - | Barter - | Gambling - | Outdoorsman diff --git a/src/Evergreen/V89/Data/Special.elm b/src/Evergreen/V89/Data/Special.elm deleted file mode 100644 index 71882ea1..00000000 --- a/src/Evergreen/V89/Data/Special.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V89.Data.Special exposing (..) - - -type alias Special = - { strength : Int - , perception : Int - , endurance : Int - , charisma : Int - , intelligence : Int - , agility : Int - , luck : Int - } - - -type Type - = Strength - | Perception - | Endurance - | Charisma - | Intelligence - | Agility - | Luck diff --git a/src/Evergreen/V89/Data/Trait.elm b/src/Evergreen/V89/Data/Trait.elm deleted file mode 100644 index 11816d0f..00000000 --- a/src/Evergreen/V89/Data/Trait.elm +++ /dev/null @@ -1,11 +0,0 @@ -module Evergreen.V89.Data.Trait exposing (..) - - -type Trait - = Kamikaze - | Bruiser - | Gifted - | SmallFrame - | Skilled - | HeavyHanded - | Finesse diff --git a/src/Evergreen/V89/Data/Vendor.elm b/src/Evergreen/V89/Data/Vendor.elm deleted file mode 100644 index 596bda9b..00000000 --- a/src/Evergreen/V89/Data/Vendor.elm +++ /dev/null @@ -1,20 +0,0 @@ -module Evergreen.V89.Data.Vendor exposing (..) - -import Dict -import Evergreen.V89.Data.Item - - -type Name - = ArroyoHakunin - | KlamathMaidaBuckner - | DenFlick - | ModocJo - | VaultCityHappyHarry - - -type alias Vendor = - { name : Name - , items : Dict.Dict Evergreen.V89.Data.Item.Id Evergreen.V89.Data.Item.Item - , caps : Int - , barterSkill : Int - } diff --git a/src/Evergreen/V89/Data/World.elm b/src/Evergreen/V89/Data/World.elm deleted file mode 100644 index 4e0602c2..00000000 --- a/src/Evergreen/V89/Data/World.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.V89.Data.World exposing (..) - -import AssocList -import Evergreen.V89.Data.Auth -import Evergreen.V89.Data.Player -import Evergreen.V89.Data.Player.PlayerName -import Evergreen.V89.Data.Vendor -import Time - - -type alias WorldLoggedOutData = - { players : List Evergreen.V89.Data.Player.COtherPlayer - } - - -type alias WorldLoggedInData = - { player : Evergreen.V89.Data.Player.Player Evergreen.V89.Data.Player.CPlayer - , otherPlayers : List Evergreen.V89.Data.Player.COtherPlayer - , playerRank : Int - , vendors : AssocList.Dict Evergreen.V89.Data.Vendor.Name Evergreen.V89.Data.Vendor.Vendor - } - - -type alias AdminData = - { players : List (Evergreen.V89.Data.Player.Player Evergreen.V89.Data.Player.SPlayer) - , loggedInPlayers : List Evergreen.V89.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - } - - -type World - = WorldNotInitialized (Evergreen.V89.Data.Auth.Auth Evergreen.V89.Data.Auth.Plaintext) - | WorldLoggedOut (Evergreen.V89.Data.Auth.Auth Evergreen.V89.Data.Auth.Plaintext) WorldLoggedOutData - | WorldLoggedIn WorldLoggedInData - | WorldAdmin AdminData diff --git a/src/Evergreen/V89/Data/Xp.elm b/src/Evergreen/V89/Data/Xp.elm deleted file mode 100644 index 9051bc44..00000000 --- a/src/Evergreen/V89/Data/Xp.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V89.Data.Xp exposing (..) - - -type alias Level = - Int - - -type alias Xp = - Int diff --git a/src/Evergreen/V89/Frontend/HoveredItem.elm b/src/Evergreen/V89/Frontend/HoveredItem.elm deleted file mode 100644 index a30da247..00000000 --- a/src/Evergreen/V89/Frontend/HoveredItem.elm +++ /dev/null @@ -1,13 +0,0 @@ -module Evergreen.V89.Frontend.HoveredItem exposing (..) - -import Evergreen.V89.Data.Perk -import Evergreen.V89.Data.Skill -import Evergreen.V89.Data.Special -import Evergreen.V89.Data.Trait - - -type HoveredItem - = HoveredPerk Evergreen.V89.Data.Perk.Perk - | HoveredTrait Evergreen.V89.Data.Trait.Trait - | HoveredSpecial Evergreen.V89.Data.Special.Type - | HoveredSkill Evergreen.V89.Data.Skill.Skill diff --git a/src/Evergreen/V89/Frontend/Route.elm b/src/Evergreen/V89/Frontend/Route.elm deleted file mode 100644 index c0af1776..00000000 --- a/src/Evergreen/V89/Frontend/Route.elm +++ /dev/null @@ -1,31 +0,0 @@ -module Evergreen.V89.Frontend.Route exposing (..) - -import Evergreen.V89.Data.Barter -import Evergreen.V89.Data.Fight -import Evergreen.V89.Data.Message - - -type TownRoute - = MainSquare - | Store - { barter : Evergreen.V89.Data.Barter.State - } - - -type AdminRoute - = LoggedIn - - -type Route - = Character - | Inventory - | Map - | Ladder - | Town TownRoute - | About - | News - | Fight Evergreen.V89.Data.Fight.Info - | Messages - | Message Evergreen.V89.Data.Message.Message - | CharCreation - | Admin AdminRoute diff --git a/src/Evergreen/V89/Logic.elm b/src/Evergreen/V89/Logic.elm deleted file mode 100644 index 8aae8204..00000000 --- a/src/Evergreen/V89/Logic.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V89.Logic exposing (..) - - -type alias AttackStats = - { minDamage : Int - , maxDamage : Int - , criticalChanceBonus : Int - } diff --git a/src/Evergreen/V89/Types.elm b/src/Evergreen/V89/Types.elm deleted file mode 100644 index 9cd432e3..00000000 --- a/src/Evergreen/V89/Types.elm +++ /dev/null @@ -1,164 +0,0 @@ -module Evergreen.V89.Types exposing (..) - -import AssocList -import Browser -import Browser.Navigation -import Dict -import Evergreen.V89.Data.Auth -import Evergreen.V89.Data.Barter -import Evergreen.V89.Data.Fight -import Evergreen.V89.Data.Fight.Generator -import Evergreen.V89.Data.Item -import Evergreen.V89.Data.Map -import Evergreen.V89.Data.Message -import Evergreen.V89.Data.NewChar -import Evergreen.V89.Data.Perk -import Evergreen.V89.Data.Player -import Evergreen.V89.Data.Player.PlayerName -import Evergreen.V89.Data.Skill -import Evergreen.V89.Data.Special -import Evergreen.V89.Data.Trait -import Evergreen.V89.Data.Vendor -import Evergreen.V89.Data.World -import Evergreen.V89.Frontend.HoveredItem -import Evergreen.V89.Frontend.Route -import File exposing (File) -import Lamdera -import Set -import Time -import Url - - -type alias FrontendModel = - { key : Browser.Navigation.Key - , time : Time.Posix - , zone : Time.Zone - , route : Evergreen.V89.Frontend.Route.Route - , world : Evergreen.V89.Data.World.World - , newChar : Evergreen.V89.Data.NewChar.NewChar - , alertMessage : Maybe String - , mapMouseCoords : Maybe ( Evergreen.V89.Data.Map.TileCoords, Set.Set Evergreen.V89.Data.Map.TileCoords ) - , hoveredItem : Maybe Evergreen.V89.Frontend.HoveredItem.HoveredItem - } - - -type alias BackendModel = - { players : Dict.Dict Evergreen.V89.Data.Player.PlayerName.PlayerName (Evergreen.V89.Data.Player.Player Evergreen.V89.Data.Player.SPlayer) - , loggedInPlayers : Dict.Dict Lamdera.ClientId Evergreen.V89.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - , adminLoggedIn : Maybe ( Lamdera.ClientId, Lamdera.SessionId ) - , time : Time.Posix - , vendors : AssocList.Dict Evergreen.V89.Data.Vendor.Name Evergreen.V89.Data.Vendor.Vendor - , lastItemId : Int - } - - -type BarterMsg - = AddPlayerItem Evergreen.V89.Data.Item.Id Int - | AddVendorItem Evergreen.V89.Data.Item.Id Int - | AddPlayerCaps Int - | AddVendorCaps Int - | RemovePlayerItem Evergreen.V89.Data.Item.Id Int - | RemoveVendorItem Evergreen.V89.Data.Item.Id Int - | RemovePlayerCaps Int - | RemoveVendorCaps Int - | ResetBarter - | ConfirmBarter - | SetTransferNInput Evergreen.V89.Data.Barter.TransferNPosition String - | SetTransferNHover Evergreen.V89.Data.Barter.TransferNPosition - | UnsetTransferNHover - - -type FrontendMsg - = UrlClicked Browser.UrlRequest - | UrlChanged Url.Url - | GoToRoute Evergreen.V89.Frontend.Route.Route - | Logout - | Login - | Register - | GotZone Time.Zone - | GotTime Time.Posix - | AskToFight Evergreen.V89.Data.Player.PlayerName.PlayerName - | AskToHeal - | AskToUseItem Evergreen.V89.Data.Item.Id - | AskToWander - | AskToChoosePerk Evergreen.V89.Data.Perk.Perk - | AskToEquipItem Evergreen.V89.Data.Item.Id - | AskToUnequipArmor - | AskForExport - | ImportButtonClicked - | ImportFileSelected File - | AskToImport String - | Refresh - | AskToTagSkill Evergreen.V89.Data.Skill.Skill - | AskToUseSkillPoints Evergreen.V89.Data.Skill.Skill - | SetAuthName String - | SetAuthPassword String - | CreateChar - | NewCharIncSpecial Evergreen.V89.Data.Special.Type - | NewCharDecSpecial Evergreen.V89.Data.Special.Type - | NewCharToggleTaggedSkill Evergreen.V89.Data.Skill.Skill - | NewCharToggleTrait Evergreen.V89.Data.Trait.Trait - | MapMouseAtCoords Evergreen.V89.Data.Map.TileCoords - | MapMouseOut - | MapMouseClick - | OpenMessage Evergreen.V89.Data.Message.Message - | AskToRemoveMessage Evergreen.V89.Data.Message.Message - | BarterMsg BarterMsg - | HoverItem Evergreen.V89.Frontend.HoveredItem.HoveredItem - | StopHoveringItem - - -type AdminToBackend - = ExportJson - | ImportJson String - - -type ToBackend - = LogMeIn (Evergreen.V89.Data.Auth.Auth Evergreen.V89.Data.Auth.Hashed) - | RegisterMe (Evergreen.V89.Data.Auth.Auth Evergreen.V89.Data.Auth.Hashed) - | CreateNewChar Evergreen.V89.Data.NewChar.NewChar - | LogMeOut - | Fight Evergreen.V89.Data.Player.PlayerName.PlayerName - | HealMe - | UseItem Evergreen.V89.Data.Item.Id - | Wander - | EquipItem Evergreen.V89.Data.Item.Id - | UnequipArmor - | RefreshPlease - | TagSkill Evergreen.V89.Data.Skill.Skill - | UseSkillPoints Evergreen.V89.Data.Skill.Skill - | ChoosePerk Evergreen.V89.Data.Perk.Perk - | MoveTo Evergreen.V89.Data.Map.TileCoords (Set.Set Evergreen.V89.Data.Map.TileCoords) - | MessageWasRead Evergreen.V89.Data.Message.Message - | RemoveMessage Evergreen.V89.Data.Message.Message - | Barter Evergreen.V89.Data.Barter.State - | AdminToBackend AdminToBackend - - -type BackendMsg - = Connected Lamdera.SessionId Lamdera.ClientId - | Disconnected Lamdera.SessionId Lamdera.ClientId - | GeneratedFight Lamdera.ClientId Evergreen.V89.Data.Player.SPlayer ( Evergreen.V89.Data.Fight.Generator.Fight, Int ) - | GeneratedNewVendorsStock ( AssocList.Dict Evergreen.V89.Data.Vendor.Name Evergreen.V89.Data.Vendor.Vendor, Int ) - | Tick Time.Posix - | CreateNewCharWithTime Lamdera.ClientId Evergreen.V89.Data.NewChar.NewChar Time.Posix - | LoggedToBackendMsg - - -type ToFrontend - = YourCurrentWorld Evergreen.V89.Data.World.WorldLoggedInData - | InitWorld Evergreen.V89.Data.World.WorldLoggedOutData - | RefreshedLoggedOut Evergreen.V89.Data.World.WorldLoggedOutData - | CurrentAdminData Evergreen.V89.Data.World.AdminData - | YourFightResult ( Evergreen.V89.Data.Fight.Info, Evergreen.V89.Data.World.WorldLoggedInData ) - | YoureLoggedIn Evergreen.V89.Data.World.WorldLoggedInData - | YoureRegistered Evergreen.V89.Data.World.WorldLoggedInData - | CharCreationError Evergreen.V89.Data.NewChar.CreationError - | YouHaveCreatedChar Evergreen.V89.Data.World.WorldLoggedInData - | YoureLoggedOut Evergreen.V89.Data.World.WorldLoggedOutData - | AlertMessage String - | YoureLoggedInAsAdmin Evergreen.V89.Data.World.AdminData - | JsonExportDone String - | BarterDone ( Evergreen.V89.Data.World.WorldLoggedInData, Maybe Evergreen.V89.Data.Barter.Message ) - | BarterMessage Evergreen.V89.Data.Barter.Message diff --git a/src/Evergreen/V96/Data/Auth.elm b/src/Evergreen/V96/Data/Auth.elm deleted file mode 100644 index 98c1b310..00000000 --- a/src/Evergreen/V96/Data/Auth.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V96.Data.Auth exposing (..) - - -type Plaintext - = Plaintext - - -type Password a - = Password String - - -type alias Auth a = - { name : String - , password : Password a - } - - -type Verified - = Verified - - -type Hashed - = Hashed diff --git a/src/Evergreen/V96/Data/Barter.elm b/src/Evergreen/V96/Data/Barter.elm deleted file mode 100644 index 58e97d4c..00000000 --- a/src/Evergreen/V96/Data/Barter.elm +++ /dev/null @@ -1,33 +0,0 @@ -module Evergreen.V96.Data.Barter exposing (..) - -import AssocList -import Dict -import Evergreen.V96.Data.Item - - -type Message - = BarterIsEmpty - | PlayerOfferNotValuableEnough - | YouGaveStuffForFree - - -type TransferNPosition - = PlayerKeptItem Evergreen.V96.Data.Item.Id - | VendorKeptItem Evergreen.V96.Data.Item.Id - | PlayerTradedItem Evergreen.V96.Data.Item.Id - | VendorTradedItem Evergreen.V96.Data.Item.Id - | PlayerKeptCaps - | VendorKeptCaps - | PlayerTradedCaps - | VendorTradedCaps - - -type alias State = - { playerItems : Dict.Dict Evergreen.V96.Data.Item.Id Int - , vendorItems : Dict.Dict Evergreen.V96.Data.Item.Id Int - , playerCaps : Int - , vendorCaps : Int - , lastMessage : Maybe Message - , transferNInputs : AssocList.Dict TransferNPosition String - , transferNHover : Maybe TransferNPosition - } diff --git a/src/Evergreen/V96/Data/Enemy.elm b/src/Evergreen/V96/Data/Enemy.elm deleted file mode 100644 index e8a798c0..00000000 --- a/src/Evergreen/V96/Data/Enemy.elm +++ /dev/null @@ -1,14 +0,0 @@ -module Evergreen.V96.Data.Enemy exposing (..) - - -type Type - = Brahmin - | AngryBrahmin - | WeakBrahmin - | WildBrahmin - | GiantAnt - | ToughGiantAnt - | BlackRadscorpion - | LesserBlackRadscorpion - | LesserRadscorpion - | Radscorpion diff --git a/src/Evergreen/V96/Data/Fight.elm b/src/Evergreen/V96/Data/Fight.elm deleted file mode 100644 index 6bf7b2ef..00000000 --- a/src/Evergreen/V96/Data/Fight.elm +++ /dev/null @@ -1,90 +0,0 @@ -module Evergreen.V96.Data.Fight exposing (..) - -import AssocList -import AssocSet -import Evergreen.V96.Data.Enemy -import Evergreen.V96.Data.Fight.ShotType -import Evergreen.V96.Data.Item -import Evergreen.V96.Data.Perk -import Evergreen.V96.Data.Player.PlayerName -import Evergreen.V96.Data.Skill -import Evergreen.V96.Data.Special -import Evergreen.V96.Data.Trait -import Evergreen.V96.Logic - - -type alias PlayerOpponent = - { name : Evergreen.V96.Data.Player.PlayerName.PlayerName - , xp : Int - } - - -type OpponentType - = Npc Evergreen.V96.Data.Enemy.Type - | Player PlayerOpponent - - -type Who - = Attacker - | Target - - -type Action - = Start - { distanceHexes : Int - } - | ComeCloser - { hexes : Int - , remainingDistanceHexes : Int - } - | Attack - { damage : Int - , shotType : Evergreen.V96.Data.Fight.ShotType.ShotType - , remainingHp : Int - , isCritical : Bool - } - | Miss - { shotType : Evergreen.V96.Data.Fight.ShotType.ShotType - } - - -type Result - = AttackerWon - { xpGained : Int - , capsGained : Int - , itemsGained : List Evergreen.V96.Data.Item.Item - } - | TargetWon - { xpGained : Int - , capsGained : Int - , itemsGained : List Evergreen.V96.Data.Item.Item - } - | TargetAlreadyDead - | BothDead - | NobodyDead - - -type alias Info = - { attacker : OpponentType - , target : OpponentType - , log : List ( Who, Action ) - , result : Result - } - - -type alias Opponent = - { type_ : OpponentType - , hp : Int - , maxHp : Int - , maxAp : Int - , sequence : Int - , traits : AssocSet.Set Evergreen.V96.Data.Trait.Trait - , perks : AssocList.Dict Evergreen.V96.Data.Perk.Perk Int - , caps : Int - , drops : List Evergreen.V96.Data.Item.Item - , equippedArmor : Maybe Evergreen.V96.Data.Item.Kind - , naturalArmorClass : Int - , attackStats : Evergreen.V96.Logic.AttackStats - , addedSkillPercentages : AssocList.Dict Evergreen.V96.Data.Skill.Skill Int - , special : Evergreen.V96.Data.Special.Special - } diff --git a/src/Evergreen/V96/Data/Fight/Generator.elm b/src/Evergreen/V96/Data/Fight/Generator.elm deleted file mode 100644 index 4b5c386d..00000000 --- a/src/Evergreen/V96/Data/Fight/Generator.elm +++ /dev/null @@ -1,12 +0,0 @@ -module Evergreen.V96.Data.Fight.Generator exposing (..) - -import Evergreen.V96.Data.Fight -import Evergreen.V96.Data.Message - - -type alias Fight = - { finalAttacker : Evergreen.V96.Data.Fight.Opponent - , finalTarget : Evergreen.V96.Data.Fight.Opponent - , fightInfo : Evergreen.V96.Data.Fight.Info - , messageForTarget : Evergreen.V96.Data.Message.Message - } diff --git a/src/Evergreen/V96/Data/Fight/ShotType.elm b/src/Evergreen/V96/Data/Fight/ShotType.elm deleted file mode 100644 index 89ee716e..00000000 --- a/src/Evergreen/V96/Data/Fight/ShotType.elm +++ /dev/null @@ -1,17 +0,0 @@ -module Evergreen.V96.Data.Fight.ShotType exposing (..) - - -type AimedShot - = Head - | Torso - | Eyes - | Groin - | LeftArm - | RightArm - | LeftLeg - | RightLeg - - -type ShotType - = NormalShot - | AimedShot AimedShot diff --git a/src/Evergreen/V96/Data/HealthStatus.elm b/src/Evergreen/V96/Data/HealthStatus.elm deleted file mode 100644 index b31e0579..00000000 --- a/src/Evergreen/V96/Data/HealthStatus.elm +++ /dev/null @@ -1,16 +0,0 @@ -module Evergreen.V96.Data.HealthStatus exposing (..) - - -type HealthStatus - = ExactHp - { current : Int - , max : Int - } - | Unhurt - | SlightlyWounded - | Wounded - | SeverelyWounded - | AlmostDead - | Dead - | Alive - | Unknown diff --git a/src/Evergreen/V96/Data/Item.elm b/src/Evergreen/V96/Data/Item.elm deleted file mode 100644 index 5ecf6c07..00000000 --- a/src/Evergreen/V96/Data/Item.elm +++ /dev/null @@ -1,27 +0,0 @@ -module Evergreen.V96.Data.Item exposing (..) - - -type alias Id = - Int - - -type Kind - = Fruit - | HealingPowder - | Stimpak - | BigBookOfScience - | DeansElectronics - | FirstAidBook - | GunsAndBullets - | ScoutHandbook - | Robes - | LeatherJacket - | LeatherArmor - | MetalArmor - - -type alias Item = - { id : Id - , kind : Kind - , count : Int - } diff --git a/src/Evergreen/V96/Data/Map.elm b/src/Evergreen/V96/Data/Map.elm deleted file mode 100644 index 93b36a8c..00000000 --- a/src/Evergreen/V96/Data/Map.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V96.Data.Map exposing (..) - - -type alias TileNum = - Int - - -type alias TileCoords = - ( Int, Int ) diff --git a/src/Evergreen/V96/Data/Message.elm b/src/Evergreen/V96/Data/Message.elm deleted file mode 100644 index b89d3b37..00000000 --- a/src/Evergreen/V96/Data/Message.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V96.Data.Message exposing (..) - -import Evergreen.V96.Data.Fight -import Evergreen.V96.Data.Player.PlayerName -import Time - - -type Type - = Welcome - | YouAdvancedLevel - { newLevel : Int - } - | YouWereAttacked - { attacker : Evergreen.V96.Data.Player.PlayerName.PlayerName - , fightInfo : Evergreen.V96.Data.Fight.Info - } - - -type alias Message = - { type_ : Type - , hasBeenRead : Bool - , date : Time.Posix - } diff --git a/src/Evergreen/V96/Data/NewChar.elm b/src/Evergreen/V96/Data/NewChar.elm deleted file mode 100644 index cba7412a..00000000 --- a/src/Evergreen/V96/Data/NewChar.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V96.Data.NewChar exposing (..) - -import AssocSet -import Evergreen.V96.Data.Skill -import Evergreen.V96.Data.Special -import Evergreen.V96.Data.Trait - - -type CreationError - = DoesNotHaveThreeTaggedSkills - | HasSpecialPointsLeft - | UsedMoreSpecialPointsThanAvailable - | HasSpecialOutOfRange - | HasMoreThanTwoTraits - - -type alias NewChar = - { baseSpecial : Evergreen.V96.Data.Special.Special - , availableSpecial : Int - , taggedSkills : AssocSet.Set Evergreen.V96.Data.Skill.Skill - , traits : AssocSet.Set Evergreen.V96.Data.Trait.Trait - , error : Maybe CreationError - } diff --git a/src/Evergreen/V96/Data/Perk.elm b/src/Evergreen/V96/Data/Perk.elm deleted file mode 100644 index fc435c05..00000000 --- a/src/Evergreen/V96/Data/Perk.elm +++ /dev/null @@ -1,45 +0,0 @@ -module Evergreen.V96.Data.Perk exposing (..) - - -type Perk - = BonusHthDamage - | Awareness - | CautiousNature - | Comprehension - | EarlierSequence - | FasterHealing - | HereAndNow - | Survivalist - | SwiftLearner - | Thief - | Toughness - | AdrenalineRush - | Educated - | FortuneFinder - | Gambler - | MoreCriticals - | Negotiator - | Pathfinder - | Ranger - | Salesman - | BetterCriticals - | Dodger - | Speaker - | ActionBoy - | GainStrength - | GainPerception - | GainEndurance - | GainCharisma - | GainIntelligence - | GainAgility - | GainLuck - | HthEvade - | Lifegiver - | LivingAnatomy - | MasterThief - | MasterTrader - | Medic - | MrFixit - | Tag - | BonusHthAttacks - | Slayer diff --git a/src/Evergreen/V96/Data/Player.elm b/src/Evergreen/V96/Data/Player.elm deleted file mode 100644 index 9378db0d..00000000 --- a/src/Evergreen/V96/Data/Player.elm +++ /dev/null @@ -1,77 +0,0 @@ -module Evergreen.V96.Data.Player exposing (..) - -import AssocList -import AssocSet -import Dict -import Evergreen.V96.Data.Auth -import Evergreen.V96.Data.HealthStatus -import Evergreen.V96.Data.Item -import Evergreen.V96.Data.Map -import Evergreen.V96.Data.Message -import Evergreen.V96.Data.Perk -import Evergreen.V96.Data.Player.PlayerName -import Evergreen.V96.Data.Skill -import Evergreen.V96.Data.Special -import Evergreen.V96.Data.Trait -import Evergreen.V96.Data.Xp - - -type alias COtherPlayer = - { level : Evergreen.V96.Data.Xp.Level - , name : Evergreen.V96.Data.Player.PlayerName.PlayerName - , wins : Int - , losses : Int - , healthStatus : Evergreen.V96.Data.HealthStatus.HealthStatus - } - - -type alias CPlayer = - { hp : Int - , maxHp : Int - , xp : Evergreen.V96.Data.Xp.Xp - , name : Evergreen.V96.Data.Player.PlayerName.PlayerName - , special : Evergreen.V96.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V96.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V96.Data.Perk.Perk Int - , messages : List Evergreen.V96.Data.Message.Message - , items : Dict.Dict Evergreen.V96.Data.Item.Id Evergreen.V96.Data.Item.Item - , traits : AssocSet.Set Evergreen.V96.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V96.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V96.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - , equippedArmor : Maybe Evergreen.V96.Data.Item.Item - } - - -type Player a - = NeedsCharCreated (Evergreen.V96.Data.Auth.Auth Evergreen.V96.Data.Auth.Verified) - | Player a - - -type alias SPlayer = - { name : Evergreen.V96.Data.Player.PlayerName.PlayerName - , password : Evergreen.V96.Data.Auth.Password Evergreen.V96.Data.Auth.Verified - , hp : Int - , maxHp : Int - , xp : Int - , special : Evergreen.V96.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V96.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V96.Data.Perk.Perk Int - , messages : List Evergreen.V96.Data.Message.Message - , items : Dict.Dict Evergreen.V96.Data.Item.Id Evergreen.V96.Data.Item.Item - , traits : AssocSet.Set Evergreen.V96.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V96.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V96.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - , equippedArmor : Maybe Evergreen.V96.Data.Item.Item - } diff --git a/src/Evergreen/V96/Data/Player/PlayerName.elm b/src/Evergreen/V96/Data/Player/PlayerName.elm deleted file mode 100644 index 09b23341..00000000 --- a/src/Evergreen/V96/Data/Player/PlayerName.elm +++ /dev/null @@ -1,5 +0,0 @@ -module Evergreen.V96.Data.Player.PlayerName exposing (..) - - -type alias PlayerName = - String diff --git a/src/Evergreen/V96/Data/Skill.elm b/src/Evergreen/V96/Data/Skill.elm deleted file mode 100644 index 8208224d..00000000 --- a/src/Evergreen/V96/Data/Skill.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V96.Data.Skill exposing (..) - - -type Skill - = SmallGuns - | BigGuns - | EnergyWeapons - | Unarmed - | MeleeWeapons - | Throwing - | FirstAid - | Doctor - | Sneak - | Lockpick - | Steal - | Traps - | Science - | Repair - | Speech - | Barter - | Gambling - | Outdoorsman diff --git a/src/Evergreen/V96/Data/Special.elm b/src/Evergreen/V96/Data/Special.elm deleted file mode 100644 index 6f26fc38..00000000 --- a/src/Evergreen/V96/Data/Special.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V96.Data.Special exposing (..) - - -type alias Special = - { strength : Int - , perception : Int - , endurance : Int - , charisma : Int - , intelligence : Int - , agility : Int - , luck : Int - } - - -type Type - = Strength - | Perception - | Endurance - | Charisma - | Intelligence - | Agility - | Luck diff --git a/src/Evergreen/V96/Data/Trait.elm b/src/Evergreen/V96/Data/Trait.elm deleted file mode 100644 index a1c330b6..00000000 --- a/src/Evergreen/V96/Data/Trait.elm +++ /dev/null @@ -1,11 +0,0 @@ -module Evergreen.V96.Data.Trait exposing (..) - - -type Trait - = Kamikaze - | Bruiser - | Gifted - | SmallFrame - | Skilled - | HeavyHanded - | Finesse diff --git a/src/Evergreen/V96/Data/Vendor.elm b/src/Evergreen/V96/Data/Vendor.elm deleted file mode 100644 index 5432962a..00000000 --- a/src/Evergreen/V96/Data/Vendor.elm +++ /dev/null @@ -1,20 +0,0 @@ -module Evergreen.V96.Data.Vendor exposing (..) - -import Dict -import Evergreen.V96.Data.Item - - -type Name - = ArroyoHakunin - | KlamathMaidaBuckner - | DenFlick - | ModocJo - | VaultCityHappyHarry - - -type alias Vendor = - { name : Name - , items : Dict.Dict Evergreen.V96.Data.Item.Id Evergreen.V96.Data.Item.Item - , caps : Int - , barterSkill : Int - } diff --git a/src/Evergreen/V96/Data/World.elm b/src/Evergreen/V96/Data/World.elm deleted file mode 100644 index 7e01daff..00000000 --- a/src/Evergreen/V96/Data/World.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.V96.Data.World exposing (..) - -import AssocList -import Evergreen.V96.Data.Auth -import Evergreen.V96.Data.Player -import Evergreen.V96.Data.Player.PlayerName -import Evergreen.V96.Data.Vendor -import Time - - -type alias WorldLoggedOutData = - { players : List Evergreen.V96.Data.Player.COtherPlayer - } - - -type alias WorldLoggedInData = - { player : Evergreen.V96.Data.Player.Player Evergreen.V96.Data.Player.CPlayer - , otherPlayers : List Evergreen.V96.Data.Player.COtherPlayer - , playerRank : Int - , vendors : AssocList.Dict Evergreen.V96.Data.Vendor.Name Evergreen.V96.Data.Vendor.Vendor - } - - -type alias AdminData = - { players : List (Evergreen.V96.Data.Player.Player Evergreen.V96.Data.Player.SPlayer) - , loggedInPlayers : List Evergreen.V96.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - } - - -type World - = WorldNotInitialized (Evergreen.V96.Data.Auth.Auth Evergreen.V96.Data.Auth.Plaintext) - | WorldLoggedOut (Evergreen.V96.Data.Auth.Auth Evergreen.V96.Data.Auth.Plaintext) WorldLoggedOutData - | WorldLoggedIn WorldLoggedInData - | WorldAdmin AdminData diff --git a/src/Evergreen/V96/Data/Xp.elm b/src/Evergreen/V96/Data/Xp.elm deleted file mode 100644 index 09928368..00000000 --- a/src/Evergreen/V96/Data/Xp.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V96.Data.Xp exposing (..) - - -type alias Level = - Int - - -type alias Xp = - Int diff --git a/src/Evergreen/V96/Frontend/HoveredItem.elm b/src/Evergreen/V96/Frontend/HoveredItem.elm deleted file mode 100644 index 28f29b78..00000000 --- a/src/Evergreen/V96/Frontend/HoveredItem.elm +++ /dev/null @@ -1,13 +0,0 @@ -module Evergreen.V96.Frontend.HoveredItem exposing (..) - -import Evergreen.V96.Data.Perk -import Evergreen.V96.Data.Skill -import Evergreen.V96.Data.Special -import Evergreen.V96.Data.Trait - - -type HoveredItem - = HoveredPerk Evergreen.V96.Data.Perk.Perk - | HoveredTrait Evergreen.V96.Data.Trait.Trait - | HoveredSpecial Evergreen.V96.Data.Special.Type - | HoveredSkill Evergreen.V96.Data.Skill.Skill diff --git a/src/Evergreen/V96/Frontend/Route.elm b/src/Evergreen/V96/Frontend/Route.elm deleted file mode 100644 index 9be72ee3..00000000 --- a/src/Evergreen/V96/Frontend/Route.elm +++ /dev/null @@ -1,31 +0,0 @@ -module Evergreen.V96.Frontend.Route exposing (..) - -import Evergreen.V96.Data.Barter -import Evergreen.V96.Data.Fight -import Evergreen.V96.Data.Message - - -type TownRoute - = MainSquare - | Store - { barter : Evergreen.V96.Data.Barter.State - } - - -type AdminRoute - = LoggedIn - - -type Route - = Character - | Inventory - | Map - | Ladder - | Town TownRoute - | About - | News - | Fight Evergreen.V96.Data.Fight.Info - | Messages - | Message Evergreen.V96.Data.Message.Message - | CharCreation - | Admin AdminRoute diff --git a/src/Evergreen/V96/Logic.elm b/src/Evergreen/V96/Logic.elm deleted file mode 100644 index 4c5372f2..00000000 --- a/src/Evergreen/V96/Logic.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V96.Logic exposing (..) - - -type alias AttackStats = - { minDamage : Int - , maxDamage : Int - , criticalChanceBonus : Int - } diff --git a/src/Evergreen/V96/Types.elm b/src/Evergreen/V96/Types.elm deleted file mode 100644 index e186a16f..00000000 --- a/src/Evergreen/V96/Types.elm +++ /dev/null @@ -1,164 +0,0 @@ -module Evergreen.V96.Types exposing (..) - -import AssocList -import Browser -import Browser.Navigation -import Dict -import Evergreen.V96.Data.Auth -import Evergreen.V96.Data.Barter -import Evergreen.V96.Data.Fight -import Evergreen.V96.Data.Fight.Generator -import Evergreen.V96.Data.Item -import Evergreen.V96.Data.Map -import Evergreen.V96.Data.Message -import Evergreen.V96.Data.NewChar -import Evergreen.V96.Data.Perk -import Evergreen.V96.Data.Player -import Evergreen.V96.Data.Player.PlayerName -import Evergreen.V96.Data.Skill -import Evergreen.V96.Data.Special -import Evergreen.V96.Data.Trait -import Evergreen.V96.Data.Vendor -import Evergreen.V96.Data.World -import Evergreen.V96.Frontend.HoveredItem -import Evergreen.V96.Frontend.Route -import File exposing (File) -import Lamdera -import Set -import Time -import Url - - -type alias FrontendModel = - { key : Browser.Navigation.Key - , time : Time.Posix - , zone : Time.Zone - , route : Evergreen.V96.Frontend.Route.Route - , world : Evergreen.V96.Data.World.World - , newChar : Evergreen.V96.Data.NewChar.NewChar - , alertMessage : Maybe String - , mapMouseCoords : Maybe ( Evergreen.V96.Data.Map.TileCoords, Set.Set Evergreen.V96.Data.Map.TileCoords ) - , hoveredItem : Maybe Evergreen.V96.Frontend.HoveredItem.HoveredItem - } - - -type alias BackendModel = - { players : Dict.Dict Evergreen.V96.Data.Player.PlayerName.PlayerName (Evergreen.V96.Data.Player.Player Evergreen.V96.Data.Player.SPlayer) - , loggedInPlayers : Dict.Dict Lamdera.ClientId Evergreen.V96.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - , adminLoggedIn : Maybe ( Lamdera.ClientId, Lamdera.SessionId ) - , time : Time.Posix - , vendors : AssocList.Dict Evergreen.V96.Data.Vendor.Name Evergreen.V96.Data.Vendor.Vendor - , lastItemId : Int - } - - -type BarterMsg - = AddPlayerItem Evergreen.V96.Data.Item.Id Int - | AddVendorItem Evergreen.V96.Data.Item.Id Int - | AddPlayerCaps Int - | AddVendorCaps Int - | RemovePlayerItem Evergreen.V96.Data.Item.Id Int - | RemoveVendorItem Evergreen.V96.Data.Item.Id Int - | RemovePlayerCaps Int - | RemoveVendorCaps Int - | ResetBarter - | ConfirmBarter - | SetTransferNInput Evergreen.V96.Data.Barter.TransferNPosition String - | SetTransferNHover Evergreen.V96.Data.Barter.TransferNPosition - | UnsetTransferNHover - - -type FrontendMsg - = UrlClicked Browser.UrlRequest - | UrlChanged Url.Url - | GoToRoute Evergreen.V96.Frontend.Route.Route - | Logout - | Login - | Register - | GotZone Time.Zone - | GotTime Time.Posix - | AskToFight Evergreen.V96.Data.Player.PlayerName.PlayerName - | AskToHeal - | AskToUseItem Evergreen.V96.Data.Item.Id - | AskToWander - | AskToChoosePerk Evergreen.V96.Data.Perk.Perk - | AskToEquipItem Evergreen.V96.Data.Item.Id - | AskToUnequipArmor - | AskForExport - | ImportButtonClicked - | ImportFileSelected File - | AskToImport String - | Refresh - | AskToTagSkill Evergreen.V96.Data.Skill.Skill - | AskToUseSkillPoints Evergreen.V96.Data.Skill.Skill - | SetAuthName String - | SetAuthPassword String - | CreateChar - | NewCharIncSpecial Evergreen.V96.Data.Special.Type - | NewCharDecSpecial Evergreen.V96.Data.Special.Type - | NewCharToggleTaggedSkill Evergreen.V96.Data.Skill.Skill - | NewCharToggleTrait Evergreen.V96.Data.Trait.Trait - | MapMouseAtCoords Evergreen.V96.Data.Map.TileCoords - | MapMouseOut - | MapMouseClick - | OpenMessage Evergreen.V96.Data.Message.Message - | AskToRemoveMessage Evergreen.V96.Data.Message.Message - | BarterMsg BarterMsg - | HoverItem Evergreen.V96.Frontend.HoveredItem.HoveredItem - | StopHoveringItem - - -type AdminToBackend - = ExportJson - | ImportJson String - - -type ToBackend - = LogMeIn (Evergreen.V96.Data.Auth.Auth Evergreen.V96.Data.Auth.Hashed) - | RegisterMe (Evergreen.V96.Data.Auth.Auth Evergreen.V96.Data.Auth.Hashed) - | CreateNewChar Evergreen.V96.Data.NewChar.NewChar - | LogMeOut - | Fight Evergreen.V96.Data.Player.PlayerName.PlayerName - | HealMe - | UseItem Evergreen.V96.Data.Item.Id - | Wander - | EquipItem Evergreen.V96.Data.Item.Id - | UnequipArmor - | RefreshPlease - | TagSkill Evergreen.V96.Data.Skill.Skill - | UseSkillPoints Evergreen.V96.Data.Skill.Skill - | ChoosePerk Evergreen.V96.Data.Perk.Perk - | MoveTo Evergreen.V96.Data.Map.TileCoords (Set.Set Evergreen.V96.Data.Map.TileCoords) - | MessageWasRead Evergreen.V96.Data.Message.Message - | RemoveMessage Evergreen.V96.Data.Message.Message - | Barter Evergreen.V96.Data.Barter.State - | AdminToBackend AdminToBackend - - -type BackendMsg - = Connected Lamdera.SessionId Lamdera.ClientId - | Disconnected Lamdera.SessionId Lamdera.ClientId - | GeneratedFight Lamdera.ClientId Evergreen.V96.Data.Player.SPlayer ( Evergreen.V96.Data.Fight.Generator.Fight, Int ) - | GeneratedNewVendorsStock ( AssocList.Dict Evergreen.V96.Data.Vendor.Name Evergreen.V96.Data.Vendor.Vendor, Int ) - | Tick Time.Posix - | CreateNewCharWithTime Lamdera.ClientId Evergreen.V96.Data.NewChar.NewChar Time.Posix - | LoggedToBackendMsg - - -type ToFrontend - = YourCurrentWorld Evergreen.V96.Data.World.WorldLoggedInData - | InitWorld Evergreen.V96.Data.World.WorldLoggedOutData - | RefreshedLoggedOut Evergreen.V96.Data.World.WorldLoggedOutData - | CurrentAdminData Evergreen.V96.Data.World.AdminData - | YourFightResult ( Evergreen.V96.Data.Fight.Info, Evergreen.V96.Data.World.WorldLoggedInData ) - | YoureLoggedIn Evergreen.V96.Data.World.WorldLoggedInData - | YoureRegistered Evergreen.V96.Data.World.WorldLoggedInData - | CharCreationError Evergreen.V96.Data.NewChar.CreationError - | YouHaveCreatedChar Evergreen.V96.Data.World.WorldLoggedInData - | YoureLoggedOut Evergreen.V96.Data.World.WorldLoggedOutData - | AlertMessage String - | YoureLoggedInAsAdmin Evergreen.V96.Data.World.AdminData - | JsonExportDone String - | BarterDone ( Evergreen.V96.Data.World.WorldLoggedInData, Maybe Evergreen.V96.Data.Barter.Message ) - | BarterMessage Evergreen.V96.Data.Barter.Message diff --git a/src/Evergreen/V97/Data/Auth.elm b/src/Evergreen/V97/Data/Auth.elm deleted file mode 100644 index 1c2a97c9..00000000 --- a/src/Evergreen/V97/Data/Auth.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V97.Data.Auth exposing (..) - - -type Plaintext - = Plaintext - - -type Password a - = Password String - - -type alias Auth a = - { name : String - , password : Password a - } - - -type Verified - = Verified - - -type Hashed - = Hashed diff --git a/src/Evergreen/V97/Data/Barter.elm b/src/Evergreen/V97/Data/Barter.elm deleted file mode 100644 index 17050058..00000000 --- a/src/Evergreen/V97/Data/Barter.elm +++ /dev/null @@ -1,33 +0,0 @@ -module Evergreen.V97.Data.Barter exposing (..) - -import AssocList -import Dict -import Evergreen.V97.Data.Item - - -type Message - = BarterIsEmpty - | PlayerOfferNotValuableEnough - | YouGaveStuffForFree - - -type TransferNPosition - = PlayerKeptItem Evergreen.V97.Data.Item.Id - | VendorKeptItem Evergreen.V97.Data.Item.Id - | PlayerTradedItem Evergreen.V97.Data.Item.Id - | VendorTradedItem Evergreen.V97.Data.Item.Id - | PlayerKeptCaps - | VendorKeptCaps - | PlayerTradedCaps - | VendorTradedCaps - - -type alias State = - { playerItems : Dict.Dict Evergreen.V97.Data.Item.Id Int - , vendorItems : Dict.Dict Evergreen.V97.Data.Item.Id Int - , playerCaps : Int - , vendorCaps : Int - , lastMessage : Maybe Message - , transferNInputs : AssocList.Dict TransferNPosition String - , transferNHover : Maybe TransferNPosition - } diff --git a/src/Evergreen/V97/Data/Enemy.elm b/src/Evergreen/V97/Data/Enemy.elm deleted file mode 100644 index 07a75933..00000000 --- a/src/Evergreen/V97/Data/Enemy.elm +++ /dev/null @@ -1,14 +0,0 @@ -module Evergreen.V97.Data.Enemy exposing (..) - - -type Type - = Brahmin - | AngryBrahmin - | WeakBrahmin - | WildBrahmin - | GiantAnt - | ToughGiantAnt - | BlackRadscorpion - | LesserBlackRadscorpion - | LesserRadscorpion - | Radscorpion diff --git a/src/Evergreen/V97/Data/Fight.elm b/src/Evergreen/V97/Data/Fight.elm deleted file mode 100644 index 8be30438..00000000 --- a/src/Evergreen/V97/Data/Fight.elm +++ /dev/null @@ -1,90 +0,0 @@ -module Evergreen.V97.Data.Fight exposing (..) - -import AssocList -import AssocSet -import Evergreen.V97.Data.Enemy -import Evergreen.V97.Data.Fight.ShotType -import Evergreen.V97.Data.Item -import Evergreen.V97.Data.Perk -import Evergreen.V97.Data.Player.PlayerName -import Evergreen.V97.Data.Skill -import Evergreen.V97.Data.Special -import Evergreen.V97.Data.Trait -import Evergreen.V97.Logic - - -type alias PlayerOpponent = - { name : Evergreen.V97.Data.Player.PlayerName.PlayerName - , xp : Int - } - - -type OpponentType - = Npc Evergreen.V97.Data.Enemy.Type - | Player PlayerOpponent - - -type Who - = Attacker - | Target - - -type Action - = Start - { distanceHexes : Int - } - | ComeCloser - { hexes : Int - , remainingDistanceHexes : Int - } - | Attack - { damage : Int - , shotType : Evergreen.V97.Data.Fight.ShotType.ShotType - , remainingHp : Int - , isCritical : Bool - } - | Miss - { shotType : Evergreen.V97.Data.Fight.ShotType.ShotType - } - - -type Result - = AttackerWon - { xpGained : Int - , capsGained : Int - , itemsGained : List Evergreen.V97.Data.Item.Item - } - | TargetWon - { xpGained : Int - , capsGained : Int - , itemsGained : List Evergreen.V97.Data.Item.Item - } - | TargetAlreadyDead - | BothDead - | NobodyDead - - -type alias Info = - { attacker : OpponentType - , target : OpponentType - , log : List ( Who, Action ) - , result : Result - } - - -type alias Opponent = - { type_ : OpponentType - , hp : Int - , maxHp : Int - , maxAp : Int - , sequence : Int - , traits : AssocSet.Set Evergreen.V97.Data.Trait.Trait - , perks : AssocList.Dict Evergreen.V97.Data.Perk.Perk Int - , caps : Int - , drops : List Evergreen.V97.Data.Item.Item - , equippedArmor : Maybe Evergreen.V97.Data.Item.Kind - , naturalArmorClass : Int - , attackStats : Evergreen.V97.Logic.AttackStats - , addedSkillPercentages : AssocList.Dict Evergreen.V97.Data.Skill.Skill Int - , special : Evergreen.V97.Data.Special.Special - } diff --git a/src/Evergreen/V97/Data/Fight/Generator.elm b/src/Evergreen/V97/Data/Fight/Generator.elm deleted file mode 100644 index 708d063b..00000000 --- a/src/Evergreen/V97/Data/Fight/Generator.elm +++ /dev/null @@ -1,13 +0,0 @@ -module Evergreen.V97.Data.Fight.Generator exposing (..) - -import Evergreen.V97.Data.Fight -import Evergreen.V97.Data.Message - - -type alias Fight = - { finalAttacker : Evergreen.V97.Data.Fight.Opponent - , finalTarget : Evergreen.V97.Data.Fight.Opponent - , fightInfo : Evergreen.V97.Data.Fight.Info - , messageForTarget : Evergreen.V97.Data.Message.Message - , messageForAttacker : Evergreen.V97.Data.Message.Message - } diff --git a/src/Evergreen/V97/Data/Fight/ShotType.elm b/src/Evergreen/V97/Data/Fight/ShotType.elm deleted file mode 100644 index 659bd163..00000000 --- a/src/Evergreen/V97/Data/Fight/ShotType.elm +++ /dev/null @@ -1,17 +0,0 @@ -module Evergreen.V97.Data.Fight.ShotType exposing (..) - - -type AimedShot - = Head - | Torso - | Eyes - | Groin - | LeftArm - | RightArm - | LeftLeg - | RightLeg - - -type ShotType - = NormalShot - | AimedShot AimedShot diff --git a/src/Evergreen/V97/Data/HealthStatus.elm b/src/Evergreen/V97/Data/HealthStatus.elm deleted file mode 100644 index 23617a10..00000000 --- a/src/Evergreen/V97/Data/HealthStatus.elm +++ /dev/null @@ -1,16 +0,0 @@ -module Evergreen.V97.Data.HealthStatus exposing (..) - - -type HealthStatus - = ExactHp - { current : Int - , max : Int - } - | Unhurt - | SlightlyWounded - | Wounded - | SeverelyWounded - | AlmostDead - | Dead - | Alive - | Unknown diff --git a/src/Evergreen/V97/Data/Item.elm b/src/Evergreen/V97/Data/Item.elm deleted file mode 100644 index dde92ba6..00000000 --- a/src/Evergreen/V97/Data/Item.elm +++ /dev/null @@ -1,27 +0,0 @@ -module Evergreen.V97.Data.Item exposing (..) - - -type alias Id = - Int - - -type Kind - = Fruit - | HealingPowder - | Stimpak - | BigBookOfScience - | DeansElectronics - | FirstAidBook - | GunsAndBullets - | ScoutHandbook - | Robes - | LeatherJacket - | LeatherArmor - | MetalArmor - - -type alias Item = - { id : Id - , kind : Kind - , count : Int - } diff --git a/src/Evergreen/V97/Data/Map.elm b/src/Evergreen/V97/Data/Map.elm deleted file mode 100644 index 80a5f6ec..00000000 --- a/src/Evergreen/V97/Data/Map.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V97.Data.Map exposing (..) - - -type alias TileNum = - Int - - -type alias TileCoords = - ( Int, Int ) diff --git a/src/Evergreen/V97/Data/Message.elm b/src/Evergreen/V97/Data/Message.elm deleted file mode 100644 index 6b57f2ef..00000000 --- a/src/Evergreen/V97/Data/Message.elm +++ /dev/null @@ -1,27 +0,0 @@ -module Evergreen.V97.Data.Message exposing (..) - -import Evergreen.V97.Data.Fight -import Evergreen.V97.Data.Player.PlayerName -import Time - - -type Type - = Welcome - | YouAdvancedLevel - { newLevel : Int - } - | YouWereAttacked - { attacker : Evergreen.V97.Data.Player.PlayerName.PlayerName - , fightInfo : Evergreen.V97.Data.Fight.Info - } - | YouAttacked - { target : Evergreen.V97.Data.Player.PlayerName.PlayerName - , fightInfo : Evergreen.V97.Data.Fight.Info - } - - -type alias Message = - { type_ : Type - , hasBeenRead : Bool - , date : Time.Posix - } diff --git a/src/Evergreen/V97/Data/NewChar.elm b/src/Evergreen/V97/Data/NewChar.elm deleted file mode 100644 index cb582f0b..00000000 --- a/src/Evergreen/V97/Data/NewChar.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V97.Data.NewChar exposing (..) - -import AssocSet -import Evergreen.V97.Data.Skill -import Evergreen.V97.Data.Special -import Evergreen.V97.Data.Trait - - -type CreationError - = DoesNotHaveThreeTaggedSkills - | HasSpecialPointsLeft - | UsedMoreSpecialPointsThanAvailable - | HasSpecialOutOfRange - | HasMoreThanTwoTraits - - -type alias NewChar = - { baseSpecial : Evergreen.V97.Data.Special.Special - , availableSpecial : Int - , taggedSkills : AssocSet.Set Evergreen.V97.Data.Skill.Skill - , traits : AssocSet.Set Evergreen.V97.Data.Trait.Trait - , error : Maybe CreationError - } diff --git a/src/Evergreen/V97/Data/Perk.elm b/src/Evergreen/V97/Data/Perk.elm deleted file mode 100644 index 4d2b7ac5..00000000 --- a/src/Evergreen/V97/Data/Perk.elm +++ /dev/null @@ -1,45 +0,0 @@ -module Evergreen.V97.Data.Perk exposing (..) - - -type Perk - = BonusHthDamage - | Awareness - | CautiousNature - | Comprehension - | EarlierSequence - | FasterHealing - | HereAndNow - | Survivalist - | SwiftLearner - | Thief - | Toughness - | AdrenalineRush - | Educated - | FortuneFinder - | Gambler - | MoreCriticals - | Negotiator - | Pathfinder - | Ranger - | Salesman - | BetterCriticals - | Dodger - | Speaker - | ActionBoy - | GainStrength - | GainPerception - | GainEndurance - | GainCharisma - | GainIntelligence - | GainAgility - | GainLuck - | HthEvade - | Lifegiver - | LivingAnatomy - | MasterThief - | MasterTrader - | Medic - | MrFixit - | Tag - | BonusHthAttacks - | Slayer diff --git a/src/Evergreen/V97/Data/Player.elm b/src/Evergreen/V97/Data/Player.elm deleted file mode 100644 index be14f6a6..00000000 --- a/src/Evergreen/V97/Data/Player.elm +++ /dev/null @@ -1,77 +0,0 @@ -module Evergreen.V97.Data.Player exposing (..) - -import AssocList -import AssocSet -import Dict -import Evergreen.V97.Data.Auth -import Evergreen.V97.Data.HealthStatus -import Evergreen.V97.Data.Item -import Evergreen.V97.Data.Map -import Evergreen.V97.Data.Message -import Evergreen.V97.Data.Perk -import Evergreen.V97.Data.Player.PlayerName -import Evergreen.V97.Data.Skill -import Evergreen.V97.Data.Special -import Evergreen.V97.Data.Trait -import Evergreen.V97.Data.Xp - - -type alias COtherPlayer = - { level : Evergreen.V97.Data.Xp.Level - , name : Evergreen.V97.Data.Player.PlayerName.PlayerName - , wins : Int - , losses : Int - , healthStatus : Evergreen.V97.Data.HealthStatus.HealthStatus - } - - -type alias CPlayer = - { hp : Int - , maxHp : Int - , xp : Evergreen.V97.Data.Xp.Xp - , name : Evergreen.V97.Data.Player.PlayerName.PlayerName - , special : Evergreen.V97.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V97.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V97.Data.Perk.Perk Int - , messages : List Evergreen.V97.Data.Message.Message - , items : Dict.Dict Evergreen.V97.Data.Item.Id Evergreen.V97.Data.Item.Item - , traits : AssocSet.Set Evergreen.V97.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V97.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V97.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - , equippedArmor : Maybe Evergreen.V97.Data.Item.Item - } - - -type Player a - = NeedsCharCreated (Evergreen.V97.Data.Auth.Auth Evergreen.V97.Data.Auth.Verified) - | Player a - - -type alias SPlayer = - { name : Evergreen.V97.Data.Player.PlayerName.PlayerName - , password : Evergreen.V97.Data.Auth.Password Evergreen.V97.Data.Auth.Verified - , hp : Int - , maxHp : Int - , xp : Int - , special : Evergreen.V97.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V97.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V97.Data.Perk.Perk Int - , messages : List Evergreen.V97.Data.Message.Message - , items : Dict.Dict Evergreen.V97.Data.Item.Id Evergreen.V97.Data.Item.Item - , traits : AssocSet.Set Evergreen.V97.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V97.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V97.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - , equippedArmor : Maybe Evergreen.V97.Data.Item.Item - } diff --git a/src/Evergreen/V97/Data/Player/PlayerName.elm b/src/Evergreen/V97/Data/Player/PlayerName.elm deleted file mode 100644 index 0c9e4ce1..00000000 --- a/src/Evergreen/V97/Data/Player/PlayerName.elm +++ /dev/null @@ -1,5 +0,0 @@ -module Evergreen.V97.Data.Player.PlayerName exposing (..) - - -type alias PlayerName = - String diff --git a/src/Evergreen/V97/Data/Skill.elm b/src/Evergreen/V97/Data/Skill.elm deleted file mode 100644 index 671ab397..00000000 --- a/src/Evergreen/V97/Data/Skill.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V97.Data.Skill exposing (..) - - -type Skill - = SmallGuns - | BigGuns - | EnergyWeapons - | Unarmed - | MeleeWeapons - | Throwing - | FirstAid - | Doctor - | Sneak - | Lockpick - | Steal - | Traps - | Science - | Repair - | Speech - | Barter - | Gambling - | Outdoorsman diff --git a/src/Evergreen/V97/Data/Special.elm b/src/Evergreen/V97/Data/Special.elm deleted file mode 100644 index 142cf4cf..00000000 --- a/src/Evergreen/V97/Data/Special.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V97.Data.Special exposing (..) - - -type alias Special = - { strength : Int - , perception : Int - , endurance : Int - , charisma : Int - , intelligence : Int - , agility : Int - , luck : Int - } - - -type Type - = Strength - | Perception - | Endurance - | Charisma - | Intelligence - | Agility - | Luck diff --git a/src/Evergreen/V97/Data/Trait.elm b/src/Evergreen/V97/Data/Trait.elm deleted file mode 100644 index cd378be5..00000000 --- a/src/Evergreen/V97/Data/Trait.elm +++ /dev/null @@ -1,11 +0,0 @@ -module Evergreen.V97.Data.Trait exposing (..) - - -type Trait - = Kamikaze - | Bruiser - | Gifted - | SmallFrame - | Skilled - | HeavyHanded - | Finesse diff --git a/src/Evergreen/V97/Data/Vendor.elm b/src/Evergreen/V97/Data/Vendor.elm deleted file mode 100644 index 42fec890..00000000 --- a/src/Evergreen/V97/Data/Vendor.elm +++ /dev/null @@ -1,20 +0,0 @@ -module Evergreen.V97.Data.Vendor exposing (..) - -import Dict -import Evergreen.V97.Data.Item - - -type Name - = ArroyoHakunin - | KlamathMaidaBuckner - | DenFlick - | ModocJo - | VaultCityHappyHarry - - -type alias Vendor = - { name : Name - , items : Dict.Dict Evergreen.V97.Data.Item.Id Evergreen.V97.Data.Item.Item - , caps : Int - , barterSkill : Int - } diff --git a/src/Evergreen/V97/Data/World.elm b/src/Evergreen/V97/Data/World.elm deleted file mode 100644 index d546059e..00000000 --- a/src/Evergreen/V97/Data/World.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.V97.Data.World exposing (..) - -import AssocList -import Evergreen.V97.Data.Auth -import Evergreen.V97.Data.Player -import Evergreen.V97.Data.Player.PlayerName -import Evergreen.V97.Data.Vendor -import Time - - -type alias WorldLoggedOutData = - { players : List Evergreen.V97.Data.Player.COtherPlayer - } - - -type alias WorldLoggedInData = - { player : Evergreen.V97.Data.Player.Player Evergreen.V97.Data.Player.CPlayer - , otherPlayers : List Evergreen.V97.Data.Player.COtherPlayer - , playerRank : Int - , vendors : AssocList.Dict Evergreen.V97.Data.Vendor.Name Evergreen.V97.Data.Vendor.Vendor - } - - -type alias AdminData = - { players : List (Evergreen.V97.Data.Player.Player Evergreen.V97.Data.Player.SPlayer) - , loggedInPlayers : List Evergreen.V97.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - } - - -type World - = WorldNotInitialized (Evergreen.V97.Data.Auth.Auth Evergreen.V97.Data.Auth.Plaintext) - | WorldLoggedOut (Evergreen.V97.Data.Auth.Auth Evergreen.V97.Data.Auth.Plaintext) WorldLoggedOutData - | WorldLoggedIn WorldLoggedInData - | WorldAdmin AdminData diff --git a/src/Evergreen/V97/Data/Xp.elm b/src/Evergreen/V97/Data/Xp.elm deleted file mode 100644 index e0e866ae..00000000 --- a/src/Evergreen/V97/Data/Xp.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V97.Data.Xp exposing (..) - - -type alias Level = - Int - - -type alias Xp = - Int diff --git a/src/Evergreen/V97/Frontend/HoveredItem.elm b/src/Evergreen/V97/Frontend/HoveredItem.elm deleted file mode 100644 index af489c6d..00000000 --- a/src/Evergreen/V97/Frontend/HoveredItem.elm +++ /dev/null @@ -1,13 +0,0 @@ -module Evergreen.V97.Frontend.HoveredItem exposing (..) - -import Evergreen.V97.Data.Perk -import Evergreen.V97.Data.Skill -import Evergreen.V97.Data.Special -import Evergreen.V97.Data.Trait - - -type HoveredItem - = HoveredPerk Evergreen.V97.Data.Perk.Perk - | HoveredTrait Evergreen.V97.Data.Trait.Trait - | HoveredSpecial Evergreen.V97.Data.Special.Type - | HoveredSkill Evergreen.V97.Data.Skill.Skill diff --git a/src/Evergreen/V97/Frontend/Route.elm b/src/Evergreen/V97/Frontend/Route.elm deleted file mode 100644 index 3f1264c6..00000000 --- a/src/Evergreen/V97/Frontend/Route.elm +++ /dev/null @@ -1,31 +0,0 @@ -module Evergreen.V97.Frontend.Route exposing (..) - -import Evergreen.V97.Data.Barter -import Evergreen.V97.Data.Fight -import Evergreen.V97.Data.Message - - -type TownRoute - = MainSquare - | Store - { barter : Evergreen.V97.Data.Barter.State - } - - -type AdminRoute - = LoggedIn - - -type Route - = Character - | Inventory - | Map - | Ladder - | Town TownRoute - | About - | News - | Fight Evergreen.V97.Data.Fight.Info - | Messages - | Message Evergreen.V97.Data.Message.Message - | CharCreation - | Admin AdminRoute diff --git a/src/Evergreen/V97/Logic.elm b/src/Evergreen/V97/Logic.elm deleted file mode 100644 index 57dab323..00000000 --- a/src/Evergreen/V97/Logic.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V97.Logic exposing (..) - - -type alias AttackStats = - { minDamage : Int - , maxDamage : Int - , criticalChanceBonus : Int - } diff --git a/src/Evergreen/V97/Types.elm b/src/Evergreen/V97/Types.elm deleted file mode 100644 index 8ea0ef2b..00000000 --- a/src/Evergreen/V97/Types.elm +++ /dev/null @@ -1,164 +0,0 @@ -module Evergreen.V97.Types exposing (..) - -import AssocList -import Browser -import Browser.Navigation -import Dict -import Evergreen.V97.Data.Auth -import Evergreen.V97.Data.Barter -import Evergreen.V97.Data.Fight -import Evergreen.V97.Data.Fight.Generator -import Evergreen.V97.Data.Item -import Evergreen.V97.Data.Map -import Evergreen.V97.Data.Message -import Evergreen.V97.Data.NewChar -import Evergreen.V97.Data.Perk -import Evergreen.V97.Data.Player -import Evergreen.V97.Data.Player.PlayerName -import Evergreen.V97.Data.Skill -import Evergreen.V97.Data.Special -import Evergreen.V97.Data.Trait -import Evergreen.V97.Data.Vendor -import Evergreen.V97.Data.World -import Evergreen.V97.Frontend.HoveredItem -import Evergreen.V97.Frontend.Route -import File exposing (File) -import Lamdera -import Set -import Time -import Url - - -type alias FrontendModel = - { key : Browser.Navigation.Key - , time : Time.Posix - , zone : Time.Zone - , route : Evergreen.V97.Frontend.Route.Route - , world : Evergreen.V97.Data.World.World - , newChar : Evergreen.V97.Data.NewChar.NewChar - , alertMessage : Maybe String - , mapMouseCoords : Maybe ( Evergreen.V97.Data.Map.TileCoords, Set.Set Evergreen.V97.Data.Map.TileCoords ) - , hoveredItem : Maybe Evergreen.V97.Frontend.HoveredItem.HoveredItem - } - - -type alias BackendModel = - { players : Dict.Dict Evergreen.V97.Data.Player.PlayerName.PlayerName (Evergreen.V97.Data.Player.Player Evergreen.V97.Data.Player.SPlayer) - , loggedInPlayers : Dict.Dict Lamdera.ClientId Evergreen.V97.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - , adminLoggedIn : Maybe ( Lamdera.ClientId, Lamdera.SessionId ) - , time : Time.Posix - , vendors : AssocList.Dict Evergreen.V97.Data.Vendor.Name Evergreen.V97.Data.Vendor.Vendor - , lastItemId : Int - } - - -type BarterMsg - = AddPlayerItem Evergreen.V97.Data.Item.Id Int - | AddVendorItem Evergreen.V97.Data.Item.Id Int - | AddPlayerCaps Int - | AddVendorCaps Int - | RemovePlayerItem Evergreen.V97.Data.Item.Id Int - | RemoveVendorItem Evergreen.V97.Data.Item.Id Int - | RemovePlayerCaps Int - | RemoveVendorCaps Int - | ResetBarter - | ConfirmBarter - | SetTransferNInput Evergreen.V97.Data.Barter.TransferNPosition String - | SetTransferNHover Evergreen.V97.Data.Barter.TransferNPosition - | UnsetTransferNHover - - -type FrontendMsg - = UrlClicked Browser.UrlRequest - | UrlChanged Url.Url - | GoToRoute Evergreen.V97.Frontend.Route.Route - | Logout - | Login - | Register - | GotZone Time.Zone - | GotTime Time.Posix - | AskToFight Evergreen.V97.Data.Player.PlayerName.PlayerName - | AskToHeal - | AskToUseItem Evergreen.V97.Data.Item.Id - | AskToWander - | AskToChoosePerk Evergreen.V97.Data.Perk.Perk - | AskToEquipItem Evergreen.V97.Data.Item.Id - | AskToUnequipArmor - | AskForExport - | ImportButtonClicked - | ImportFileSelected File - | AskToImport String - | Refresh - | AskToTagSkill Evergreen.V97.Data.Skill.Skill - | AskToUseSkillPoints Evergreen.V97.Data.Skill.Skill - | SetAuthName String - | SetAuthPassword String - | CreateChar - | NewCharIncSpecial Evergreen.V97.Data.Special.Type - | NewCharDecSpecial Evergreen.V97.Data.Special.Type - | NewCharToggleTaggedSkill Evergreen.V97.Data.Skill.Skill - | NewCharToggleTrait Evergreen.V97.Data.Trait.Trait - | MapMouseAtCoords Evergreen.V97.Data.Map.TileCoords - | MapMouseOut - | MapMouseClick - | OpenMessage Evergreen.V97.Data.Message.Message - | AskToRemoveMessage Evergreen.V97.Data.Message.Message - | BarterMsg BarterMsg - | HoverItem Evergreen.V97.Frontend.HoveredItem.HoveredItem - | StopHoveringItem - - -type AdminToBackend - = ExportJson - | ImportJson String - - -type ToBackend - = LogMeIn (Evergreen.V97.Data.Auth.Auth Evergreen.V97.Data.Auth.Hashed) - | RegisterMe (Evergreen.V97.Data.Auth.Auth Evergreen.V97.Data.Auth.Hashed) - | CreateNewChar Evergreen.V97.Data.NewChar.NewChar - | LogMeOut - | Fight Evergreen.V97.Data.Player.PlayerName.PlayerName - | HealMe - | UseItem Evergreen.V97.Data.Item.Id - | Wander - | EquipItem Evergreen.V97.Data.Item.Id - | UnequipArmor - | RefreshPlease - | TagSkill Evergreen.V97.Data.Skill.Skill - | UseSkillPoints Evergreen.V97.Data.Skill.Skill - | ChoosePerk Evergreen.V97.Data.Perk.Perk - | MoveTo Evergreen.V97.Data.Map.TileCoords (Set.Set Evergreen.V97.Data.Map.TileCoords) - | MessageWasRead Evergreen.V97.Data.Message.Message - | RemoveMessage Evergreen.V97.Data.Message.Message - | Barter Evergreen.V97.Data.Barter.State - | AdminToBackend AdminToBackend - - -type BackendMsg - = Connected Lamdera.SessionId Lamdera.ClientId - | Disconnected Lamdera.SessionId Lamdera.ClientId - | GeneratedFight Lamdera.ClientId Evergreen.V97.Data.Player.SPlayer ( Evergreen.V97.Data.Fight.Generator.Fight, Int ) - | GeneratedNewVendorsStock ( AssocList.Dict Evergreen.V97.Data.Vendor.Name Evergreen.V97.Data.Vendor.Vendor, Int ) - | Tick Time.Posix - | CreateNewCharWithTime Lamdera.ClientId Evergreen.V97.Data.NewChar.NewChar Time.Posix - | LoggedToBackendMsg - - -type ToFrontend - = YourCurrentWorld Evergreen.V97.Data.World.WorldLoggedInData - | InitWorld Evergreen.V97.Data.World.WorldLoggedOutData - | RefreshedLoggedOut Evergreen.V97.Data.World.WorldLoggedOutData - | CurrentAdminData Evergreen.V97.Data.World.AdminData - | YourFightResult ( Evergreen.V97.Data.Fight.Info, Evergreen.V97.Data.World.WorldLoggedInData ) - | YoureLoggedIn Evergreen.V97.Data.World.WorldLoggedInData - | YoureRegistered Evergreen.V97.Data.World.WorldLoggedInData - | CharCreationError Evergreen.V97.Data.NewChar.CreationError - | YouHaveCreatedChar Evergreen.V97.Data.World.WorldLoggedInData - | YoureLoggedOut Evergreen.V97.Data.World.WorldLoggedOutData - | AlertMessage String - | YoureLoggedInAsAdmin Evergreen.V97.Data.World.AdminData - | JsonExportDone String - | BarterDone ( Evergreen.V97.Data.World.WorldLoggedInData, Maybe Evergreen.V97.Data.Barter.Message ) - | BarterMessage Evergreen.V97.Data.Barter.Message diff --git a/src/Frontend.elm b/src/Frontend.elm index 19c45976..2f264375 100644 --- a/src/Frontend.elm +++ b/src/Frontend.elm @@ -82,11 +82,13 @@ import Result.Extra as Result import Set exposing (Set) import Svg as S exposing (Svg) import Svg.Attributes as SA +import Tailwind as TW import Task import Time exposing (Posix) import Time.Extra as Time import Time.ExtraExtra as Time import Types exposing (..) +import UI import Url exposing (Url) @@ -134,6 +136,7 @@ init url key = , fightInfo = Nothing , fightStrategyText = "" , expandedQuests = Set_.empty + , userWantsToShowAreaDanger = False -- backend state , lastTenToBackendMsgs = [] @@ -144,6 +147,21 @@ init url key = [ Task.perform GotZone Time.here , Task.perform GotTime Time.now , Nav.pushUrl key (Route.toString route) + + -- TODO don't push this, only for developing styles + , let + initAuth = + Auth.init + in + Lamdera.sendToBackend <| + LogMeIn <| + Auth.hash + ({ initAuth + | name = "j2" + , worldName = "main" + } + |> Auth.setPlaintextPassword "j2" + ) ] ) @@ -480,6 +498,11 @@ update msg ({ loginForm } as model) = , Lamdera.sendToBackend <| MoveTo newCoords path ) + SetShowAreaDanger newShow -> + ( { model | userWantsToShowAreaDanger = newShow } + , Cmd.none + ) + OpenMessage messageId -> ( model , Lamdera.sendToBackend <| MessageWasRead messageId @@ -514,8 +537,8 @@ update msg ({ loginForm } as model) = , Cmd.none ) - ToggleAdminNewWorldFast -> - ( { model | adminNewWorldFast = not model.adminNewWorldFast } + SetAdminNewWorldFast new -> + ( { model | adminNewWorldFast = new } , Cmd.none ) @@ -685,7 +708,9 @@ updateFromBackend msg model = YoureLoggedOut worlds -> { model - | loginForm = Auth.init + | loginForm = + Auth.init + |> Auth.selectDefaultWorld worlds , alertMessage = Nothing , worlds = Just worlds , worldData = NotLoggedIn @@ -695,7 +720,9 @@ updateFromBackend msg model = CurrentWorlds worlds -> ( { model | worlds = Just worlds - , loginForm = Auth.selectDefaultWorld worlds model.loginForm + , loginForm = + model.loginForm + |> Auth.selectDefaultWorld worlds } , Cmd.none ) @@ -790,15 +817,43 @@ updateFromBackend msg model = view : Model -> Browser.Document FrontendMsg view model = + let + worldNames : List World.Name + worldNames = + model.worlds + |> Maybe.withDefault [] + |> List.map .name + + leftNav = + case model.worldData of + IsAdmin _ -> + [ alertMessageView model.alertMessage + , H.div [ HA.class "flex flex-col gap-4" ] + [ adminLinksView model.route + , commonLinksView model.route + ] + ] + + IsPlayer data -> + [ alertMessageView model.alertMessage + , playerInfoView data.player + , H.div [ HA.class "flex flex-col gap-4" ] + [ loggedInLinksView data.player model.route + , commonLinksView model.route + ] + ] + + NotLoggedIn -> + [ loginFormView worldNames model.loginForm + , alertMessageView model.alertMessage + , H.div [ HA.class "flex flex-col gap-4" ] + [ loggedOutLinksView model.route + , commonLinksView model.route + ] + ] + in { title = "NuAshworld " ++ Version.version - , body = - [ stylesLinkView - , favicon16View - , favicon32View - , genericFaviconView - , genericFavicon2View - , view_ model - ] + , body = [ appView { leftNav = leftNav } model ] } @@ -807,70 +862,90 @@ appView : -> Model -> Html FrontendMsg appView { leftNav } model = + H.div [ HA.class "flex flex-1 flex-row bg-green-900 max-w-vw max-h-vh overflow-hidden" ] + [ leftNavView leftNav model + , contentView model + ] + + +leftNavView : List (Html FrontendMsg) -> Model -> Html FrontendMsg +leftNavView leftNav model = let - tickFrequency : Maybe Time.Interval - tickFrequency = + tickData : + Maybe + { tickFrequency : Time.Interval + , worldName : String + } + tickData = case model.worldData of IsAdmin _ -> Nothing IsPlayer data -> - Just data.tickFrequency + Just + { tickFrequency = data.tickFrequency + , worldName = data.worldName + } NotLoggedIn -> Nothing in - H.div - [ HA.id "app" - , HA.classList - [ ( "player", isPlayer model ) - , ( "admin", isAdmin model ) - ] - ] - [ H.div [ HA.id "left-nav" ] - [ logoView - , H.div [ HA.id "left-nav-content" ] - ((tickFrequency - |> H.viewMaybe (\freq -> nextTickView freq model.zone model.time) - ) - :: leftNav - ++ [ commonLinksView model.route ] - ) - ] - , contentView model + H.div [ HA.class "bg-green-800 min-w-fit px-6 pb-10 pt-[26px] flex flex-col gap-10 items-center max-h-vh overflow-auto" ] + [ logoView model + , H.div [ HA.class "flex flex-col items-center gap-6" ] + ((tickData |> H.viewMaybe (nextTickView model.zone model.time)) + :: leftNav + ) ] -nextTickView : Time.Interval -> Time.Zone -> Posix -> Html FrontendMsg -nextTickView tickFrequency zone time = +nextTickView : + Time.Zone + -> Posix + -> + { tickFrequency : Time.Interval + , worldName : String + } + -> Html FrontendMsg +nextTickView zone time { tickFrequency, worldName } = let millis = Time.posixToMillis time in - H.div [ HA.id "next-tick" ] <| - if millis == 0 then - [] - - else - let - nextTick = - Tick.nextTick tickFrequency time + -- The -0.5px is a hack to prevent text on Windows from being blurry (basically aligning it back to the pixel grid) + H.div [ HA.class "grid grid-cols-2 gap-x-[1ch] -translate-x-[0.5px]" ] <| + List.concat + [ [ H.span + [ HA.class "text-green-300 text-right" ] + [ H.text "World:" ] + , H.span [] [ H.text worldName ] + ] + , if millis == 0 then + [] - nextTickString = - DateFormat.format - [ DateFormat.hourMilitaryFixed - , DateFormat.text ":" - , DateFormat.minuteFixed - , DateFormat.text ":" - , DateFormat.secondFixed - ] - zone - nextTick - in - [ H.text "Next tick: " - , H.span - [ HA.class "slightly-emphasized" ] - [ H.text nextTickString ] + else + let + nextTick = + Tick.nextTick tickFrequency time + + nextTickString = + DateFormat.format + [ DateFormat.hourMilitaryFixed + , DateFormat.text ":" + , DateFormat.minuteFixed + , DateFormat.text ":" + , DateFormat.secondFixed + ] + zone + nextTick + in + [ H.span + [ HA.class "text-green-300 text-right" ] + [ H.text "Next tick:" ] + , H.span + [ HA.class "text-green-100" ] + [ H.text nextTickString ] + ] ] @@ -900,7 +975,7 @@ contentView model = |> Maybe.map (\loc -> withCreatedPlayer data (fn loc)) |> Maybe.withDefault contentUnavailableWhenNotInTownView in - H.div [ HA.id "content" ] + H.div [ HA.class "pt-8 px-10 pb-10 flex flex-col flex-1 items-start overflow-auto max-h-vh" ] (case ( model.route, model.worldData ) of ( AdminRoute subroute, IsAdmin data ) -> case subroute of @@ -929,7 +1004,7 @@ contentView model = notFoundView url ( Map, IsPlayer data ) -> - withCreatedPlayer data (mapView model.mapMouseCoords) + withCreatedPlayer data (mapView model) ( Map, _ ) -> mapLoggedOutView @@ -995,27 +1070,27 @@ contentView model = pageTitleView : String -> Html FrontendMsg pageTitleView title = H.h2 - [ HA.id "page-title" ] + [ HA.class "text-lg font-extraBold mb-10" ] [ H.text title ] aboutView : List (Html FrontendMsg) aboutView = [ pageTitleView "About" - , Markdown.toHtml - [ HA.id "about-content" ] - """ -Welcome to **NuAshworld** - a multiplayer turn-based browser game set in the -universe of Fallout 2. - -Do you have what it takes to survive in the post-apocalyptic wasteland? Can you -shape the world for the better? - -What more, **can you stand up to the Enclave?** - -Many thanks to Patreons: -* DJetelina (iScrE4m) -""" + , H.div [ HA.class "flex flex-col gap-4 max-w-[60ch]" ] + [ H.p [] + [ H.text "Welcome to " + , H.span [ HA.class "text-green-100" ] [ H.text "NuAshworld" ] + , H.text " - a multiplayer turn-based browser game set in the universe of Fallout 2." + ] + , H.p [] + [ H.text "Do you have what it takes to survive in the post-apocalyptic wasteland? Can you shape the world for the better?" + ] + , H.p [] + [ H.text "What more, " + , H.span [ HA.class "text-green-100" ] [ H.text "can you stand up to the Enclave?" ] + ] + ] ] @@ -1027,11 +1102,19 @@ worldsListView worlds = Just worlds_ -> [ pageTitleView "Worlds" - , H.ul [] + , H.div [ HA.class "flex flex-row flex-wrap gap-4" ] (worlds_ + |> List.sortBy + (\w -> + if w.name == Logic.mainWorldName then + 0 + + else + 1 + ) |> List.map (\world -> - H.li [] + H.div [ HA.class "bg-green-800 p-[2ch]" ] [ worldInfoView { name = world.name , description = world.description @@ -1097,13 +1180,16 @@ adminMapView worldName adminData = |> List.map (.location >> Map.toTileCoords) in H.div - [ HA.id "map" - , HA.class "admin-map" - , cssVars + [ cssVars [ ( "--map-columns", String.fromInt Map.columns ) , ( "--map-rows", String.fromInt Map.rows ) , ( "--map-cell-size", String.fromInt Map.tileSize ++ "px" ) ] + , HA.class "relative bg-black bg-[url('/public/images/map_whole.webp')] bg-[0_0] bg-no-repeat select-none" + , HA.class "min-w-[calc(var(--map-columns)*var(--map-cell-size))]" + , HA.class "max-w-[calc(var(--map-columns)*var(--map-cell-size))]" + , HA.class "min-h-[calc(var(--map-rows)*var(--map-cell-size))]" + , HA.class "max-h-[calc(var(--map-rows)*var(--map-cell-size))]" ] (locationsView Nothing :: List.map mapMarkerView playerCoords @@ -1111,11 +1197,14 @@ adminMapView worldName adminData = mapView : - Maybe ( TileCoords, Set TileCoords ) + { model + | mapMouseCoords : Maybe ( TileCoords, Set TileCoords ) + , userWantsToShowAreaDanger : Bool + } -> PlayerData -> CPlayer -> List (Html FrontendMsg) -mapView mouseCoords _ player = +mapView { mapMouseCoords, userWantsToShowAreaDanger } _ player = let perceptionLevel : PerceptionLevel perceptionLevel = @@ -1129,13 +1218,16 @@ mapView mouseCoords _ player = Map.toTileCoords player.location mouseRelatedView : ( TileCoords, Set TileCoords ) -> Html FrontendMsg - mouseRelatedView ( ( x, y ) as mouseCoords_, pathTaken ) = + mouseRelatedView ( ( x, y ) as mouseCoords, pathTaken ) = let + impassableTiles : Set TileCoords + impassableTiles = + pathTaken + |> Set.filter (Terrain.forCoords >> Terrain.isPassable >> not) + notAllPassable : Bool notAllPassable = - pathTaken - |> Set.toList - |> List.any (Terrain.forCoords >> Terrain.isPassable >> not) + not (Set.isEmpty impassableTiles) cost : Int cost = @@ -1158,32 +1250,50 @@ mapView mouseCoords _ player = bigChunk : BigChunk bigChunk = - BigChunk.forCoords mouseCoords_ - in - H.div - [ HA.id "map-mouse-layer" - , HA.classList - [ ( "too-distant", tooDistant ) - , ( "not-all-passable", notAllPassable ) - ] - ] - [ H.div - [ HA.id "map-mouse-tile" - , HA.class "tile" - , cssVars - [ ( "--tile-coord-x", String.fromInt x ) - , ( "--tile-coord-y", String.fromInt y ) + BigChunk.forCoords mouseCoords + + impossiblePath : Bool + impossiblePath = + tooDistant || notAllPassable + + ( pathTextColor, pathBgColor ) = + if impossiblePath then + ( "text-orange", "bg-orange" ) + + else + ( "text-green-200", "bg-green-300" ) + + tileUnderCursor = + H.div + [ tileClass + , HA.class + (if Set.member mouseCoords impassableTiles then + "bg-red" + + else + pathBgColor + ) + , HA.class "opacity-75 pointer-events-none z-[1]" + , cssVars + [ ( "--tile-coord-x", String.fromInt x ) + , ( "--tile-coord-y", String.fromInt y ) + ] ] - ] - [] - , H.div - [ HA.id "map-path-tiles" ] - (List.map pathTileView - (Set.toList (Set.remove mouseCoords_ pathTaken)) - ) - , H.viewIf (Perception.atLeast Perception.Good perceptionLevel) <| + [] + + pathTiles = + H.div + [ HA.class "absolute inset-0" ] + (List.map (pathTileView pathBgColor impassableTiles) + (Set.toList (Set.remove mouseCoords pathTaken)) + ) + + tooltip = H.div - [ HA.id "map-cost-info" + [ HA.class "w-fit whitespace-nowrap p-5 bg-green-900 relative z-[3]" + , HA.class pathTextColor + , HA.class "translate-x-[calc(var(--map-cell-size)*(0.5+var(--tile-coord-x))-50%)]" + , HA.class "translate-y-[calc(var(--map-cell-size)*var(--tile-coord-y)-100%-10px)]" , cssVars [ ( "--tile-coord-x", String.fromInt x ) , ( "--tile-coord-y", String.fromInt y ) @@ -1197,19 +1307,31 @@ mapView mouseCoords _ player = [ H.div [] [ H.text <| "Path cost: " ++ String.fromInt cost ++ " " ++ ticksString ] , H.viewIf tooDistant <| H.div [] [ H.text "You don't have enough ticks." ] - , H.viewIf shouldShowBigChunks <| - H.div [] [ H.text <| "Map tile difficulty: " ++ BigChunk.difficulty bigChunk ] + , H.viewIf canShowAreaDanger <| + H.div [] [ H.text <| "Map area danger: " ++ BigChunk.difficulty bigChunk ] ] ] + in + H.div + [ HA.class "absolute inset-0" ] + [ tileUnderCursor + , pathTiles + , tooltip + |> H.viewIf (Perception.atLeast Perception.Good perceptionLevel) ] - pathTileView : TileCoords -> Html FrontendMsg - pathTileView ( x, y ) = + pathTileView : String -> Set TileCoords -> TileCoords -> Html FrontendMsg + pathTileView pathBgColor impassableTiles (( x, y ) as coord) = H.div - [ HA.classList - [ ( "tile", True ) - , ( "map-path-tile", True ) - ] + [ HA.class + (if Set.member coord impassableTiles then + "bg-red" + + else + pathBgColor + ) + , HA.class "opacity-50 pointer-events-none z-[1]" + , tileClass , cssVars [ ( "--tile-coord-x", String.fromInt x ) , ( "--tile-coord-y", String.fromInt y ) @@ -1219,12 +1341,12 @@ mapView mouseCoords _ player = mouseCoordsOnly : Maybe TileCoords mouseCoordsOnly = - Maybe.map Tuple.first mouseCoords + Maybe.map Tuple.first mapMouseCoords mouseEventCatcherView : Html FrontendMsg mouseEventCatcherView = H.div - [ HA.id "map-mouse-event-catcher" + [ HA.class "absolute inset-0 z-[4]" , HE.stopPropagationOn "mouseover" (JD.map (\c -> ( MapMouseAtCoords c, True )) <| changedCoordsDecoder mouseCoordsOnly @@ -1259,8 +1381,7 @@ mapView mouseCoords _ player = bigChunkLayerView : () -> Html FrontendMsg bigChunkLayerView () = S.svg - [ HA.id "map-fog" - , SA.viewBox <| "0 0 " ++ String.fromInt Map.columns ++ " " ++ String.fromInt Map.rows + [ SA.viewBox <| "0 0 " ++ String.fromInt Map.columns ++ " " ++ String.fromInt Map.rows ] (BigChunk.all |> List.map @@ -1274,24 +1395,41 @@ mapView mouseCoords _ player = ) ) - shouldShowBigChunks : Bool - shouldShowBigChunks = + canShowAreaDanger : Bool + canShowAreaDanger = Perception.atLeast Perception.Perfect perceptionLevel + + showAreaDanger : Bool + showAreaDanger = + canShowAreaDanger && userWantsToShowAreaDanger in [ pageTitleView "Map" - , H.div - [ HA.id "map" - , cssVars - [ ( "--map-columns", String.fromInt Map.columns ) - , ( "--map-rows", String.fromInt Map.rows ) - , ( "--map-cell-size", String.fromInt Map.tileSize ++ "px" ) + , H.div [ HA.class "flex flex-col items-start gap-4" ] + [ H.viewIf canShowAreaDanger <| + UI.checkbox + { isOn = userWantsToShowAreaDanger + , toggle = SetShowAreaDanger + , label = "Show area danger levels" + } + , H.div + [ cssVars + [ ( "--map-columns", String.fromInt Map.columns ) + , ( "--map-rows", String.fromInt Map.rows ) + , ( "--map-cell-size", String.fromInt Map.tileSize ++ "px" ) + ] + , HA.class "relative bg-black bg-[url('/public/images/map_whole.webp')] bg-[0_0] bg-no-repeat select-none" + , HA.class "min-w-[calc(var(--map-columns)*var(--map-cell-size))]" + , HA.class "max-w-[calc(var(--map-columns)*var(--map-cell-size))]" + , HA.class "min-h-[calc(var(--map-rows)*var(--map-cell-size))]" + , HA.class "max-h-[calc(var(--map-rows)*var(--map-cell-size))]" + ] + [ locationsView (Just playerCoords) + , mapMarkerView playerCoords + , bigChunkLayerView + |> H.viewIfLazy showAreaDanger + , mouseEventCatcherView + , H.viewMaybe mouseRelatedView mapMouseCoords ] - ] - [ locationsView (Just playerCoords) - , mapMarkerView playerCoords - , H.viewIfLazy shouldShowBigChunks bigChunkLayerView - , mouseEventCatcherView - , H.viewMaybe mouseRelatedView mouseCoords ] ] @@ -1330,6 +1468,11 @@ svgPolygonForTiles color coords = [] +tileClass : Attribute msg +tileClass = + HA.class "absolute left-0 top-0 w-[var(--map-cell-size)] h-[var(--map-cell-size)] translate-x-[calc(var(--map-cell-size)*var(--tile-coord-x))] translate-y-[calc(var(--map-cell-size)*var(--tile-coord-y))]" + + locationView : Maybe TileCoords -> Location -> Html FrontendMsg locationView maybePlayer location = let @@ -1351,22 +1494,52 @@ locationView maybePlayer location = isCurrent : Bool isCurrent = maybePlayer == Just ( x, y ) + + borderWidth : String + borderWidth = + case size of + Location.Small -> + "border" + + Location.Middle -> + "border" + + Location.Large -> + "border-2" in H.div - [ HA.classList - [ ( "tile", True ) - , ( "map-location", True ) - , ( "small", size == Location.Small ) - , ( "middle", size == Location.Middle ) - , ( "large", size == Location.Large ) - , ( "has-vendor", hasVendor ) - , ( "is-current", isCurrent ) - ] + [ tileClass + , HA.class "opacity-50 text-green-100 absolute inset-0" + , HA.classList + [ ( "!opacity-100", hasVendor || isCurrent ) ] , HA.attribute "data-location-name" name - , cssVars - [ ( "--tile-coord-x", String.fromInt x ) - , ( "--tile-coord-y", String.fromInt y ) - ] + , TW.mod "hover" "opacity-100" + , TW.mod "before" <| + "absolute top-1/2 left-1/2 content-[''] block w-[var(--location-size)] h-[var(--location-size)] border-green-100 rounded-full -translate-x-1/2 -translate-y-1/2 bg-[radial-gradient(circle,var(--green-100-fully-transparent)_0%,var(--green-100-half-transparent)_100%)] " + ++ borderWidth + , TW.mod "after" "content-[attr(data-location-name)] block top-[var(--location-name-top)] left-1/2 -translate-x-1/2 text-center absolute whitespace-nowrap bg-black-transparent p-x-1 leading-[13px]" + , HA.style "text-shadow" "2px 0 2px #000, 0 2px 2px #000, -2px 0 2px #000, 0 -2px 2px #000" + , cssVars <| + List.concat + [ [ ( "--tile-coord-x", String.fromInt x ) + , ( "--tile-coord-y", String.fromInt y ) + ] + , case size of + Location.Small -> + [ ( "--location-size", "11px" ) + , ( "--location-name-top", "68%" ) + ] + + Location.Middle -> + [ ( "--location-size", "23px" ) + , ( "--location-name-top", "75%" ) + ] + + Location.Large -> + [ ( "--location-size", "45px" ) + , ( "--location-name-top", "100%" ) + ] + ] ] [] @@ -1375,7 +1548,7 @@ locationsView : Maybe TileCoords -> Html FrontendMsg locationsView maybePlayer = Location.allLocations |> List.map (locationView maybePlayer) - |> H.div [ HA.id "map-locations" ] + |> H.div [ HA.class "absolute inset-0 bg-black-transparent" ] changedCoordsDecoder : Maybe TileCoords -> Decoder TileCoords @@ -1407,12 +1580,14 @@ changedCoordsDecoder mouseCoords = mapMarkerView : TileCoords -> Html FrontendMsg mapMarkerView ( x, y ) = H.img - [ HA.class "map-marker" + [ HA.class "absolute left-0 top-0 z-[2]" + , HA.class "translate-x-[calc(var(--map-cell-size)*(0.5+var(--player-coord-x))-50%)]" + , HA.class "translate-y-[calc(var(--map-cell-size)*(0.5+var(--player-coord-y))-50%)]" , cssVars [ ( "--player-coord-x", String.fromInt x ) , ( "--player-coord-y", String.fromInt y ) ] - , HA.src "/images/map_marker.png" + , HA.src "/images/map_marker.webp" , HA.width 25 , HA.height 13 ] @@ -1430,15 +1605,21 @@ cssVars vars = mapLoggedOutView : List (Html FrontendMsg) mapLoggedOutView = [ pageTitleView "Map" - , H.div - [ HA.id "map" - , cssVars - [ ( "--map-columns", String.fromInt Map.columns ) - , ( "--map-rows", String.fromInt Map.rows ) - , ( "--map-cell-size", String.fromInt Map.tileSize ++ "px" ) + , H.div [ HA.class "flex flex-col items-start gap-4" ] + [ H.div + [ cssVars + [ ( "--map-columns", String.fromInt Map.columns ) + , ( "--map-rows", String.fromInt Map.rows ) + , ( "--map-cell-size", String.fromInt Map.tileSize ++ "px" ) + ] + , HA.class "relative bg-black bg-[url('/public/images/map_whole.webp')] bg-[0_0] bg-no-repeat select-none" + , HA.class "min-w-[calc(var(--map-columns)*var(--map-cell-size))]" + , HA.class "max-w-[calc(var(--map-columns)*var(--map-cell-size))]" + , HA.class "min-h-[calc(var(--map-rows)*var(--map-cell-size))]" + , HA.class "max-h-[calc(var(--map-rows)*var(--map-cell-size))]" ] + [ locationsView Nothing ] ] - [ locationsView Nothing ] ] @@ -1467,28 +1648,24 @@ questProgressbarView { ticksGiven, ticksNeeded, ticksGivenByPlayer } = emptyCount = totalCount - doneCount in - H.div [ HA.class "quest-progressbar" ] - [ H.span [] [ H.text "[" ] - , H.span [] [ H.text <| String.repeat doneCount "=" ++ String.repeat emptyCount "-" ] - , H.span [] [ H.text "]" ] - , H.span [ HA.class "quest-progressbar-text" ] - [ H.span - [ HA.class "quest-number" ] - [ H.text <| String.fromInt (round (percentDone * 100)) ++ "%" ] - , H.span [] [ H.text " done (" ] - , H.span - [ HA.class "quest-number" ] - [ H.text <| String.fromInt ticksGiven ] - , H.span [] [ H.text "/" ] - , H.span - [ HA.class "quest-number" ] - [ H.text <| String.fromInt ticksNeeded ] - , H.span [] [ H.text " ticks, you gave " ] - , H.span - [ HA.class "quest-number" ] - [ H.text <| String.fromInt ticksGivenByPlayer ] - , H.span [] [ H.text ")" ] + H.div [ HA.class "flex flex-row gap-[1ch]" ] + [ H.span [ HA.class "text-green-300" ] + [ H.text <| + "[" + ++ String.repeat doneCount "=" + ++ String.repeat emptyCount "-" + ++ "]" ] + , H.text <| + String.fromInt (round (percentDone * 100)) + ++ "%" + ++ " done (" + ++ String.fromInt ticksGiven + ++ "/" + ++ String.fromInt ticksNeeded + ++ " ticks, you gave " + ++ String.fromInt ticksGivenByPlayer + ++ ")" ] @@ -1504,24 +1681,25 @@ townMainSquareView expandedQuests location { questsProgress } player = not <| List.isEmpty quests in [ pageTitleView <| "Town: " ++ Location.name location - , if Vendor.isInLocation location then - H.div [] - [ H.button - [ HE.onClick GoToTownStore ] - [ H.text "[Visit store]" ] - ] + , H.div [ HA.class "flex flex-col gap-4" ] + [ if Vendor.isInLocation location then + H.div [] + [ UI.button + [ HE.onClick GoToTownStore ] + [ H.text "[Visit store]" ] + ] - else - H.div [] [ H.text "No vendor in this town..." ] - , if hasQuests then - H.h3 [] [ H.text "Quests" ] + else + H.div [] [ H.text "No vendor in this town..." ] + , if hasQuests then + H.h3 [] [ H.text "Quests" ] - else - H.text "No quests in this town..." - , H.viewIf hasQuests <| - H.ul - [ HA.class "quests" ] - (List.map (questView player questsProgress expandedQuests) quests) + else + H.text "No quests in this town..." + , H.viewIf hasQuests <| + H.ul [] + (List.map (questView player questsProgress expandedQuests) quests) + ] ] @@ -1538,17 +1716,8 @@ questView player questsProgress expandedQuests quest = Set_.member quest expandedQuests in H.li - [ HE.onClick - (if isExpanded then - CollapseQuestItem quest - - else - ExpandQuestItem quest - ) - , HA.classList - [ ( "quest", True ) - , ( "expanded", isExpanded ) - ] + [ HA.classList + [ ( "[&:not(:last-child)]:mb-5", isExpanded ) ] ] (if isExpanded then expandedQuestView player progress quest @@ -1560,7 +1729,16 @@ questView player questsProgress expandedQuests quest = collapsedQuestView : Quest.Name -> List (Html FrontendMsg) collapsedQuestView quest = - [ H.text <| Quest.title quest + [ H.span + [ HA.class "cursor-pointer" + , TW.mod "hover" "text-green-100" + , HE.onClick (ExpandQuestItem quest) + ] + [ H.span + [ HA.class "text-green-100 pr-2" ] + [ H.text "[+]" ] + , H.text <| Quest.title quest + ] ] @@ -1591,119 +1769,119 @@ expandedQuestView player progress quest = ticksNeeded = Quest.ticksNeeded quest in - [ H.div [ HA.class "quest-inner" ] + [ H.div [ HA.class "flex flex-col gap-[2ch]" ] [ H.div [] [ H.span - [ HA.class "quest-name" - , HE.onClick <| CollapseQuestItem quest + [ HE.onClick <| CollapseQuestItem quest + , HA.class "cursor-pointer" + , TW.mod "hover" "text-green-100" + ] + [ H.span + [ HA.class "text-green-100 pr-2" ] + [ H.text "[" + , H.span [ HA.class "min-w-[1ch] text-center inline-block" ] [ H.text "-" ] + , H.text "]" + ] + , H.text <| Quest.title quest ] - [ H.text <| Quest.title quest ] , if Set_.member quest player.questsActive then - H.button - [ HA.class "quest-toggle-btn" + UI.button + [ HA.class "ml-[1ch] !text-green-100" + , TW.mod "hover" "text-orange" , HE.onClickStopPropagation <| AskToStopProgressing quest ] [ H.text "[STOP]" ] else - H.button - [ HA.class "quest-toggle-btn" + UI.button + [ HA.class "ml-[1ch] !text-green-100" + , TW.mod "hover" "text-orange" , HE.onClickStopPropagation <| AskToStartProgressing quest ] [ H.text "[START]" ] ] - , questProgressbarView - { ticksGiven = progress.ticksGiven - , ticksNeeded = ticksNeeded - , ticksGivenByPlayer = progress.ticksGivenByPlayer - } - , H.div [ HA.class "quest-players" ] - [ H.span [] [ H.text "Players active: " ] - , H.span - [ HA.class "quest-number" ] - [ H.text <| String.fromInt progress.playersActive ] - , H.span [] [ H.text " (" ] - , H.span - [ HA.class "quest-number" ] - [ H.text <| String.fromInt progress.ticksPerHour ] - , H.span [] [ H.text " ticks/hour)" ] - ] - , H.div [ HA.class "quest-xp-per-tick" ] - [ H.text "XP per tick: " - , H.span - [ HA.class "quest-number" ] - [ H.text <| String.fromInt (Quest.xpPerTickGiven quest) ] - ] - , H.div - [ HA.class "quest-requirements-title" ] - [ H.text "Quest Requirements" ] - , if List.isEmpty questRequirements then - H.div - [ HA.class "quest-requirements-none" ] - [ H.text "NONE" ] + , H.div [ HA.class "bg-green-800 p-[2ch]" ] + [ questProgressbarView + { ticksGiven = progress.ticksGiven + , ticksNeeded = ticksNeeded + , ticksGivenByPlayer = progress.ticksGivenByPlayer + } + , H.div [] + [ H.text <| + "Players active: " + ++ String.fromInt progress.playersActive + ++ " (" + ++ String.fromInt progress.ticksPerHour + ++ " ticks/hour)" + ] + , H.div [] + [ H.text <| + "XP per tick: " + ++ String.fromInt (Quest.xpPerTickGiven quest) + ] + , H.div + [ HA.class "mt-5" ] + [ H.text "Quest Requirements" ] + , if List.isEmpty questRequirements then + H.div + [ HA.class "ml-[4ch]" ] + [ H.text "NONE" ] - else - H.ul - [ HA.class "quest-requirements-list" ] - (List.map (Quest.title >> liText) questRequirements) - , H.div - [ HA.class "quest-requirements-title" ] - [ H.text "Player Requirements" - , H.span - [ HA.class "deemphasized" ] - [ H.text " (affect ticks/hour)" ] - ] - , if List.isEmpty playerRequirements then - H.div - [ HA.class "quest-requirements-none" ] - [ H.text "NONE" ] + else + H.ul + [ HA.class "ps-[4ch]" ] + (List.map (Quest.title >> liText) questRequirements) + , H.div + [ HA.class "mt-5" ] + [ H.text "Player Requirements (affect ticks/hour)" ] + , if List.isEmpty playerRequirements then + H.div + [ HA.class "ml-[4ch]" ] + [ H.text "NONE" ] - else - H.ul - [ HA.class "quest-requirements-list" ] - (List.map (Quest.playerRequirementTitle >> liText) playerRequirements) - , H.div - [ HA.class "quest-requirements-title" ] - [ H.text "Global Rewards" ] - , if List.isEmpty globalRewards then - H.div - [ HA.class "quest-requirements-none" ] - [ H.text "NONE" ] + else + H.ul + [ HA.class "ps-[4ch]" ] + (List.map (Quest.playerRequirementTitle >> liText) playerRequirements) + , H.div + [ HA.class "mt-5" ] + [ H.text "Global Rewards" ] + , if List.isEmpty globalRewards then + H.div + [ HA.class "ml-[4ch]" ] + [ H.text "NONE" ] - else - H.ul - [ HA.class "quest-requirements-list" ] - (List.map (Quest.globalRewardTitle >> liText) globalRewards) - , H.div - [ HA.class "quest-requirements-title" ] - (if List.isEmpty playerRewards then - [ H.text "Player Rewards" ] + else + H.ul + [ HA.class "ps-[4ch]" ] + (List.map (Quest.globalRewardTitle >> liText) globalRewards) + , H.div + [ HA.class "mt-5" ] + (if List.isEmpty playerRewards then + [ H.text "Player Rewards" ] - else - [ H.text "Player Rewards" - , H.span - [ HA.class "deemphasized" ] - [ H.text " (if you give " ] - , H.span - [ HA.class "quest-number" ] - [ H.text <| - String.fromInt (Quest.ticksNeededForPlayerReward quest) - ++ "+" + else + [ H.text "Player Rewards" + , H.text " (if you give " + , H.span + [] + [ H.text <| + String.fromInt (Quest.ticksNeededForPlayerReward quest) + ++ "+" + ] + , H.text " ticks)" ] - , H.span - [ HA.class "deemphasized" ] - [ H.text " ticks)" ] - ] - ) - , if List.isEmpty playerRewards then - H.div - [ HA.class "quest-requirements-none" ] - [ H.text "NONE" ] + ) + , if List.isEmpty playerRewards then + H.div + [ HA.class "ml-[4ch]" ] + [ H.text "NONE" ] - else - H.ul - [ HA.class "quest-requirements-list" ] - (List.map (Quest.playerRewardTitle >> liText) playerRewards) + else + H.ul + [ HA.class "ps-[4ch]" ] + (List.map (Quest.playerRewardTitle >> liText) playerRewards) + ] ] ] @@ -1825,28 +2003,29 @@ townStoreView barter location world player = resetBtn : Html FrontendMsg resetBtn = - H.button - [ HA.id "town-store-reset-btn" + UI.button + [ HA.style "grid-area" "barter-reset-btn" , HE.onClick <| BarterMsg ResetBarter ] [ H.text "[Reset]" ] confirmBtn : Html FrontendMsg confirmBtn = - H.button - [ HA.id "town-store-confirm-btn" + UI.button + [ HA.style "grid-area" "barter-confirm-btn" , HE.onClick <| BarterMsg ConfirmBarter ] [ H.text "[Confirm]" ] capsView : - { class : String + { itemLabelClass : String + , gridArea : String , transfer : Int -> FrontendMsg , transferNPosition : Barter.TransferNPosition } -> Int -> Html FrontendMsg - capsView { class, transfer, transferNPosition } caps = + capsView { itemLabelClass, gridArea, transfer, transferNPosition } caps = let capsString : String capsString = @@ -1867,18 +2046,22 @@ townStoreView barter location world player = transferNView = H.div - [ HA.class "town-store-transfer-n-area" + [ HA.class "flex group" , HE.onMouseEnter <| BarterMsg <| SetTransferNHover transferNPosition , HE.onMouseLeave <| BarterMsg UnsetTransferNHover ] - [ H.button - [ HA.class "town-store-transfer-btn before-hover" + [ UI.button + [ HA.class "py-0.5 px-1 mx-1 bg-green-800 text-green-200 block" + , TW.mod "group-hover" "hidden" + , TW.mod "disabled" "text-green-300 opacity-50 pointer-events-none" + , TW.mod "[&:not(:disabled):hover]" "bg-green-300 text-green-100" , HA.disabled <| caps <= 0 , HA.title "Transfer N items" ] [ H.text "N" ] - , H.input - [ HA.class "town-store-transfer-n-input after-hover" + , UI.input + [ HA.class "w-10 bg-green-800 pl-[6px] hidden" + , TW.mod "group-hover" "block" , HA.value transferNValue , HE.onInput <| BarterMsg << SetTransferNInput transferNPosition , HA.title "Transfer N items" @@ -1886,54 +2069,62 @@ townStoreView barter location world player = [] , case String.toInt transferNValue of Nothing -> - H.button + UI.button [ HA.disabled True - , HA.class "town-store-transfer-btn after-hover" + , HA.class "py-0.5 px-1 mx-1 bg-green-800 text-green-200 hidden" + , TW.mod "disabled" "text-green-300 opacity-50 pointer-events-none" + , TW.mod "[&:not(:disabled):hover]" "bg-green-300 text-green-100" + , TW.mod "group-hover" "block" , HA.title "Transfer N items" ] [ H.text "OK" ] Just n -> - H.button + UI.button [ HE.onClick <| transfer n , HA.disabled <| n <= 0 || n > caps - , HA.class "town-store-transfer-btn after-hover" + , HA.class "py-0.5 px-1 mx-1 bg-green-800 text-green-200 hidden" + , TW.mod "disabled" "text-green-300 opacity-50 pointer-events-none" + , TW.mod "[&:not(:disabled):hover]" "bg-green-300 text-green-100" + , TW.mod "group-hover" "block" , HA.title "Transfer N items" ] [ H.text "OK" ] ] transferOneView = - H.button + UI.button [ HE.onClick <| transfer 1 , HA.disabled <| caps <= 0 - , HA.classList - [ ( "town-store-transfer-btn", True ) - , ( "hidden", isNHovered ) - ] + , HA.class "py-0.5 px-1 mx-1 bg-green-800 text-green-200" + , TW.mod "disabled" "text-green-300 opacity-50 pointer-events-none" + , TW.mod "[&:not(:disabled):hover]" "bg-green-300 text-green-100" + , HA.classList [ ( "hidden", isNHovered ) ] , HA.title "Transfer 1 item" ] [ H.text <| Barter.singleArrow arrowsDirection ] transferAllView = - H.button + UI.button [ HE.onClick <| transfer caps , HA.disabled <| caps <= 0 - , HA.classList - [ ( "town-store-transfer-btn", True ) - , ( "hidden", isNHovered ) - ] + , HA.class "py-0.5 px-1 mx-1 bg-green-800 text-green-200" + , TW.mod "disabled" "text-green-300 opacity-50 pointer-events-none" + , TW.mod "[&:not(:disabled):hover]" "bg-green-300 text-green-100" + , HA.classList [ ( "hidden", isNHovered ) ] , HA.title "Transfer all items" ] [ H.text <| Barter.doubleArrow arrowsDirection ] itemView = H.span - [ HA.class "town-store-item-label" ] + [ HA.class <| "flex-1 " ++ itemLabelClass ] [ H.text <| "Caps: $" ++ capsString ] in H.div - [ HA.class <| "town-store-item town-store-caps " ++ class + [ HA.class <| "flex items-center px-2 pt-1 pb-0.5" + , TW.mod "[&[data-caps='0']]" "text-green-300" + , HA.style "grid-area" gridArea , HA.attribute "data-caps" capsString ] <| @@ -1954,13 +2145,13 @@ townStoreView barter location world player = playerItemView : { items : Dict Item.Id Item - , class : String + , itemLabelClass : String , transfer : Item.Id -> Int -> FrontendMsg , transferNPosition : Item.Id -> Barter.TransferNPosition } -> ( Item.Id, Int ) -> Html FrontendMsg - playerItemView { items, class, transfer, transferNPosition } ( id, count ) = + playerItemView { items, itemLabelClass, transfer, transferNPosition } ( id, count ) = let itemName = case Dict.get id items of @@ -1989,18 +2180,22 @@ townStoreView barter location world player = transferNView = H.div - [ HA.class "town-store-transfer-n-area" + [ HA.class "flex group" , HE.onMouseEnter <| BarterMsg <| SetTransferNHover position , HE.onMouseLeave <| BarterMsg UnsetTransferNHover ] - [ H.button - [ HA.class "town-store-transfer-btn before-hover" + [ UI.button + [ HA.class "py-0.5 px-1 mx-1 bg-green-800 text-green-200 block" + , TW.mod "disabled" "text-green-300 opacity-50 pointer-events-none" + , TW.mod "[&:not(:disabled):hover]" "bg-green-300 text-green-100" + , TW.mod "group-hover" "hidden" , HA.disabled <| count <= 0 , HA.title "Transfer N items" ] [ H.text "N" ] - , H.input - [ HA.class "town-store-transfer-n-input after-hover" + , UI.input + [ HA.class "w-10 bg-green-800 pl-[6px] hidden" + , TW.mod "group-hover" "block" , HA.value transferNValue , HE.onInput <| BarterMsg << SetTransferNInput position , HA.title "Transfer N items" @@ -2008,53 +2203,59 @@ townStoreView barter location world player = [] , case String.toInt transferNValue of Nothing -> - H.button + UI.button [ HA.disabled True - , HA.class "town-store-transfer-btn after-hover" + , HA.class "py-0.5 px-1 mx-1 bg-green-800 text-green-200 hidden" + , TW.mod "disabled" "text-green-300 opacity-50 pointer-events-none" + , TW.mod "[&:not(:disabled):hover]" "bg-green-300 text-green-100" + , TW.mod "group-hover" "block" , HA.title "Transfer N items" ] [ H.text "OK" ] Just n -> - H.button + UI.button [ HE.onClick <| transfer id n , HA.disabled <| n <= 0 || n > count - , HA.class "town-store-transfer-btn after-hover" + , HA.class "py-0.5 px-1 mx-1 bg-green-800 text-green-200 hidden" + , TW.mod "disabled" "text-green-300 opacity-50 pointer-events-none" + , TW.mod "[&:not(:disabled):hover]" "bg-green-300 text-green-100" + , TW.mod "group-hover" "block" , HA.title "Transfer N items" ] [ H.text "OK" ] ] transferOneView = - H.button + UI.button [ HE.onClick <| transfer id 1 , HA.disabled <| count <= 0 - , HA.classList - [ ( "town-store-transfer-btn", True ) - , ( "hidden", isNHovered ) - ] + , HA.class "py-0.5 px-1 mx-1 bg-green-800 text-green-200" + , TW.mod "disabled" "text-green-300 opacity-50 pointer-events-none" + , TW.mod "[&:not(:disabled):hover]" "bg-green-300 text-green-100" + , HA.classList [ ( "hidden", isNHovered ) ] , HA.title "Transfer 1 item" ] [ H.text <| Barter.singleArrow arrowsDirection ] transferAllView = - H.button + UI.button [ HE.onClick <| transfer id count , HA.disabled <| count <= 0 - , HA.classList - [ ( "town-store-transfer-btn", True ) - , ( "hidden", isNHovered ) - ] + , HA.class "py-0.5 px-1 mx-1 bg-green-800 text-green-200" + , TW.mod "disabled" "text-green-300 opacity-50 pointer-events-none" + , TW.mod "[&:not(:disabled):hover]" "bg-green-300 text-green-100" + , HA.classList [ ( "hidden", isNHovered ) ] , HA.title "Transfer all items" ] [ H.text <| Barter.doubleArrow arrowsDirection ] itemView = H.span - [ HA.class "town-store-item-label" ] + [ HA.class <| "flex-1 " ++ itemLabelClass ] [ H.text <| String.fromInt count ++ "x " ++ itemName ] in - H.div [ HA.class <| "town-store-item " ++ class ] <| + H.div [ HA.class "flex items-center px-2 py-0.5" ] <| case arrowsDirection of Barter.ArrowLeft -> [ transferAllView @@ -2073,34 +2274,42 @@ townStoreView barter location world player = playerNameView : Html FrontendMsg playerNameView = H.div - [ HA.id "town-store-player-name" ] + [ HA.class "p-2 border-b-2 border-b-green-800" + , HA.style "grid-area" "player-name" + ] [ H.text <| "Player: " ++ player.name ] vendorNameView : Html FrontendMsg vendorNameView = H.div - [ HA.id "town-store-vendor-name" ] + [ HA.class "p-2 border-b-2 border-b-green-800 text-right" + , HA.style "grid-area" "vendor-name" + ] [ H.text <| "Vendor: " ++ Vendor.nameWithLocation vendor.name ] playerTradedValueView : Html FrontendMsg playerTradedValueView = H.div - [ HA.id "town-store-player-traded-value" ] + [ HA.class "text-green-100 text-center p-2" + , HA.style "grid-area" "player-traded-value" + ] [ H.text <| "Value: $" ++ String.fromInt playerTradedValue ] vendorTradedValueView : Html FrontendMsg vendorTradedValueView = H.div - [ HA.id "town-store-vendor-traded-value" ] + [ HA.class "text-green-100 text-center p-2" + , HA.style "grid-area" "vendor-traded-value" + ] [ H.text <| "Value: $" ++ String.fromInt vendorTradedValue ] playerKeptItemsView : Html FrontendMsg playerKeptItemsView = - H.div [ HA.id "town-store-player-kept-items" ] + H.div [ HA.style "grid-area" "player-kept-items" ] (List.map (playerItemView { items = player.items - , class = "player-kept-item" + , itemLabelClass = "" , transfer = \id count -> BarterMsg <| AddPlayerItem id count , transferNPosition = Barter.PlayerKeptItem } @@ -2110,11 +2319,11 @@ townStoreView barter location world player = playerTradedItemsView : Html FrontendMsg playerTradedItemsView = - H.div [ HA.id "town-store-player-traded-items" ] + H.div [ HA.style "grid-area" "player-traded-items" ] (List.map (playerItemView { items = player.items - , class = "player-traded-item" + , itemLabelClass = "ml-1" , transfer = \id count -> BarterMsg <| RemovePlayerItem id count , transferNPosition = Barter.PlayerTradedItem } @@ -2124,11 +2333,11 @@ townStoreView barter location world player = vendorKeptItemsView : Html FrontendMsg vendorKeptItemsView = - H.div [ HA.id "town-store-vendor-kept-items" ] + H.div [ HA.style "grid-area" "vendor-kept-items" ] (List.map (playerItemView { items = vendor.items - , class = "vendor-kept-item" + , itemLabelClass = "ml-1" , transfer = \id count -> BarterMsg <| AddVendorItem id count , transferNPosition = Barter.VendorKeptItem } @@ -2138,11 +2347,11 @@ townStoreView barter location world player = vendorTradedItemsView : Html FrontendMsg vendorTradedItemsView = - H.div [ HA.id "town-store-vendor-traded-items" ] + H.div [ HA.style "grid-area" "vendor-traded-items" ] (List.map (playerItemView { items = vendor.items - , class = "vendor-traded-item" + , itemLabelClass = "" , transfer = \id count -> BarterMsg <| RemoveVendorItem id count , transferNPosition = Barter.VendorTradedItem } @@ -2153,7 +2362,8 @@ townStoreView barter location world player = playerKeptCapsView : Html FrontendMsg playerKeptCapsView = capsView - { class = "player-kept-caps" + { itemLabelClass = "" + , gridArea = "player-kept-caps" , transfer = BarterMsg << AddPlayerCaps , transferNPosition = Barter.PlayerKeptCaps } @@ -2162,7 +2372,8 @@ townStoreView barter location world player = playerTradedCapsView : Html FrontendMsg playerTradedCapsView = capsView - { class = "player-traded-caps" + { itemLabelClass = "ml-1" + , gridArea = "player-traded-caps" , transfer = BarterMsg << RemovePlayerCaps , transferNPosition = Barter.PlayerTradedCaps } @@ -2171,7 +2382,8 @@ townStoreView barter location world player = vendorKeptCapsView : Html FrontendMsg vendorKeptCapsView = capsView - { class = "vendor-kept-caps" + { itemLabelClass = "ml-1" + , gridArea = "vendor-kept-caps" , transfer = BarterMsg << AddVendorCaps , transferNPosition = Barter.VendorKeptCaps } @@ -2180,7 +2392,8 @@ townStoreView barter location world player = vendorTradedCapsView : Html FrontendMsg vendorTradedCapsView = capsView - { class = "vendor-traded-caps" + { itemLabelClass = "" + , gridArea = "vendor-traded-caps" , transfer = BarterMsg << RemoveVendorCaps , transferNPosition = Barter.VendorTradedCaps } @@ -2188,11 +2401,19 @@ townStoreView barter location world player = playerTradedBg : Html FrontendMsg playerTradedBg = - H.div [ HA.id "town-store-player-traded-bg" ] [] + H.div + [ HA.style "grid-area" "2 / 2 / 5 / 3" + , HA.class "bg-green-800-half-transparent border-r border-r-green-800" + ] + [] vendorTradedBg : Html FrontendMsg vendorTradedBg = - H.div [ HA.id "town-store-vendor-traded-bg" ] [] + H.div + [ HA.style "grid-area" "2 / 3 / 5 / 4" + , HA.class "bg-green-800-half-transparent border-l border-l-green-800" + ] + [] gridContents : List (Html FrontendMsg) gridContents = @@ -2215,14 +2436,18 @@ townStoreView barter location world player = ] in [ pageTitleView <| "Store: " ++ Location.name location - , H.button + , UI.button [ HE.onClick (GoToRoute (PlayerRoute Route.TownMainSquare)) ] [ H.text "[Back]" ] - , H.div [ HA.id "town-store-grid" ] gridContents + , H.div + [ HA.class "mt-10 self-stretch grid grid-cols-[repeat(4,1fr)]" + , HA.class "town-store-grid" + ] + gridContents , H.viewMaybe (\message -> H.div - [ HA.id "town-store-barter-message" ] + [ HA.class "mt-10 text-orange" ] [ H.text <| Barter.messageText message ] ) barter.lastMessage @@ -2233,36 +2458,33 @@ newCharView : Maybe HoveredItem -> NewChar -> List (Html FrontendMsg) newCharView hoveredItem newChar = let createBtnView = - H.div [ HA.id "new-character-create-btn" ] - [ H.button + H.div [ HA.class "mt-10" ] + [ UI.button [ HE.onClick CreateChar ] - [ H.text "[Create]" ] + [ H.text "[ Create ]" ] ] errorView = H.viewMaybe (\error -> - H.div [ HA.id "new-character-error" ] + H.div [ HA.class "text-orange mt-5" ] [ H.text <| NewChar.error error ] ) newChar.error in [ pageTitleView "New Character" , H.div - [ HA.id "new-character-grid" ] - [ H.div - [ HA.class "new-character-column" ] + [ HA.class "grid grid-cols-[42ch_42ch_minmax(0,1fr)] gap-5" ] + [ H.div [ HA.class "flex flex-col gap-8" ] [ newCharSpecialView newChar , newCharTraitsView newChar.traits , createBtnView , errorView ] - , H.div - [ HA.class "new-character-column" ] + , H.div [ HA.class "flex flex-col gap-8" ] [ newCharSkillsView newChar ] - , H.div - [ HA.class "new-character-column" ] + , H.div [ HA.class "flex flex-col gap-8" ] [ newCharDerivedStatsView newChar , newCharHelpView hoveredItem ] @@ -2277,24 +2499,27 @@ newCharHelpView maybeHoveredItem = helpContent = case maybeHoveredItem of Nothing -> - H.p [] [ H.text "Hover over an item to show more information about it here!" ] + H.p + [ HA.class "max-w-[50ch] text-green-300" ] + [ H.text "Hover over an item to show more information about it here!" ] Just hoveredItem -> let { title, description } = HoveredItem.text hoveredItem in - H.div [] + H.div [ HA.class "max-w-[50ch]" ] [ H.h4 - [ HA.class "hovered-item-title" ] + [ HA.class "text-orange" ] [ H.text title ] - , Markdown.toHtml [] description + , -- TODO formatting of lists etc. + Markdown.toHtml [] description ] in H.div - [ HA.id "new-character-help" ] + [ HA.class "flex flex-col gap-4" ] [ H.h3 - [ HA.class "new-character-section-title" ] + [ HA.class "text-green-300" ] [ H.text "Help" ] , helpContent ] @@ -2311,22 +2536,28 @@ newCharDerivedStatsView newChar = , hasSmallFrameTrait = Trait.isSelected Trait.SmallFrame newChar.traits } - itemView : ( String, String, Maybe String ) -> Html FrontendMsg - itemView ( label, value, tooltip ) = + itemView : ( String, String, Maybe HoveredItem ) -> Html FrontendMsg + itemView ( label, value, hoveredItem ) = let - ( liAttrs, valueAttrs ) = - case tooltip of - Just tooltip_ -> - ( [ HA.title tooltip_ ] - , [ HA.class "has-tooltip" ] - ) + liAttrs = + case hoveredItem of + Just hoveredItem_ -> + [ HE.onMouseOver <| HoverItem hoveredItem_ + , HE.onMouseOut StopHoveringItem + ] Nothing -> - ( [], [] ) + [] in - H.li liAttrs - [ H.text <| label ++ ": " - , H.span valueAttrs [ H.text value ] + H.li + (TW.mod "hover" "bg-green-800" + :: liAttrs + ) + [ UI.liBullet + , H.text <| label ++ ": " + , H.span + [ HA.class "text-green-100" ] + [ H.text value ] ] perceptionLevel : PerceptionLevel @@ -2336,12 +2567,11 @@ newCharDerivedStatsView newChar = , hasAwarenessPerk = False } in - H.div - [ HA.id "new-character-derived-stats" ] + H.div [ HA.class "flex flex-col gap-4" ] [ H.h3 - [ HA.class "new-character-section-title" ] + [ HA.class "text-green-300" ] [ H.text "Derived stats" ] - , H.ul [ HA.id "new-character-derived-stats-list" ] <| + , H.ul [] <| List.map itemView [ ( "Hitpoints" , String.fromInt <| @@ -2364,7 +2594,7 @@ newCharDerivedStatsView newChar = ) , ( "Perception Level" , Perception.label perceptionLevel - , Just <| Perception.tooltip perceptionLevel + , Just <| HoveredPerceptionLevel perceptionLevel ) , ( "Action Points" , String.fromInt <| @@ -2395,36 +2625,40 @@ newCharSpecialView newChar = value = Special.get type_ finalSpecial in - H.tr - [ HA.class "character-special-attribute" - , HE.onMouseOver <| HoverItem <| HoveredSpecial type_ + H.div + [ HE.onMouseOver <| HoverItem <| HoveredSpecial type_ , HE.onMouseOut StopHoveringItem + , HA.class "contents group" ] - [ H.td - [ HA.class "character-special-attribute-dec" ] - [ H.button + [ H.div [] + [ UI.button [ HE.onClick <| NewCharDecSpecial type_ , HA.disabled <| not <| Special.canDecrement type_ finalSpecial + , HA.class "!text-green-100" + , TW.mod "disabled" "!text-green-300 cursor-not-allowed" + , TW.mod "[&:not(:disabled):hover]" "!text-orange" + , TW.mod "group-hover" "bg-green-800" ] [ H.text "[-]" ] ] - , H.td - [ HA.class "character-special-attribute-label" ] + , H.div + [ HA.class "px-[1ch]" + , TW.mod "group-hover" "text-green-100 bg-green-800" + ] [ H.text <| Special.label type_ ] - , H.td - [ HA.classList - [ ( "character-special-attribute-value", True ) - , ( "out-of-range", not <| Special.isValueInRange value ) - ] + , H.div + [ HA.class "pr-[1ch] text-right" + , HA.classList [ ( "!text-orange", not <| Special.isValueInRange value ) ] + , TW.mod "group-hover" "text-green-100 bg-green-800" ] [ H.text <| String.fromInt value ] - , H.td - [ HA.class "character-special-attribute-inc" ] - [ H.button + , H.div + [] + [ UI.button [ HE.onClick <| NewCharIncSpecial type_ , HA.disabled <| not <| @@ -2432,25 +2666,30 @@ newCharSpecialView newChar = newChar.availableSpecial type_ finalSpecial + , HA.class "!text-green-100" + , TW.mod "disabled" "!text-green-300 cursor-not-allowed" + , TW.mod "[&:not(:disabled):hover]" "!text-orange" + , TW.mod "group-hover" "bg-green-800" ] [ H.text "[+]" ] ] ] in H.div - [ HA.id "new-character-special" ] + [ HA.class "flex flex-col gap-4" ] [ H.h3 - [ HA.class "new-character-section-title" ] + [ HA.class "text-green-300" ] [ H.text "SPECIAL (" , H.span - [ HA.class "new-character-section-available-number" ] + [ HA.class "text-orange" ] [ H.text <| String.fromInt newChar.availableSpecial ] , H.text " points left)" ] - , H.table - [ HA.id "character-special-table" ] + , H.div [ HA.class "grid grid-cols-[3ch_13ch_3ch_3ch] auto-rows-auto" ] (List.map specialItemView Special.all) - , H.p [] [ H.text "Distribute your SPECIAL points (each attribute can be in range 1..10)." ] + , H.p + [ HA.class "text-green-300" ] + [ H.text "Distribute your SPECIAL points (each attribute can be in range 1..10)." ] ] @@ -2467,46 +2706,41 @@ newCharTraitsView traits = isToggled : Bool isToggled = Set_.member trait traits - - buttonLabel : String - buttonLabel = - if isToggled then - "[*]" - - else - "[ ]" in H.li - [ HA.classList - [ ( "new-character-traits-trait", True ) - , ( "is-toggled", isToggled ) - ] + [ HA.class "flex flex-row gap-[1ch] pr-[2ch] justify-start cursor-pointer group" + , TW.mod "hover" "text-orange bg-green-800" + , HA.classList [ ( "text-orange", isToggled ) ] , HE.onClick <| NewCharToggleTrait trait , HE.onMouseOver <| HoverItem <| HoveredTrait trait , HE.onMouseOut StopHoveringItem ] - [ H.button + [ UI.button [ HE.onClickStopPropagation <| NewCharToggleTrait trait - , HA.class "new-character-trait-tag-btn" + , HA.class "!text-green-100" + , HA.classList [ ( "!text-orange", isToggled ) ] + , TW.mod "group-hover" "!text-orange bg-green-800" ] - [ H.text buttonLabel ] + [ H.text <| UI.checkboxLabel isToggled ] , H.div [] [ H.text <| Trait.name trait ] ] in H.div - [ HA.id "new-character-traits" ] + [ HA.class "flex flex-col gap-4" ] [ H.h3 - [ HA.class "new-character-section-title" ] + [ HA.class "text-green-300" ] [ H.text "Traits (" , H.span - [ HA.class "new-character-section-available-number" ] + [ HA.class "text-orange" ] [ H.text <| String.fromInt availableTraits ] , H.text " available)" ] , H.ul - [ HA.id "new-character-traits-list" ] + [ HA.class "w-max grid grid-cols-2 gap-x-[2ch]" ] (List.map traitView Trait.all) - , H.p [] [ H.text "Select up to two traits." ] + , H.p + [ HA.class "text-green-300" ] + [ H.text "Select up to two traits." ] ] @@ -2533,7 +2767,6 @@ newCharSkillsView newChar = , hasTagPerk = False , availableSkillPoints = 0 , isNewChar = True - , id = "new-character-skills" } @@ -2568,21 +2801,24 @@ choosePerkView maybeHoveredItem applicablePerks = perkView perk = H.li [ HE.onClick <| AskToChoosePerk perk - , HA.class "character-choose-perk-item" + , HA.class "cursor-pointer group" , HE.onMouseOver <| HoverItem <| HoveredPerk perk , HE.onMouseOut StopHoveringItem ] - [ H.text <| Perk.name perk ] + [ UI.liBullet + , H.span + [ TW.mod "group-hover" "text-orange" + ] + [ H.text <| Perk.name perk ] + ] in H.div - [ HA.id "character-choose-perk" ] + [ HA.class "flex-1 flex flex-col self-stretch" ] [ H.div - [ HA.id "character-choose-perk-columns" ] - [ H.div [] + [ HA.class "flex-1 grid grid-cols-[minmax(0,max-content)_minmax(0,60ch)] gap-8" ] + [ H.div [ HA.class "flex flex-col gap-4" ] [ H.h3 [] [ H.text "Choose a perk!" ] - , H.ul - [ HA.id "character-choose-perk-list" ] - (List.map perkView applicablePerks) + , H.ul [] (List.map perkView applicablePerks) ] , H.viewMaybe perkDescriptionView maybeHoveredItem ] @@ -2605,19 +2841,16 @@ perkDescriptionView hoveredItem = normalCharacterView : Maybe HoveredItem -> CPlayer -> Html FrontendMsg normalCharacterView maybeHoveredItem player = H.div - [ HA.id "character-grid" ] - [ H.div - [ HA.class "character-column" ] + [ HA.class "grid grid-cols-[24ch_34ch_minmax(0,1fr)] gap-5" ] + [ H.div [ HA.class "flex flex-col gap-8" ] [ charSpecialView player , charTraitsView player.traits , charPerksView player.perks ] - , H.div - [ HA.class "character-column" ] + , H.div [ HA.class "flex flex-col gap-8" ] [ charSkillsView player ] - , H.div - [ HA.class "character-column" ] + , H.div [ HA.class "flex flex-col gap-8" ] [ charDerivedStatsView player , charHelpView maybeHoveredItem ] @@ -2630,23 +2863,27 @@ charTraitsView traits = itemView : Trait -> Html FrontendMsg itemView trait = H.li - [ HA.class "character-traits-trait" + [ HA.class "pr-[2ch]" + , TW.mod "hover" "text-green-100 bg-green-800" , HE.onMouseOver <| HoverItem <| HoveredTrait trait , HE.onMouseOut StopHoveringItem ] - [ H.text <| Trait.name trait ] + [ UI.liBullet + , H.text <| Trait.name trait + ] in H.div - [ HA.id "character-traits" ] + [ HA.class "flex flex-col" ] [ H.h3 - [ HA.class "character-section-title" ] + [ HA.class "text-green-300" ] [ H.text "Traits" ] , if Set_.isEmpty traits then - H.p [] [ H.text "You have no traits." ] + H.p + [ HA.class "text-green-300" ] + [ H.text "You have no traits." ] else - H.ul - [ HA.id "character-traits-list" ] + H.ul [ HA.class "w-fit" ] (List.map itemView <| Set_.toList traits) ] @@ -2658,24 +2895,26 @@ charHelpView maybeHoveredItem = helpContent = case maybeHoveredItem of Nothing -> - H.p [] [ H.text "Hover over an item to show more information about it here!" ] + H.p + [ HA.class "max-w-[50ch] text-green-300" ] + [ H.text "Hover over an item to show more information about it here!" ] Just hoveredItem -> let { title, description } = HoveredItem.text hoveredItem in - H.div [] + H.div [ HA.class "max-w-[50ch]" ] [ H.h4 - [ HA.class "hovered-item-title" ] + [ HA.class "text-orange" ] [ H.text title ] , Markdown.toHtml [] description ] in H.div - [ HA.id "character-help" ] + [ HA.class "flex flex-col gap-4" ] [ H.h3 - [ HA.class "character-section-title" ] + [ HA.class "text-green-300" ] [ H.text "Help" ] , helpContent ] @@ -2684,22 +2923,28 @@ charHelpView maybeHoveredItem = charDerivedStatsView : CPlayer -> Html FrontendMsg charDerivedStatsView player = let - itemView : ( String, String, Maybe String ) -> Html FrontendMsg - itemView ( label, value, tooltip ) = + itemView : ( String, String, Maybe HoveredItem ) -> Html FrontendMsg + itemView ( label, value, hoveredItem ) = let - ( liAttrs, valueAttrs ) = - case tooltip of - Just tooltip_ -> - ( [ HA.title tooltip_ ] - , [ HA.class "has-tooltip" ] - ) + liAttrs = + case hoveredItem of + Just hoveredItem_ -> + [ HE.onMouseOver <| HoverItem hoveredItem_ + , HE.onMouseOut StopHoveringItem + ] Nothing -> - ( [], [] ) + [] in - H.li liAttrs - [ H.text <| label ++ ": " - , H.span valueAttrs [ H.text value ] + H.li + (TW.mod "hover" "bg-green-800" + :: liAttrs + ) + [ UI.liBullet + , H.text <| label ++ ": " + , H.span + [ HA.class "text-green-100" ] + [ H.text value ] ] perceptionLevel : PerceptionLevel @@ -2709,12 +2954,11 @@ charDerivedStatsView player = , hasAwarenessPerk = Perk.rank Perk.Awareness player.perks > 0 } in - H.div - [ HA.id "character-derived-stats" ] + H.div [ HA.class "flex flex-col gap-4" ] [ H.h3 - [ HA.class "character-section-title" ] + [ HA.class "text-green-300" ] [ H.text "Derived stats" ] - , H.ul [ HA.id "character-derived-stats-list" ] <| + , H.ul [] <| List.map itemView [ ( "Max HP" , String.fromInt <| @@ -2744,7 +2988,7 @@ charDerivedStatsView player = ) , ( "Perception Level" , Perception.label perceptionLevel - , Just <| Perception.tooltip perceptionLevel + , Just <| HoveredPerceptionLevel perceptionLevel ) , ( "Action Points" , String.fromInt <| @@ -2767,29 +3011,30 @@ charSpecialView player = value = Special.get type_ player.special in - H.tr - [ HA.class "character-special-attribute" - , HE.onMouseOver <| HoverItem <| HoveredSpecial type_ + H.div + [ HE.onMouseOver <| HoverItem <| HoveredSpecial type_ , HE.onMouseOut StopHoveringItem + , HA.class "contents group" ] - [ H.td - [ HA.class "character-special-attribute-label" ] + [ H.div + [ HA.class "px-[1ch]" + , TW.mod "group-hover" "text-green-100 bg-green-800" + ] [ H.text <| Special.label type_ ] - , H.td - [ HA.class "character-special-attribute-value" - + , H.div -- TODO highlighted if addiction etc? + [ HA.class "text-right pr-[1ch]" + , TW.mod "group-hover" "text-green-100 bg-green-800" ] [ H.text <| String.fromInt value ] ] in H.div - [ HA.id "character-special" ] + [ HA.class "flex flex-col gap-4" ] [ H.h3 - [ HA.class "character-section-title" ] + [ HA.class "text-green-300" ] [ H.text "SPECIAL" ] - , H.table - [ HA.id "character-special-table" ] + , H.div [ HA.class "grid grid-cols-[13ch_3ch]" ] (List.map specialItemView Special.all) ] @@ -2801,7 +3046,6 @@ skillsView_ : , hasTagPerk : Bool , availableSkillPoints : Int , isNewChar : Bool - , id : String } -> Html FrontendMsg skillsView_ r = @@ -2837,95 +3081,114 @@ skillsView_ r = isTagged = Set_.member skill r.taggedSkills - ( showTagButton, isTaggingDisabled, tagButtonLabel ) = + ( showTagButton, isTaggingDisabled ) = case ( r.isNewChar, isTagged ) of ( True, True ) -> - ( True, False, "[*]" ) + ( True, False ) ( True, False ) -> - ( True, availableTags == 0, "[ ]" ) + ( True, availableTags == 0 ) ( False, True ) -> - ( availableTags > 0, True, "[*]" ) + ( availableTags > 0, True ) ( False, False ) -> - ( availableTags > 0, availableTags == 0, "[ ]" ) + ( availableTags > 0, availableTags == 0 ) isIncButtonDisabled : Bool isIncButtonDisabled = r.availableSkillPoints <= 0 + + isTaggable : Bool + isTaggable = + showTagButton && not isTaggingDisabled + + hoverTextColor : String + hoverTextColor = + if r.isNewChar then + "text-orange" + + else + "text-green-100" in - H.li - [ HA.classList - [ ( "character-skills-skill", True ) - , ( "not-useful", notUseful ) - , ( "is-tagged", isTagged ) - , ( "is-taggable", showTagButton && not isTaggingDisabled ) + H.div + [ HA.class "contents group" + , TW.mod "hover" hoverTextColor + , HA.classList + [ ( "text-green-300", notUseful ) + , ( "text-orange", isTagged ) + , ( "cursor-pointer", isTaggable ) ] , HA.attributeIf (not isTaggingDisabled) <| HE.onClick <| onTag skill , HE.onMouseOver <| HoverItem <| HoveredSkill skill , HE.onMouseOut StopHoveringItem ] - [ H.div - [ HA.class "character-skill-name" ] - [ H.viewIf showTagButton <| - H.button - [ HE.onClickStopPropagation <| onTag skill - , HA.disabled isTaggingDisabled - , HA.class "character-skill-tag-btn" + [ H.viewIf showTagButton <| + UI.button + [ HE.onClickStopPropagation <| onTag skill + , HA.disabled isTaggingDisabled + , HA.class "!text-green-100 px-[1ch]" + , HA.classList + [ ( "!text-orange", isTagged ) + , ( "!text-green-300", notUseful ) ] - [ H.text tagButtonLabel ] - , H.text <| Skill.name skill + , TW.mod "group-hover" "!text-orange bg-green-800" + ] + [ H.text <| UI.checkboxLabel isTagged ] + , H.div + [ HA.class "pr-[1ch]" + , HA.classList [ ( "pl-[1ch]", not showTagButton ) ] + , TW.mod "group-hover" "bg-green-800" ] + [ H.text <| Skill.name skill ] , H.div - [ HA.class "character-skill-value" ] - [ H.div - [ HA.class "character-skill-percent" ] - [ H.text <| String.fromInt percent ++ "%" ] - , H.viewIf (not r.isNewChar) <| - H.button - [ HE.onClickStopPropagation <| AskToUseSkillPoints skill - , HA.class "character-skill-inc-btn" - , HA.disabled isIncButtonDisabled - , HA.attributeIf isIncButtonDisabled <| - HA.title "You have no skill points available." - ] - [ H.text "[+]" ] + [ HA.class "text-right" + , TW.mod "group-hover" "bg-green-800" ] + [ H.text <| String.fromInt percent ++ "%" ] + , H.viewIf (not r.isNewChar) <| + UI.button + [ HE.onClickStopPropagation <| AskToUseSkillPoints skill + , HA.disabled isIncButtonDisabled + , HA.attributeIf isIncButtonDisabled <| + HA.title "You have no skill points available." + , HA.class "pl-[1ch]" + , TW.mod "[&:not(:disabled):hover]" "!text-green-100 cursor-pointer" + , TW.mod "disabled" "cursor-not-allowed opacity-50" + , TW.mod "group-hover" "bg-green-800" + ] + [ H.text "[+]" ] ] in if r.isNewChar then H.div - [ HA.id r.id ] + [ HA.class "flex flex-col gap-4" ] [ H.h3 - [ HA.class "new-character-section-title" ] + [ HA.class "text-green-300" ] [ H.text "Skills (" , H.span - [ HA.class "new-character-section-available-number" ] + [ HA.class "text-orange" ] [ H.text <| String.fromInt availableTags ] , H.text " tags left)" ] - , H.ul - [ HA.id "character-skills-list" ] + , H.div [ HA.class "grid grid-cols-[5ch_16ch_minmax(auto,5ch)]" ] (List.map skillView Skill.all) - , H.p [] [ H.text "Tag three skills. Dimmed skills are not yet useful in the game." ] + , H.p + [ HA.class "text-green-300" ] + [ H.text "Tag three skills. Dimmed skills are not yet useful in the game." ] ] else - H.div - [ HA.id r.id - , HA.classList [ ( "cannot-inc", r.availableSkillPoints <= 0 ) ] - ] + H.div [ HA.class "flex flex-col gap-4" ] [ H.h3 - [ HA.class "character-section-title" ] + [ HA.class "text-green-300" ] [ H.text "Skills (" , H.span - [ HA.class "character-section-available-number" ] + [ HA.class "text-orange" ] [ H.text <| String.fromInt r.availableSkillPoints ] , H.text " points available)" ] - , H.ul - [ HA.id "character-skills-list" ] + , H.div [ HA.class "grid grid-cols-[16ch_minmax(auto,5ch)_4ch]" ] (List.map skillView Skill.all) , H.viewIf (availableTags > 0) <| H.p [] [ H.text <| "Tags available: " ++ String.fromInt availableTags ] @@ -2941,7 +3204,6 @@ charSkillsView player = , hasTagPerk = Perk.rank Perk.Tag player.perks > 0 , availableSkillPoints = player.availableSkillPoints , isNewChar = False - , id = "character-skills" } @@ -2956,11 +3218,13 @@ charPerksView perks = Perk.maxRank perk in H.li - [ HA.class "character-perks-perk" - , HE.onMouseOver <| HoverItem <| HoveredPerk perk + [ HE.onMouseOver <| HoverItem <| HoveredPerk perk , HE.onMouseOut StopHoveringItem + , HA.class "pr-[2ch]" + , TW.mod "hover" "text-green-100 bg-green-800" ] - [ H.text <| + [ UI.liBullet + , H.text <| if maxRank == 1 then Perk.name perk @@ -2968,17 +3232,15 @@ charPerksView perks = Perk.name perk ++ " (" ++ String.fromInt rank ++ "x)" ] in - H.div - [ HA.id "character-perks" ] + H.div [] [ H.h3 - [ HA.class "character-section-title" ] + [ HA.class "text-green-300" ] [ H.text "Perks" ] , if Dict_.isEmpty perks then H.p [] [ H.text "No perks yet!" ] else - H.ul - [ HA.id "character-perks-list" ] + H.ul [] (List.map itemView <| Dict_.toList perks) ] @@ -3024,21 +3286,20 @@ inventoryView _ player = ( True, Just "You're at full HP." ) in H.li - [ HA.class "inventory-item" - , HA.attributeMaybe HA.title tooltip - ] - [ H.button - [ HA.class "inventory-item-use-btn" - , HE.onClick <| AskToUseItem item.id - , HA.disabled isDisabled - ] - [ H.text "[Use]" ] - , H.viewIf (Item.isEquippable item.kind) <| - H.button - [ HA.class "inventory-item-equip-btn" - , HE.onClick <| AskToEquipItem item.id + [ HA.class "flex flex-row gap-[1ch]" ] + [ UI.liBullet + , H.span + [ HA.class "flex flex-row gap-[2ch]" ] + [ UI.button + [ HE.onClick <| AskToUseItem item.id + , HA.disabled isDisabled ] - [ H.text "[Equip]" ] + [ H.text "[Use]" ] + , H.viewIf (Item.isEquippable item.kind) <| + UI.button + [ HE.onClick <| AskToEquipItem item.id ] + [ H.text "[Equip]" ] + ] , H.span [ HA.class "inventory-item-label" ] [ H.text <| String.fromInt item.count ++ "x " ++ Item.name item.kind ] @@ -3098,61 +3359,102 @@ inventoryView _ player = } in [ pageTitleView "Inventory" - , H.p [] [ H.text <| "Total value: $" ++ String.fromInt totalValue ] - , if Dict.isEmpty player.items then - H.p [] [ H.text "You have no items!" ] + , H.div [ HA.class "flex flex-col gap-4" ] + [ H.p [] + [ H.text <| "Total value: " + , H.span [ HA.class "text-green-100" ] [ H.text <| "$" ++ String.fromInt totalValue ] + ] + , H.h3 + [ HA.class "text-green-300" ] + [ H.text "Items" ] + , if Dict.isEmpty player.items then + H.p [] [ H.text "You have no items!" ] - else - H.ul - [ HA.id "inventory-list" ] - (player.items - |> Dict.values - |> List.sortBy - (\{ kind } -> - ( Item.typeName (Item.type_ kind) - , Item.baseValue kind - , Item.name kind + else + H.ul [] + (player.items + |> Dict.values + |> List.sortBy + (\{ kind } -> + ( Item.typeName (Item.type_ kind) + , Item.baseValue kind + , Item.name kind + ) ) - ) - |> List.map itemView - ) - , H.h3 - [ HA.id "inventory-equipment" ] - [ H.text "Equipment" ] - , H.div - [ HA.id "inventory-equipment-armor" ] - [ H.text "Armor: " - , case player.equippedArmor of - Nothing -> - H.text "None" - - Just armor -> - H.span [] - [ H.text <| Item.name armor.kind - , H.button - [ HE.onClick AskToUnequipArmor - , HA.class "inventory-equipment-unequip-btn" + |> List.map itemView + ) + , H.h3 + [ HA.class "text-green-300" ] + [ H.text "Equipment" ] + , H.div [] + [ UI.liBullet + , H.text "Armor: " + , H.span [ HA.class "text-green-100" ] <| + case player.equippedArmor of + Nothing -> + [ H.text "None" ] + + Just armor -> + [ H.text <| Item.name armor.kind + , UI.button + [ HE.onClick AskToUnequipArmor + , HA.class "ml-[1ch]" + ] + [ H.text "[Unequip]" ] ] - [ H.text "[Unequip]" ] - ] - ] - , H.h3 - [ HA.id "inventory-stats" ] - [ H.text "Defence stats" ] - , H.ul - [] - [ H.li [] [ H.text <| "Armor Class: " ++ String.fromInt armorClass ] - , H.li [] [ H.text <| "Damage Threshold: " ++ String.fromInt damageThreshold ] - , H.li [] [ H.text <| "Damage Resistance: " ++ String.fromInt damageResistance ] - ] - , H.h3 - [ HA.id "inventory-stats" ] - [ H.text "Attack stats" ] - , H.ul - [] - [ H.li [] [ H.text <| "Min Damage: " ++ String.fromInt attackStats.minDamage ] - , H.li [] [ H.text <| "Max Damage: " ++ String.fromInt attackStats.maxDamage ] - , H.li [] [ H.text <| "Chance to hit at target armor class 0: " ++ String.fromInt chanceToHitAtArmorClass0 ++ "%" ] + ] + , H.h3 + [ HA.class "text-green-300" ] + [ H.text "Defence stats" ] + , H.ul [] + [ H.li [] + [ UI.liBullet + , H.text "Armor Class: " + , H.span + [ HA.class "text-green-100" ] + [ H.text <| String.fromInt armorClass ] + ] + , H.li [] + [ UI.liBullet + , H.text "Damage Threshold: " + , H.span + [ HA.class "text-green-100" ] + [ H.text <| String.fromInt damageThreshold ] + ] + , H.li [] + [ UI.liBullet + , H.text "Damage Resistance: " + , H.span + [ HA.class "text-green-100" ] + [ H.text <| String.fromInt damageResistance ] + ] + ] + , H.h3 + [ HA.class "text-green-300" ] + [ H.text "Attack stats" ] + , H.ul [] + [ H.li [] + [ UI.liBullet + , H.text "Min Damage: " + , H.span + [ HA.class "text-green-100" ] + [ H.text <| String.fromInt attackStats.minDamage ] + ] + , H.li [] + [ UI.liBullet + , H.text "Max Damage: " + , H.span + [ HA.class "text-green-100" ] + [ H.text <| String.fromInt attackStats.maxDamage ] + ] + , H.li [] + [ UI.liBullet + , H.text "Chance to hit at target armor class 0: " + , H.span + [ HA.class "text-green-100" ] + [ H.text <| String.fromInt chanceToHitAtArmorClass0 ++ "%" ] + ] + ] ] ] @@ -3160,81 +3462,65 @@ inventoryView _ player = messagesView : Posix -> Time.Zone -> PlayerData -> CPlayer -> List (Html FrontendMsg) messagesView currentTime zone _ player = [ pageTitleView "Messages" - , H.table [ HA.id "messages-table" ] - [ H.thead [] - [ H.tr [] - [ H.th - [ HA.class "messages-unread" - , HA.title "Unread" - ] - [ H.text "U" ] - , H.th [ HA.class "messages-summary" ] [ H.text "Summary" ] - , H.th [ HA.class "messages-date" ] [ H.text "Date" ] - , H.th - [ HA.class "messages-remove" - , HA.title "Remove" + , H.div [ HA.class "flex flex-col gap-4" ] + [ H.table [ HA.id "messages-table" ] + [ H.thead [] + [ H.tr [] + [ H.th [ HA.title "Unread" ] [ H.text "U" ] + , H.th [] [ H.text "Summary" ] + , H.th [] [ H.text "Date" ] + , H.th [ HA.title "Remove" ] [ H.text "X" ] ] - [ H.text "✗" ] ] - ] - , H.tbody [] - (player.messages - |> Dict.values - |> List.sortBy (.id >> negate) - |> List.map - (\message -> - let - isUnread : Bool - isUnread = - not message.hasBeenRead - - summary : String - summary = - Message.summary message - - relativeDate : String - relativeDate = - DateFormat.Relative.relativeTime - currentTime - message.date - in - H.tr - [ HA.classList [ ( "is-unread", isUnread ) ] - , HE.onClick <| OpenMessage message.id - ] - [ if isUnread then - H.td - [ HA.class "messages-unread" - , HA.title "Unread" - ] - [ H.text "*" ] - - else - H.td [ HA.class "messages-unread" ] [] - , H.td - [ HA.class "messages-summary" - , HA.title summary - ] - [ H.text summary ] - , H.td - [ HA.class "messages-date" - , HA.title <| Message.fullDate zone message + , H.tbody [] + (player.messages + |> Dict.values + |> List.sortBy (.id >> negate) + |> List.map + (\message -> + let + isUnread : Bool + isUnread = + not message.hasBeenRead + + summary : String + summary = + Message.summary message + + relativeDate : String + relativeDate = + DateFormat.Relative.relativeTime + currentTime + message.date + in + H.tr + [ HA.classList [ ( "text-green-100", isUnread ) ] + , HE.onClick <| OpenMessage message.id ] - [ H.text relativeDate ] - , H.td - [ HA.class "messages-remove" - , HA.title "Remove" - , HE.onClickStopPropagation <| AskToRemoveMessage message.id + [ if isUnread then + H.td [ HA.title "Unread" ] [ H.text "*" ] + + else + H.td [] [] + , H.td + [ HA.title summary ] + [ H.text summary ] + , H.td + [ HA.title <| Message.fullDate zone message ] + [ H.text relativeDate ] + , H.td + [ TW.mod "hover" "text-orange" + , HA.title "Remove" + , HE.onClickStopPropagation <| AskToRemoveMessage message.id + ] + [ H.text "X" ] ] - [ H.text "✗" ] - ] - ) - ) + ) + ) + ] + , H.viewIf (Dict.isEmpty player.messages) <| + H.div [] [ H.text "No messages right now!" ] ] - , H.viewIf (Dict.isEmpty player.messages) <| - H.div - [ HA.id "messages-empty-note" ] - [ H.text "No messages right now!" ] ] @@ -3256,21 +3542,23 @@ messageView zone messageId _ player = } in [ pageTitleView "Message" - , H.h3 - [ HA.id "message-summary" ] - [ H.text <| Message.summary message ] - , H.div - [ HA.id "message-date" ] - [ H.text <| Message.fullDate zone message ] - , Message.content - [ HA.id "message-content" ] - perceptionLevel - message - , H.button - [ HE.onClick <| GoToRoute (PlayerRoute Route.Messages) - , HA.id "message-back-button" + , H.div [ HA.class "flex flex-col gap-4" ] + [ H.div [ HA.class "flex flex-col items-start" ] + [ H.h3 + [ HA.class "m-0 text-green-100 font-bold" ] + [ H.text <| Message.summary message ] + , H.div + [ HA.class "text-green-300" ] + [ H.text <| Message.fullDate zone message ] + , UI.button + [ HE.onClick <| GoToRoute (PlayerRoute Route.Messages) ] + [ H.text "[Back]" ] + ] + , Message.content + [ HA.class "max-w-[70ch]" ] + perceptionLevel + message ] - [ H.text "[Back]" ] ] @@ -3285,7 +3573,7 @@ settingsFightStrategySyntaxHelpView maybeHoveredItem = FightStrategyHelp.Reference reference -> H.span - [ HA.class "fight-strategy-syntax-help-reference" + [ HA.class "text-orange font-mono" , HE.onMouseOver <| HoverItem <| HoveredFightStrategyReference reference , HE.onMouseOut StopHoveringItem ] @@ -3294,7 +3582,7 @@ settingsFightStrategySyntaxHelpView maybeHoveredItem = hoverInfo = case maybeHoveredItem of Nothing -> - { title = "Hover for help" + { title = "Hover a [THING] for help" , description = "" } @@ -3302,20 +3590,29 @@ settingsFightStrategySyntaxHelpView maybeHoveredItem = HoveredItem.text hoveredItem in [ pageTitleView "Fight Strategy syntax help" - , H.button - [ HE.onClick (GoToRoute (PlayerRoute Route.SettingsFightStrategy)) ] - [ H.text "[Back]" ] - , H.div - [ HA.class "fight-strategy-syntax-help-grid" ] - [ H.pre - [ HA.class "fight-strategy-syntax-help-cheatsheet" ] - (List.map viewMarkup FightStrategyHelp.help) + , H.div [ HA.class "flex flex-col gap-4 items-start" ] + [ UI.button + [ HE.onClick (GoToRoute (PlayerRoute Route.SettingsFightStrategy)) ] + [ H.text "[Back]" ] , H.div - [ HA.class "fight-strategy-syntax-help-hover" ] - [ H.h3 [] [ H.text hoverInfo.title ] - , H.pre - [ HA.class "fight-strategy-syntax-help-hover-description" ] - [ H.text hoverInfo.description ] + [ HA.class "flex flex-row gap-[2ch]" ] + [ H.div [ HA.class "w-[80ch]" ] + [ H.div [] + [ H.text "Your strategy needs to be of the shape " + , H.span [ HA.class "text-green-100" ] [ H.text "[STRATEGY]" ] + , H.text ", and its goal is to choose which " + , H.span [ HA.class "text-green-100" ] [ H.text "[COMMAND]" ] + , H.text " to do in your current turn. See below for your options:" + ] + , H.pre [ HA.class "font-mono" ] + (List.map viewMarkup FightStrategyHelp.help) + ] + , H.div [ HA.class "flex-1" ] + [ H.h3 [ HA.classList [ ( "text-orange pb-4", maybeHoveredItem /= Nothing ) ] ] [ H.text hoverInfo.title ] + , H.pre + [ HA.class "font-sans whitespace-pre-wrap max-w-[60ch]" ] + [ H.text hoverInfo.description ] + ] ] ] ] @@ -3348,8 +3645,9 @@ settingsFightStrategyView fightStrategyText _ player = viewWarning : FightStrategy.ValidationWarning -> Html FrontendMsg viewWarning warning = H.li - [ HA.class "fight-strategy-warning" ] - [ H.text <| + [ TW.mod "hover" "text-green-100" ] + [ UI.liBullet + , H.text <| case warning of FightStrategy.ItemDoesntHeal itemKind -> "Item doesn't heal: " ++ Item.name itemKind @@ -3387,9 +3685,12 @@ settingsFightStrategyView fightStrategyText _ player = _ -> "" in + -- TODO when user clicks the dead end, splice it into the program H.li - [ HA.class "fight-strategy-dead-end" ] - [ H.text <| "- " ++ item ] + [ TW.mod "hover" "text-green-100" ] + [ UI.liBullet + , H.text item + ] deadEndCategorization : Parser.DeadEnd -> ( ( Int, Int ), String, String ) deadEndCategorization deadEnd = @@ -3417,8 +3718,8 @@ settingsFightStrategyView fightStrategyText _ player = ) helpBtn = - H.button - [ HA.class "fight-strategy-help-btn" + UI.button + [ HA.class "ml-[1ch]" , HE.onClick (GoToRoute (PlayerRoute Route.SettingsFightStrategySyntaxHelp)) ] [ H.text "[Syntax cheatsheet]" ] @@ -3445,72 +3746,101 @@ settingsFightStrategyView fightStrategyText _ player = in [ pageTitleView "Settings: Fight Strategy" , H.div - [ HA.class "fight-strategy-grid" ] - [ H.div [ HA.class "fight-strategy-examples" ] - (H.text "Examples: " - :: (FightStrategy.all - |> List.map - (\( name, strategy ) -> - H.button - [ HE.onClick <| SetFightStrategyText <| FightStrategy.toString strategy - , HA.class "fight-strategy-example" + [ HA.class "flex flex-row gap-4" ] + [ H.div [ HA.class "flex flex-col" ] + [ H.div [] + (H.text "Examples: " + :: (FightStrategy.all + |> List.map + (\( name, strategy ) -> + UI.button + [ HE.onClick <| SetFightStrategyText <| FightStrategy.toString strategy + , HA.class "normal-case" + , TW.mod "before" "content-['[']" + , TW.mod "after" "content-[']']" + ] + [ H.text name ] + ) + |> List.intersperse (H.text ", ") + ) + ) + , H.div [ HA.class "relative" ] + -- TODO change ch measurements to some kind of pixels. We'll have to hardcode this + [ UI.textarea + [ HE.onInput SetFightStrategyText + , HA.class "!bg-green-800 w-[70ch] h-[25rem] my-4 py-4 px-4 rounded leading-[18px] whitespace-pre font-mono" + , HA.value fightStrategyText + ] + [] + , firstDeadEnd + |> H.viewMaybe + (\{ row, col } -> + H.div + [ HA.class "absolute left-4 top-4 pointer-events-none select-none w-[24px] h-4 -ml-0.5 pl-0.5 border-l border-l-orange leading-[18px]" + , HA.class "bg-[linear-gradient(90deg,var(--orange-transparent)_0%,var(--orange-fully-transparent)_100%)]" + , HA.class "translate-x-[calc((var(--error-col)-1)*8px+1px)]" + , HA.class "translate-y-[calc((var(--error-row)-1)*18px+16px+1px)]" + , cssVars + [ ( "--error-row", String.fromInt row ) + , ( "--error-col", String.fromInt col ) ] - [ H.text name ] + ] + [] + ) + ] + , H.div + [ HA.class "flex flex-row gap-[1ch]" ] + [ UI.button + [ HA.disabled <| not hasTextChanged || Result.isErr parseResult + , parseResult + |> Result.toMaybe + |> HA.attributeMaybe + (\strategy -> + HE.onClick <| + AskToSetFightStrategy ( strategy, fightStrategyText ) ) - |> List.intersperse (H.text ", ") - ) - ) - , H.textarea - [ HE.onInput SetFightStrategyText - , HA.class "fight-strategy-textarea" - , HA.value fightStrategyText + ] + [ H.text "[Save]" ] + , UI.button + [ HA.disabled <| not hasTextChanged + , HE.onClick <| SetFightStrategyText player.fightStrategyText + ] + [ H.text "[Reset to saved]" ] + ] ] - [] - , firstDeadEnd - |> H.viewMaybe - (\{ row, col } -> - H.div - [ HA.class "fight-strategy-hovered-error" - , cssVars - [ ( "--error-row", String.fromInt row ) - , ( "--error-col", String.fromInt col ) - ] - ] - [] - ) - , H.div - [ HA.class "fight-strategy-info" ] - (H.div - [ HA.class "fight-strategy-info-heading" ] + , H.div [ HA.class "flex flex-col gap-4 max-w-[50ch]" ] + (H.div [] [ H.text "Info:" , helpBtn ] :: (if Result.isOk parseResult then - [ H.p - [ HA.class "fight-strategy-info-paragraph" ] - [ H.text "Your strategy is OK" ] + [ H.p [] + [ H.text "Your strategy is " + , H.span [ HA.class "text-green-100" ] [ H.text "OK" ] + ] ] else - [ H.p - [ HA.class "fight-strategy-info-paragraph" ] - [ H.text "Your strategy is not finished yet." ] - , H.p - [ HA.class "fight-strategy-info-paragraph" ] + [ H.p [] + [ H.text "Your strategy is " + , H.span + [ HA.class "text-orange" ] + [ H.text "not finished yet." ] + ] + , H.p [] [ H.text "See the yellow indicator on the left and the notes below to figure out where the problem is." ] - , H.p - [ HA.class "fight-strategy-info-paragraph" ] + , H.p [] [ H.text "If needed, ask on Discord in the " , H.a [ HA.href discordFightStrategiesChannelInviteLink , HA.target "_blank" - , HA.class "fight-strategy-info-link" + , HA.class "text-green-100 whitespace-pre" + , TW.mod "hover" "text-orange" ] [ H.text "#fight-strategies" ] , H.text " channel." ] - , H.p - [ HA.class "fight-strategy-info-paragraph" ] + , H.p [] [ H.text <| if String.isEmpty (String.trim fightStrategyText) then "Start with:" @@ -3528,7 +3858,7 @@ settingsFightStrategyView fightStrategyText _ player = ":" ) ] - , H.ul [ HA.class "fight-strategy-dead-ends" ] + , H.ul [] (deadEnds |> List.sortBy deadEndCategorization |> List.map viewDeadEnd @@ -3539,61 +3869,39 @@ settingsFightStrategyView fightStrategyText _ player = [] else - [ H.p - [ HA.class "fight-strategy-info-paragraph" ] + [ H.p [ HA.class "text-green-300" ] [ H.text "Warnings:" ] - , H.ul - [ HA.class "fight-strategy-warnings" ] + , H.ul [] (List.map viewWarning warnings) ] ) ) ] - , H.div - [ HA.class "fight-strategy-buttons" ] - [ H.button - [ HA.class "fight-strategy-save-btn" - , HA.disabled <| not hasTextChanged || Result.isErr parseResult - , parseResult - |> Result.toMaybe - |> HA.attributeMaybe - (\strategy -> - HE.onClick <| - AskToSetFightStrategy ( strategy, fightStrategyText ) - ) - ] - [ H.text "[Save]" ] - , H.button - [ HA.class "fight-strategy-reset-btn" - , HA.disabled <| not hasTextChanged - , HE.onClick <| SetFightStrategyText player.fightStrategyText - ] - [ H.text "[Reset to saved]" ] - ] ] newsItemView : Time.Zone -> News.Item -> Html FrontendMsg newsItemView zone { date, title, text } = - H.div - [ HA.class "news-item" ] + H.div [] [ H.h3 - [ HA.class "news-item-title" ] + [ HA.class "text-green-100 font-bold" ] [ H.text title ] , H.time - [ HA.class "news-item-date" ] + [ HA.class "text-green-300" ] [ date |> News.formatDate zone |> H.text ] - , News.formatText "news-item-text" text + , News.formatText "max-w-[60ch]" text ] newsView : Time.Zone -> List (Html FrontendMsg) newsView zone = - pageTitleView "News" - :: List.map (newsItemView zone) News.items + [ pageTitleView "News" + , H.div [ HA.class "flex flex-col gap-15" ] + (List.map (newsItemView zone) News.items) + ] fightView : Maybe Fight.Info -> PlayerData -> CPlayer -> List (Html FrontendMsg) @@ -3619,34 +3927,34 @@ fightView maybeFight _ player = } in [ pageTitleView "Fight" - , H.div [] - [ H.text <| - "Attacker: " - ++ Fight.opponentName fight.attacker - ++ (if youAreAttacker then - " (you)" + , H.div [ HA.class "flex flex-col gap-4" ] + [ H.div [] + [ H.text <| + "Attacker: " + ++ Fight.opponentName fight.attacker + ++ (if youAreAttacker then + " (you)" - else - "" - ) - ] - , H.div [] - [ H.text <| - "Target: " - ++ Fight.opponentName fight.target - ++ (if youAreAttacker then - "" + else + "" + ) + ] + , H.div [] + [ H.text <| + "Target: " + ++ Fight.opponentName fight.target + ++ (if youAreAttacker then + "" - else - " (you)" - ) - ] - , Data.Fight.View.view perceptionLevel fight player.name - , H.button - [ HE.onClick <| GoToRoute (PlayerRoute Route.Ladder) - , HA.id "fight-back-button" + else + " (you)" + ) + ] + , Data.Fight.View.view perceptionLevel fight player.name + , UI.button + [ HE.onClick <| GoToRoute (PlayerRoute Route.Ladder) ] + [ H.text "[Back]" ] ] - [ H.text "[Back]" ] ] @@ -3663,23 +3971,36 @@ ladderLoadingView = worldInfoView : WorldInfo -> Html FrontendMsg worldInfoView data = H.ul [] - [ H.li [] [ H.text <| "Name: " ++ data.name ] + [ H.li [] + [ H.text "Name: " + , H.span [ HA.class "text-green-100" ] [ H.text data.name ] + ] , H.li [] - [ H.text <| - "Players: " - ++ String.fromInt data.playersCount + [ H.text "Players: " + , H.span [ HA.class "text-green-100" ] [ H.text (String.fromInt data.playersCount) ] ] , H.li [] - [ H.text <| - "Tick frequency: " - ++ Tick.curveToString data.tickPerIntervalCurve - ++ " ticks every " - ++ Time.intervalToString data.tickFrequency + [ H.text "Tick frequency: " + , H.span [ HA.class "text-green-100" ] + [ case data.tickPerIntervalCurve of + Tick.Linear n -> + H.text <| String.fromInt n ++ " ticks every " ++ Time.intervalToString data.tickFrequency + + Tick.QuarterAndRest { quarter, rest } -> + H.text <| + String.fromInt quarter + ++ " ticks every " + ++ Time.intervalToString data.tickFrequency + ++ " until " + ++ String.fromInt (Tick.limit // 4) + ++ " ticks are reached, then " + ++ String.fromInt rest + ] ] , H.li [] - [ H.text <| - "Vendor restock frequency: every " - ++ Time.intervalToString data.vendorRestockFrequency + [ H.text "Vendor restock frequency: " + , H.span [ HA.class "text-green-100" ] + [ H.text <| "every " ++ Time.intervalToString data.vendorRestockFrequency ] ] ] @@ -3687,15 +4008,17 @@ worldInfoView data = aboutWorldView : PlayerData -> CPlayer -> List (Html FrontendMsg) aboutWorldView data _ = [ pageTitleView <| "About world: " ++ data.worldName - , worldInfoView - { name = data.worldName - , description = data.description - , startedAt = data.startedAt - , tickFrequency = data.tickFrequency - , tickPerIntervalCurve = data.tickPerIntervalCurve - , vendorRestockFrequency = data.vendorRestockFrequency - , playersCount = List.length data.otherPlayers + 1 - } + , H.div [ HA.class "p-[2ch]" ] + [ worldInfoView + { name = data.worldName + , description = data.description + , startedAt = data.startedAt + , tickFrequency = data.tickFrequency + , tickPerIntervalCurve = data.tickPerIntervalCurve + , vendorRestockFrequency = data.vendorRestockFrequency + , playersCount = List.length data.otherPlayers + 1 + } + ] ] @@ -3713,41 +4036,26 @@ ladderView data loggedInPlayer = playerLadderTableView : List COtherPlayer -> CPlayer -> Html FrontendMsg playerLadderTableView players loggedInPlayer = - let - cantFight : String -> Html FrontendMsg - cantFight message = - H.td - [ HA.class "ladder-fight" - , HA.title message - ] - [ H.text "-" ] - in - H.table [ HA.id "ladder-table" ] + H.table + [] [ H.thead [] [ H.tr [] [ H.th - [ HA.class "ladder-rank" + [ HA.class "text-right" , HA.title "Rank" ] [ H.text "#" ] - , H.th [ HA.class "ladder-fight" ] [ H.text "Fight" ] - , H.th [ HA.class "ladder-name" ] [ H.text "Name" ] + , H.th [] [ H.text "Fight" ] + , H.th [] [ H.text "Name" ] + , H.th [ HA.title "Health status" ] [ H.text "Status" ] + , H.th [ HA.class "text-right" ] [ H.text "Lvl" ] , H.th - [ HA.class "ladder-status" - , HA.title "Health status" - ] - [ H.text "Status" ] - , H.th [ HA.class "ladder-lvl" ] [ H.text "Lvl" ] - - --, H.th [HA.class "ladder-city"] [ H.text "City" ] -- city - --, H.th [HA.class "ladder-flag"] [] -- flag - , H.th - [ HA.class "ladder-wins" + [ HA.class "text-right" , HA.title "Wins" ] [ H.text "W" ] , H.th - [ HA.class "ladder-losses" + [ HA.class "text-right" , HA.title "Losses" ] [ H.text "L" ] @@ -3757,12 +4065,25 @@ playerLadderTableView players loggedInPlayer = (players |> List.indexedMap (\i player -> + let + isYou = + loggedInPlayer.name == player.name + + cantFight : String -> Html FrontendMsg + cantFight message = + H.td + [ HA.class "text-green-300 cursor-not-allowed" + , HA.classList [ ( "bg-green-800", isYou ) ] + , HA.title message + ] + [ H.text "-" ] + in H.tr - [ HA.classList - [ ( "is-player", loggedInPlayer.name == player.name ) ] + [ HA.classList [ ( "text-green-100", isYou ) ] ] [ H.td - [ HA.class "ladder-rank" + [ HA.class "text-right" + , HA.classList [ ( "bg-green-800", isYou ) ] , HA.title "Rank" ] [ H.text <| String.fromInt <| i + 1 ] @@ -3780,17 +4101,19 @@ playerLadderTableView players loggedInPlayer = else H.td - [ HA.class "ladder-fight" - , HE.onClick <| AskToFight player.name + [ HE.onClick <| AskToFight player.name + , HA.class "cursor-pointer bg-green-800 text-green-100" + , HA.classList [ ( "bg-green-800", isYou ) ] + , TW.mod "hover" "text-orange" ] [ H.text "Fight" ] , H.td - [ HA.class "ladder-name" + [ HA.classList [ ( "bg-green-800", isYou ) ] , HA.title "Name" ] [ H.text player.name ] , H.td - [ HA.class "ladder-status" + [ HA.classList [ ( "bg-green-800", isYou ) ] , HA.title <| if loggedInPlayer.special.perception <= 1 then "Health status. Your perception is so low you genuinely can't say whether they're even alive or dead." @@ -3800,17 +4123,20 @@ playerLadderTableView players loggedInPlayer = ] [ H.text <| HealthStatus.label player.healthStatus ] , H.td - [ HA.class "ladder-lvl" + [ HA.class "text-right" + , HA.classList [ ( "bg-green-800", isYou ) ] , HA.title "Level" ] [ H.text <| String.fromInt player.level ] , H.td - [ HA.class "ladder-wins" + [ HA.class "text-right" + , HA.classList [ ( "bg-green-800", isYou ) ] , HA.title "Wins" ] [ H.text <| String.fromInt player.wins ] , H.td - [ HA.class "ladder-losses" + [ HA.class "text-right" + , HA.classList [ ( "bg-green-800", isYou ) ] , HA.title "Losses" ] [ H.text <| String.fromInt player.losses ] @@ -3822,7 +4148,7 @@ playerLadderTableView players loggedInPlayer = adminLadderTableView : List SPlayer -> Html FrontendMsg adminLadderTableView players = - H.table [ HA.id "ladder-table" ] + H.table [] [ H.thead [] [ H.tr [] [ H.th @@ -3926,10 +4252,8 @@ contentUnavailableView reason = "Content unavailable (" ++ reason ++ "). This is most likely a bug. We should have redirected you someplace else. Could you report this to the developers please?" - , H.button - [ HE.onClick <| GoToRoute News - , HA.id "message-back-button" - ] + , UI.button + [ HE.onClick <| GoToRoute News ] [ H.text "[Back]" ] ] @@ -3955,51 +4279,23 @@ notInitializedView model = loadingNavView : Html FrontendMsg loadingNavView = - H.div - [ HA.id "loading-nav" ] + H.div [] [ H.text "Loading..." - , H.span [ HA.class "loading-cursor" ] [] + , H.span + [ HA.class "loading-cursor" + , HA.class "inline-block w-[1ch] h-4 -mb-0.5 ml-0.5" + ] + [] ] -view_ : Model -> Html FrontendMsg -view_ model = - let - worldNames : List World.Name - worldNames = - model.worlds - |> Maybe.withDefault [] - |> List.map .name - - leftNav = - case model.worldData of - IsAdmin _ -> - [ alertMessageView model.alertMessage - , adminLinksView model.route - ] - - IsPlayer data -> - [ alertMessageView model.alertMessage - , playerInfoView data.player - , loggedInLinksView data.player model.route - ] - - NotLoggedIn -> - [ loginFormView worldNames model.loginForm - , alertMessageView model.alertMessage - , loggedOutLinksView model.route - ] - in - appView { leftNav = leftNav } model - - alertMessageView : Maybe String -> Html FrontendMsg alertMessageView maybeMessage = maybeMessage |> H.viewMaybe (\message -> H.div - [ HA.id "alert-message" ] + [ HA.class "text-orange" ] [ H.text message ] ) @@ -4007,38 +4303,53 @@ alertMessageView maybeMessage = loginFormView : List World.Name -> Auth Plaintext -> Html FrontendMsg loginFormView worlds auth = let - formId = - "login-form" + input attrs children = + UI.input + (HA.class "text-green-100 w-[18ch] font-extraBold" + :: TW.mod "focus" "bg-green-900" + :: attrs + ) + children in H.form - [ HA.id formId + [ HA.class "w-[20ch]" , HE.onSubmit Login ] - [ H.input - [ HA.id "login-name-input" - , HA.value auth.name + [ input + [ HA.value auth.name , HA.placeholder "Username_______________" , HE.onInput SetAuthName ] [] - , H.input - [ HA.id "login-password-input" - , HA.type_ "password" + , input + [ HA.type_ "password" , HA.value <| Auth.unwrap auth.password , HA.placeholder "Password_______________" , HE.onInput SetAuthPassword ] [] , H.div - [ HA.class "login-world-select-label" ] + [ HA.class "mt-5" ] [ H.text "World: " ] , H.div - [ HA.class "login-world-select-wrapper" ] + [ HA.class "select-wrapper" + , HA.class "grid items-center relative w-[20ch] rounded cursor-pointer bg-green-200 mt-2 text-black" + , TW.mod "after" "justify-self-end -translate-y-0.5 rotate-180 px-2 text-black" + ] [ H.select [ HE.onChange SetAuthWorld - , HA.class "login-world-select" + , HA.class "select" + , HA.class "peer appearance-none bg-transparent border-0 m-0 py-1 pl-2 pr-8 w-full z-[1] outline-none" ] - (("" :: worlds) + (worlds + |> List.sortBy + (\worldName -> + if worldName == Logic.mainWorldName then + 0 + + else + 1 + ) |> List.map (\worldName -> H.option @@ -4048,19 +4359,17 @@ loginFormView worlds auth = [ H.text worldName ] ) ) - , H.span [ HA.class "login-world-select-focus" ] [] + , H.span + [ TW.mod "peer-focus" "absolute inset-[-1px] border-2 border-green-100 rounded-[inherit]" ] + [] ] , H.div - [ HA.id "login-form-buttons" ] - [ H.button - [ HA.id "login-button" - , HE.onClickPreventDefault Login - ] + [ HA.class "mt-4 flex justify-between" ] + [ UI.button + [ HE.onClickPreventDefault Login ] [ H.text "[ Login ]" ] - , H.button - [ HA.id "register-button" - , HE.onClickPreventDefault Register - ] + , UI.button + [ HE.onClickPreventDefault Register ] [ H.text "[ Register ]" ] ] ] @@ -4089,7 +4398,7 @@ linkView currentRoute { label, type_, tooltip, disabled, dimmed } = ) LinkIn { route, isActive } -> - ( H.button + ( UI.button , [ HE.onClick <| GoToRoute route , HA.attributeMaybe HA.title tooltip , HA.attributeIf (isActive currentRoute) <| HA.class "active" @@ -4098,7 +4407,7 @@ linkView currentRoute { label, type_, tooltip, disabled, dimmed } = ) LinkMsg msg -> - ( H.button + ( UI.button , [ HE.onClick msg , HA.attributeMaybe HA.title tooltip , HA.disabled disabled @@ -4107,9 +4416,7 @@ linkView currentRoute { label, type_, tooltip, disabled, dimmed } = in tag (HA.class "link" - :: HA.classList - [ ( "dimmed", dimmed ) - ] + :: HA.classList [ ( "dimmed", dimmed ) ] :: linkAttrs ) [ H.span @@ -4252,10 +4559,7 @@ loggedInLinksView player currentRoute = , linkMsg "Logout" Logout Nothing False ] in - H.div - [ HA.id "logged-in-links" - , HA.class "links" - ] + H.div [] (List.map (linkView currentRoute) links) @@ -4267,23 +4571,16 @@ adminLinksView currentRoute = , linkIn "Worlds" (AdminRoute AdminWorldsList) Nothing False , linkMsg "Import" ImportButtonClicked Nothing False , linkMsg "Export" AskForExport Nothing False - , linkIn "Ladder" (PlayerRoute Route.Ladder) Nothing False , linkMsg "Logout" Logout Nothing False ] in - H.div - [ HA.id "logged-in-links" - , HA.class "links" - ] + H.div [] (List.map (linkView currentRoute) links) loggedOutLinksView : Route -> Html FrontendMsg loggedOutLinksView currentRoute = - H.div - [ HA.id "logged-out-links" - , HA.class "links" - ] + H.div [] ([ linkMsg "Refresh" Refresh Nothing False , linkIn "Map" Map Nothing False , linkIn "Worlds" WorldsList Nothing False @@ -4294,17 +4591,14 @@ loggedOutLinksView currentRoute = commonLinksView : Route -> Html FrontendMsg commonLinksView currentRoute = - H.div - [ HA.id "common-links" - , HA.class "links" - ] + H.div [] ([ linkIn "News" News Nothing False , linkIn "About" About Nothing False , linkOut "Discord" "https://discord.gg/SxymXxvehS" Nothing False , linkOut "Twitter" "https://twitter.com/NuAshworld" Nothing False , linkOut "GitHub" "https://github.com/Janiczek/nu-ashworld" Nothing False , linkOut "Reddit" "https://www.reddit.com/r/NuAshworld/" Nothing False - , linkOut "Donate" "https://patreon.com/janiczek" Nothing False + , linkOut "Donate" "https://github.com/sponsors/Janiczek" Nothing False ] |> List.map (linkView currentRoute) ) @@ -4313,8 +4607,7 @@ commonLinksView currentRoute = adminWorldsListView : String -> Bool -> AdminData -> List (Html FrontendMsg) adminWorldsListView newWorldName newWorldFast data = [ pageTitleView "Admin :: Worlds" - , H.div - [ HA.id "admin-worlds-list" ] + , H.div [] [ H.table [] [ H.thead [] [ H.tr [] @@ -4330,10 +4623,10 @@ adminWorldsListView newWorldName newWorldFast data = H.tr [ HA.class "world" ] [ H.td [] [ H.text worldName ] , H.td [] - [ H.button + [ UI.button [ HE.onClick (GoToRoute (AdminRoute (Route.AdminWorldActivity worldName))) ] [ H.text "[Activity]" ] - , H.button + , UI.button [ HE.onClick (GoToRoute (AdminRoute (Route.AdminWorldHiscores worldName))) ] [ H.text "[Hiscores]" ] ] @@ -4342,26 +4635,19 @@ adminWorldsListView newWorldName newWorldFast data = ) ] ] - , H.div [ HA.id "admin-new-world-form" ] - [ H.input + , H.div [] + [ UI.input [ HE.onInput SetAdminNewWorldName , HA.placeholder "New world name" , HA.value newWorldName ] [] - , H.label - [ HA.for "admin-new-world-fast-checkbox" - , HE.onClick ToggleAdminNewWorldFast - ] - [ H.input - [ HA.type_ "checkbox" - , HA.id "admin-new-world-fast-checkbox" - , HA.checked newWorldFast - ] - [] - , H.text "Fast?" - ] - , H.button + , UI.checkbox + { isOn = newWorldFast + , label = "Fast?" + , toggle = SetAdminNewWorldFast + } + , UI.button [ HE.onClick AskToCreateNewWorld , HA.disabled (Dict.member newWorldName data.worlds) ] @@ -4382,7 +4668,7 @@ adminWorldActivityView lastTenToBackendMsgs worldName data = Just _ -> [ pageTitleView <| "Admin :: World: " ++ worldName ++ " - Activity" , H.h3 [] [ H.text "Last 10 messages" ] - , H.table [ HA.id "admin-last-ten-msgs-table" ] + , H.table [] (H.thead [] [ H.tr [] [ H.th [] [ H.text "World" ] @@ -4452,8 +4738,7 @@ adminWorldHiscoresView worldName data = ] in [ pageTitleView <| "Admin :: World: " ++ worldName ++ " - Hiscores" - , H.div - [ HA.id "admin-hiscores-content" ] + , H.div [] [ H.ul [] (List.map viewMaxBy [ ( "Most money", .caps ) @@ -4503,111 +4788,94 @@ playerInfoView player = createdPlayerInfoView : CPlayer -> Html FrontendMsg createdPlayerInfoView player = H.div - [ HA.id "player-info" ] - [ H.div [ HA.class "player-stat-label" ] [ H.text "Name:" ] + [ HA.class "grid grid-cols-2" ] + [ H.div + [ HA.class "col-start-1 text-right text-green-300 mr-[1ch]" ] + [ H.text "Name:" ] , H.div - [ HA.classList - [ ( "player-stat-value", True ) - , ( "emphasized", True ) - ] - ] + [ HA.class "col-start-2 text-green-100" ] [ H.text player.name ] , H.div - [ HA.class "player-stat-label" + [ HA.class "col-start-1 text-right text-green-300 mr-[1ch]" , HA.title "Hitpoints" ] [ H.text "HP:" ] - , H.div [ HA.class "player-stat-value" ] [ H.text <| String.fromInt player.hp ++ "/" ++ String.fromInt player.maxHp ] , H.div - [ HA.class "player-stat-label" + [ HA.class "col-start-2" ] + [ "{HP}/{MAXHP}" + |> String.replace "{HP}" (String.fromInt player.hp) + |> String.replace "{MAXHP}" (String.fromInt player.maxHp) + |> H.text + ] + , H.div + [ HA.class "col-start-1 text-right text-green-300 mr-[1ch]" , HA.title "Experience points" ] [ H.text "XP:" ] - , H.div [ HA.class "player-stat-value" ] + , H.div [ HA.class "col-start-2" ] [ H.span [] [ H.text <| String.fromInt player.xp ] , H.span - [ HA.class "deemphasized" ] + [ HA.class "text-green-300" ] [ H.text <| "/" ++ String.fromInt (Xp.nextLevelXp player.xp) ] ] - , H.div [ HA.class "player-stat-label" ] [ H.text "Level:" ] - , H.div [ HA.class "player-stat-value" ] [ H.text <| String.fromInt <| Xp.currentLevel player.xp ] , H.div - [ HA.class "player-stat-label" + [ HA.class "col-start-1 text-right text-green-300 mr-[1ch]" ] + [ H.text "Level:" ] + , H.div + [ HA.class "col-start-2" ] + [ H.text <| String.fromInt <| Xp.currentLevel player.xp ] + , H.div + [ HA.class "col-start-1 text-right text-green-300 mr-[1ch]" , HA.title "Wins/Losses" ] [ H.text "W/L:" ] - , H.div [ HA.class "player-stat-value" ] [ H.text <| String.fromInt player.wins ++ "/" ++ String.fromInt player.losses ] - , H.div [ HA.class "player-stat-label" ] [ H.text "Caps:" ] - , H.div [ HA.class "player-stat-value" ] [ H.text <| "$" ++ String.fromInt player.caps ] , H.div - [ HA.class "player-stat-label" + [ HA.class "col-start-2" ] + [ "{WINS}/{LOSSES}" + |> String.replace "{WINS}" (String.fromInt player.wins) + |> String.replace "{LOSSES}" (String.fromInt player.losses) + |> H.text + ] + , H.div + [ HA.class "col-start-1 text-right text-green-300 mr-[1ch]" ] + [ H.text "Caps:" ] + , H.div + [ HA.class "col-start-2" ] + [ "${CAPS}" + |> String.replace "{CAPS}" (String.fromInt player.caps) + |> H.text + ] + , H.div + [ HA.class "col-start-1 text-right text-green-300 mr-[1ch]" , HA.title "Ticks" ] [ H.text "Ticks:" ] - , H.div [ HA.class "player-stat-value" ] [ H.text <| String.fromInt player.ticks ] - ] - - -stylesLinkView : Html msg -stylesLinkView = - H.node "link" - [ HA.rel "stylesheet" - , HA.href <| "/styles/app.css?v=" ++ Version.version - ] - [] - - -favicon16View : Html msg -favicon16View = - H.node "link" - [ HA.rel "icon" - , HA.href "/images/favicon-16.png" - ] - [] - - -favicon32View : Html msg -favicon32View = - H.node "link" - [ HA.rel "icon" - , HA.href "/images/favicon-32.png" - ] - [] - - -genericFaviconView : Html msg -genericFaviconView = - H.node "link" - [ HA.rel "shortcut icon" - , HA.type_ "image/png" - , HA.href "/images/favicon-392.png" + , H.div + [ HA.class "col-start-2" ] + [ H.text <| String.fromInt player.ticks ] ] - [] - -genericFavicon2View : Html msg -genericFavicon2View = - H.node "link" - [ HA.rel "apple-touch-icon" - , HA.href "/images/favicon-392.png" - ] - [] - -logoView : Html msg -logoView = - H.div [ HA.id "logo-wrapper" ] +logoView : Model -> Html msg +logoView model = + H.div [ HA.class "flex flex-col items-end" ] [ H.img [ HA.src "/images/logo-black-small.png" , HA.alt "NuAshworld Logo" , HA.title "NuAshworld - go to homepage" - , HA.id "logo" + , HA.class + (if isPlayer model || isAdmin model then + "filter-logo-active" + + else + "filter-logo-inactive" + ) , HA.width 190 , HA.height 36 ] [] , H.div - [ HA.id "version" + [ HA.class "text-green-300" , HA.title "Game version" ] [ H.text Version.version ] diff --git a/src/Frontend/HoveredItem.elm b/src/Frontend/HoveredItem.elm index 95665c85..89a91097 100644 --- a/src/Frontend/HoveredItem.elm +++ b/src/Frontend/HoveredItem.elm @@ -4,6 +4,7 @@ import Data.FightStrategy.Help as FightStrategyHelp import Data.Perk as Perk exposing (Perk) import Data.Skill as Skill exposing (Skill) import Data.Special as Special +import Data.Special.Perception as Perception exposing (PerceptionLevel) import Data.Trait as Trait exposing (Trait) @@ -13,6 +14,7 @@ type HoveredItem | HoveredSpecial Special.Type | HoveredSkill Skill | HoveredFightStrategyReference FightStrategyHelp.Reference + | HoveredPerceptionLevel PerceptionLevel text : HoveredItem -> { title : String, description : String } @@ -49,3 +51,8 @@ text hoveredItem = { title = FightStrategyHelp.referenceTitle reference , description = FightStrategyHelp.referenceDescription reference } + + HoveredPerceptionLevel perceptionLevel -> + { title = "Perception Level: " ++ Perception.label perceptionLevel + , description = Perception.tooltip perceptionLevel + } diff --git a/src/Frontend/News.elm b/src/Frontend/News.elm index 0bc06a4f..4272e9f6 100644 --- a/src/Frontend/News.elm +++ b/src/Frontend/News.elm @@ -1,10 +1,15 @@ module Frontend.News exposing (Item, formatDate, formatText, items) import DateFormat -import Html exposing (Html) +import Html as H exposing (Html) import Html.Attributes as HA -import Markdown +import Html.Attributes.Extra as HAE +import Markdown.Block +import Markdown.Parser +import Markdown.Renderer exposing (defaultHtmlRenderer) +import Tailwind as TW import Time +import UI type alias Item = @@ -16,568 +21,19 @@ type alias Item = items : List Item items = - [ { date = 0 - , title = "TODO" - , text = """ -Changelog: - -* Quests!! - -* items are now **sorted by type** (food, books, armor, ...) on the inventory page - -* new perk: **Gecko Skinning**: each gecko kill has a guaranteed drop of gecko skin. Given as a reward for a quest. - -* new item: **Meat Jerky** (value $30, heals 40 HP) -* new item: **Beer** (value $200, can't currently be used) -* new item: **BB Gun** (value $3500, small gun, uses BB ammo, can't currently be used) -* new item: **BB Ammo** (value $20, ammo, can't currently be used) - -* new enemy: **Silver Gecko** -* new enemy: **Tough Silver Gecko** -* new enemy: **Golden Gecko** -* new enemy: **Tough Golden Gecko** -* new enemy: **Fire Gecko** -* new enemy: **Tough Fire Gecko** - -TODO: - -* TODO make some vendors sell meat jerky -* TODO new enemy: silver gecko -* TODO make geckos drop the skins if attacker has the perk -* TODO new item: silver gecko skin -* TODO new item: golden gecko skin -* TODO new item: fire gecko skin -* TODO on each tick, progress the quests -* TODO validate startProgressing -* TODO handle quest complete (global rewards) -* TODO handle quest complete (player rewards) -* TODO global rewards - track them in backend model? -* TODO global rewards - use them? -* TODO write more details to the news about the geckos -* TODO check that we're not progressing quests when hard cap is reached -* TODO maybe quest finish XP reward for those who gave enough? - -~janiczek -""" - } - , { date = 1638276029 - , title = "Worlds, fix for a vendor bug" - , text = """ -A big release in preparation for my talk about NuAshworld at NDC Oslo 2021 :) - -You can now play on different worlds with different tick speed settings. - -* For reference, the default speed on the "main" world is 2-4 ticks (depending -on whether you have above or below 50 ticks) per hour. -* The world for NDC Oslo will run at 1-2 ticks per second. -* Depending on how that one goes, I'll create a public "blitz round" world -after the conference. - -A bug was fixed related to being in the middle of a trade while the vendor -restocks. - -Pages in the game now each have their URL. - -(Vendor restock frequency is separate from the tick frequency; 1x per hour on -the main world, 1x per minute for the NDC Oslo world.) - -~janiczek -""" - } - , { date = 1626037313 - , title = "Fight strategy editor now more lenient toward whitespace" - , text = """ -While experimenting with the editor I found I'd like it to allow me to write eg. - -``` -if ((opponent is player - and my AP < 4) - and my HP < 100) -then do whatever -else attack (eyes) -``` - -In other words, newlines all over the place. And that's now possible! - -~janiczek -""" - } - , { date = 1626033582 - , title = "Fight strategy editor" - , text = """ -You can now write your own fight strategies in the **editor** on the Settings page. - -You can learn what's possible from the **examples** above the editor or via the **syntax cheatsheet** page. The info bar on the right of the editor should lead you through writing your strategies. - -There is a [#fight-strategies](https://discord.gg/9NuCZs3YZa) channel on the Discord where you can ask for help or share your own creations. - -~janiczek -""" - } - , { date = 1625920050 - , title = "Fixes for fight strategies" - , text = """ -Running two players with the YOLO strategy has uncovered a few bugs, so here -are the fixes for them: - -* Items in inventory with 0x count can't be used anymore - -* Items used during fight get removed correctly: they don't show up as 0x in -the inventory after the fight - -* Exact HP after healing during fight is only shown to you if it was you -healing yourself, or if you have enough PerceptionLevel to see the opponent's -exact HP. - -* It was possible to craft strategies such that the fight would never end. -We've now enforced a limit of 1000 actions - after that, both players give up -the fight and nobody wins. - -* If falling back to a backup strategy in case action from your strategy cannot -be used, we now correctly let the rest of your turn play back instead of -cutting it after the fallback action. - -* Action 'Heal' isn't needlessly taken if you have full HP. - -~janiczek -""" - } - , { date = 1625880726 - , title = "Fight strategies!" - , text = """ -You can now choose between different **fight strategies** on the **Settings -page** and actually **heal** during fights! - -I'll probably implement an editor to let you write your own strategies before I -dive back into quests. - -~janiczek -""" - } - , { date = 1623181215 - , title = "Your attacks are logged now, fights have a stats section" - , text = """ -A little procrastination patch while I chip away at quests: - -* **each fight has a stats section** with hit rate, damage dealt, critical hit -chance, average damage, max hit for both you and your opponent. - -* **your PvP attacks are now logged** into your messages. You can look at your -fights later if you want. - -This will probably later evolve into some filtering/tab system for the -messages, and/or a checkbox in settings to disable this recording behaviour, -but... we'll get there when we get there. - -Re quests: I have them all listed, the XP rewards roughly distributed, now just -to fill the rest of the data (description, requirements, item rewards, global -and private permanent buff rewards, etc.) and plug it into the code. Please be -patient with me :) - -~janiczek -""" - } - , { date = 1622292832 - , title = "XP and caps nerf in PvP fights" - , text = """ -We're experimenting with balancing the fights. The way things worked until now -is that - -* XP gained from a won fight was **10xp x damage dealt** (HP taken) - -* winner took **all the caps** the loser had on them - -In this update, we're changing that to: - -* XP gained is the above formula **scaled by (loser level / winner level)**. -Thus if a player with a level 20 kills a player with a level 6, they will only -get **6/20** as much of the XP. This works in the other way too! The weaker -player will get **20/6** as much XP if they manage to kill the stronger player. - -* caps gained are **scaled between 50% and 100%** of the full amount based on -the percentage of max HP taken during that fight. Formula: -**loser caps x (50% + 0.5 x damage dealt / max HP)**. -Example: Loser (with 34/80 HP) has 1234 caps on them. Winner kills them and -gets 879 caps. But if the loser was at full HP (80/80), the winner would get -all of the 1234 caps. - -Other changes: - -* the Messages link in menu is now dimmed if you have no unread messages -* the Messages link in menu is now highlighted even if you're in a specific message - -~janiczek -""" - } - , { date = 1621718718 - , title = "About page + Patreons + endgame!" - , text = """ -I've finally filled in the **About page**, because I needed somewhere to thank -my Patreons :) - -Thanks again, **djetelina**! - -To be a bit enigmatic: in my almost-a-week of not working on the game some -thoughts have crystallized on **how I want the endgame to look.** It also -nicely circumvents my fear of writing quests being too time consuming. The -solution is also a mechanic I haven't yet seen in any game I've played, so I'm -very interested in how well will it work. - -Stay tuned! - -~janiczek -""" - } - , { date = 1621370196 - , title = "Map chunks and enemies randomization" - , text = """ -I've separated the map into [five -regions](https://twitter.com/NuAshworld/status/1394754684129267718) of -increasing difficulty: - -1. Arroyo, Klamath, Den -2. Modoc, Vault City, Gecko -3. New Reno, Broken Hills, Redding, Raiders -4. NCR, Vault 13, Vault 15, Military Base -5. San Francisco, Navarro, Enclave - -Rest of the changelog: - -* **The enemies are now generated based on which chunk you're in!** So hopefully no -angry brahmins killing newbies next to the first town :) - -* **Added towns**: Raiders, Navarro, Vault 13, Vault 15 (no vendor in any of -them yet - you can see from them being transparent on the map) - -We'll need to add more enemies so that there is more variety, but maybe I'll -prioritize melee weapons first. Who knows? - -~ janiczek -""" - } - , { date = 1621248342 - , title = "Inventory total value" - , text = """ -A quick little change today - the inventory screen now shows the total value of your items. - -~janiczek -""" - } - , { date = 1621111128 - , title = "One more thing..." - , text = """ -Out of sheer procrastination I've implemented the help descriptions for SPECIAL -attributes, skills and traits. - -~janiczek -""" - } - , { date = 1621102934 - , title = "PvM drops and Brahmins" - , text = """ -Today's update will be short and sweet: **enemies can drop items** and -**Brahmins** were added as new enemies, along with two harder variants of Radscorpions. - -Since right now all enemies spawn everywhere, those radscorpions will probably -give you a bit of trouble. **The next patch** should be about restricting them to -certain areas, so that players can naturally progress from low-level areas to -higher-level areas as they see fit. - -Changelog: - -* Discord invite link was updated to point to the #welcome channel -* Item added: **Fruit** (heals 15 HP, base value $10) -* New enemies: **Brahmins**. Variants are: Brahmin, Angry Brahmin, Weak Brahmin, Wild Brahmin. -* New enemies: two **black** variants of **Radscorpions**. -* Enemies can now drop items: expect fruit, healing powder and an ocassional stimpak for now. - -~janiczek -""" - } - , { date = 1620669882 - , title = "More perks and UI improvements" - , text = """ -I have went through most of the perks in the original game and "ported" the -applicable ones to NuAshworld. Most other perks that are still missing are -waiting for non-unarmed combat, actual weapons etc. to be implemented. - -There is one big bug fixed: the armor class in fights was computed from the -attacker, not from the defending party! This is now fixed, so your hard-earned -metal armor will now finally be useful to you ;) - -And the unused Action Points from your turns in fights get converted to bonus -Armor Class for the next turn - again bringing us closer to what's in Fallout. -See also the **HtH Evade** perk that upgrades this behaviour and makes your -Unarmed skill much more useful. - -Changelog: - -* fixed bug: **Max HP** in Character Screen now shows the proper value instead of one calculated for level 1. -* UI improvement: **Tick heal** in Character Screen now shows the specific HP value healed in addition to the percentage of max HP. -* UI improvement: **Perk selection screen** now shows perk descriptions on hover. -* UI improvement: **Character screen** now shows perk descriptions on hover. - -* new perk: **Action Boy**: gives you +1 Action Point per rank (for use in fights etc). Max rank: 2. Reqs: lvl 12, Agility >= 5 -* new perk: **Adrenaline Rush**: gives you +1 Strength whenever your HP drops below 50%. Max rank: 1. Reqs: lvl 6, Strength < 10 -* new perk: **Bonus HtH Attacks**: all your unarmed attacks consume 1 less AP (so, 2 instead of 3 for normal attacks and 3 instead of 4 for aimed attacks). Max rank: 1. Reqs: lvl 15, Agility >= 6 -* new perk: **Dodger**: gives you +5 to Armor Class. Max rank: 1. Reqs: lvl 9, Agility >= 6 -* new perk: **Fortune Finder**: all caps NPC drops are doubled. Max rank: 1. Reqs: lvl 6, Luck >= 8 -* new perk: **Gambler**: gives you +20% to Gambling. Max rank: 1. Reqs: lvl 6, Gambling >= 50% -* new perk: **HtH Evade**: each Action Point unused in your fight turn gets converted to 2 Armor Class instead of 1. You also gain 1/12 of your Unarmed skill as additional Armor Class. Max rank: 1. Reqs: lvl 12, Unarmed >= 75% -* new perk: **Lifegiver**: gives you +4 HP per level per rank. Max rank: 2. Reqs: lvl 12, Endurance >= 4 -* new perk: **Living Anatomy**: gives you +10% to Doctor and +5 damage to any attack that lands. Max rank: 1. Reqs: lvl 12, Doctor >= 60% -* new perk: **Master Thief**: gives you +15% to Lockpick and Steal. Max rank: 1. Reqs: lvl 12, Lockpick >= 50%, Steal >= 50% -* new perk: **Medic**: gives you +10% to First Aid and Doctor. Max rank: 1. Reqs: lvl 12, First Aid >= 40% or Doctor >= 40% -* new perk: **Mr. Fixit**: gives you +10% to Repair and Science. Max rank: 1. Reqs: lvl 12, Science >= 40% or Repair >= 40% -* new perk: **Negotiator**: gives you +10% to Speech and Barter. Max rank: 1. Reqs: lvl 6, Barter >= 50%, Speech >= 50% -* new perk: **Pathfinder**: your tick cost for map movement is reduced by 25% per rank. Max rank: 2. Reqs: lvl 6, Endurance >= 6, Outdoorsman >= 40% -* new perk: **Ranger**: gives you +15% to Outdoorsman. Max rank: 1. Reqs: lvl 6, Perception >= 6 -* new perk: **Salesman**: gives you +20% to Barter. Max rank: 1. Reqs: lvl 6, Barter >= 50% -* new perk: **Speaker**: gives you +20% to Speech. Max rank: 1. Reqs: lvl 9, Speech >= 50% -* new perk: **Speaker**: gives you +20% to Speech. Max rank: 1. Reqs: lvl 9, Speech >= 50% -* new perk: **Swift Learner**: gives you 5% more XP per rank. Max rank: 3. Reqs: lvl 3, Intelligence >= 4 -* new perk: **Thief**: gives you +10% to Sneak, Lockpick, Steal and Traps. Max rank: 1. Reqs: lvl 3 -* new perk: **Toughness**: gives you +10 to Damage Resistance per rank. Max rank: 3. Reqs: lvl 3, Endurance >= 6, Luck >= 6 - -~ janiczek -""" - } - , { date = 1620348829 - , title = "Critical hits" - , text = """ -The game now properly tracks **critical hits**. You'll find that both you and -your enemies have a chance of hitting each other extra hard (**damage -multiplier** 1.5x to 4x depending on chance and whether you have some of the -critical-enhancing perks). - -As always, it has generated a bunch of TODOs for me to go through - mainly -status effects like crippled legs, knockback / knockout, blindness etc. - well, -one day maybe they'll come! :) - -I've been given feedback by ~djetelina that it would be nice to have -changelogs. So, here goes! - -Changelog: -* fights now correctly name body parts. So, no more ants with arms. -* **critical hits**: ocassionally damage is multiplied. You'll see which hit was -critical in the fight log. -* fixed damage formula: damage resistance is not affected by armor-ignoring -attacks (those don't exist yet anyways!) -* new perk: **Better Criticals**. Upgrades your critical hits' effects -- but not -chance for a critical happening. Reqs: lvl 9, luck 6, perception 6, agility 4 -* new perk: **More Criticals**. Max 3 ranks, each rank gives you 5% extra chance to -score a critical hit. Reqs: lvl 6, luck 6 -* new perk: **Slayer**. All non-miss unarmed/melee hits are upgraded to criticals. -Reqs: lvl 24, agility 8, strength 8, unarmed 80% -* trait **Heavy Handed** now has its critical hit effect debuff implemented. Note -this debuff is larger (-30) than the buff given by Better Criticals (+20). -* new trait: **Finesse**. Critical chance increased by 10%, but all damage is -reduced by 30%. -* map tooltip now correctly pluralizes ticks, so no more "1 ticks". -* fixed bug where damage in a fight could sometimes be negative (healing you) - -~janiczek -""" - } - , { date = 1620065638 - , title = "Armor!" - , text = """ -I have added a few kinds of **armor** to the game and a few new merchants that -can sell it. You can equip it in the Inventory screen - it should make you a -bit more durable in the battle. - -As a reminder, vendors change their stock every tick (so, every hour). May the -odds be ever in your favour :) - -Oh and we now have **Healing Powder** (Hakunin in **Arroyo** sells a bunch of -it) in an attempt to balance the healing in this damn game a bit. - -~janiczek -""" - } - , { date = 1619718120 - , title = "Books, more perks, and a new merchant" - , text = """ -I've been **adding more perks,** prioritizing those unlocked at level 3 (I have -enough time to do those at lvl 6/9/12/... - you guys don't level up that fast -;) ). One of them is related to -[books!](https://fallout.fandom.com/wiki/Fallout_2_skill_books) Which means, I -went and also implemented books. If you go look in the **Klamath** or **Den** -stores (yeah, there's now a vendor in Den!), you might get lucky and find one -of them. - -The books will give you up to 10% to their respective skills, capping somewhere -around 91%. After that, the book for that particular skill is useless to you. - -Note that using a book requires some ticks, related to your Intelligence -attribute. - -Oh and I've also slowed the game again. We now know 60x is too fast! (Duh.) - -~janiczek -""" - } - , { date = 1619693804 - , title = "Perks and a fast testing round" - , text = """ -Perks can now be added from within the **Character** screen (if you have perks -available - usually every 3 levels). Take them for a spin! - -I'm also making the game run a bit faster for a limited time, to let folks test -it and give me some feedback before I make a bigger marketing push :) - -So, enjoy a game tick every minute! - -~janiczek -""" - } - , { date = 1619480881 - , title = "PvM fights" - , text = """ -You can now fight some NPC enemies and get those sweet caps flowing into the -economy! - -When you move out of any town, you'll see that the **[Town]** link in -your menu changes to a **[Wander]** one. Clicking it will find you a NPC to fight -for the price of **one tick,** similarly to the PvP fights. - -Go forth and save up for those stimpaks! And don't forget, if you fight another -player, you get all their caps (or they yours). Should get much more exciting now! - -~janiczek -""" - } - , { date = 1618787348 - , title = "Skills and traits" - , text = """ -I've just revamped the **character creation screen** and added some initial -**traits** and support for **tagged skills** there. On each level-up you'll get -**skill points** to upgrade your skills with. This should all result in more -interesting characters and meta. - -Since I'm resetting the ladder instead of -attempting a complicated migration, you can try the new features out with new -characters! :) - -I also have a basic **perk** support implemented under the hood, but the "pick -a perk" screen is still TODO. - -Next up, the PvM encounters that should pump some caps into the economy, -finally! - -~janiczek -""" - } - , { date = 1618521323 - , title = "Beginnings of economy" - , text = """ -A big change just landed in NuAshworld: - -* you now have an **inventory** (visible on the Character page), and -* there is now a **store** in Klamath where you'll be able to barter with the -one and only [Maida Buckner](https://fallout.fandom.com/wiki/Maida_Buckner). - -The stores will, in general, restock periodically each tick. - -Note that this feature makes use of the **Charisma attribute**, since Charisma -affects your Barter skill, and that affects the prices you'll be getting when -trading with NPCs. - -There is currently only one item available in the game: -the healing item -[Stimpak](https://fallout.fandom.com/wiki/Stimpak_%28Fallout%29). - -A caveat: it doesn't currently do anything yet (this is a huge update as it -is!), but later you'll be able to: - -* use it to **heal yourself manually** (thus saving ticks), and -* **set automatic rules for your fights** ("heal whenever my HP drops below -30%" and so on). - -For trade to be truly useful, I'll have to add **NPC fights** as the next -thing, so that you can farm some caps. - -Stay tuned, good stuff coming soon! - -~janiczek -""" - } - , { date = 1617309687 - , title = "Fight system" - , text = """ -Fights should, now that I've -[implemented](https://twitter.com/janiczek/status/1377043815043846149) the -unarmed version of Fallout 2 combat algorithm and raised the XP rewards, be -interesting and rewarding enough that getting to a level 2 shouldn't be too -much of a problem :) At least, that would be the case if you had an option to -heal instantly. It's planned, read more below! - -What's planned for the immediate future: - -* Fast healing (Pip-boy rest-until-healed that would cost you ticks) -* Skill system (train your Unarmed skill for better damage etc.) -* PvM random encounters to train on -* Inventory system, items, drops -* Non-unarmed combat (melee, guns, ammo) - -And more long-term plans: - -* Perks / traits -* Quests -* Town NPCs (barter vendors, quest givers) - -P.S.: I've created a Twitter account -[@NuAshworld](https://twitter.com/NuAshworld) where I share screenshots from -development. Follow me! - -~janiczek -""" - } - , { date = 1614637525 - , title = "Plans before alpha" - , text = """ -I've just added a tick system (one tick at the start of every hour) which -should heal you and give you ticks to use for movement, fights, etc. Let's hope -it's not too broken :) - -I want to talk about my plans a bit. Some of my immediate plans are: - -* [NEW CHAR] finish the screen -* [FIGHT] dice-rolling instead of 50/50 win chance -* [ECONOMY] source of caps and items: random encounters / quests (simplified) - -More broadly, I'd like the game to have these mechanics: - -* when you lose, the other player gets all the caps you currently have with you -* thus, there is the need for having a stash / vault (hehe) to hide your caps -* I'm thinking that there might be some NPC in every town that will hold on to stuff for you, for a fee (per day?) -* these wouldn't be connected: if you keep 500 caps in Den and go to Redding, you won't be able to pick up the 500 caps there -* thus, there will (probably) be a period of danger where you need to move caps from one town to another -* perhaps even hidden stashes (anywhere on the map, or in locations given by random encounters?) -* these would have a chance to be found out by other players / NPC raiders / whoever - -But I need to somehow trim that down to a small prototype to test the idea out. - -~janiczek -""" - } - , { date = 1614543901 - , title = "Discord" - , text = """ -Development is chugging along; I've also created a [Discord](https://discord.gg/HUmwvnv4xV) server for NuAshworld. Looking forward to seeing you there! - -~janiczek -""" - } - , { date = 1614377234 - , title = "New beginnings!" + [ { date = 1614377234 + , title = "Hello!" , text = """ -Hello everybody! I just want to announce that I'm starting to work on this game again. +This is a test news post. I'll have to **flesh this out.** -You can watch the development plans on NuAshworld's [Trello](https://trello.com/b/WevjfFrt/nuashworld) and the game development itself on [GitHub](https://github.com/Janiczek/nu-ashworld-lamdera). +Check out this [link](https://google.com)! -I want to stay close to finding the fun in the game -- closing in on the mechanics, not getting stuck on unimportant things. We'll see how that goes :) +Some list: + +- one +- second +- 3! ~janiczek """ @@ -587,9 +43,36 @@ I want to stay close to finding the fun in the game -- closing in on the mechani formatText : String -> String -> Html a formatText class markdown = - Markdown.toHtml - [ HA.class class ] - markdown + markdown + |> Markdown.Parser.parse + |> Result.mapError (\_ -> "") + |> Result.andThen (Markdown.Renderer.render renderer) + |> Result.withDefault [ H.text "Failed to parse Markdown" ] + |> H.div [ HA.class ("flex flex-col gap-4 mt-4 " ++ class) ] + + +renderer : Markdown.Renderer.Renderer (Html a) +renderer = + { defaultHtmlRenderer + | link = + \{ title, destination } children -> + H.a + [ HA.class "text-orange relative no-underline" + , TW.mod "after" "absolute content-[''] bg-orange-transparent inset-x-[-3px] bottom-[-2px] h-1 transition-all duration-[250ms]" + , TW.mod "hover:after" "bottom-0 h-full" + , HA.href destination + , HAE.attributeMaybe HA.title title + ] + children + , unorderedList = + \list -> + list + |> List.map + (\(Markdown.Block.ListItem _ children) -> + H.li [] (UI.liBullet :: children) + ) + |> H.ul [ HA.class "flex flex-col" ] + } formatDate : Time.Zone -> Int -> String diff --git a/src/Lamdera/Hash.elm b/src/Lamdera/Hash.elm new file mode 100644 index 00000000..6820c43b --- /dev/null +++ b/src/Lamdera/Hash.elm @@ -0,0 +1,26 @@ +module Lamdera.Hash exposing (hasChanged, hash) + +import Dict exposing (Dict) +import FNV1a +import Hex.Convert +import Lamdera exposing (ClientId) +import Lamdera.Wire3 + + +hash : (a -> Lamdera.Wire3.Encoder) -> a -> Int +hash encode value = + value + |> encode + |> Lamdera.Wire3.bytesEncode + |> Hex.Convert.toString + |> FNV1a.hash + + +hasChanged : Int -> ClientId -> Dict ClientId Int -> Bool +hasChanged newHash clientId cache = + case Dict.get clientId cache of + Nothing -> + True + + Just oldHash -> + oldHash /= newHash diff --git a/src/Tailwind.elm b/src/Tailwind.elm new file mode 100644 index 00000000..74313f87 --- /dev/null +++ b/src/Tailwind.elm @@ -0,0 +1,13 @@ +module Tailwind exposing (mod) + +import Html exposing (Attribute) +import Html.Attributes as HA + + +mod : String -> String -> Attribute msg +mod modifier classes = + classes + |> String.words + |> List.map (\word -> modifier ++ ":" ++ word) + |> String.join " " + |> HA.class diff --git a/src/Types.elm b/src/Types.elm index 1de7365c..06e7e5fc 100644 --- a/src/Types.elm +++ b/src/Types.elm @@ -1,6 +1,7 @@ module Types exposing (..) import AssocSet as Set_ +import BiDict exposing (BiDict) import Browser exposing (UrlRequest) import Browser.Navigation exposing (Key) import Data.Auth exposing (Auth, Hashed, Plaintext) @@ -56,6 +57,7 @@ type alias FrontendModel = , barter : Barter.State , fightStrategyText : String , expandedQuests : Set_.Set Quest.Name + , userWantsToShowAreaDanger : Bool -- admin state , lastTenToBackendMsgs : List ( PlayerName, World.Name, ToBackend ) @@ -68,14 +70,16 @@ type alias BackendModel = { worlds : Dict World.Name World , time : Posix , loggedInPlayers : - Dict - ClientId - { worldName : World.Name - , playerName : PlayerName - } + -- Lets multiple browser windows log into the same (WorldName, PlayerName). + -- BiDict lets us get all the ClientIds for a certain player, meaning we + -- can compute their data just once. + BiDict ClientId ( World.Name, PlayerName ) , adminLoggedIn : Maybe ( ClientId, SessionId ) , lastTenToBackendMsgs : Queue ( PlayerName, World.Name, ToBackend ) , randomSeed : Random.Seed + , -- We don't want to send the same data to players over and over when + -- Tick-ing. This lets us skip that work. + playerDataCache : Dict ClientId Int } @@ -115,6 +119,7 @@ type FrontendMsg | MapMouseAtCoords TileCoords | MapMouseOut | MapMouseClick + | SetShowAreaDanger Bool | OpenMessage Message.Id | AskToRemoveMessage Message.Id | BarterMsg BarterMsg @@ -122,7 +127,7 @@ type FrontendMsg | StopHoveringItem | SetFightStrategyText String | SetAdminNewWorldName String - | ToggleAdminNewWorldFast + | SetAdminNewWorldFast Bool | AskToCreateNewWorld | ExpandQuestItem Quest.Name | CollapseQuestItem Quest.Name @@ -186,6 +191,13 @@ type BackendMsg | LoggedToBackendMsg +{-| Only done for getting the automatic `Types.w3_encode_PlayerData_` encoder +(for hashing a type to Int, for caching purposes) +-} +type alias PlayerData_ = + PlayerData + + type ToFrontend = CurrentPlayer PlayerData | CurrentWorlds (List WorldInfo) diff --git a/src/UI.elm b/src/UI.elm new file mode 100644 index 00000000..4121708c --- /dev/null +++ b/src/UI.elm @@ -0,0 +1,86 @@ +module UI exposing + ( bold + , button + , checkbox + , checkboxLabel + , input + , liBullet + , textarea + ) + +import Html as H exposing (Attribute, Html) +import Html.Attributes as HA +import Html.Events as HE +import Tailwind as TW + + +button : List (Attribute msg) -> List (Html msg) -> Html msg +button attrs content = + H.button + (HA.class "uppercase whitespace-pre cursor-pointer text-green-200 select-none" + :: TW.mod "disabled" "text-green-300" + :: TW.mod "hover" "text-green-100" + :: TW.mod "active" "text-orange" + :: attrs + ) + content + + +input : List (Attribute msg) -> List (Html msg) -> Html msg +input attrs content = + H.input + (HA.class "bg-transparent" + :: TW.mod "focus" "outline-none" + :: attrs + ) + content + + +textarea : List (Attribute msg) -> List (Html msg) -> Html msg +textarea attrs content = + H.textarea + (HA.class "bg-transparent" + :: TW.mod "focus" "outline-none" + :: attrs + ) + content + + +bold : String -> Html msg +bold text = + H.span + [ HA.class "font-bold" ] + [ H.text text ] + + +liBullet : Html msg +liBullet = + H.span + [ HA.class "text-green-300 pl-[1ch]" ] + [ H.text "- " ] + + +checkboxLabel : Bool -> String +checkboxLabel isOn = + if isOn then + "[X]" + + else + -- Space the width of one 'X' (in the font PixelOperator) + "[\u{2007}]" + + +checkbox : + { label : String + , isOn : Bool + , toggle : Bool -> msg + } + -> Html msg +checkbox { label, isOn, toggle } = + H.button + [ HE.onClick (toggle (not isOn)) + , HA.class "cursor-pointer text-green-200 select-none" + , TW.mod "hover" "text-green-100 bg-green-800" + , TW.mod "active" "text-orange" + ] + [ H.text <| checkboxLabel isOn ++ " " ++ label ] diff --git a/tests/Data/FightStrategy/ParserTest.elm b/tests/Data/FightStrategy/ParserTest.elm index c25cec72..d0e18949 100644 --- a/tests/Data/FightStrategy/ParserTest.elm +++ b/tests/Data/FightStrategy/ParserTest.elm @@ -92,6 +92,7 @@ condition = [ ( "op: my HP < 50", "my HP < 50", Just (Operator { value = MyHP, op = LT_, number_ = 50 }) ) , ( "op: my AP >= 3", "my AP >= 3", Just (Operator { value = MyAP, op = GTE, number_ = 3 }) ) , ( "opponent is player", "opponent is player", Just OpponentIsPlayer ) + , ( "opponent is NPC", "opponent is NPC", Just OpponentIsNPC ) , ( "and" , "(my HP < 50 and my AP >= 3)" , Just diff --git a/tests/TestHelpers.elm b/tests/TestHelpers.elm index 67434a2a..1782a880 100644 --- a/tests/TestHelpers.elm +++ b/tests/TestHelpers.elm @@ -164,6 +164,7 @@ conditionFuzzer r = , Fuzz.map2 And conditionFuzzer_ conditionFuzzer_ , Fuzz.map Operator operatorDataFuzzer , Fuzz.constant OpponentIsPlayer + , Fuzz.constant OpponentIsNPC ] diff --git a/yarn.lock b/yarn.lock index f61a62d6..2a8ecde5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,81 @@ # yarn lockfile v1 +"@alloc/quick-lru@^5.2.0": + version "5.2.0" + resolved "https://registry.yarnpkg.com/@alloc/quick-lru/-/quick-lru-5.2.0.tgz#7bf68b20c0a350f936915fcae06f58e32007ce30" + integrity sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw== + +"@isaacs/cliui@^8.0.2": + version "8.0.2" + resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" + integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== + dependencies: + string-width "^5.1.2" + string-width-cjs "npm:string-width@^4.2.0" + strip-ansi "^7.0.1" + strip-ansi-cjs "npm:strip-ansi@^6.0.1" + wrap-ansi "^8.1.0" + wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" + +"@jridgewell/gen-mapping@^0.3.2": + version "0.3.5" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz#dcce6aff74bdf6dad1a95802b69b04a2fcb1fb36" + integrity sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg== + dependencies: + "@jridgewell/set-array" "^1.2.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.24" + +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" + integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== + +"@jridgewell/set-array@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.2.1.tgz#558fb6472ed16a4c850b889530e6b36438c49280" + integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== + +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" + integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== + +"@jridgewell/trace-mapping@^0.3.24": + version "0.3.25" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" + integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@pkgjs/parseargs@^0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" + integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== + "@sindresorhus/is@^2.0.0": version "2.1.1" resolved "https://registry.npmjs.org/@sindresorhus/is/-/is-2.1.1.tgz" @@ -60,6 +135,16 @@ ansi-regex@^5.0.0: resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz" integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-regex@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.1.0.tgz#95ec409c69619d6cb1b8b34f14b660ef28ebd654" + integrity sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA== + ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" @@ -67,6 +152,16 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" +ansi-styles@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + +any-promise@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== + anymatch@~3.1.1: version "3.1.1" resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz" @@ -75,6 +170,19 @@ anymatch@~3.1.1: normalize-path "^3.0.0" picomatch "^2.0.4" +anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +arg@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.2.tgz#c81433cc427c92c4dcf4865142dbca6f15acd59c" + integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg== + at-least-node@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz" @@ -112,6 +220,20 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + +braces@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" + integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== + dependencies: + fill-range "^7.1.1" + braces@~3.0.2: version "3.0.2" resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" @@ -148,6 +270,11 @@ cacheable-request@^7.0.1: normalize-url "^4.1.0" responselike "^2.0.0" +camelcase-css@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5" + integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== + chalk@^4.0.0, chalk@^4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz" @@ -171,6 +298,21 @@ chokidar@^3.4.0: optionalDependencies: fsevents "~2.3.1" +chokidar@^3.5.3: + version "3.6.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" + integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + cli-cursor@^3.1.0: version "3.1.0" resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz" @@ -207,12 +349,17 @@ color-name@~1.1.4: resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +commander@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== + concat-map@0.0.1: version "0.0.1" resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= -cross-spawn@^7.0.3: +cross-spawn@^7.0.0, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -221,6 +368,11 @@ cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + debug@^4.1.1: version "4.3.1" resolved "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz" @@ -247,11 +399,26 @@ defer-to-connect@^2.0.0: resolved "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz" integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== +didyoumean@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037" + integrity sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw== + +dlv@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/dlv/-/dlv-1.1.3.tgz#5c198a8a11453596e751494d49874bc7732f2e79" + integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA== + duplexer3@^0.1.4: version "0.1.4" resolved "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz" integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== + elm-review@^2.5.0: version "2.5.0" resolved "https://registry.npmjs.org/elm-review/-/elm-review-2.5.0.tgz" @@ -286,6 +453,11 @@ emoji-regex@^8.0.0: resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + end-of-stream@^1.1.0: version "1.4.4" resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz" @@ -293,6 +465,17 @@ end-of-stream@^1.1.0: dependencies: once "^1.4.0" +fast-glob@^3.3.0: + version "3.3.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + fast-levenshtein@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-3.0.0.tgz" @@ -305,6 +488,13 @@ fastest-levenshtein@^1.0.7: resolved "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz" integrity sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow== +fastq@^1.6.0: + version "1.17.1" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47" + integrity sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w== + dependencies: + reusify "^1.0.4" + fill-range@^7.0.1: version "7.0.1" resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" @@ -312,6 +502,13 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" +fill-range@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" + integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== + dependencies: + to-regex-range "^5.0.1" + find-up@^4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz" @@ -329,6 +526,14 @@ folder-hash@^3.3.0: graceful-fs "~4.2.0" minimatch "~3.0.4" +foreground-child@^3.1.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.3.0.tgz#0ac8644c06e431439f8561db8ecf29a7b5519c77" + integrity sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg== + dependencies: + cross-spawn "^7.0.0" + signal-exit "^4.0.1" + fs-extra@^9.0.0: version "9.1.0" resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz" @@ -349,6 +554,16 @@ fsevents@~2.3.1: resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== +fsevents@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + get-stream@^5.0.0, get-stream@^5.1.0: version "5.2.0" resolved "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz" @@ -356,13 +571,32 @@ get-stream@^5.0.0, get-stream@^5.1.0: dependencies: pump "^3.0.0" -glob-parent@~5.1.0: +glob-parent@^5.1.2, glob-parent@~5.1.0, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" +glob-parent@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + +glob@^10.3.10: + version "10.4.5" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.5.tgz#f4d9f0b90ffdbab09c9d77f5f29b4262517b0956" + integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg== + dependencies: + foreground-child "^3.1.0" + jackspeak "^3.1.2" + minimatch "^9.0.4" + minipass "^7.1.2" + package-json-from-dist "^1.0.0" + path-scurry "^1.11.1" + glob@^7.1.3, glob@^7.1.4: version "7.1.6" resolved "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz" @@ -406,6 +640,13 @@ has-flag@^4.0.0: resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== +hasown@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" + integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== + dependencies: + function-bind "^1.1.2" + http-cache-semantics@^4.0.0: version "4.1.0" resolved "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz" @@ -436,6 +677,13 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" +is-core-module@^2.13.0: + version "2.15.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.15.1.tgz#a7363a25bee942fefab0de13bf6aa372c82dcc37" + integrity sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ== + dependencies: + hasown "^2.0.2" + is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" @@ -453,6 +701,13 @@ is-glob@^4.0.1, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" +is-glob@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + is-interactive@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz" @@ -473,6 +728,20 @@ isexe@^2.0.0: resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= +jackspeak@^3.1.2: + version "3.4.3" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-3.4.3.tgz#8833a9d89ab4acde6188942bd1c53b6390ed5a8a" + integrity sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + +jiti@^1.21.0: + version "1.21.6" + resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.6.tgz#6c7f7398dd4b3142767f9a168af2f317a428d268" + integrity sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w== + json-buffer@3.0.1: version "3.0.1" resolved "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz" @@ -499,6 +768,21 @@ kleur@^3.0.3: resolved "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== +lilconfig@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52" + integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== + +lilconfig@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-3.1.2.tgz#e4a7c3cb549e3a606c8dcc32e5ae1005e62c05cb" + integrity sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow== + +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + locate-path@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz" @@ -519,6 +803,24 @@ lowercase-keys@^2.0.0: resolved "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz" integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== +lru-cache@^10.2.0: + version "10.4.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" + integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== + +merge2@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +micromatch@^4.0.4, micromatch@^4.0.5: + version "4.0.8" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" + integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== + dependencies: + braces "^3.0.3" + picomatch "^2.3.1" + mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" @@ -541,11 +843,23 @@ minimatch@^3.0.4, minimatch@~3.0.4: dependencies: brace-expansion "^1.1.7" +minimatch@^9.0.4: + version "9.0.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" + integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== + dependencies: + brace-expansion "^2.0.1" + minimist@^1.2.0, minimist@^1.2.5: version "1.2.5" resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707" + integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== + mkdirp@^0.5.1: version "0.5.5" resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz" @@ -558,6 +872,20 @@ ms@2.1.2: resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +mz@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" + integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== + dependencies: + any-promise "^1.0.0" + object-assign "^4.0.1" + thenify-all "^1.0.0" + +nanoid@^3.3.7: + version "3.3.7" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" + integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== + normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" @@ -568,6 +896,16 @@ normalize-url@^4.1.0: resolved "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz" integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ== +object-assign@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + +object-hash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-3.0.0.tgz#73f97f753e7baffc0e2cc9d6e079079744ac82e9" + integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== + once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" @@ -640,6 +978,11 @@ p-try@^2.0.0: resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== +package-json-from-dist@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz#e501cd3094b278495eb4258d4c9f6d5ac3019f00" + integrity sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw== + path-exists@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" @@ -655,11 +998,97 @@ path-key@^3.1.0: resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-scurry@^1.11.1: + version "1.11.1" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.11.1.tgz#7960a668888594a0720b12a911d1a742ab9f11d2" + integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA== + dependencies: + lru-cache "^10.2.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + +picocolors@^1.0.0, picocolors@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.0.tgz#5358b76a78cde483ba5cef6a9dc9671440b27d59" + integrity sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw== + picomatch@^2.0.4, picomatch@^2.2.1: version "2.2.2" resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz" integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== +picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pify@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== + +pirates@^4.0.1: + version "4.0.6" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" + integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== + +postcss-import@^15.1.0: + version "15.1.0" + resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-15.1.0.tgz#41c64ed8cc0e23735a9698b3249ffdbf704adc70" + integrity sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew== + dependencies: + postcss-value-parser "^4.0.0" + read-cache "^1.0.0" + resolve "^1.1.7" + +postcss-js@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-4.0.1.tgz#61598186f3703bab052f1c4f7d805f3991bee9d2" + integrity sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw== + dependencies: + camelcase-css "^2.0.1" + +postcss-load-config@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-4.0.2.tgz#7159dcf626118d33e299f485d6afe4aff7c4a3e3" + integrity sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ== + dependencies: + lilconfig "^3.0.0" + yaml "^2.3.4" + +postcss-nested@^6.0.1: + version "6.2.0" + resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-6.2.0.tgz#4c2d22ab5f20b9cb61e2c5c5915950784d068131" + integrity sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ== + dependencies: + postcss-selector-parser "^6.1.1" + +postcss-selector-parser@^6.0.11, postcss-selector-parser@^6.1.1: + version "6.1.2" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz#27ecb41fb0e3b6ba7a1ec84fff347f734c7929de" + integrity sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-value-parser@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" + integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== + +postcss@^8.4.23: + version "8.4.47" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.47.tgz#5bf6c9a010f3e724c503bf03ef7947dcb0fea365" + integrity sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ== + dependencies: + nanoid "^3.3.7" + picocolors "^1.1.0" + source-map-js "^1.2.1" + prompts@^2.2.1: version "2.4.0" resolved "https://registry.npmjs.org/prompts/-/prompts-2.4.0.tgz" @@ -676,6 +1105,18 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +read-cache@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774" + integrity sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA== + dependencies: + pify "^2.3.0" + readable-stream@^3.4.0: version "3.6.0" resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz" @@ -692,6 +1133,22 @@ readdirp@~3.5.0: dependencies: picomatch "^2.2.1" +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +resolve@^1.1.7, resolve@^1.22.2: + version "1.22.8" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + responselike@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz" @@ -707,6 +1164,11 @@ restore-cursor@^3.1.0: onetime "^5.1.0" signal-exit "^3.0.2" +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + rimraf@~2.6.2: version "2.6.3" resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz" @@ -714,6 +1176,13 @@ rimraf@~2.6.2: dependencies: glob "^7.1.3" +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" @@ -736,11 +1205,30 @@ signal-exit@^3.0.2: resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz" integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== +signal-exit@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== + sisteransi@^1.0.5: version "1.0.5" resolved "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz" integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== +source-map-js@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" + integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== + +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + string-width@^4.1.0: version "4.2.2" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz" @@ -750,6 +1238,15 @@ string-width@^4.1.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.0" +string-width@^5.0.1, string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== + dependencies: + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" + string_decoder@^1.1.1: version "1.3.0" resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" @@ -757,6 +1254,13 @@ string_decoder@^1.1.1: dependencies: safe-buffer "~5.2.0" +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + strip-ansi@^6.0.0: version "6.0.0" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz" @@ -764,6 +1268,33 @@ strip-ansi@^6.0.0: dependencies: ansi-regex "^5.0.0" +strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^7.0.1: + version "7.1.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== + dependencies: + ansi-regex "^6.0.1" + +sucrase@^3.32.0: + version "3.35.0" + resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.35.0.tgz#57f17a3d7e19b36d8995f06679d121be914ae263" + integrity sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA== + dependencies: + "@jridgewell/gen-mapping" "^0.3.2" + commander "^4.0.0" + glob "^10.3.10" + lines-and-columns "^1.1.6" + mz "^2.7.0" + pirates "^4.0.1" + ts-interface-checker "^0.1.9" + supports-color@^7.0.0, supports-color@^7.1.0: version "7.2.0" resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" @@ -779,6 +1310,39 @@ supports-hyperlinks@^2.0.0: has-flag "^4.0.0" supports-color "^7.0.0" +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +tailwindcss@^3.4.12: + version "3.4.12" + resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.4.12.tgz#fd3b67c6d2c04d9d7bfa13e3fc70ccef9fef0455" + integrity sha512-Htf/gHj2+soPb9UayUNci/Ja3d8pTmu9ONTfh4QY8r3MATTZOzmv6UYWF7ZwikEIC8okpfqmGqrmDehua8mF8w== + dependencies: + "@alloc/quick-lru" "^5.2.0" + arg "^5.0.2" + chokidar "^3.5.3" + didyoumean "^1.2.2" + dlv "^1.1.3" + fast-glob "^3.3.0" + glob-parent "^6.0.2" + is-glob "^4.0.3" + jiti "^1.21.0" + lilconfig "^2.1.0" + micromatch "^4.0.5" + normalize-path "^3.0.0" + object-hash "^3.0.0" + picocolors "^1.0.0" + postcss "^8.4.23" + postcss-import "^15.1.0" + postcss-js "^4.0.1" + postcss-load-config "^4.0.1" + postcss-nested "^6.0.1" + postcss-selector-parser "^6.0.11" + resolve "^1.22.2" + sucrase "^3.32.0" + temp@^0.9.1: version "0.9.4" resolved "https://registry.npmjs.org/temp/-/temp-0.9.4.tgz" @@ -795,6 +1359,20 @@ terminal-link@^2.1.1: ansi-escapes "^4.2.1" supports-hyperlinks "^2.0.0" +thenify-all@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" + integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA== + dependencies: + thenify ">= 3.1.0 < 4" + +"thenify@>= 3.1.0 < 4": + version "3.3.1" + resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" + integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== + dependencies: + any-promise "^1.0.0" + to-readable-stream@^2.0.0: version "2.1.0" resolved "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-2.1.0.tgz" @@ -807,6 +1385,11 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" +ts-interface-checker@^0.1.9: + version "0.1.13" + resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699" + integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA== + type-fest@^0.10.0: version "0.10.0" resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.10.0.tgz" @@ -822,7 +1405,7 @@ universalify@^2.0.0: resolved "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz" integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== -util-deprecate@^1.0.1: +util-deprecate@^1.0.1, util-deprecate@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= @@ -841,6 +1424,15 @@ which@^2.0.1, which@^2.0.2: dependencies: isexe "^2.0.0" +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^6.2.0: version "6.2.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz" @@ -850,7 +1442,21 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== + dependencies: + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" + wrappy@1: version "1.0.2" resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +yaml@^2.3.4: + version "2.5.1" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.5.1.tgz#c9772aacf62cb7494a95b0c4f1fb065b563db130" + integrity sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==
m?u[c][f]=a+1:n.charAt(c-1)===r.charAt(f-1)?u[c][f]=u[c-1][f-1]:u[c][f]=Math.min(u[c-1][f-1]+1,Math.min(u[c][f-1]+1,u[c-1][f]+1)),u[c][f]a)return a+1}return u[o][s]}})()});var Rh=v((fD,qh)=>{l();var Oo="(".charCodeAt(0),Eo=")".charCodeAt(0),In="'".charCodeAt(0),To='"'.charCodeAt(0),Po="\\".charCodeAt(0),Vt="/".charCodeAt(0),Do=",".charCodeAt(0),Io=":".charCodeAt(0),qn="*".charCodeAt(0),a2="u".charCodeAt(0),o2="U".charCodeAt(0),l2="+".charCodeAt(0),u2=/^[a-f0-9?-]+$/i;qh.exports=function(i){for(var e=[],t=i,r,n,a,s,o,u,c,f,d=0,p=t.charCodeAt(d),m=t.length,b=[{nodes:e}],x=0,y,w="",k="",S="";d{l();Mh.exports=function i(e,t,r){var n,a,s,o;for(n=0,a=e.length;n{l();function Fh(i,e){var t=i.type,r=i.value,n,a;return e&&(a=e(i))!==void 0?a:t==="word"||t==="space"?r:t==="string"?(n=i.quote||"",n+r+(i.unclosed?"":n)):t==="comment"?"/*"+r+(i.unclosed?"":"*/"):t==="div"?(i.before||"")+r+(i.after||""):Array.isArray(i.nodes)?(n=Nh(i.nodes,e),t!=="function"?n:r+"("+(i.before||"")+n+(i.after||"")+(i.unclosed?"":")")):r}function Nh(i,e){var t,r;if(Array.isArray(i)){for(t="",r=i.length-1;~r;r-=1)t=Fh(i[r],e)+t;return t}return Fh(i,e)}Lh.exports=Nh});var zh=v((dD,jh)=>{l();var Rn="-".charCodeAt(0),Mn="+".charCodeAt(0),qo=".".charCodeAt(0),f2="e".charCodeAt(0),c2="E".charCodeAt(0);function p2(i){var e=i.charCodeAt(0),t;if(e===Mn||e===Rn){if(t=i.charCodeAt(1),t>=48&&t<=57)return!0;var r=i.charCodeAt(2);return t===qo&&r>=48&&r<=57}return e===qo?(t=i.charCodeAt(1),t>=48&&t<=57):e>=48&&e<=57}jh.exports=function(i){var e=0,t=i.length,r,n,a;if(t===0||!p2(i))return!1;for(r=i.charCodeAt(e),(r===Mn||r===Rn)&&e++;e57));)e+=1;if(r=i.charCodeAt(e),n=i.charCodeAt(e+1),r===qo&&n>=48&&n<=57)for(e+=2;e57));)e+=1;if(r=i.charCodeAt(e),n=i.charCodeAt(e+1),a=i.charCodeAt(e+2),(r===f2||r===c2)&&(n>=48&&n<=57||(n===Mn||n===Rn)&&a>=48&&a<=57))for(e+=n===Mn||n===Rn?3:2;e57));)e+=1;return{number:i.slice(0,e),unit:i.slice(e)}}});var Gh=v((hD,Wh)=>{l();var d2=Rh(),Vh=Bh(),Uh=$h();function ct(i){return this instanceof ct?(this.nodes=d2(i),this):new ct(i)}ct.prototype.toString=function(){return Array.isArray(this.nodes)?Uh(this.nodes):""};ct.prototype.walk=function(i,e){return Vh(this.nodes,i,e),this};ct.unit=zh();ct.walk=Vh;ct.stringify=Uh;Wh.exports=ct});function Mo(i){return typeof i=="object"&&i!==null}function h2(i,e){let t=Ke(e);do if(t.pop(),(0,ri.default)(i,t)!==void 0)break;while(t.length);return t.length?t:void 0}function Ut(i){return typeof i=="string"?i:i.reduce((e,t,r)=>t.includes(".")?`${e}[${t}]`:r===0?t:`${e}.${t}`,"")}function Yh(i){return i.map(e=>`'${e}'`).join(", ")}function Qh(i){return Yh(Object.keys(i))}function Bo(i,e,t,r={}){let n=Array.isArray(e)?Ut(e):e.replace(/^['"]+|['"]+$/g,""),a=Array.isArray(e)?e:Ke(n),s=(0,ri.default)(i.theme,a,t);if(s===void 0){let u=`'${n}' does not exist in your theme config.`,c=a.slice(0,-1),f=(0,ri.default)(i.theme,c);if(Mo(f)){let d=Object.keys(f).filter(m=>Bo(i,[...c,m]).isValid),p=(0,Hh.default)(a[a.length-1],d);p?u+=` Did you mean '${Ut([...c,p])}'?`:d.length>0&&(u+=` '${Ut(c)}' has the following valid keys: ${Yh(d)}`)}else{let d=h2(i.theme,n);if(d){let p=(0,ri.default)(i.theme,d);Mo(p)?u+=` '${Ut(d)}' has the following keys: ${Qh(p)}`:u+=` '${Ut(d)}' is not an object.`}else u+=` Your theme has the following top-level keys: ${Qh(i.theme)}`}return{isValid:!1,error:u}}if(!(typeof s=="string"||typeof s=="number"||typeof s=="function"||s instanceof String||s instanceof Number||Array.isArray(s))){let u=`'${n}' was found but does not resolve to a string.`;if(Mo(s)){let c=Object.keys(s).filter(f=>Bo(i,[...a,f]).isValid);c.length&&(u+=` Did you mean something like '${Ut([...a,c[0]])}'?`)}return{isValid:!1,error:u}}let[o]=a;return{isValid:!0,value:Ge(o)(s,r)}}function m2(i,e,t){e=e.map(n=>Jh(i,n,t));let r=[""];for(let n of e)n.type==="div"&&n.value===","?r.push(""):r[r.length-1]+=Ro.default.stringify(n);return r}function Jh(i,e,t){if(e.type==="function"&&t[e.value]!==void 0){let r=m2(i,e.nodes,t);e.type="word",e.value=t[e.value](i,...r)}return e}function g2(i,e,t){return Object.keys(t).some(n=>e.includes(`${n}(`))?(0,Ro.default)(e).walk(n=>{Jh(i,n,t)}).toString():e}function*w2(i){i=i.replace(/^['"]+|['"]+$/g,"");let e=i.match(/^([^\s]+)(?![^\[]*\])(?:\s*\/\s*([^\/\s]+))$/),t;yield[i,void 0],e&&(i=e[1],t=e[2],yield[i,t])}function b2(i,e,t){let r=Array.from(w2(e)).map(([n,a])=>Object.assign(Bo(i,n,t,{opacityValue:a}),{resolvedPath:n,alpha:a}));return r.find(n=>n.isValid)??r[0]}function Xh(i){let e=i.tailwindConfig,t={theme:(r,n,...a)=>{let{isValid:s,value:o,error:u,alpha:c}=b2(e,n,a.length?a:void 0);if(!s){let p=r.parent,m=p?.raws.tailwind?.candidate;if(p&&m!==void 0){i.markInvalidUtilityNode(p),p.remove(),F.warn("invalid-theme-key-in-class",[`The utility \`${m}\` contains an invalid theme value and was not generated.`]);return}throw r.error(u)}let f=At(o),d=f!==void 0&&typeof f=="function";return(c!==void 0||d)&&(c===void 0&&(c=1),o=qe(f,c,f)),o},screen:(r,n)=>{n=n.replace(/^['"]+/g,"").replace(/['"]+$/g,"");let s=at(e.theme.screens).find(({name:o})=>o===n);if(!s)throw r.error(`The '${n}' screen does not exist in your theme.`);return st(s)}};return r=>{r.walk(n=>{let a=y2[n.type];a!==void 0&&(n[a]=g2(n,n[a],t))})}}var ri,Hh,Ro,y2,Kh=C(()=>{l();ri=X(Ls()),Hh=X(Ih());Yr();Ro=X(Gh());hn();cn();pi();lr();pr();Ee();y2={atrule:"params",decl:"value"}});function Zh({tailwindConfig:{theme:i}}){return function(e){e.walkAtRules("screen",t=>{let r=t.params,a=at(i.screens).find(({name:s})=>s===r);if(!a)throw t.error(`No \`${r}\` screen found.`);t.name="media",t.params=st(a)})}}var em=C(()=>{l();hn();cn()});function v2(i){let e=i.filter(o=>o.type!=="pseudo"||o.nodes.length>0?!0:o.value.startsWith("::")||[":before",":after",":first-line",":first-letter"].includes(o.value)).reverse(),t=new Set(["tag","class","id","attribute"]),r=e.findIndex(o=>t.has(o.type));if(r===-1)return e.reverse().join("").trim();let n=e[r],a=tm[n.type]?tm[n.type](n):n;e=e.slice(0,r);let s=e.findIndex(o=>o.type==="combinator"&&o.value===">");return s!==-1&&(e.splice(0,s),e.unshift(Bn.default.universal())),[a,...e.reverse()].join("").trim()}function k2(i){return Fo.has(i)||Fo.set(i,x2.transformSync(i)),Fo.get(i)}function No({tailwindConfig:i}){return e=>{let t=new Map,r=new Set;if(e.walkAtRules("defaults",n=>{if(n.nodes&&n.nodes.length>0){r.add(n);return}let a=n.params;t.has(a)||t.set(a,new Set),t.get(a).add(n.parent),n.remove()}),Z(i,"optimizeUniversalDefaults"))for(let n of r){let a=new Map,s=t.get(n.params)??[];for(let o of s)for(let u of k2(o.selector)){let c=u.includes(":-")||u.includes("::-")||u.includes(":has")?u:"__DEFAULT__",f=a.get(c)??new Set;a.set(c,f),f.add(u)}if(Z(i,"optimizeUniversalDefaults")){if(a.size===0){n.remove();continue}for(let[,o]of a){let u=z.rule({source:n.source});u.selectors=[...o],u.append(n.nodes.map(c=>c.clone())),n.before(u)}}n.remove()}else if(r.size){let n=z.rule({selectors:["*","::before","::after"]});for(let s of r)n.append(s.nodes),n.parent||s.before(n),n.source||(n.source=s.source),s.remove();let a=n.clone({selectors:["::backdrop"]});n.after(a)}}}var Bn,tm,x2,Fo,rm=C(()=>{l();nt();Bn=X(Be());ze();tm={id(i){return Bn.default.attribute({attribute:"id",operator:"=",value:i.value,quoteMark:'"'})}};x2=(0,Bn.default)(i=>i.map(e=>{let t=e.split(r=>r.type==="combinator"&&r.value===" ").pop();return v2(t)})),Fo=new Map});function Lo(){function i(e){let t=null;e.each(r=>{if(!S2.has(r.type)){t=null;return}if(t===null){t=r;return}let n=im[r.type];r.type==="atrule"&&r.name==="font-face"?t=r:n.every(a=>(r[a]??"").replace(/\s+/g," ")===(t[a]??"").replace(/\s+/g," "))?(r.nodes&&t.append(r.nodes),r.remove()):t=r}),e.each(r=>{r.type==="atrule"&&i(r)})}return e=>{i(e)}}var im,S2,nm=C(()=>{l();im={atrule:["name","params"],rule:["selector"]},S2=new Set(Object.keys(im))});function $o(){return i=>{i.walkRules(e=>{let t=new Map,r=new Set([]),n=new Map;e.walkDecls(a=>{if(a.parent===e){if(t.has(a.prop)){if(t.get(a.prop).value===a.value){r.add(t.get(a.prop)),t.set(a.prop,a);return}n.has(a.prop)||n.set(a.prop,new Set),n.get(a.prop).add(t.get(a.prop)),n.get(a.prop).add(a)}t.set(a.prop,a)}});for(let a of r)a.remove();for(let a of n.values()){let s=new Map;for(let o of a){let u=A2(o.value);u!==null&&(s.has(u)||s.set(u,new Set),s.get(u).add(o))}for(let o of s.values()){let u=Array.from(o).slice(0,-1);for(let c of u)c.remove()}}})}}function A2(i){let e=/^-?\d*.?\d+([\w%]+)?$/g.exec(i);return e?e[1]??C2:null}var C2,sm=C(()=>{l();C2=Symbol("unitless-number")});function _2(i){if(!i.walkAtRules)return;let e=new Set;if(i.walkAtRules("apply",t=>{e.add(t.parent)}),e.size!==0)for(let t of e){let r=[],n=[];for(let a of t.nodes)a.type==="atrule"&&a.name==="apply"?(n.length>0&&(r.push(n),n=[]),r.push([a])):n.push(a);if(n.length>0&&r.push(n),r.length!==1){for(let a of[...r].reverse()){let s=t.clone({nodes:[]});s.append(a),t.after(s)}t.remove()}}}function Fn(){return i=>{_2(i)}}var am=C(()=>{l()});function Nn(i){return async function(e,t){let{tailwindDirectives:r,applyDirectives:n}=xo(e);Fn()(e,t);let a=i({tailwindDirectives:r,applyDirectives:n,registerDependency(s){t.messages.push({plugin:"tailwindcss",parent:t.opts.from,...s})},createContext(s,o){return co(s,o,e)}})(e,t);if(a.tailwindConfig.separator==="-")throw new Error("The '-' character cannot be used as a custom separator in JIT mode due to parsing ambiguity. Please use another character like '_' instead.");Su(a.tailwindConfig),await Co(a)(e,t),Fn()(e,t),_o(a)(e,t),Xh(a)(e,t),Zh(a)(e,t),No(a)(e,t),Lo(a)(e,t),$o(a)(e,t)}}var om=C(()=>{l();hh();Ah();Dh();Kh();em();rm();nm();sm();am();Xr();ze()});function lm(i,e){let t=null,r=null;return i.walkAtRules("config",n=>{if(r=n.source?.input.file??e.opts.from??null,r===null)throw n.error("The `@config` directive cannot be used without setting `from` in your PostCSS config.");if(t)throw n.error("Only one `@config` directive is allowed per file.");let a=n.params.match(/(['"])(.*?)\1/);if(!a)throw n.error("A path is required when using the `@config` directive.");let s=a[2];if(ee.isAbsolute(s))throw n.error("The `@config` directive cannot be used with an absolute path.");if(t=ee.resolve(ee.dirname(r),s),!re.existsSync(t))throw n.error(`The config file at "${s}" does not exist. Make sure the path is correct and the file exists.`);n.remove()}),t||null}var um=C(()=>{l();je();wt()});var fm=v((XD,jo)=>{l();dh();om();lt();um();jo.exports=function(e){return{postcssPlugin:"tailwindcss",plugins:[De.DEBUG&&function(t){return console.log(` +`),console.time("JIT TOTAL"),t},async function(t,r){e=lm(t,r)??e;let n=vo(e);if(t.type==="document"){let a=t.nodes.filter(s=>s.type==="root");for(let s of a)s.type==="root"&&await Nn(n)(s,r);return}await Nn(n)(t,r)},De.DEBUG&&function(t){return console.timeEnd("JIT TOTAL"),console.log(` +`),t}].filter(Boolean)}};jo.exports.postcss=!0});var pm=v((KD,cm)=>{l();cm.exports=fm()});var zo=v((ZD,dm)=>{l();dm.exports=()=>["and_chr 114","and_uc 15.5","chrome 114","chrome 113","chrome 109","edge 114","firefox 114","ios_saf 16.5","ios_saf 16.4","ios_saf 16.3","ios_saf 16.1","opera 99","safari 16.5","samsung 21"]});var Ln={};_e(Ln,{agents:()=>O2,feature:()=>E2});function E2(){return{status:"cr",title:"CSS Feature Queries",stats:{ie:{"6":"n","7":"n","8":"n","9":"n","10":"n","11":"n","5.5":"n"},edge:{"12":"y","13":"y","14":"y","15":"y","16":"y","17":"y","18":"y","79":"y","80":"y","81":"y","83":"y","84":"y","85":"y","86":"y","87":"y","88":"y","89":"y","90":"y","91":"y","92":"y","93":"y","94":"y","95":"y","96":"y","97":"y","98":"y","99":"y","100":"y","101":"y","102":"y","103":"y","104":"y","105":"y","106":"y","107":"y","108":"y","109":"y","110":"y","111":"y","112":"y","113":"y","114":"y"},firefox:{"2":"n","3":"n","4":"n","5":"n","6":"n","7":"n","8":"n","9":"n","10":"n","11":"n","12":"n","13":"n","14":"n","15":"n","16":"n","17":"n","18":"n","19":"n","20":"n","21":"n","22":"y","23":"y","24":"y","25":"y","26":"y","27":"y","28":"y","29":"y","30":"y","31":"y","32":"y","33":"y","34":"y","35":"y","36":"y","37":"y","38":"y","39":"y","40":"y","41":"y","42":"y","43":"y","44":"y","45":"y","46":"y","47":"y","48":"y","49":"y","50":"y","51":"y","52":"y","53":"y","54":"y","55":"y","56":"y","57":"y","58":"y","59":"y","60":"y","61":"y","62":"y","63":"y","64":"y","65":"y","66":"y","67":"y","68":"y","69":"y","70":"y","71":"y","72":"y","73":"y","74":"y","75":"y","76":"y","77":"y","78":"y","79":"y","80":"y","81":"y","82":"y","83":"y","84":"y","85":"y","86":"y","87":"y","88":"y","89":"y","90":"y","91":"y","92":"y","93":"y","94":"y","95":"y","96":"y","97":"y","98":"y","99":"y","100":"y","101":"y","102":"y","103":"y","104":"y","105":"y","106":"y","107":"y","108":"y","109":"y","110":"y","111":"y","112":"y","113":"y","114":"y","115":"y","116":"y","117":"y","3.5":"n","3.6":"n"},chrome:{"4":"n","5":"n","6":"n","7":"n","8":"n","9":"n","10":"n","11":"n","12":"n","13":"n","14":"n","15":"n","16":"n","17":"n","18":"n","19":"n","20":"n","21":"n","22":"n","23":"n","24":"n","25":"n","26":"n","27":"n","28":"y","29":"y","30":"y","31":"y","32":"y","33":"y","34":"y","35":"y","36":"y","37":"y","38":"y","39":"y","40":"y","41":"y","42":"y","43":"y","44":"y","45":"y","46":"y","47":"y","48":"y","49":"y","50":"y","51":"y","52":"y","53":"y","54":"y","55":"y","56":"y","57":"y","58":"y","59":"y","60":"y","61":"y","62":"y","63":"y","64":"y","65":"y","66":"y","67":"y","68":"y","69":"y","70":"y","71":"y","72":"y","73":"y","74":"y","75":"y","76":"y","77":"y","78":"y","79":"y","80":"y","81":"y","83":"y","84":"y","85":"y","86":"y","87":"y","88":"y","89":"y","90":"y","91":"y","92":"y","93":"y","94":"y","95":"y","96":"y","97":"y","98":"y","99":"y","100":"y","101":"y","102":"y","103":"y","104":"y","105":"y","106":"y","107":"y","108":"y","109":"y","110":"y","111":"y","112":"y","113":"y","114":"y","115":"y","116":"y","117":"y"},safari:{"4":"n","5":"n","6":"n","7":"n","8":"n","9":"y","10":"y","11":"y","12":"y","13":"y","14":"y","15":"y","17":"y","9.1":"y","10.1":"y","11.1":"y","12.1":"y","13.1":"y","14.1":"y","15.1":"y","15.2-15.3":"y","15.4":"y","15.5":"y","15.6":"y","16.0":"y","16.1":"y","16.2":"y","16.3":"y","16.4":"y","16.5":"y","16.6":"y",TP:"y","3.1":"n","3.2":"n","5.1":"n","6.1":"n","7.1":"n"},opera:{"9":"n","11":"n","12":"n","15":"y","16":"y","17":"y","18":"y","19":"y","20":"y","21":"y","22":"y","23":"y","24":"y","25":"y","26":"y","27":"y","28":"y","29":"y","30":"y","31":"y","32":"y","33":"y","34":"y","35":"y","36":"y","37":"y","38":"y","39":"y","40":"y","41":"y","42":"y","43":"y","44":"y","45":"y","46":"y","47":"y","48":"y","49":"y","50":"y","51":"y","52":"y","53":"y","54":"y","55":"y","56":"y","57":"y","58":"y","60":"y","62":"y","63":"y","64":"y","65":"y","66":"y","67":"y","68":"y","69":"y","70":"y","71":"y","72":"y","73":"y","74":"y","75":"y","76":"y","77":"y","78":"y","79":"y","80":"y","81":"y","82":"y","83":"y","84":"y","85":"y","86":"y","87":"y","88":"y","89":"y","90":"y","91":"y","92":"y","93":"y","94":"y","95":"y","96":"y","97":"y","98":"y","99":"y","100":"y","12.1":"y","9.5-9.6":"n","10.0-10.1":"n","10.5":"n","10.6":"n","11.1":"n","11.5":"n","11.6":"n"},ios_saf:{"8":"n","17":"y","9.0-9.2":"y","9.3":"y","10.0-10.2":"y","10.3":"y","11.0-11.2":"y","11.3-11.4":"y","12.0-12.1":"y","12.2-12.5":"y","13.0-13.1":"y","13.2":"y","13.3":"y","13.4-13.7":"y","14.0-14.4":"y","14.5-14.8":"y","15.0-15.1":"y","15.2-15.3":"y","15.4":"y","15.5":"y","15.6":"y","16.0":"y","16.1":"y","16.2":"y","16.3":"y","16.4":"y","16.5":"y","16.6":"y","3.2":"n","4.0-4.1":"n","4.2-4.3":"n","5.0-5.1":"n","6.0-6.1":"n","7.0-7.1":"n","8.1-8.4":"n"},op_mini:{all:"y"},android:{"3":"n","4":"n","114":"y","4.4":"y","4.4.3-4.4.4":"y","2.1":"n","2.2":"n","2.3":"n","4.1":"n","4.2-4.3":"n"},bb:{"7":"n","10":"n"},op_mob:{"10":"n","11":"n","12":"n","73":"y","11.1":"n","11.5":"n","12.1":"n"},and_chr:{"114":"y"},and_ff:{"115":"y"},ie_mob:{"10":"n","11":"n"},and_uc:{"15.5":"y"},samsung:{"4":"y","20":"y","21":"y","5.0-5.4":"y","6.2-6.4":"y","7.2-7.4":"y","8.2":"y","9.2":"y","10.1":"y","11.1-11.2":"y","12.0":"y","13.0":"y","14.0":"y","15.0":"y","16.0":"y","17.0":"y","18.0":"y","19.0":"y"},and_qq:{"13.1":"y"},baidu:{"13.18":"y"},kaios:{"2.5":"y","3.0-3.1":"y"}}}}var O2,$n=C(()=>{l();O2={ie:{prefix:"ms"},edge:{prefix:"webkit",prefix_exceptions:{"12":"ms","13":"ms","14":"ms","15":"ms","16":"ms","17":"ms","18":"ms"}},firefox:{prefix:"moz"},chrome:{prefix:"webkit"},safari:{prefix:"webkit"},opera:{prefix:"webkit",prefix_exceptions:{"9":"o","11":"o","12":"o","9.5-9.6":"o","10.0-10.1":"o","10.5":"o","10.6":"o","11.1":"o","11.5":"o","11.6":"o","12.1":"o"}},ios_saf:{prefix:"webkit"},op_mini:{prefix:"o"},android:{prefix:"webkit"},bb:{prefix:"webkit"},op_mob:{prefix:"o",prefix_exceptions:{"73":"webkit"}},and_chr:{prefix:"webkit"},and_ff:{prefix:"moz"},ie_mob:{prefix:"ms"},and_uc:{prefix:"webkit",prefix_exceptions:{"15.5":"webkit"}},samsung:{prefix:"webkit"},and_qq:{prefix:"webkit"},baidu:{prefix:"webkit"},kaios:{prefix:"moz"}}});var hm=v(()=>{l()});var ue=v((r4,pt)=>{l();var{list:Vo}=ye();pt.exports.error=function(i){let e=new Error(i);throw e.autoprefixer=!0,e};pt.exports.uniq=function(i){return[...new Set(i)]};pt.exports.removeNote=function(i){return i.includes(" ")?i.split(" ")[0]:i};pt.exports.escapeRegexp=function(i){return i.replace(/[$()*+-.?[\\\]^{|}]/g,"\\$&")};pt.exports.regexp=function(i,e=!0){return e&&(i=this.escapeRegexp(i)),new RegExp(`(^|[\\s,(])(${i}($|[\\s(,]))`,"gi")};pt.exports.editList=function(i,e){let t=Vo.comma(i),r=e(t,[]);if(t===r)return i;let n=i.match(/,\s*/);return n=n?n[0]:", ",r.join(n)};pt.exports.splitSelector=function(i){return Vo.comma(i).map(e=>Vo.space(e).map(t=>t.split(/(?=\.|#)/g)))}});var dt=v((i4,ym)=>{l();var T2=zo(),mm=($n(),Ln).agents,P2=ue(),gm=class{static prefixes(){if(this.prefixesCache)return this.prefixesCache;this.prefixesCache=[];for(let e in mm)this.prefixesCache.push(`-${mm[e].prefix}-`);return this.prefixesCache=P2.uniq(this.prefixesCache).sort((e,t)=>t.length-e.length),this.prefixesCache}static withPrefix(e){return this.prefixesRegexp||(this.prefixesRegexp=new RegExp(this.prefixes().join("|"))),this.prefixesRegexp.test(e)}constructor(e,t,r,n){this.data=e,this.options=r||{},this.browserslistOpts=n||{},this.selected=this.parse(t)}parse(e){let t={};for(let r in this.browserslistOpts)t[r]=this.browserslistOpts[r];return t.path=this.options.from,T2(e,t)}prefix(e){let[t,r]=e.split(" "),n=this.data[t],a=n.prefix_exceptions&&n.prefix_exceptions[r];return a||(a=n.prefix),`-${a}-`}isSelected(e){return this.selected.includes(e)}};ym.exports=gm});var ii=v((n4,wm)=>{l();wm.exports={prefix(i){let e=i.match(/^(-\w+-)/);return e?e[0]:""},unprefixed(i){return i.replace(/^-\w+-/,"")}}});var Wt=v((s4,vm)=>{l();var D2=dt(),bm=ii(),I2=ue();function Uo(i,e){let t=new i.constructor;for(let r of Object.keys(i||{})){let n=i[r];r==="parent"&&typeof n=="object"?e&&(t[r]=e):r==="source"||r===null?t[r]=n:Array.isArray(n)?t[r]=n.map(a=>Uo(a,t)):r!=="_autoprefixerPrefix"&&r!=="_autoprefixerValues"&&r!=="proxyCache"&&(typeof n=="object"&&n!==null&&(n=Uo(n,t)),t[r]=n)}return t}var jn=class{static hack(e){return this.hacks||(this.hacks={}),e.names.map(t=>(this.hacks[t]=e,this.hacks[t]))}static load(e,t,r){let n=this.hacks&&this.hacks[e];return n?new n(e,t,r):new this(e,t,r)}static clone(e,t){let r=Uo(e);for(let n in t)r[n]=t[n];return r}constructor(e,t,r){this.prefixes=t,this.name=e,this.all=r}parentPrefix(e){let t;return typeof e._autoprefixerPrefix!="undefined"?t=e._autoprefixerPrefix:e.type==="decl"&&e.prop[0]==="-"?t=bm.prefix(e.prop):e.type==="root"?t=!1:e.type==="rule"&&e.selector.includes(":-")&&/:(-\w+-)/.test(e.selector)?t=e.selector.match(/:(-\w+-)/)[1]:e.type==="atrule"&&e.name[0]==="-"?t=bm.prefix(e.name):t=this.parentPrefix(e.parent),D2.prefixes().includes(t)||(t=!1),e._autoprefixerPrefix=t,e._autoprefixerPrefix}process(e,t){if(!this.check(e))return;let r=this.parentPrefix(e),n=this.prefixes.filter(s=>!r||r===I2.removeNote(s)),a=[];for(let s of n)this.add(e,s,a.concat([s]),t)&&a.push(s);return a}clone(e,t){return jn.clone(e,t)}};vm.exports=jn});var M=v((a4,Sm)=>{l();var q2=Wt(),R2=dt(),xm=ue(),km=class extends q2{check(){return!0}prefixed(e,t){return t+e}normalize(e){return e}otherPrefixes(e,t){for(let r of R2.prefixes())if(r!==t&&e.includes(r))return!0;return!1}set(e,t){return e.prop=this.prefixed(e.prop,t),e}needCascade(e){return e._autoprefixerCascade||(e._autoprefixerCascade=this.all.options.cascade!==!1&&e.raw("before").includes(` +`)),e._autoprefixerCascade}maxPrefixed(e,t){if(t._autoprefixerMax)return t._autoprefixerMax;let r=0;for(let n of e)n=xm.removeNote(n),n.length>r&&(r=n.length);return t._autoprefixerMax=r,t._autoprefixerMax}calcBefore(e,t,r=""){let a=this.maxPrefixed(e,t)-xm.removeNote(r).length,s=t.raw("before");return a>0&&(s+=Array(a).fill(" ").join("")),s}restoreBefore(e){let t=e.raw("before").split(` +`),r=t[t.length-1];this.all.group(e).up(n=>{let a=n.raw("before").split(` +`),s=a[a.length-1];s.lengths.prop===n.prop&&s.value===n.value)))return this.needCascade(e)&&(n.raws.before=this.calcBefore(r,e,t)),e.parent.insertBefore(e,n)}isAlready(e,t){let r=this.all.group(e).up(n=>n.prop===t);return r||(r=this.all.group(e).down(n=>n.prop===t)),r}add(e,t,r,n){let a=this.prefixed(e.prop,t);if(!(this.isAlready(e,a)||this.otherPrefixes(e.value,t)))return this.insert(e,t,r,n)}process(e,t){if(!this.needCascade(e)){super.process(e,t);return}let r=super.process(e,t);!r||!r.length||(this.restoreBefore(e),e.raws.before=this.calcBefore(r,e))}old(e,t){return[this.prefixed(e,t)]}};Sm.exports=km});var Am=v((o4,Cm)=>{l();Cm.exports=function i(e){return{mul:t=>new i(e*t),div:t=>new i(e/t),simplify:()=>new i(e),toString:()=>e.toString()}}});var Em=v((l4,Om)=>{l();var M2=Am(),B2=Wt(),Wo=ue(),F2=/(min|max)-resolution\s*:\s*\d*\.?\d+(dppx|dpcm|dpi|x)/gi,N2=/(min|max)-resolution(\s*:\s*)(\d*\.?\d+)(dppx|dpcm|dpi|x)/i,_m=class extends B2{prefixName(e,t){return e==="-moz-"?t+"--moz-device-pixel-ratio":e+t+"-device-pixel-ratio"}prefixQuery(e,t,r,n,a){return n=new M2(n),a==="dpi"?n=n.div(96):a==="dpcm"&&(n=n.mul(2.54).div(96)),n=n.simplify(),e==="-o-"&&(n=n.n+"/"+n.d),this.prefixName(e,t)+r+n}clean(e){if(!this.bad){this.bad=[];for(let t of this.prefixes)this.bad.push(this.prefixName(t,"min")),this.bad.push(this.prefixName(t,"max"))}e.params=Wo.editList(e.params,t=>t.filter(r=>this.bad.every(n=>!r.includes(n))))}process(e){let t=this.parentPrefix(e),r=t?[t]:this.prefixes;e.params=Wo.editList(e.params,(n,a)=>{for(let s of n){if(!s.includes("min-resolution")&&!s.includes("max-resolution")){a.push(s);continue}for(let o of r){let u=s.replace(F2,c=>{let f=c.match(N2);return this.prefixQuery(o,f[1],f[2],f[3],f[4])});a.push(u)}a.push(s)}return Wo.uniq(a)})}};Om.exports=_m});var Pm=v((u4,Tm)=>{l();var Go="(".charCodeAt(0),Ho=")".charCodeAt(0),zn="'".charCodeAt(0),Yo='"'.charCodeAt(0),Qo="\\".charCodeAt(0),Gt="/".charCodeAt(0),Jo=",".charCodeAt(0),Xo=":".charCodeAt(0),Vn="*".charCodeAt(0),L2="u".charCodeAt(0),$2="U".charCodeAt(0),j2="+".charCodeAt(0),z2=/^[a-f0-9?-]+$/i;Tm.exports=function(i){for(var e=[],t=i,r,n,a,s,o,u,c,f,d=0,p=t.charCodeAt(d),m=t.length,b=[{nodes:e}],x=0,y,w="",k="",S="";d{l();Dm.exports=function i(e,t,r){var n,a,s,o;for(n=0,a=e.length;n{l();function qm(i,e){var t=i.type,r=i.value,n,a;return e&&(a=e(i))!==void 0?a:t==="word"||t==="space"?r:t==="string"?(n=i.quote||"",n+r+(i.unclosed?"":n)):t==="comment"?"/*"+r+(i.unclosed?"":"*/"):t==="div"?(i.before||"")+r+(i.after||""):Array.isArray(i.nodes)?(n=Rm(i.nodes,e),t!=="function"?n:r+"("+(i.before||"")+n+(i.after||"")+(i.unclosed?"":")")):r}function Rm(i,e){var t,r;if(Array.isArray(i)){for(t="",r=i.length-1;~r;r-=1)t=qm(i[r],e)+t;return t}return qm(i,e)}Mm.exports=Rm});var Nm=v((p4,Fm)=>{l();var Un="-".charCodeAt(0),Wn="+".charCodeAt(0),Ko=".".charCodeAt(0),V2="e".charCodeAt(0),U2="E".charCodeAt(0);function W2(i){var e=i.charCodeAt(0),t;if(e===Wn||e===Un){if(t=i.charCodeAt(1),t>=48&&t<=57)return!0;var r=i.charCodeAt(2);return t===Ko&&r>=48&&r<=57}return e===Ko?(t=i.charCodeAt(1),t>=48&&t<=57):e>=48&&e<=57}Fm.exports=function(i){var e=0,t=i.length,r,n,a;if(t===0||!W2(i))return!1;for(r=i.charCodeAt(e),(r===Wn||r===Un)&&e++;e57));)e+=1;if(r=i.charCodeAt(e),n=i.charCodeAt(e+1),r===Ko&&n>=48&&n<=57)for(e+=2;e57));)e+=1;if(r=i.charCodeAt(e),n=i.charCodeAt(e+1),a=i.charCodeAt(e+2),(r===V2||r===U2)&&(n>=48&&n<=57||(n===Wn||n===Un)&&a>=48&&a<=57))for(e+=n===Wn||n===Un?3:2;e57));)e+=1;return{number:i.slice(0,e),unit:i.slice(e)}}});var Gn=v((d4,jm)=>{l();var G2=Pm(),Lm=Im(),$m=Bm();function ht(i){return this instanceof ht?(this.nodes=G2(i),this):new ht(i)}ht.prototype.toString=function(){return Array.isArray(this.nodes)?$m(this.nodes):""};ht.prototype.walk=function(i,e){return Lm(this.nodes,i,e),this};ht.unit=Nm();ht.walk=Lm;ht.stringify=$m;jm.exports=ht});var Gm=v((h4,Wm)=>{l();var{list:H2}=ye(),zm=Gn(),Y2=dt(),Vm=ii(),Um=class{constructor(e){this.props=["transition","transition-property"],this.prefixes=e}add(e,t){let r,n,a=this.prefixes.add[e.prop],s=this.ruleVendorPrefixes(e),o=s||a&&a.prefixes||[],u=this.parse(e.value),c=u.map(m=>this.findProp(m)),f=[];if(c.some(m=>m[0]==="-"))return;for(let m of u){if(n=this.findProp(m),n[0]==="-")continue;let b=this.prefixes.add[n];if(!(!b||!b.prefixes))for(r of b.prefixes){if(s&&!s.some(y=>r.includes(y)))continue;let x=this.prefixes.prefixed(n,r);x!=="-ms-transform"&&!c.includes(x)&&(this.disabled(n,r)||f.push(this.clone(n,x,m)))}}u=u.concat(f);let d=this.stringify(u),p=this.stringify(this.cleanFromUnprefixed(u,"-webkit-"));if(o.includes("-webkit-")&&this.cloneBefore(e,`-webkit-${e.prop}`,p),this.cloneBefore(e,e.prop,p),o.includes("-o-")){let m=this.stringify(this.cleanFromUnprefixed(u,"-o-"));this.cloneBefore(e,`-o-${e.prop}`,m)}for(r of o)if(r!=="-webkit-"&&r!=="-o-"){let m=this.stringify(this.cleanOtherPrefixes(u,r));this.cloneBefore(e,r+e.prop,m)}d!==e.value&&!this.already(e,e.prop,d)&&(this.checkForWarning(t,e),e.cloneBefore(),e.value=d)}findProp(e){let t=e[0].value;if(/^\d/.test(t)){for(let[r,n]of e.entries())if(r!==0&&n.type==="word")return n.value}return t}already(e,t,r){return e.parent.some(n=>n.prop===t&&n.value===r)}cloneBefore(e,t,r){this.already(e,t,r)||e.cloneBefore({prop:t,value:r})}checkForWarning(e,t){if(t.prop!=="transition-property")return;let r=!1,n=!1;t.parent.each(a=>{if(a.type!=="decl"||a.prop.indexOf("transition-")!==0)return;let s=H2.comma(a.value);if(a.prop==="transition-property"){s.forEach(o=>{let u=this.prefixes.add[o];u&&u.prefixes&&u.prefixes.length>0&&(r=!0)});return}return n=n||s.length>1,!1}),r&&n&&t.warn(e,"Replace transition-property to transition, because Autoprefixer could not support any cases of transition-property and other transition-*")}remove(e){let t=this.parse(e.value);t=t.filter(s=>{let o=this.prefixes.remove[this.findProp(s)];return!o||!o.remove});let r=this.stringify(t);if(e.value===r)return;if(t.length===0){e.remove();return}let n=e.parent.some(s=>s.prop===e.prop&&s.value===r),a=e.parent.some(s=>s!==e&&s.prop===e.prop&&s.value.length>r.length);if(n||a){e.remove();return}e.value=r}parse(e){let t=zm(e),r=[],n=[];for(let a of t.nodes)n.push(a),a.type==="div"&&a.value===","&&(r.push(n),n=[]);return r.push(n),r.filter(a=>a.length>0)}stringify(e){if(e.length===0)return"";let t=[];for(let r of e)r[r.length-1].type!=="div"&&r.push(this.div(e)),t=t.concat(r);return t[0].type==="div"&&(t=t.slice(1)),t[t.length-1].type==="div"&&(t=t.slice(0,-2+1||void 0)),zm.stringify({nodes:t})}clone(e,t,r){let n=[],a=!1;for(let s of r)!a&&s.type==="word"&&s.value===e?(n.push({type:"word",value:t}),a=!0):n.push(s);return n}div(e){for(let t of e)for(let r of t)if(r.type==="div"&&r.value===",")return r;return{type:"div",value:",",after:" "}}cleanOtherPrefixes(e,t){return e.filter(r=>{let n=Vm.prefix(this.findProp(r));return n===""||n===t})}cleanFromUnprefixed(e,t){let r=e.map(a=>this.findProp(a)).filter(a=>a.slice(0,t.length)===t).map(a=>this.prefixes.unprefixed(a)),n=[];for(let a of e){let s=this.findProp(a),o=Vm.prefix(s);!r.includes(s)&&(o===t||o==="")&&n.push(a)}return n}disabled(e,t){let r=["order","justify-content","align-self","align-content"];if(e.includes("flex")||r.includes(e)){if(this.prefixes.options.flexbox===!1)return!0;if(this.prefixes.options.flexbox==="no-2009")return t.includes("2009")}}ruleVendorPrefixes(e){let{parent:t}=e;if(t.type!=="rule")return!1;if(!t.selector.includes(":-"))return!1;let r=Y2.prefixes().filter(n=>t.selector.includes(":"+n));return r.length>0?r:!1}};Wm.exports=Um});var Ht=v((m4,Ym)=>{l();var Q2=ue(),Hm=class{constructor(e,t,r,n){this.unprefixed=e,this.prefixed=t,this.string=r||t,this.regexp=n||Q2.regexp(t)}check(e){return e.includes(this.string)?!!e.match(this.regexp):!1}};Ym.exports=Hm});var Se=v((g4,Jm)=>{l();var J2=Wt(),X2=Ht(),K2=ii(),Z2=ue(),Qm=class extends J2{static save(e,t){let r=t.prop,n=[];for(let a in t._autoprefixerValues){let s=t._autoprefixerValues[a];if(s===t.value)continue;let o,u=K2.prefix(r);if(u==="-pie-")continue;if(u===a){o=t.value=s,n.push(o);continue}let c=e.prefixed(r,a),f=t.parent;if(!f.every(b=>b.prop!==c)){n.push(o);continue}let d=s.replace(/\s+/," ");if(f.some(b=>b.prop===t.prop&&b.value.replace(/\s+/," ")===d)){n.push(o);continue}let m=this.clone(t,{value:s});o=t.parent.insertBefore(t,m),n.push(o)}return n}check(e){let t=e.value;return t.includes(this.name)?!!t.match(this.regexp()):!1}regexp(){return this.regexpCache||(this.regexpCache=Z2.regexp(this.name))}replace(e,t){return e.replace(this.regexp(),`$1${t}$2`)}value(e){return e.raws.value&&e.raws.value.value===e.value?e.raws.value.raw:e.value}add(e,t){e._autoprefixerValues||(e._autoprefixerValues={});let r=e._autoprefixerValues[t]||this.value(e),n;do if(n=r,r=this.replace(r,t),r===!1)return;while(r!==n);e._autoprefixerValues[t]=r}old(e){return new X2(this.name,e+this.name)}};Jm.exports=Qm});var mt=v((y4,Xm)=>{l();Xm.exports={}});var el=v((w4,eg)=>{l();var Km=Gn(),eA=Se(),tA=mt().insertAreas,rA=/(^|[^-])linear-gradient\(\s*(top|left|right|bottom)/i,iA=/(^|[^-])radial-gradient\(\s*\d+(\w*|%)\s+\d+(\w*|%)\s*,/i,nA=/(!\s*)?autoprefixer:\s*ignore\s+next/i,sA=/(!\s*)?autoprefixer\s*grid:\s*(on|off|(no-)?autoplace)/i,aA=["width","height","min-width","max-width","min-height","max-height","inline-size","min-inline-size","max-inline-size","block-size","min-block-size","max-block-size"];function Zo(i){return i.parent.some(e=>e.prop==="grid-template"||e.prop==="grid-template-areas")}function oA(i){let e=i.parent.some(r=>r.prop==="grid-template-rows"),t=i.parent.some(r=>r.prop==="grid-template-columns");return e&&t}var Zm=class{constructor(e){this.prefixes=e}add(e,t){let r=this.prefixes.add["@resolution"],n=this.prefixes.add["@keyframes"],a=this.prefixes.add["@viewport"],s=this.prefixes.add["@supports"];e.walkAtRules(f=>{if(f.name==="keyframes"){if(!this.disabled(f,t))return n&&n.process(f)}else if(f.name==="viewport"){if(!this.disabled(f,t))return a&&a.process(f)}else if(f.name==="supports"){if(this.prefixes.options.supports!==!1&&!this.disabled(f,t))return s.process(f)}else if(f.name==="media"&&f.params.includes("-resolution")&&!this.disabled(f,t))return r&&r.process(f)}),e.walkRules(f=>{if(!this.disabled(f,t))return this.prefixes.add.selectors.map(d=>d.process(f,t))});function o(f){return f.parent.nodes.some(d=>{if(d.type!=="decl")return!1;let p=d.prop==="display"&&/(inline-)?grid/.test(d.value),m=d.prop.startsWith("grid-template"),b=/^grid-([A-z]+-)?gap/.test(d.prop);return p||m||b})}function u(f){return f.parent.some(d=>d.prop==="display"&&/(inline-)?flex/.test(d.value))}let c=this.gridStatus(e,t)&&this.prefixes.add["grid-area"]&&this.prefixes.add["grid-area"].prefixes;return e.walkDecls(f=>{if(this.disabledDecl(f,t))return;let d=f.parent,p=f.prop,m=f.value;if(p==="grid-row-span"){t.warn("grid-row-span is not part of final Grid Layout. Use grid-row.",{node:f});return}else if(p==="grid-column-span"){t.warn("grid-column-span is not part of final Grid Layout. Use grid-column.",{node:f});return}else if(p==="display"&&m==="box"){t.warn("You should write display: flex by final spec instead of display: box",{node:f});return}else if(p==="text-emphasis-position")(m==="under"||m==="over")&&t.warn("You should use 2 values for text-emphasis-position For example, `under left` instead of just `under`.",{node:f});else if(/^(align|justify|place)-(items|content)$/.test(p)&&u(f))(m==="start"||m==="end")&&t.warn(`${m} value has mixed support, consider using flex-${m} instead`,{node:f});else if(p==="text-decoration-skip"&&m==="ink")t.warn("Replace text-decoration-skip: ink to text-decoration-skip-ink: auto, because spec had been changed",{node:f});else{if(c&&this.gridStatus(f,t))if(f.value==="subgrid"&&t.warn("IE does not support subgrid",{node:f}),/^(align|justify|place)-items$/.test(p)&&o(f)){let x=p.replace("-items","-self");t.warn(`IE does not support ${p} on grid containers. Try using ${x} on child elements instead: ${f.parent.selector} > * { ${x}: ${f.value} }`,{node:f})}else if(/^(align|justify|place)-content$/.test(p)&&o(f))t.warn(`IE does not support ${f.prop} on grid containers`,{node:f});else if(p==="display"&&f.value==="contents"){t.warn("Please do not use display: contents; if you have grid setting enabled",{node:f});return}else if(f.prop==="grid-gap"){let x=this.gridStatus(f,t);x==="autoplace"&&!oA(f)&&!Zo(f)?t.warn("grid-gap only works if grid-template(-areas) is being used or both rows and columns have been declared and cells have not been manually placed inside the explicit grid",{node:f}):(x===!0||x==="no-autoplace")&&!Zo(f)&&t.warn("grid-gap only works if grid-template(-areas) is being used",{node:f})}else if(p==="grid-auto-columns"){t.warn("grid-auto-columns is not supported by IE",{node:f});return}else if(p==="grid-auto-rows"){t.warn("grid-auto-rows is not supported by IE",{node:f});return}else if(p==="grid-auto-flow"){let x=d.some(w=>w.prop==="grid-template-rows"),y=d.some(w=>w.prop==="grid-template-columns");Zo(f)?t.warn("grid-auto-flow is not supported by IE",{node:f}):m.includes("dense")?t.warn("grid-auto-flow: dense is not supported by IE",{node:f}):!x&&!y&&t.warn("grid-auto-flow works only if grid-template-rows and grid-template-columns are present in the same rule",{node:f});return}else if(m.includes("auto-fit")){t.warn("auto-fit value is not supported by IE",{node:f,word:"auto-fit"});return}else if(m.includes("auto-fill")){t.warn("auto-fill value is not supported by IE",{node:f,word:"auto-fill"});return}else p.startsWith("grid-template")&&m.includes("[")&&t.warn("Autoprefixer currently does not support line names. Try using grid-template-areas instead.",{node:f,word:"["});if(m.includes("radial-gradient"))if(iA.test(f.value))t.warn("Gradient has outdated direction syntax. New syntax is like `closest-side at 0 0` instead of `0 0, closest-side`.",{node:f});else{let x=Km(m);for(let y of x.nodes)if(y.type==="function"&&y.value==="radial-gradient")for(let w of y.nodes)w.type==="word"&&(w.value==="cover"?t.warn("Gradient has outdated direction syntax. Replace `cover` to `farthest-corner`.",{node:f}):w.value==="contain"&&t.warn("Gradient has outdated direction syntax. Replace `contain` to `closest-side`.",{node:f}))}m.includes("linear-gradient")&&rA.test(m)&&t.warn("Gradient has outdated direction syntax. New syntax is like `to left` instead of `right`.",{node:f})}aA.includes(f.prop)&&(f.value.includes("-fill-available")||(f.value.includes("fill-available")?t.warn("Replace fill-available to stretch, because spec had been changed",{node:f}):f.value.includes("fill")&&Km(m).nodes.some(y=>y.type==="word"&&y.value==="fill")&&t.warn("Replace fill to stretch, because spec had been changed",{node:f})));let b;if(f.prop==="transition"||f.prop==="transition-property")return this.prefixes.transition.add(f,t);if(f.prop==="align-self"){if(this.displayType(f)!=="grid"&&this.prefixes.options.flexbox!==!1&&(b=this.prefixes.add["align-self"],b&&b.prefixes&&b.process(f)),this.gridStatus(f,t)!==!1&&(b=this.prefixes.add["grid-row-align"],b&&b.prefixes))return b.process(f,t)}else if(f.prop==="justify-self"){if(this.gridStatus(f,t)!==!1&&(b=this.prefixes.add["grid-column-align"],b&&b.prefixes))return b.process(f,t)}else if(f.prop==="place-self"){if(b=this.prefixes.add["place-self"],b&&b.prefixes&&this.gridStatus(f,t)!==!1)return b.process(f,t)}else if(b=this.prefixes.add[f.prop],b&&b.prefixes)return b.process(f,t)}),this.gridStatus(e,t)&&tA(e,this.disabled),e.walkDecls(f=>{if(this.disabledValue(f,t))return;let d=this.prefixes.unprefixed(f.prop),p=this.prefixes.values("add",d);if(Array.isArray(p))for(let m of p)m.process&&m.process(f,t);eA.save(this.prefixes,f)})}remove(e,t){let r=this.prefixes.remove["@resolution"];e.walkAtRules((n,a)=>{this.prefixes.remove[`@${n.name}`]?this.disabled(n,t)||n.parent.removeChild(a):n.name==="media"&&n.params.includes("-resolution")&&r&&r.clean(n)});for(let n of this.prefixes.remove.selectors)e.walkRules((a,s)=>{n.check(a)&&(this.disabled(a,t)||a.parent.removeChild(s))});return e.walkDecls((n,a)=>{if(this.disabled(n,t))return;let s=n.parent,o=this.prefixes.unprefixed(n.prop);if((n.prop==="transition"||n.prop==="transition-property")&&this.prefixes.transition.remove(n),this.prefixes.remove[n.prop]&&this.prefixes.remove[n.prop].remove){let u=this.prefixes.group(n).down(c=>this.prefixes.normalize(c.prop)===o);if(o==="flex-flow"&&(u=!0),n.prop==="-webkit-box-orient"){let c={"flex-direction":!0,"flex-flow":!0};if(!n.parent.some(f=>c[f.prop]))return}if(u&&!this.withHackValue(n)){n.raw("before").includes(` +`)&&this.reduceSpaces(n),s.removeChild(a);return}}for(let u of this.prefixes.values("remove",o)){if(!u.check||!u.check(n.value))continue;if(o=u.unprefixed,this.prefixes.group(n).down(f=>f.value.includes(o))){s.removeChild(a);return}}})}withHackValue(e){return e.prop==="-webkit-background-clip"&&e.value==="text"}disabledValue(e,t){return this.gridStatus(e,t)===!1&&e.type==="decl"&&e.prop==="display"&&e.value.includes("grid")||this.prefixes.options.flexbox===!1&&e.type==="decl"&&e.prop==="display"&&e.value.includes("flex")||e.type==="decl"&&e.prop==="content"?!0:this.disabled(e,t)}disabledDecl(e,t){if(this.gridStatus(e,t)===!1&&e.type==="decl"&&(e.prop.includes("grid")||e.prop==="justify-items"))return!0;if(this.prefixes.options.flexbox===!1&&e.type==="decl"){let r=["order","justify-content","align-items","align-content"];if(e.prop.includes("flex")||r.includes(e.prop))return!0}return this.disabled(e,t)}disabled(e,t){if(!e)return!1;if(e._autoprefixerDisabled!==void 0)return e._autoprefixerDisabled;if(e.parent){let n=e.prev();if(n&&n.type==="comment"&&nA.test(n.text))return e._autoprefixerDisabled=!0,e._autoprefixerSelfDisabled=!0,!0}let r=null;if(e.nodes){let n;e.each(a=>{a.type==="comment"&&/(!\s*)?autoprefixer:\s*(off|on)/i.test(a.text)&&(typeof n!="undefined"?t.warn("Second Autoprefixer control comment was ignored. Autoprefixer applies control comment to whole block, not to next rules.",{node:a}):n=/on/i.test(a.text))}),n!==void 0&&(r=!n)}if(!e.nodes||r===null)if(e.parent){let n=this.disabled(e.parent,t);e.parent._autoprefixerSelfDisabled===!0?r=!1:r=n}else r=!1;return e._autoprefixerDisabled=r,r}reduceSpaces(e){let t=!1;if(this.prefixes.group(e).up(()=>(t=!0,!0)),t)return;let r=e.raw("before").split(` +`),n=r[r.length-1].length,a=!1;this.prefixes.group(e).down(s=>{r=s.raw("before").split(` +`);let o=r.length-1;r[o].length>n&&(a===!1&&(a=r[o].length-n),r[o]=r[o].slice(0,-a),s.raws.before=r.join(` +`))})}displayType(e){for(let t of e.parent.nodes)if(t.prop==="display"){if(t.value.includes("flex"))return"flex";if(t.value.includes("grid"))return"grid"}return!1}gridStatus(e,t){if(!e)return!1;if(e._autoprefixerGridStatus!==void 0)return e._autoprefixerGridStatus;let r=null;if(e.nodes){let n;e.each(a=>{if(a.type==="comment"&&sA.test(a.text)){let s=/:\s*autoplace/i.test(a.text),o=/no-autoplace/i.test(a.text);typeof n!="undefined"?t.warn("Second Autoprefixer grid control comment was ignored. Autoprefixer applies control comments to the whole block, not to the next rules.",{node:a}):s?n="autoplace":o?n=!0:n=/on/i.test(a.text)}}),n!==void 0&&(r=n)}if(e.type==="atrule"&&e.name==="supports"){let n=e.params;n.includes("grid")&&n.includes("auto")&&(r=!1)}if(!e.nodes||r===null)if(e.parent){let n=this.gridStatus(e.parent,t);e.parent._autoprefixerSelfDisabled===!0?r=!1:r=n}else typeof this.prefixes.options.grid!="undefined"?r=this.prefixes.options.grid:typeof h.env.AUTOPREFIXER_GRID!="undefined"?h.env.AUTOPREFIXER_GRID==="autoplace"?r="autoplace":r=!0:r=!1;return e._autoprefixerGridStatus=r,r}};eg.exports=Zm});var rg=v((b4,tg)=>{l();tg.exports={A:{A:{"2":"K E F G A B JC"},B:{"1":"C L M H N D O P Q R S T U V W X Y Z a b c d e f g h i j n o p q r s t u v w x y z I"},C:{"1":"2 3 4 5 6 7 8 9 AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB VB WB XB YB ZB aB bB cB 0B dB 1B eB fB gB hB iB jB kB lB mB nB oB m pB qB rB sB tB P Q R 2B S T U V W X Y Z a b c d e f g h i j n o p q r s t u v w x y z I uB 3B 4B","2":"0 1 KC zB J K E F G A B C L M H N D O k l LC MC"},D:{"1":"8 9 AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB VB WB XB YB ZB aB bB cB 0B dB 1B eB fB gB hB iB jB kB lB mB nB oB m pB qB rB sB tB P Q R S T U V W X Y Z a b c d e f g h i j n o p q r s t u v w x y z I uB 3B 4B","2":"0 1 2 3 4 5 6 7 J K E F G A B C L M H N D O k l"},E:{"1":"G A B C L M H D RC 6B vB wB 7B SC TC 8B 9B xB AC yB BC CC DC EC FC GC UC","2":"0 J K E F NC 5B OC PC QC"},F:{"1":"1 2 3 4 5 6 7 8 9 H N D O k l AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB VB WB XB YB ZB aB bB cB dB eB fB gB hB iB jB kB lB mB nB oB m pB qB rB sB tB P Q R 2B S T U V W X Y Z a b c d e f g h i j wB","2":"G B C VC WC XC YC vB HC ZC"},G:{"1":"D fC gC hC iC jC kC lC mC nC oC pC qC rC sC tC 8B 9B xB AC yB BC CC DC EC FC GC","2":"F 5B aC IC bC cC dC eC"},H:{"1":"uC"},I:{"1":"I zC 0C","2":"zB J vC wC xC yC IC"},J:{"2":"E A"},K:{"1":"m","2":"A B C vB HC wB"},L:{"1":"I"},M:{"1":"uB"},N:{"2":"A B"},O:{"1":"xB"},P:{"1":"J k l 1C 2C 3C 4C 5C 6B 6C 7C 8C 9C AD yB BD CD DD"},Q:{"1":"7B"},R:{"1":"ED"},S:{"1":"FD GD"}},B:4,C:"CSS Feature Queries"}});var ag=v((v4,sg)=>{l();function ig(i){return i[i.length-1]}var ng={parse(i){let e=[""],t=[e];for(let r of i){if(r==="("){e=[""],ig(t).push(e),t.push(e);continue}if(r===")"){t.pop(),e=ig(t),e.push("");continue}e[e.length-1]+=r}return t[0]},stringify(i){let e="";for(let t of i){if(typeof t=="object"){e+=`(${ng.stringify(t)})`;continue}e+=t}return e}};sg.exports=ng});var cg=v((x4,fg)=>{l();var lA=rg(),{feature:uA}=($n(),Ln),{parse:fA}=ye(),cA=dt(),tl=ag(),pA=Se(),dA=ue(),og=uA(lA),lg=[];for(let i in og.stats){let e=og.stats[i];for(let t in e){let r=e[t];/y/.test(r)&&lg.push(i+" "+t)}}var ug=class{constructor(e,t){this.Prefixes=e,this.all=t}prefixer(){if(this.prefixerCache)return this.prefixerCache;let e=this.all.browsers.selected.filter(r=>lg.includes(r)),t=new cA(this.all.browsers.data,e,this.all.options);return this.prefixerCache=new this.Prefixes(this.all.data,t,this.all.options),this.prefixerCache}parse(e){let t=e.split(":"),r=t[0],n=t[1];return n||(n=""),[r.trim(),n.trim()]}virtual(e){let[t,r]=this.parse(e),n=fA("a{}").first;return n.append({prop:t,value:r,raws:{before:""}}),n}prefixed(e){let t=this.virtual(e);if(this.disabled(t.first))return t.nodes;let r={warn:()=>null},n=this.prefixer().add[t.first.prop];n&&n.process&&n.process(t.first,r);for(let a of t.nodes){for(let s of this.prefixer().values("add",t.first.prop))s.process(a);pA.save(this.all,a)}return t.nodes}isNot(e){return typeof e=="string"&&/not\s*/i.test(e)}isOr(e){return typeof e=="string"&&/\s*or\s*/i.test(e)}isProp(e){return typeof e=="object"&&e.length===1&&typeof e[0]=="string"}isHack(e,t){return!new RegExp(`(\\(|\\s)${dA.escapeRegexp(t)}:`).test(e)}toRemove(e,t){let[r,n]=this.parse(e),a=this.all.unprefixed(r),s=this.all.cleaner();if(s.remove[r]&&s.remove[r].remove&&!this.isHack(t,a))return!0;for(let o of s.values("remove",a))if(o.check(n))return!0;return!1}remove(e,t){let r=0;for(;rtypeof t!="object"?t:t.length===1&&typeof t[0]=="object"?this.cleanBrackets(t[0]):this.cleanBrackets(t))}convert(e){let t=[""];for(let r of e)t.push([`${r.prop}: ${r.value}`]),t.push(" or ");return t[t.length-1]="",t}normalize(e){if(typeof e!="object")return e;if(e=e.filter(t=>t!==""),typeof e[0]=="string"){let t=e[0].trim();if(t.includes(":")||t==="selector"||t==="not selector")return[tl.stringify(e)]}return e.map(t=>this.normalize(t))}add(e,t){return e.map(r=>{if(this.isProp(r)){let n=this.prefixed(r[0]);return n.length>1?this.convert(n):r}return typeof r=="object"?this.add(r,t):r})}process(e){let t=tl.parse(e.params);t=this.normalize(t),t=this.remove(t,e.params),t=this.add(t,e.params),t=this.cleanBrackets(t),e.params=tl.stringify(t)}disabled(e){if(!this.all.options.grid&&(e.prop==="display"&&e.value.includes("grid")||e.prop.includes("grid")||e.prop==="justify-items"))return!0;if(this.all.options.flexbox===!1){if(e.prop==="display"&&e.value.includes("flex"))return!0;let t=["order","justify-content","align-items","align-content"];if(e.prop.includes("flex")||t.includes(e.prop))return!0}return!1}};fg.exports=ug});var hg=v((k4,dg)=>{l();var pg=class{constructor(e,t){this.prefix=t,this.prefixed=e.prefixed(this.prefix),this.regexp=e.regexp(this.prefix),this.prefixeds=e.possible().map(r=>[e.prefixed(r),e.regexp(r)]),this.unprefixed=e.name,this.nameRegexp=e.regexp()}isHack(e){let t=e.parent.index(e)+1,r=e.parent.nodes;for(;t{l();var{list:hA}=ye(),mA=hg(),gA=Wt(),yA=dt(),wA=ue(),mg=class extends gA{constructor(e,t,r){super(e,t,r);this.regexpCache=new Map}check(e){return e.selector.includes(this.name)?!!e.selector.match(this.regexp()):!1}prefixed(e){return this.name.replace(/^(\W*)/,`$1${e}`)}regexp(e){if(!this.regexpCache.has(e)){let t=e?this.prefixed(e):this.name;this.regexpCache.set(e,new RegExp(`(^|[^:"'=])${wA.escapeRegexp(t)}`,"gi"))}return this.regexpCache.get(e)}possible(){return yA.prefixes()}prefixeds(e){if(e._autoprefixerPrefixeds){if(e._autoprefixerPrefixeds[this.name])return e._autoprefixerPrefixeds}else e._autoprefixerPrefixeds={};let t={};if(e.selector.includes(",")){let n=hA.comma(e.selector).filter(a=>a.includes(this.name));for(let a of this.possible())t[a]=n.map(s=>this.replace(s,a)).join(", ")}else for(let r of this.possible())t[r]=this.replace(e.selector,r);return e._autoprefixerPrefixeds[this.name]=t,e._autoprefixerPrefixeds}already(e,t,r){let n=e.parent.index(e)-1;for(;n>=0;){let a=e.parent.nodes[n];if(a.type!=="rule")return!1;let s=!1;for(let o in t[this.name]){let u=t[this.name][o];if(a.selector===u){if(r===o)return!0;s=!0;break}}if(!s)return!1;n-=1}return!1}replace(e,t){return e.replace(this.regexp(),`$1${this.prefixed(t)}`)}add(e,t){let r=this.prefixeds(e);if(this.already(e,r,t))return;let n=this.clone(e,{selector:r[this.name][t]});e.parent.insertBefore(e,n)}old(e){return new mA(this,e)}};gg.exports=mg});var bg=v((C4,wg)=>{l();var bA=Wt(),yg=class extends bA{add(e,t){let r=t+e.name;if(e.parent.some(s=>s.name===r&&s.params===e.params))return;let a=this.clone(e,{name:r});return e.parent.insertBefore(e,a)}process(e){let t=this.parentPrefix(e);for(let r of this.prefixes)(!t||t===r)&&this.add(e,r)}};wg.exports=yg});var xg=v((A4,vg)=>{l();var vA=Yt(),rl=class extends vA{prefixed(e){return e==="-webkit-"?":-webkit-full-screen":e==="-moz-"?":-moz-full-screen":`:${e}fullscreen`}};rl.names=[":fullscreen"];vg.exports=rl});var Sg=v((_4,kg)=>{l();var xA=Yt(),il=class extends xA{possible(){return super.possible().concat(["-moz- old","-ms- old"])}prefixed(e){return e==="-webkit-"?"::-webkit-input-placeholder":e==="-ms-"?"::-ms-input-placeholder":e==="-ms- old"?":-ms-input-placeholder":e==="-moz- old"?":-moz-placeholder":`::${e}placeholder`}};il.names=["::placeholder"];kg.exports=il});var Ag=v((O4,Cg)=>{l();var kA=Yt(),nl=class extends kA{prefixed(e){return e==="-ms-"?":-ms-input-placeholder":`:${e}placeholder-shown`}};nl.names=[":placeholder-shown"];Cg.exports=nl});var Og=v((E4,_g)=>{l();var SA=Yt(),CA=ue(),sl=class extends SA{constructor(e,t,r){super(e,t,r);this.prefixes&&(this.prefixes=CA.uniq(this.prefixes.map(n=>"-webkit-")))}prefixed(e){return e==="-webkit-"?"::-webkit-file-upload-button":`::${e}file-selector-button`}};sl.names=["::file-selector-button"];_g.exports=sl});var de=v((T4,Eg)=>{l();Eg.exports=function(i){let e;return i==="-webkit- 2009"||i==="-moz-"?e=2009:i==="-ms-"?e=2012:i==="-webkit-"&&(e="final"),i==="-webkit- 2009"&&(i="-webkit-"),[e,i]}});var Ig=v((P4,Dg)=>{l();var Tg=ye().list,Pg=de(),AA=M(),Qt=class extends AA{prefixed(e,t){let r;return[r,t]=Pg(t),r===2009?t+"box-flex":super.prefixed(e,t)}normalize(){return"flex"}set(e,t){let r=Pg(t)[0];if(r===2009)return e.value=Tg.space(e.value)[0],e.value=Qt.oldValues[e.value]||e.value,super.set(e,t);if(r===2012){let n=Tg.space(e.value);n.length===3&&n[2]==="0"&&(e.value=n.slice(0,2).concat("0px").join(" "))}return super.set(e,t)}};Qt.names=["flex","box-flex"];Qt.oldValues={auto:"1",none:"0"};Dg.exports=Qt});var Mg=v((D4,Rg)=>{l();var qg=de(),_A=M(),al=class extends _A{prefixed(e,t){let r;return[r,t]=qg(t),r===2009?t+"box-ordinal-group":r===2012?t+"flex-order":super.prefixed(e,t)}normalize(){return"order"}set(e,t){return qg(t)[0]===2009&&/\d/.test(e.value)?(e.value=(parseInt(e.value)+1).toString(),super.set(e,t)):super.set(e,t)}};al.names=["order","flex-order","box-ordinal-group"];Rg.exports=al});var Fg=v((I4,Bg)=>{l();var OA=M(),ol=class extends OA{check(e){let t=e.value;return!t.toLowerCase().includes("alpha(")&&!t.includes("DXImageTransform.Microsoft")&&!t.includes("data:image/svg+xml")}};ol.names=["filter"];Bg.exports=ol});var Lg=v((q4,Ng)=>{l();var EA=M(),ll=class extends EA{insert(e,t,r,n){if(t!=="-ms-")return super.insert(e,t,r);let a=this.clone(e),s=e.prop.replace(/end$/,"start"),o=t+e.prop.replace(/end$/,"span");if(!e.parent.some(u=>u.prop===o)){if(a.prop=o,e.value.includes("span"))a.value=e.value.replace(/span\s/i,"");else{let u;if(e.parent.walkDecls(s,c=>{u=c}),u){let c=Number(e.value)-Number(u.value)+"";a.value=c}else e.warn(n,`Can not prefix ${e.prop} (${s} is not found)`)}e.cloneBefore(a)}}};ll.names=["grid-row-end","grid-column-end"];Ng.exports=ll});var jg=v((R4,$g)=>{l();var TA=M(),ul=class extends TA{check(e){return!e.value.split(/\s+/).some(t=>{let r=t.toLowerCase();return r==="reverse"||r==="alternate-reverse"})}};ul.names=["animation","animation-direction"];$g.exports=ul});var Vg=v((M4,zg)=>{l();var PA=de(),DA=M(),fl=class extends DA{insert(e,t,r){let n;if([n,t]=PA(t),n!==2009)return super.insert(e,t,r);let a=e.value.split(/\s+/).filter(d=>d!=="wrap"&&d!=="nowrap"&&"wrap-reverse");if(a.length===0||e.parent.some(d=>d.prop===t+"box-orient"||d.prop===t+"box-direction"))return;let o=a[0],u=o.includes("row")?"horizontal":"vertical",c=o.includes("reverse")?"reverse":"normal",f=this.clone(e);return f.prop=t+"box-orient",f.value=u,this.needCascade(e)&&(f.raws.before=this.calcBefore(r,e,t)),e.parent.insertBefore(e,f),f=this.clone(e),f.prop=t+"box-direction",f.value=c,this.needCascade(e)&&(f.raws.before=this.calcBefore(r,e,t)),e.parent.insertBefore(e,f)}};fl.names=["flex-flow","box-direction","box-orient"];zg.exports=fl});var Wg=v((B4,Ug)=>{l();var IA=de(),qA=M(),cl=class extends qA{normalize(){return"flex"}prefixed(e,t){let r;return[r,t]=IA(t),r===2009?t+"box-flex":r===2012?t+"flex-positive":super.prefixed(e,t)}};cl.names=["flex-grow","flex-positive"];Ug.exports=cl});var Hg=v((F4,Gg)=>{l();var RA=de(),MA=M(),pl=class extends MA{set(e,t){if(RA(t)[0]!==2009)return super.set(e,t)}};pl.names=["flex-wrap"];Gg.exports=pl});var Qg=v((N4,Yg)=>{l();var BA=M(),Jt=mt(),dl=class extends BA{insert(e,t,r,n){if(t!=="-ms-")return super.insert(e,t,r);let a=Jt.parse(e),[s,o]=Jt.translate(a,0,2),[u,c]=Jt.translate(a,1,3);[["grid-row",s],["grid-row-span",o],["grid-column",u],["grid-column-span",c]].forEach(([f,d])=>{Jt.insertDecl(e,f,d)}),Jt.warnTemplateSelectorNotFound(e,n),Jt.warnIfGridRowColumnExists(e,n)}};dl.names=["grid-area"];Yg.exports=dl});var Xg=v((L4,Jg)=>{l();var FA=M(),ni=mt(),hl=class extends FA{insert(e,t,r){if(t!=="-ms-")return super.insert(e,t,r);if(e.parent.some(s=>s.prop==="-ms-grid-row-align"))return;let[[n,a]]=ni.parse(e);a?(ni.insertDecl(e,"grid-row-align",n),ni.insertDecl(e,"grid-column-align",a)):(ni.insertDecl(e,"grid-row-align",n),ni.insertDecl(e,"grid-column-align",n))}};hl.names=["place-self"];Jg.exports=hl});var Zg=v(($4,Kg)=>{l();var NA=M(),ml=class extends NA{check(e){let t=e.value;return!t.includes("/")||t.includes("span")}normalize(e){return e.replace("-start","")}prefixed(e,t){let r=super.prefixed(e,t);return t==="-ms-"&&(r=r.replace("-start","")),r}};ml.names=["grid-row-start","grid-column-start"];Kg.exports=ml});var ry=v((j4,ty)=>{l();var ey=de(),LA=M(),Xt=class extends LA{check(e){return e.parent&&!e.parent.some(t=>t.prop&&t.prop.startsWith("grid-"))}prefixed(e,t){let r;return[r,t]=ey(t),r===2012?t+"flex-item-align":super.prefixed(e,t)}normalize(){return"align-self"}set(e,t){let r=ey(t)[0];if(r===2012)return e.value=Xt.oldValues[e.value]||e.value,super.set(e,t);if(r==="final")return super.set(e,t)}};Xt.names=["align-self","flex-item-align"];Xt.oldValues={"flex-end":"end","flex-start":"start"};ty.exports=Xt});var ny=v((z4,iy)=>{l();var $A=M(),jA=ue(),gl=class extends $A{constructor(e,t,r){super(e,t,r);this.prefixes&&(this.prefixes=jA.uniq(this.prefixes.map(n=>n==="-ms-"?"-webkit-":n)))}};gl.names=["appearance"];iy.exports=gl});var oy=v((V4,ay)=>{l();var sy=de(),zA=M(),yl=class extends zA{normalize(){return"flex-basis"}prefixed(e,t){let r;return[r,t]=sy(t),r===2012?t+"flex-preferred-size":super.prefixed(e,t)}set(e,t){let r;if([r,t]=sy(t),r===2012||r==="final")return super.set(e,t)}};yl.names=["flex-basis","flex-preferred-size"];ay.exports=yl});var uy=v((U4,ly)=>{l();var VA=M(),wl=class extends VA{normalize(){return this.name.replace("box-image","border")}prefixed(e,t){let r=super.prefixed(e,t);return t==="-webkit-"&&(r=r.replace("border","box-image")),r}};wl.names=["mask-border","mask-border-source","mask-border-slice","mask-border-width","mask-border-outset","mask-border-repeat","mask-box-image","mask-box-image-source","mask-box-image-slice","mask-box-image-width","mask-box-image-outset","mask-box-image-repeat"];ly.exports=wl});var cy=v((W4,fy)=>{l();var UA=M(),Le=class extends UA{insert(e,t,r){let n=e.prop==="mask-composite",a;n?a=e.value.split(","):a=e.value.match(Le.regexp)||[],a=a.map(c=>c.trim()).filter(c=>c);let s=a.length,o;if(s&&(o=this.clone(e),o.value=a.map(c=>Le.oldValues[c]||c).join(", "),a.includes("intersect")&&(o.value+=", xor"),o.prop=t+"mask-composite"),n)return s?(this.needCascade(e)&&(o.raws.before=this.calcBefore(r,e,t)),e.parent.insertBefore(e,o)):void 0;let u=this.clone(e);return u.prop=t+u.prop,s&&(u.value=u.value.replace(Le.regexp,"")),this.needCascade(e)&&(u.raws.before=this.calcBefore(r,e,t)),e.parent.insertBefore(e,u),s?(this.needCascade(e)&&(o.raws.before=this.calcBefore(r,e,t)),e.parent.insertBefore(e,o)):e}};Le.names=["mask","mask-composite"];Le.oldValues={add:"source-over",subtract:"source-out",intersect:"source-in",exclude:"xor"};Le.regexp=new RegExp(`\\s+(${Object.keys(Le.oldValues).join("|")})\\b(?!\\))\\s*(?=[,])`,"ig");fy.exports=Le});var hy=v((G4,dy)=>{l();var py=de(),WA=M(),Kt=class extends WA{prefixed(e,t){let r;return[r,t]=py(t),r===2009?t+"box-align":r===2012?t+"flex-align":super.prefixed(e,t)}normalize(){return"align-items"}set(e,t){let r=py(t)[0];return(r===2009||r===2012)&&(e.value=Kt.oldValues[e.value]||e.value),super.set(e,t)}};Kt.names=["align-items","flex-align","box-align"];Kt.oldValues={"flex-end":"end","flex-start":"start"};dy.exports=Kt});var gy=v((H4,my)=>{l();var GA=M(),bl=class extends GA{set(e,t){return t==="-ms-"&&e.value==="contain"&&(e.value="element"),super.set(e,t)}insert(e,t,r){if(!(e.value==="all"&&t==="-ms-"))return super.insert(e,t,r)}};bl.names=["user-select"];my.exports=bl});var by=v((Y4,wy)=>{l();var yy=de(),HA=M(),vl=class extends HA{normalize(){return"flex-shrink"}prefixed(e,t){let r;return[r,t]=yy(t),r===2012?t+"flex-negative":super.prefixed(e,t)}set(e,t){let r;if([r,t]=yy(t),r===2012||r==="final")return super.set(e,t)}};vl.names=["flex-shrink","flex-negative"];wy.exports=vl});var xy=v((Q4,vy)=>{l();var YA=M(),xl=class extends YA{prefixed(e,t){return`${t}column-${e}`}normalize(e){return e.includes("inside")?"break-inside":e.includes("before")?"break-before":"break-after"}set(e,t){return(e.prop==="break-inside"&&e.value==="avoid-column"||e.value==="avoid-page")&&(e.value="avoid"),super.set(e,t)}insert(e,t,r){if(e.prop!=="break-inside")return super.insert(e,t,r);if(!(/region/i.test(e.value)||/page/i.test(e.value)))return super.insert(e,t,r)}};xl.names=["break-inside","page-break-inside","column-break-inside","break-before","page-break-before","column-break-before","break-after","page-break-after","column-break-after"];vy.exports=xl});var Sy=v((J4,ky)=>{l();var QA=M(),kl=class extends QA{prefixed(e,t){return t+"print-color-adjust"}normalize(){return"color-adjust"}};kl.names=["color-adjust","print-color-adjust"];ky.exports=kl});var Ay=v((X4,Cy)=>{l();var JA=M(),Zt=class extends JA{insert(e,t,r){if(t==="-ms-"){let n=this.set(this.clone(e),t);this.needCascade(e)&&(n.raws.before=this.calcBefore(r,e,t));let a="ltr";return e.parent.nodes.forEach(s=>{s.prop==="direction"&&(s.value==="rtl"||s.value==="ltr")&&(a=s.value)}),n.value=Zt.msValues[a][e.value]||e.value,e.parent.insertBefore(e,n)}return super.insert(e,t,r)}};Zt.names=["writing-mode"];Zt.msValues={ltr:{"horizontal-tb":"lr-tb","vertical-rl":"tb-rl","vertical-lr":"tb-lr"},rtl:{"horizontal-tb":"rl-tb","vertical-rl":"bt-rl","vertical-lr":"bt-lr"}};Cy.exports=Zt});var Oy=v((K4,_y)=>{l();var XA=M(),Sl=class extends XA{set(e,t){return e.value=e.value.replace(/\s+fill(\s)/,"$1"),super.set(e,t)}};Sl.names=["border-image"];_y.exports=Sl});var Py=v((Z4,Ty)=>{l();var Ey=de(),KA=M(),er=class extends KA{prefixed(e,t){let r;return[r,t]=Ey(t),r===2012?t+"flex-line-pack":super.prefixed(e,t)}normalize(){return"align-content"}set(e,t){let r=Ey(t)[0];if(r===2012)return e.value=er.oldValues[e.value]||e.value,super.set(e,t);if(r==="final")return super.set(e,t)}};er.names=["align-content","flex-line-pack"];er.oldValues={"flex-end":"end","flex-start":"start","space-between":"justify","space-around":"distribute"};Ty.exports=er});var Iy=v((eI,Dy)=>{l();var ZA=M(),Ce=class extends ZA{prefixed(e,t){return t==="-moz-"?t+(Ce.toMozilla[e]||e):super.prefixed(e,t)}normalize(e){return Ce.toNormal[e]||e}};Ce.names=["border-radius"];Ce.toMozilla={};Ce.toNormal={};for(let i of["top","bottom"])for(let e of["left","right"]){let t=`border-${i}-${e}-radius`,r=`border-radius-${i}${e}`;Ce.names.push(t),Ce.names.push(r),Ce.toMozilla[t]=r,Ce.toNormal[r]=t}Dy.exports=Ce});var Ry=v((tI,qy)=>{l();var e_=M(),Cl=class extends e_{prefixed(e,t){return e.includes("-start")?t+e.replace("-block-start","-before"):t+e.replace("-block-end","-after")}normalize(e){return e.includes("-before")?e.replace("-before","-block-start"):e.replace("-after","-block-end")}};Cl.names=["border-block-start","border-block-end","margin-block-start","margin-block-end","padding-block-start","padding-block-end","border-before","border-after","margin-before","margin-after","padding-before","padding-after"];qy.exports=Cl});var By=v((rI,My)=>{l();var t_=M(),{parseTemplate:r_,warnMissedAreas:i_,getGridGap:n_,warnGridGap:s_,inheritGridGap:a_}=mt(),Al=class extends t_{insert(e,t,r,n){if(t!=="-ms-")return super.insert(e,t,r);if(e.parent.some(m=>m.prop==="-ms-grid-rows"))return;let a=n_(e),s=a_(e,a),{rows:o,columns:u,areas:c}=r_({decl:e,gap:s||a}),f=Object.keys(c).length>0,d=Boolean(o),p=Boolean(u);return s_({gap:a,hasColumns:p,decl:e,result:n}),i_(c,e,n),(d&&p||f)&&e.cloneBefore({prop:"-ms-grid-rows",value:o,raws:{}}),p&&e.cloneBefore({prop:"-ms-grid-columns",value:u,raws:{}}),e}};Al.names=["grid-template"];My.exports=Al});var Ny=v((iI,Fy)=>{l();var o_=M(),_l=class extends o_{prefixed(e,t){return t+e.replace("-inline","")}normalize(e){return e.replace(/(margin|padding|border)-(start|end)/,"$1-inline-$2")}};_l.names=["border-inline-start","border-inline-end","margin-inline-start","margin-inline-end","padding-inline-start","padding-inline-end","border-start","border-end","margin-start","margin-end","padding-start","padding-end"];Fy.exports=_l});var $y=v((nI,Ly)=>{l();var l_=M(),Ol=class extends l_{check(e){return!e.value.includes("flex-")&&e.value!=="baseline"}prefixed(e,t){return t+"grid-row-align"}normalize(){return"align-self"}};Ol.names=["grid-row-align"];Ly.exports=Ol});var zy=v((sI,jy)=>{l();var u_=M(),tr=class extends u_{keyframeParents(e){let{parent:t}=e;for(;t;){if(t.type==="atrule"&&t.name==="keyframes")return!0;({parent:t}=t)}return!1}contain3d(e){if(e.prop==="transform-origin")return!1;for(let t of tr.functions3d)if(e.value.includes(`${t}(`))return!0;return!1}set(e,t){return e=super.set(e,t),t==="-ms-"&&(e.value=e.value.replace(/rotatez/gi,"rotate")),e}insert(e,t,r){if(t==="-ms-"){if(!this.contain3d(e)&&!this.keyframeParents(e))return super.insert(e,t,r)}else if(t==="-o-"){if(!this.contain3d(e))return super.insert(e,t,r)}else return super.insert(e,t,r)}};tr.names=["transform","transform-origin"];tr.functions3d=["matrix3d","translate3d","translateZ","scale3d","scaleZ","rotate3d","rotateX","rotateY","perspective"];jy.exports=tr});var Wy=v((aI,Uy)=>{l();var Vy=de(),f_=M(),El=class extends f_{normalize(){return"flex-direction"}insert(e,t,r){let n;if([n,t]=Vy(t),n!==2009)return super.insert(e,t,r);if(e.parent.some(f=>f.prop===t+"box-orient"||f.prop===t+"box-direction"))return;let s=e.value,o,u;s==="inherit"||s==="initial"||s==="unset"?(o=s,u=s):(o=s.includes("row")?"horizontal":"vertical",u=s.includes("reverse")?"reverse":"normal");let c=this.clone(e);return c.prop=t+"box-orient",c.value=o,this.needCascade(e)&&(c.raws.before=this.calcBefore(r,e,t)),e.parent.insertBefore(e,c),c=this.clone(e),c.prop=t+"box-direction",c.value=u,this.needCascade(e)&&(c.raws.before=this.calcBefore(r,e,t)),e.parent.insertBefore(e,c)}old(e,t){let r;return[r,t]=Vy(t),r===2009?[t+"box-orient",t+"box-direction"]:super.old(e,t)}};El.names=["flex-direction","box-direction","box-orient"];Uy.exports=El});var Hy=v((oI,Gy)=>{l();var c_=M(),Tl=class extends c_{check(e){return e.value==="pixelated"}prefixed(e,t){return t==="-ms-"?"-ms-interpolation-mode":super.prefixed(e,t)}set(e,t){return t!=="-ms-"?super.set(e,t):(e.prop="-ms-interpolation-mode",e.value="nearest-neighbor",e)}normalize(){return"image-rendering"}process(e,t){return super.process(e,t)}};Tl.names=["image-rendering","interpolation-mode"];Gy.exports=Tl});var Qy=v((lI,Yy)=>{l();var p_=M(),d_=ue(),Pl=class extends p_{constructor(e,t,r){super(e,t,r);this.prefixes&&(this.prefixes=d_.uniq(this.prefixes.map(n=>n==="-ms-"?"-webkit-":n)))}};Pl.names=["backdrop-filter"];Yy.exports=Pl});var Xy=v((uI,Jy)=>{l();var h_=M(),m_=ue(),Dl=class extends h_{constructor(e,t,r){super(e,t,r);this.prefixes&&(this.prefixes=m_.uniq(this.prefixes.map(n=>n==="-ms-"?"-webkit-":n)))}check(e){return e.value.toLowerCase()==="text"}};Dl.names=["background-clip"];Jy.exports=Dl});var Zy=v((fI,Ky)=>{l();var g_=M(),y_=["none","underline","overline","line-through","blink","inherit","initial","unset"],Il=class extends g_{check(e){return e.value.split(/\s+/).some(t=>!y_.includes(t))}};Il.names=["text-decoration"];Ky.exports=Il});var rw=v((cI,tw)=>{l();var ew=de(),w_=M(),rr=class extends w_{prefixed(e,t){let r;return[r,t]=ew(t),r===2009?t+"box-pack":r===2012?t+"flex-pack":super.prefixed(e,t)}normalize(){return"justify-content"}set(e,t){let r=ew(t)[0];if(r===2009||r===2012){let n=rr.oldValues[e.value]||e.value;if(e.value=n,r!==2009||n!=="distribute")return super.set(e,t)}else if(r==="final")return super.set(e,t)}};rr.names=["justify-content","flex-pack","box-pack"];rr.oldValues={"flex-end":"end","flex-start":"start","space-between":"justify","space-around":"distribute"};tw.exports=rr});var nw=v((pI,iw)=>{l();var b_=M(),ql=class extends b_{set(e,t){let r=e.value.toLowerCase();return t==="-webkit-"&&!r.includes(" ")&&r!=="contain"&&r!=="cover"&&(e.value=e.value+" "+e.value),super.set(e,t)}};ql.names=["background-size"];iw.exports=ql});var aw=v((dI,sw)=>{l();var v_=M(),Rl=mt(),Ml=class extends v_{insert(e,t,r){if(t!=="-ms-")return super.insert(e,t,r);let n=Rl.parse(e),[a,s]=Rl.translate(n,0,1);n[0]&&n[0].includes("span")&&(s=n[0].join("").replace(/\D/g,"")),[[e.prop,a],[`${e.prop}-span`,s]].forEach(([u,c])=>{Rl.insertDecl(e,u,c)})}};Ml.names=["grid-row","grid-column"];sw.exports=Ml});var uw=v((hI,lw)=>{l();var x_=M(),{prefixTrackProp:ow,prefixTrackValue:k_,autoplaceGridItems:S_,getGridGap:C_,inheritGridGap:A_}=mt(),__=el(),Bl=class extends x_{prefixed(e,t){return t==="-ms-"?ow({prop:e,prefix:t}):super.prefixed(e,t)}normalize(e){return e.replace(/^grid-(rows|columns)/,"grid-template-$1")}insert(e,t,r,n){if(t!=="-ms-")return super.insert(e,t,r);let{parent:a,prop:s,value:o}=e,u=s.includes("rows"),c=s.includes("columns"),f=a.some(k=>k.prop==="grid-template"||k.prop==="grid-template-areas");if(f&&u)return!1;let d=new __({options:{}}),p=d.gridStatus(a,n),m=C_(e);m=A_(e,m)||m;let b=u?m.row:m.column;(p==="no-autoplace"||p===!0)&&!f&&(b=null);let x=k_({value:o,gap:b});e.cloneBefore({prop:ow({prop:s,prefix:t}),value:x});let y=a.nodes.find(k=>k.prop==="grid-auto-flow"),w="row";if(y&&!d.disabled(y,n)&&(w=y.value.trim()),p==="autoplace"){let k=a.nodes.find(_=>_.prop==="grid-template-rows");if(!k&&f)return;if(!k&&!f){e.warn(n,"Autoplacement does not work without grid-template-rows property");return}!a.nodes.find(_=>_.prop==="grid-template-columns")&&!f&&e.warn(n,"Autoplacement does not work without grid-template-columns property"),c&&!f&&S_(e,n,m,w)}}};Bl.names=["grid-template-rows","grid-template-columns","grid-rows","grid-columns"];lw.exports=Bl});var cw=v((mI,fw)=>{l();var O_=M(),Fl=class extends O_{check(e){return!e.value.includes("flex-")&&e.value!=="baseline"}prefixed(e,t){return t+"grid-column-align"}normalize(){return"justify-self"}};Fl.names=["grid-column-align"];fw.exports=Fl});var dw=v((gI,pw)=>{l();var E_=M(),Nl=class extends E_{prefixed(e,t){return t+"scroll-chaining"}normalize(){return"overscroll-behavior"}set(e,t){return e.value==="auto"?e.value="chained":(e.value==="none"||e.value==="contain")&&(e.value="none"),super.set(e,t)}};Nl.names=["overscroll-behavior","scroll-chaining"];pw.exports=Nl});var gw=v((yI,mw)=>{l();var T_=M(),{parseGridAreas:P_,warnMissedAreas:D_,prefixTrackProp:I_,prefixTrackValue:hw,getGridGap:q_,warnGridGap:R_,inheritGridGap:M_}=mt();function B_(i){return i.trim().slice(1,-1).split(/["']\s*["']?/g)}var Ll=class extends T_{insert(e,t,r,n){if(t!=="-ms-")return super.insert(e,t,r);let a=!1,s=!1,o=e.parent,u=q_(e);u=M_(e,u)||u,o.walkDecls(/-ms-grid-rows/,d=>d.remove()),o.walkDecls(/grid-template-(rows|columns)/,d=>{if(d.prop==="grid-template-rows"){s=!0;let{prop:p,value:m}=d;d.cloneBefore({prop:I_({prop:p,prefix:t}),value:hw({value:m,gap:u.row})})}else a=!0});let c=B_(e.value);a&&!s&&u.row&&c.length>1&&e.cloneBefore({prop:"-ms-grid-rows",value:hw({value:`repeat(${c.length}, auto)`,gap:u.row}),raws:{}}),R_({gap:u,hasColumns:a,decl:e,result:n});let f=P_({rows:c,gap:u});return D_(f,e,n),e}};Ll.names=["grid-template-areas"];mw.exports=Ll});var ww=v((wI,yw)=>{l();var F_=M(),$l=class extends F_{set(e,t){return t==="-webkit-"&&(e.value=e.value.replace(/\s*(right|left)\s*/i,"")),super.set(e,t)}};$l.names=["text-emphasis-position"];yw.exports=$l});var vw=v((bI,bw)=>{l();var N_=M(),jl=class extends N_{set(e,t){return e.prop==="text-decoration-skip-ink"&&e.value==="auto"?(e.prop=t+"text-decoration-skip",e.value="ink",e):super.set(e,t)}};jl.names=["text-decoration-skip-ink","text-decoration-skip"];bw.exports=jl});var _w=v((vI,Aw)=>{l();"use strict";Aw.exports={wrap:xw,limit:kw,validate:Sw,test:zl,curry:L_,name:Cw};function xw(i,e,t){var r=e-i;return((t-i)%r+r)%r+i}function kw(i,e,t){return Math.max(i,Math.min(e,t))}function Sw(i,e,t,r,n){if(!zl(i,e,t,r,n))throw new Error(t+" is outside of range ["+i+","+e+")");return t}function zl(i,e,t,r,n){return!(te||n&&t===e||r&&t===i)}function Cw(i,e,t,r){return(t?"(":"[")+i+","+e+(r?")":"]")}function L_(i,e,t,r){var n=Cw.bind(null,i,e,t,r);return{wrap:xw.bind(null,i,e),limit:kw.bind(null,i,e),validate:function(a){return Sw(i,e,a,t,r)},test:function(a){return zl(i,e,a,t,r)},toString:n,name:n}}});var Tw=v((xI,Ew)=>{l();var Vl=Gn(),$_=_w(),j_=Ht(),z_=Se(),V_=ue(),Ow=/top|left|right|bottom/gi,Qe=class extends z_{replace(e,t){let r=Vl(e);for(let n of r.nodes)if(n.type==="function"&&n.value===this.name)if(n.nodes=this.newDirection(n.nodes),n.nodes=this.normalize(n.nodes),t==="-webkit- old"){if(!this.oldWebkit(n))return!1}else n.nodes=this.convertDirection(n.nodes),n.value=t+n.value;return r.toString()}replaceFirst(e,...t){return t.map(n=>n===" "?{type:"space",value:n}:{type:"word",value:n}).concat(e.slice(1))}normalizeUnit(e,t){return`${parseFloat(e)/t*360}deg`}normalize(e){if(!e[0])return e;if(/-?\d+(.\d+)?grad/.test(e[0].value))e[0].value=this.normalizeUnit(e[0].value,400);else if(/-?\d+(.\d+)?rad/.test(e[0].value))e[0].value=this.normalizeUnit(e[0].value,2*Math.PI);else if(/-?\d+(.\d+)?turn/.test(e[0].value))e[0].value=this.normalizeUnit(e[0].value,1);else if(e[0].value.includes("deg")){let t=parseFloat(e[0].value);t=$_.wrap(0,360,t),e[0].value=`${t}deg`}return e[0].value==="0deg"?e=this.replaceFirst(e,"to"," ","top"):e[0].value==="90deg"?e=this.replaceFirst(e,"to"," ","right"):e[0].value==="180deg"?e=this.replaceFirst(e,"to"," ","bottom"):e[0].value==="270deg"&&(e=this.replaceFirst(e,"to"," ","left")),e}newDirection(e){if(e[0].value==="to"||(Ow.lastIndex=0,!Ow.test(e[0].value)))return e;e.unshift({type:"word",value:"to"},{type:"space",value:" "});for(let t=2;t0&&(e[0].value==="to"?this.fixDirection(e):e[0].value.includes("deg")?this.fixAngle(e):this.isRadial(e)&&this.fixRadial(e)),e}fixDirection(e){e.splice(0,2);for(let t of e){if(t.type==="div")break;t.type==="word"&&(t.value=this.revertDirection(t.value))}}fixAngle(e){let t=e[0].value;t=parseFloat(t),t=Math.abs(450-t)%360,t=this.roundFloat(t,3),e[0].value=`${t}deg`}fixRadial(e){let t=[],r=[],n,a,s,o,u;for(o=0;o{l();var U_=Ht(),W_=Se();function Pw(i){return new RegExp(`(^|[\\s,(])(${i}($|[\\s),]))`,"gi")}var Ul=class extends W_{regexp(){return this.regexpCache||(this.regexpCache=Pw(this.name)),this.regexpCache}isStretch(){return this.name==="stretch"||this.name==="fill"||this.name==="fill-available"}replace(e,t){return t==="-moz-"&&this.isStretch()?e.replace(this.regexp(),"$1-moz-available$3"):t==="-webkit-"&&this.isStretch()?e.replace(this.regexp(),"$1-webkit-fill-available$3"):super.replace(e,t)}old(e){let t=e+this.name;return this.isStretch()&&(e==="-moz-"?t="-moz-available":e==="-webkit-"&&(t="-webkit-fill-available")),new U_(this.name,t,t,Pw(t))}add(e,t){if(!(e.prop.includes("grid")&&t!=="-webkit-"))return super.add(e,t)}};Ul.names=["max-content","min-content","fit-content","fill","fill-available","stretch"];Dw.exports=Ul});var Mw=v((SI,Rw)=>{l();var qw=Ht(),G_=Se(),Wl=class extends G_{replace(e,t){return t==="-webkit-"?e.replace(this.regexp(),"$1-webkit-optimize-contrast"):t==="-moz-"?e.replace(this.regexp(),"$1-moz-crisp-edges"):super.replace(e,t)}old(e){return e==="-webkit-"?new qw(this.name,"-webkit-optimize-contrast"):e==="-moz-"?new qw(this.name,"-moz-crisp-edges"):super.old(e)}};Wl.names=["pixelated"];Rw.exports=Wl});var Fw=v((CI,Bw)=>{l();var H_=Se(),Gl=class extends H_{replace(e,t){let r=super.replace(e,t);return t==="-webkit-"&&(r=r.replace(/("[^"]+"|'[^']+')(\s+\d+\w)/gi,"url($1)$2")),r}};Gl.names=["image-set"];Bw.exports=Gl});var Lw=v((AI,Nw)=>{l();var Y_=ye().list,Q_=Se(),Hl=class extends Q_{replace(e,t){return Y_.space(e).map(r=>{if(r.slice(0,+this.name.length+1)!==this.name+"(")return r;let n=r.lastIndexOf(")"),a=r.slice(n+1),s=r.slice(this.name.length+1,n);if(t==="-webkit-"){let o=s.match(/\d*.?\d+%?/);o?(s=s.slice(o[0].length).trim(),s+=`, ${o[0]}`):s+=", 0.5"}return t+this.name+"("+s+")"+a}).join(" ")}};Hl.names=["cross-fade"];Nw.exports=Hl});var jw=v((_I,$w)=>{l();var J_=de(),X_=Ht(),K_=Se(),Yl=class extends K_{constructor(e,t){super(e,t);e==="display-flex"&&(this.name="flex")}check(e){return e.prop==="display"&&e.value===this.name}prefixed(e){let t,r;return[t,e]=J_(e),t===2009?this.name==="flex"?r="box":r="inline-box":t===2012?this.name==="flex"?r="flexbox":r="inline-flexbox":t==="final"&&(r=this.name),e+r}replace(e,t){return this.prefixed(t)}old(e){let t=this.prefixed(e);if(!!t)return new X_(this.name,t)}};Yl.names=["display-flex","inline-flex"];$w.exports=Yl});var Vw=v((OI,zw)=>{l();var Z_=Se(),Ql=class extends Z_{constructor(e,t){super(e,t);e==="display-grid"&&(this.name="grid")}check(e){return e.prop==="display"&&e.value===this.name}};Ql.names=["display-grid","inline-grid"];zw.exports=Ql});var Ww=v((EI,Uw)=>{l();var e5=Se(),Jl=class extends e5{constructor(e,t){super(e,t);e==="filter-function"&&(this.name="filter")}};Jl.names=["filter","filter-function"];Uw.exports=Jl});var Qw=v((TI,Yw)=>{l();var Gw=ii(),B=M(),Hw=Em(),t5=Gm(),r5=el(),i5=cg(),Xl=dt(),ir=Yt(),n5=bg(),$e=Se(),nr=ue(),s5=xg(),a5=Sg(),o5=Ag(),l5=Og(),u5=Ig(),f5=Mg(),c5=Fg(),p5=Lg(),d5=jg(),h5=Vg(),m5=Wg(),g5=Hg(),y5=Qg(),w5=Xg(),b5=Zg(),v5=ry(),x5=ny(),k5=oy(),S5=uy(),C5=cy(),A5=hy(),_5=gy(),O5=by(),E5=xy(),T5=Sy(),P5=Ay(),D5=Oy(),I5=Py(),q5=Iy(),R5=Ry(),M5=By(),B5=Ny(),F5=$y(),N5=zy(),L5=Wy(),$5=Hy(),j5=Qy(),z5=Xy(),V5=Zy(),U5=rw(),W5=nw(),G5=aw(),H5=uw(),Y5=cw(),Q5=dw(),J5=gw(),X5=ww(),K5=vw(),Z5=Tw(),eO=Iw(),tO=Mw(),rO=Fw(),iO=Lw(),nO=jw(),sO=Vw(),aO=Ww();ir.hack(s5);ir.hack(a5);ir.hack(o5);ir.hack(l5);B.hack(u5);B.hack(f5);B.hack(c5);B.hack(p5);B.hack(d5);B.hack(h5);B.hack(m5);B.hack(g5);B.hack(y5);B.hack(w5);B.hack(b5);B.hack(v5);B.hack(x5);B.hack(k5);B.hack(S5);B.hack(C5);B.hack(A5);B.hack(_5);B.hack(O5);B.hack(E5);B.hack(T5);B.hack(P5);B.hack(D5);B.hack(I5);B.hack(q5);B.hack(R5);B.hack(M5);B.hack(B5);B.hack(F5);B.hack(N5);B.hack(L5);B.hack($5);B.hack(j5);B.hack(z5);B.hack(V5);B.hack(U5);B.hack(W5);B.hack(G5);B.hack(H5);B.hack(Y5);B.hack(Q5);B.hack(J5);B.hack(X5);B.hack(K5);$e.hack(Z5);$e.hack(eO);$e.hack(tO);$e.hack(rO);$e.hack(iO);$e.hack(nO);$e.hack(sO);$e.hack(aO);var Kl=new Map,si=class{constructor(e,t,r={}){this.data=e,this.browsers=t,this.options=r,[this.add,this.remove]=this.preprocess(this.select(this.data)),this.transition=new t5(this),this.processor=new r5(this)}cleaner(){if(this.cleanerCache)return this.cleanerCache;if(this.browsers.selected.length){let e=new Xl(this.browsers.data,[]);this.cleanerCache=new si(this.data,e,this.options)}else return this;return this.cleanerCache}select(e){let t={add:{},remove:{}};for(let r in e){let n=e[r],a=n.browsers.map(u=>{let c=u.split(" ");return{browser:`${c[0]} ${c[1]}`,note:c[2]}}),s=a.filter(u=>u.note).map(u=>`${this.browsers.prefix(u.browser)} ${u.note}`);s=nr.uniq(s),a=a.filter(u=>this.browsers.isSelected(u.browser)).map(u=>{let c=this.browsers.prefix(u.browser);return u.note?`${c} ${u.note}`:c}),a=this.sort(nr.uniq(a)),this.options.flexbox==="no-2009"&&(a=a.filter(u=>!u.includes("2009")));let o=n.browsers.map(u=>this.browsers.prefix(u));n.mistakes&&(o=o.concat(n.mistakes)),o=o.concat(s),o=nr.uniq(o),a.length?(t.add[r]=a,a.length!a.includes(u)))):t.remove[r]=o}return t}sort(e){return e.sort((t,r)=>{let n=nr.removeNote(t).length,a=nr.removeNote(r).length;return n===a?r.length-t.length:a-n})}preprocess(e){let t={selectors:[],"@supports":new i5(si,this)};for(let n in e.add){let a=e.add[n];if(n==="@keyframes"||n==="@viewport")t[n]=new n5(n,a,this);else if(n==="@resolution")t[n]=new Hw(n,a,this);else if(this.data[n].selector)t.selectors.push(ir.load(n,a,this));else{let s=this.data[n].props;if(s){let o=$e.load(n,a,this);for(let u of s)t[u]||(t[u]={values:[]}),t[u].values.push(o)}else{let o=t[n]&&t[n].values||[];t[n]=B.load(n,a,this),t[n].values=o}}}let r={selectors:[]};for(let n in e.remove){let a=e.remove[n];if(this.data[n].selector){let s=ir.load(n,a);for(let o of a)r.selectors.push(s.old(o))}else if(n==="@keyframes"||n==="@viewport")for(let s of a){let o=`@${s}${n.slice(1)}`;r[o]={remove:!0}}else if(n==="@resolution")r[n]=new Hw(n,a,this);else{let s=this.data[n].props;if(s){let o=$e.load(n,[],this);for(let u of a){let c=o.old(u);if(c)for(let f of s)r[f]||(r[f]={}),r[f].values||(r[f].values=[]),r[f].values.push(c)}}else for(let o of a){let u=this.decl(n).old(n,o);if(n==="align-self"){let c=t[n]&&t[n].prefixes;if(c){if(o==="-webkit- 2009"&&c.includes("-webkit-"))continue;if(o==="-webkit-"&&c.includes("-webkit- 2009"))continue}}for(let c of u)r[c]||(r[c]={}),r[c].remove=!0}}}return[t,r]}decl(e){return Kl.has(e)||Kl.set(e,B.load(e)),Kl.get(e)}unprefixed(e){let t=this.normalize(Gw.unprefixed(e));return t==="flex-direction"&&(t="flex-flow"),t}normalize(e){return this.decl(e).normalize(e)}prefixed(e,t){return e=Gw.unprefixed(e),this.decl(e).prefixed(e,t)}values(e,t){let r=this[e],n=r["*"]&&r["*"].values,a=r[t]&&r[t].values;return n&&a?nr.uniq(n.concat(a)):n||a||[]}group(e){let t=e.parent,r=t.index(e),{length:n}=t.nodes,a=this.unprefixed(e.prop),s=(o,u)=>{for(r+=o;r>=0&&r{l();Jw.exports={"backdrop-filter":{feature:"css-backdrop-filter",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5","safari 16.5"]},element:{props:["background","background-image","border-image","mask","list-style","list-style-image","content","mask-image"],feature:"css-element-function",browsers:["firefox 114"]},"user-select":{mistakes:["-khtml-"],feature:"user-select-none",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5","safari 16.5"]},"background-clip":{feature:"background-clip-text",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},hyphens:{feature:"css-hyphens",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5","safari 16.5"]},fill:{props:["width","min-width","max-width","height","min-height","max-height","inline-size","min-inline-size","max-inline-size","block-size","min-block-size","max-block-size","grid","grid-template","grid-template-rows","grid-template-columns","grid-auto-columns","grid-auto-rows"],feature:"intrinsic-width",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"fill-available":{props:["width","min-width","max-width","height","min-height","max-height","inline-size","min-inline-size","max-inline-size","block-size","min-block-size","max-block-size","grid","grid-template","grid-template-rows","grid-template-columns","grid-auto-columns","grid-auto-rows"],feature:"intrinsic-width",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},stretch:{props:["width","min-width","max-width","height","min-height","max-height","inline-size","min-inline-size","max-inline-size","block-size","min-block-size","max-block-size","grid","grid-template","grid-template-rows","grid-template-columns","grid-auto-columns","grid-auto-rows"],feature:"intrinsic-width",browsers:["firefox 114"]},"fit-content":{props:["width","min-width","max-width","height","min-height","max-height","inline-size","min-inline-size","max-inline-size","block-size","min-block-size","max-block-size","grid","grid-template","grid-template-rows","grid-template-columns","grid-auto-columns","grid-auto-rows"],feature:"intrinsic-width",browsers:["firefox 114"]},"text-decoration-style":{feature:"text-decoration",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5"]},"text-decoration-color":{feature:"text-decoration",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5"]},"text-decoration-line":{feature:"text-decoration",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5"]},"text-decoration":{feature:"text-decoration",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5"]},"text-decoration-skip":{feature:"text-decoration",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5"]},"text-decoration-skip-ink":{feature:"text-decoration",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5"]},"text-size-adjust":{feature:"text-size-adjust",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5"]},"mask-clip":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-composite":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-image":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-origin":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-repeat":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-border-repeat":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-border-source":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},mask:{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-position":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-size":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-border":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-border-outset":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-border-width":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-border-slice":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"clip-path":{feature:"css-clip-path",browsers:["samsung 21"]},"box-decoration-break":{feature:"css-boxdecorationbreak",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5","opera 99","safari 16.5","samsung 21"]},appearance:{feature:"css-appearance",browsers:["samsung 21"]},"image-set":{props:["background","background-image","border-image","cursor","mask","mask-image","list-style","list-style-image","content"],feature:"css-image-set",browsers:["and_uc 15.5","chrome 109","samsung 21"]},"cross-fade":{props:["background","background-image","border-image","mask","list-style","list-style-image","content","mask-image"],feature:"css-cross-fade",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},isolate:{props:["unicode-bidi"],feature:"css-unicode-bidi",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5","safari 16.5"]},"color-adjust":{feature:"css-color-adjust",browsers:["chrome 109","chrome 113","chrome 114","edge 114","opera 99"]}}});var Zw=v((DI,Kw)=>{l();Kw.exports={}});var ib=v((II,rb)=>{l();var oO=zo(),{agents:lO}=($n(),Ln),Zl=hm(),uO=dt(),fO=Qw(),cO=Xw(),pO=Zw(),eb={browsers:lO,prefixes:cO},tb=` + Replace Autoprefixer \`browsers\` option to Browserslist config. + Use \`browserslist\` key in \`package.json\` or \`.browserslistrc\` file. + + Using \`browsers\` option can cause errors. Browserslist config can + be used for Babel, Autoprefixer, postcss-normalize and other tools. + + If you really need to use option, rename it to \`overrideBrowserslist\`. + + Learn more at: + https://github.com/browserslist/browserslist#readme + https://twitter.com/browserslist + +`;function dO(i){return Object.prototype.toString.apply(i)==="[object Object]"}var eu=new Map;function hO(i,e){e.browsers.selected.length!==0&&(e.add.selectors.length>0||Object.keys(e.add).length>2||i.warn(`Autoprefixer target browsers do not need any prefixes.You do not need Autoprefixer anymore. +Check your Browserslist config to be sure that your targets are set up correctly. + + Learn more at: + https://github.com/postcss/autoprefixer#readme + https://github.com/browserslist/browserslist#readme + +`))}rb.exports=sr;function sr(...i){let e;if(i.length===1&&dO(i[0])?(e=i[0],i=void 0):i.length===0||i.length===1&&!i[0]?i=void 0:i.length<=2&&(Array.isArray(i[0])||!i[0])?(e=i[1],i=i[0]):typeof i[i.length-1]=="object"&&(e=i.pop()),e||(e={}),e.browser)throw new Error("Change `browser` option to `overrideBrowserslist` in Autoprefixer");if(e.browserslist)throw new Error("Change `browserslist` option to `overrideBrowserslist` in Autoprefixer");e.overrideBrowserslist?i=e.overrideBrowserslist:e.browsers&&(typeof console!="undefined"&&console.warn&&(Zl.red?console.warn(Zl.red(tb.replace(/`[^`]+`/g,n=>Zl.yellow(n.slice(1,-1))))):console.warn(tb)),i=e.browsers);let t={ignoreUnknownVersions:e.ignoreUnknownVersions,stats:e.stats,env:e.env};function r(n){let a=eb,s=new uO(a.browsers,i,n,t),o=s.selected.join(", ")+JSON.stringify(e);return eu.has(o)||eu.set(o,new fO(a.prefixes,s,e)),eu.get(o)}return{postcssPlugin:"autoprefixer",prepare(n){let a=r({from:n.opts.from,env:e.env});return{OnceExit(s){hO(n,a),e.remove!==!1&&a.processor.remove(s,n),e.add!==!1&&a.processor.add(s,n)}}},info(n){return n=n||{},n.from=n.from||h.cwd(),pO(r(n))},options:e,browsers:i}}sr.postcss=!0;sr.data=eb;sr.defaults=oO.defaults;sr.info=()=>sr().info()});var nb={};_e(nb,{default:()=>mO});var mO,sb=C(()=>{l();mO=[]});var ob={};_e(ob,{default:()=>gO});var ab,gO,lb=C(()=>{l();hi();ab=X(bi()),gO=Ze(ab.default.theme)});var fb={};_e(fb,{default:()=>yO});var ub,yO,cb=C(()=>{l();hi();ub=X(bi()),yO=Ze(ub.default)});l();"use strict";var wO=Je(pm()),bO=Je(ye()),vO=Je(ib()),xO=Je((sb(),nb)),kO=Je((lb(),ob)),SO=Je((cb(),fb)),CO=Je((Zn(),bu)),AO=Je((mo(),ho)),_O=Je((hs(),Ku));function Je(i){return i&&i.__esModule?i:{default:i}}console.warn("cdn.tailwindcss.com should not be used in production. To use Tailwind CSS in production, install it as a PostCSS plugin or use the Tailwind CLI: https://tailwindcss.com/docs/installation");var Hn="tailwind",tu="text/tailwindcss",pb="/template.html",St,db=!0,hb=0,ru=new Set,iu,mb="",gb=(i=!1)=>({get(e,t){return(!i||t==="config")&&typeof e[t]=="object"&&e[t]!==null?new Proxy(e[t],gb()):e[t]},set(e,t,r){return e[t]=r,(!i||t==="config")&&nu(!0),!0}});window[Hn]=new Proxy({config:{},defaultTheme:kO.default,defaultConfig:SO.default,colors:CO.default,plugin:AO.default,resolveConfig:_O.default},gb(!0));function yb(i){iu.observe(i,{attributes:!0,attributeFilter:["type"],characterData:!0,subtree:!0,childList:!0})}new MutationObserver(async i=>{let e=!1;if(!iu){iu=new MutationObserver(async()=>await nu(!0));for(let t of document.querySelectorAll(`style[type="${tu}"]`))yb(t)}for(let t of i)for(let r of t.addedNodes)r.nodeType===1&&r.tagName==="STYLE"&&r.getAttribute("type")===tu&&(yb(r),e=!0);await nu(e)}).observe(document.documentElement,{attributes:!0,attributeFilter:["class"],childList:!0,subtree:!0});async function nu(i=!1){i&&(hb++,ru.clear());let e="";for(let r of document.querySelectorAll(`style[type="${tu}"]`))e+=r.textContent;let t=new Set;for(let r of document.querySelectorAll("[class]"))for(let n of r.classList)ru.has(n)||t.add(n);if(document.body&&(db||t.size>0||e!==mb||!St||!St.isConnected)){for(let n of t)ru.add(n);db=!1,mb=e,self[pb]=Array.from(t).join(" ");let{css:r}=await(0,bO.default)([(0,wO.default)({...window[Hn].config,_hash:hb,content:{files:[pb],extract:{html:n=>n.split(" ")}},plugins:[...xO.default,...Array.isArray(window[Hn].config.plugins)?window[Hn].config.plugins:[]]}),(0,vO.default)({remove:!1})]).process(`@tailwind base;@tailwind components;@tailwind utilities;${e}`);(!St||!St.isConnected)&&(St=document.createElement("style"),document.head.append(St)),St.textContent=r}}})(); +/*! https://mths.be/cssesc v3.0.0 by @mathias */ diff --git a/public/styles/app.css b/public/styles/app.css deleted file mode 100644 index 8d80352e..00000000 --- a/public/styles/app.css +++ /dev/null @@ -1,1311 +0,0 @@ -:root { - --bg01: #111810; - --bg02: #10240C; - - --fg03: #007C00; - --fg02: #00C000; - --fg01: #3CF800; - --fg-highlight: #FCFF2F; - - /* Greens: - Fallout 2 character select screen: #5BF523 - Fallout Tactics custom campaign: #4AFC24 - - Oranges: - Fallout Tactics custom campaign: #FCFF2F - */ - - --bg02-half-transparent: rgba(16,36,12,0.5); - --bg01-abovehalf-transparent: rgba(17,24,16,0.625); - --fg01-half-transparent: rgba(60,248,0,0.5); - --fg01-fully-transparent: rgba(60,248,0,0); - --fg03-half-transparent: rgba(0,124,0,0.5); - --fg-highlight-transparent: rgba(252,253,125,0.25); - --fg-highlight-fully-transparent: rgba(252,253,125,0); - - /* filters for the logo calculated with https://codepen.io/sosuke/pen/Pjoqqp */ - --filter-fg02: invert(42%) sepia(85%) saturate(1707%) hue-rotate(88deg) brightness(102%) contrast(112%); - --filter-fg01: invert(71%) sepia(54%) saturate(3327%) hue-rotate(60deg) brightness(106%) contrast(118%) drop-shadow(0px 0px 8px var(--fg03)); -} - -/* Final choice: -PixelOperator/16px for body -PixelOperatorHB/16px for bold -PixelOperatorHBSC/16px for extra bold / login form / buttons etc? -PixelOperatorMonoHB/16px for code listing -*/ - -@font-face { - font-family: "PixelOperator"; - font-weight: 400; - src: url("../fonts/PixelOperator.ttf") format('truetype'); -} -@font-face { - font-family: "PixelOperator"; - font-weight: 700; - src: url("../fonts/PixelOperatorHB.ttf") format('truetype'); -} -@font-face { - font-family: "PixelOperator"; - font-weight: 900; - src: url("../fonts/PixelOperatorHBSC.ttf") format('truetype'); -} -@font-face { - font-family: "PixelOperatorMono"; - src: url("../fonts/PixelOperatorMonoHB.ttf") format('truetype'); -} - - - -html { - width: 100%; - height: 100%; -} - -body { - display: flex; - color: var(--fg02); - margin: 0; - position: relative; - min-height: 100%; -} - -* { - font-family: "PixelOperator"; - line-height: 17px; - font-size: 16px; - font-weight: normal; - - font-smooth: never; - -webkit-font-smoothing: none; - -moz-osx-font-smoothing: none; - /* -webkit-font-smoothing: antialiased; */ -} - -body:after { - position: absolute; - content: ''; - left: 0; - right: 0; - top: 0; - bottom: 0; - z-index: 1; - border-style: solid; - border-width: 128px; - border-color: transparent; - border-image: url('../images/border-image.png') 50% repeat; - box-sizing: border-box; - pointer-events: none; -} - -p { - max-width: 60ch; -} - -button, input, textarea { - border: none; - background: transparent; - color: var(--fg02); - padding: 0; - margin: 0; -} -button:disabled { - color: var(--fg03); -} -input:focus, textarea:focus { - outline: none; -} - -button { - text-transform: uppercase; - cursor: pointer; -} - -.has-tooltip { - text-decoration: underline; - text-decoration-style: dashed; - text-decoration-color: var(--fg03); -} - -button:hover, -button:active { - color: var(--fg01); - outline-color: var(--fg01); -} - -::placeholder { - color: var(--fg03); -} - -ul { - margin: 0; -} - -#app { - display: flex; - flex: 1; - flex-direction: row; - background-color: var(--bg01); -} - -#left-nav { - background-color: var(--bg02); - min-width: 190px; - width: 190px; - display: flex; - flex-direction: column; - align-items: flex-start; - padding-bottom: 40px; - padding-left: 40px; - padding-right: 40px; -} - -#left-nav-content { - padding-left: 27px; -} - -#logo-wrapper { - display: flex; - flex-direction: column; - align-items: flex-end; - margin-top: 26px; -} - -#logo { - width: 190px; - height: 36px; - filter: var(--filter-fg02); -} - -#version { - color: var(--fg03); -} - -#app.player #logo, -#app.admin #logo { - filter: var(--filter-fg01); - animation: flicker 2s linear 1; -} - -/* Safari hack courtesy https://browserstrangeness.github.io/ - -Disable the flicker animation in Safari, since it behaves very weird and -doesn't look as nice as in Chrome/Firefox. -*/ -_::-webkit-full-page-media, _:future, :root #app.player #logo, -_::-webkit-full-page-media, _:future, :root #app.admin #logo { - animation: none; -} - -@keyframes flicker { - 0%, 19%, 26%, 46%, 65%, 82%, 86%, 87%, 90%, 95% { - filter: var(--filter-fg02); - } - 20%, 25%, 47%, 64%, 83%, 85%, 88%, 89%, 96%, 100% { - filter: var(--filter-fg01); - } -} - -#login-form { - margin-top: 40px; - width: 20ch; -} - -#login-form input { - color: var(--fg01); - width: 18ch; - margin: 0; - padding: 0; - font-weight: 900; -} - -#login-form input:focus { - background-color: var(--bg01); -} - -#admin-hiscores-content #ladder-table { - margin-top: 16px; -} -/* select+option taken mainly from https://codepen.io/5t3ph/pen/MWyyYNz */ -.login-world-select-label { - margin-top: 20px; -} -.login-world-select-wrapper { - display: grid; - grid-template-areas: "select"; - align-items: center; - position: relative; - width: 20ch; - border-radius: 4px; - cursor: pointer; - background-color: var(--fg02); - margin-top: 8px; -} -.login-world-select-wrapper::after { - grid-area: select; - content: "^"; - justify-self: end; - transform: translateY(-2px) rotate(180deg); - color: #000000; /* we can't affect color, so we give up and make the -arrow have the same color */ - padding-left: 8px; - padding-right: 8px; -} -.login-world-select { - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - background-color: transparent; - border: none; - margin: 0; - padding: 4px 32px 4px 8px; - width: 100%; - font-size: inherit; - cursor: inherit; - line-height: inherit; - z-index: 1; - outline: none; - grid-area: select; -} -.login-world-select::-ms-expand { - display: none; -} -.login-world-select:focus + .login-world-select-focus { - position: absolute; - top: -1px; - left: -1px; - right: -1px; - bottom: -1px; - border: 2px solid var(--fg01); - border-radius: inherit; -} - -#login-form-buttons { - margin-top: 1em; - display: flex; - justify-content: space-between; -} - -#alert-message { - margin-top: 40px; - color: var(--fg-highlight); -} - -#logged-out-links, -#logged-in-links { - margin-top: 40px; -} - -#common-links { - margin-top: 1em; -} - -#logged-out-links, -#logged-in-links, -#common-links { - padding-left: 24px; -} - -.link { - color: var(--fg03); - cursor: pointer; - text-decoration: none; - display: block; - text-align: left; -} - -.link-label { - color: var(--fg01); - text-transform: uppercase; - width: 9ch; - min-width: 9ch; - display: inline-block; - margin: 0 1ch; - white-space: pre; -} - -.link[target="_blank"] .link-right-bracket::before { - content: "-> "; - color: var(--fg03); - margin-left: -2ch; -} - -.link.active .link-label, -.link:hover, -.link:hover .link-label { - color: var(--fg-highlight); -} - -.link.dimmed:not(:hover):not(.active) .link-label { - color: var(--fg03); -} - -.link:disabled .link-left-bracket, -.link:disabled .link-right-bracket, -.link:disabled .link-label { - color: var(--fg03); - -} - -#player-info { - margin-top: 40px; - padding-left: 16px; - display: grid; - grid-template-columns: min-content min-content; - grid-auto-rows: auto; -} - -.player-stat-label { - grid-column: 1; - text-align: right; - color: var(--fg03); - margin-right: 1ch; -} - -.player-stat-value { - grid-column: 2; - color: var(--fg02); -} - -.emphasized { - color: var(--fg01); -} - -.slightly-emphasized { - color: var(--fg02); -} - -.deemphasized { - color: var(--fg03); -} - -#loading-nav { - margin-top: 40px; -} - -.loading-cursor { - display: inline-block; - animation: cursor-blink 1.5s linear infinite; - width: 1ch; - height: 1em; - margin-bottom: -2px; - margin-left: 2px; -} - -@keyframes cursor-blink { - 0%, 10%, 90%, 100% { - background: var(--fg02); - } - 30%, 70% { - background: transparent; - } -} - -#admin-worlds-list table { - white-space: nowrap; -} -#admin-worlds-list button+button { - margin-left: 1ch; -} - -#content { - padding: 32px 40px 40px; - display: flex; - flex-direction: column; - flex: 1; - align-items: flex-start; -} - -#page-title { - font-size: 32px; - margin: 0 0 40px; - font-weight: 900; -} - -table { - text-align: left; - border-collapse: collapse; -} - -table tbody td { - border-left: 1px solid var(--fg03-half-transparent); - padding: 4px 8px; -} - -table thead { - color: var(--fg03); - border-bottom: 3px solid var(--fg03-half-transparent); -} - -table thead th { - border-left: 3px solid var(--fg03-half-transparent); - padding: 4px 8px; - font-weight: normal; -} - -table tbody td:first-child, -table thead th:first-child { - border-left: none; -} - -table tbody tr:hover td { - background: var(--bg02); -} - -#ladder-table tbody tr.is-player { - color: var(--fg01); -} - -#ladder-table tbody tr.is-player td { - background: var(--bg02); -} - -#ladder-table tbody .ladder-rank, -#ladder-table tbody .ladder-lvl, -#ladder-table tbody .ladder-wins, -#ladder-table tbody .ladder-losses { - text-align: right; -} - -#ladder-table tbody .ladder-fight { - cursor: pointer; - background: var(--bg02); - color: var(--fg01); -} - -#ladder-table tbody .ladder-fight:hover { - color: var(--fg-highlight); -} - -#ladder-table tbody tr.is-player .ladder-fight { - color: var(--fg03); -} - -#messages-table tbody .messages-unread { - text-align: right; -} - -#messages-table tbody tr.is-unread { - color: var(--fg01); -} - -#messages-table tbody .messages-remove:hover { - color: var(--fg-highlight); -} - -#messages-empty-note { - margin-top: 40px; -} - -#message-summary { - margin: 0; - color: var(--fg01); - font-weight: 700; -} - -#message-date { - color: var(--fg03); -} - -#message-content { - max-width: 60ch; -} - -.news-item:not(:first-of-type) { - margin-top: 60px; -} - - -.news-item-title { - margin: 0; - color: var(--fg01); - font-weight: 700; -} - -.news-item-date { - color: var(--fg03); -} - -.news-item-text { - max-width: 60ch; -} - - -.news-item-text pre { - padding-left: 32px; -} -.news-item-text pre code { - color: var(--fg01); -} - -.news-item-text a { - color: var(--fg-highlight); - position: relative; - text-decoration: none; -} - -.news-item-text a:after { - position: absolute; - content: ''; - background: var(--fg-highlight-transparent); - left: -3px; - right: -3px; - bottom: -2px; - height: 4px; - transition: bottom 0.25s ease, height 0.25s ease; -} - -.news-item-text a:hover:after { - bottom: 0px; - height: 100%; -} - -.news-item-text strong { - font-weight: normal; - color: var(--fg-highlight); -} - -.news-item-text li:not(first-child) { - margin-top: 1em; -} - -.character-special-attribute-value { - padding-left: 2ch; - width: 2ch; - text-align: right; -} -.character-special-attribute-value.out-of-range { - color: var(--fg-highlight); -} - -.character-special-attribute-dec button, -.character-special-attribute-inc button { - border: none; - background: transparent; - color: var(--fg01); -} - -.character-special-attribute-dec button:not(:disabled):hover, -.character-special-attribute-inc button:not(:disabled):hover { - color: var(--fg-highlight); - background: var(--bg02); -} - -.character-special-attribute-dec { - padding-right: 20px; -} - -.character-special-attribute-inc { - padding-left: 20px; -} - -#character-stats-list { - margin-top: 40px; -} - -#fight-back-button { - margin-top: 40px; -} - -#message-back-button { - margin-top: 40px; -} - -#create-char-button { - margin-top: 40px; -} - -#next-tick, -#server-tick { - color: var(--fg03); - height: 1em; - padding-left: 10px; -} - -#next-tick { - margin-top: 20px; -} - -#server-tick { - margin-top: 10px; -} - -#map { - position: relative; - width: calc(var(--map-columns) * var(--map-cell-size)); - height: calc(var(--map-rows) * var(--map-cell-size)); - background-color: black; - background-image: url('../images/map_whole.png'); - background-position: 0 0; - background-repeat: no-repeat; - user-select: none; -} -#map.admin-map { - margin-top: 1em; -} - -#admin-last-ten-msgs-table td { - white-space: nowrap; - padding-right: 2ch; -} - -#map-cost-info { - transform: translate( - calc(var(--map-cell-size) * (0.5 + var(--tile-coord-x)) - 50%), - calc(var(--map-cell-size) * var(--tile-coord-y) - 100% - 10px) - ); - width: min-content; - white-space: nowrap; - padding: 20px; - background-color: var(--bg01); - color: var(--bad-path-color, var(--fg02)); - position: relative; - z-index: 3; -} - -#map-mouse-layer { - left: 0; - top: 0; - right: 0; - bottom: 0; - position: absolute; -} - -#map-mouse-layer.too-distant, -#map-mouse-layer.not-all-passable { - --bad-path-color: var(--fg-highlight); -} - -#map-tiles { - display: grid; - grid-template-columns: repeat(var(--map-columns), var(--map-cell-size)); - grid-template-rows: repeat(var(--map-rows), var(--map-cell-size)); -} - -#map-mouse-event-catcher { - z-index: 4; - left: 0; - top: 0; - right: 0; - bottom: 0; - position: absolute; -} - -.tile { - position: absolute; - left: 0; - top: 0; - width: var(--map-cell-size); - height: var(--map-cell-size); - transform: translate( - calc(var(--map-cell-size) * var(--tile-coord-x)), - calc(var(--map-cell-size) * var(--tile-coord-y)) - ); -} - -#map-path-tiles { - left: 0; - top: 0; - right: 0; - bottom: 0; - position: absolute; -} - -.map-path-tile { - background: var(--bad-path-color,var(--fg03)); - opacity: 0.5; - pointer-events: none; - z-index: 1; -} - -#map-mouse-tile { - background: var(--bad-path-color,var(--fg03)); - opacity: 0.75; - pointer-events: none; - z-index: 1; -} - -#map-locations { - position: absolute; - left: 0; - top: 0; - right: 0; - bottom: 0; - background-color: rgba(0,0,0,0.25); -} - -.map-location { - color: var(--fg01); - opacity: 0.5; -} -.map-location.has-vendor { opacity: 1; } -.map-location.is-current { opacity: 1; } -.map-location:hover { opacity: 1; } - -.map-location.small { - --location-border-width: 1px; - --location-size: 11px; - --location-name-top: 68%; -} - -.map-location.middle { - --location-border-width: 1px; - --location-size: 23px; - --location-name-top: 75%; -} - -.map-location.large { - --location-border-width: 2px; - --location-size: 45px; - --location-name-top: 100%; -} - -.map-location:before { - position: absolute; - top: 50%; - left: 50%; - content: ''; - display: block; - width: var(--location-size); - height: var(--location-size); - border: var(--location-border-width) solid var(--fg01); - border-radius: 50%; - background: radial-gradient(circle, - var(--fg01-fully-transparent) 0%, - var(--fg01-half-transparent) 100%); - transform: translate(-50%, -50%); -} - -.map-location:after { - content: attr(data-location-name); - display: block; - top: var(--location-name-top); - left: 50%; - transform: translate(-50%, 0); - text-align: center; - position: absolute; - white-space: nowrap; - background-color: rgba(0,0,0,0.25); - padding: 0 4px; - line-height: 13px; - text-shadow: 2px 0 2px #000, 0 2px 2px #000, -2px 0 2px #000, 0 -2px 2px #000; -} - - -.map-marker { - position: absolute; - left: 0; - top: 0; - transform: translate( - calc(var(--map-cell-size) * (0.5 + var(--player-coord-x)) - 50%), - calc(var(--map-cell-size) * (0.5 + var(--player-coord-y)) - 50%) - ); - z-index: 2; -} - -.fight-log-action strong { - color: var(--fg-highlight); -} - -.fight-info { - margin-top: 40px; -} - -#import-textarea { - border: none; - background-color: var(--bg02); - width: 80ch; - height: 20em; - margin-bottom: 1em; -} - -#town-store-grid { - margin-top: 40px; - align-self: stretch; - display: grid; - grid-template-columns: repeat(4, 1fr); - grid-template-areas: - "player-name player-name vendor-name vendor-name" - "player-kept-caps player-traded-caps vendor-traded-caps vendor-kept-caps" - "player-kept-items player-traded-items vendor-traded-items vendor-kept-items" - "barter-reset-btn player-traded-value vendor-traded-value barter-confirm-btn"; -} - -#town-store-reset-btn { - grid-area: barter-reset-btn; -} -#town-store-confirm-btn { - grid-area: barter-confirm-btn; -} -#town-store-player-name { - grid-area: player-name; - padding: 8px; -} -#town-store-vendor-name { - grid-area: vendor-name; - text-align: right; - padding: 8px; -} -#town-store-player-name, -#town-store-vendor-name { - border-bottom: 2px solid var(--bg02); -} -#town-store-player-traded-value { - grid-area: player-traded-value; - color: var(--fg01); - text-align: center; -} -#town-store-vendor-traded-value { - grid-area: vendor-traded-value; - color: var(--fg01); - text-align: center; -} -.town-store-transfer-btn { - padding: 2px 4px; - margin: 0 4px; - background: var(--bg02); - color: var(--fg02); -} -.town-store-transfer-btn:disabled { - color: var(--fg03); - opacity: 0.5; - pointer-events: none; -} -.town-store-transfer-btn:not(:disabled):hover { - background: var(--fg03); - color: var(--fg01); -} -.town-store-transfer-btn.hidden { - display: none; -} - -.town-store-item { - display: flex; - align-items: center; -} - -.town-store-item-label { - flex: 1; -} - -.player-traded-caps .town-store-item-label, -.vendor-kept-caps .town-store-item-label, -.vendor-kept-item .town-store-item-label, -.player-traded-item .town-store-item-label { - margin-left: 4px; -} - -.town-store-item, -#town-store-player-traded-value, -#town-store-vendor-traded-value { - padding: 8px; -} - -#town-store-player-traded-bg { - grid-area: 2 / 2 / 5 / 3; - background-color: var(--bg02-half-transparent); - border-right: 1px solid var(--bg02); -} -#town-store-vendor-traded-bg { - grid-area: 2 / 3 / 5 / 4; - background-color: var(--bg02-half-transparent); - border-left: 1px solid var(--bg02); -} - -.town-store-item.player-kept-caps { grid-area: player-kept-caps; } -.town-store-item.player-traded-caps { grid-area: player-traded-caps; } -.town-store-item.vendor-kept-caps { grid-area: vendor-kept-caps; } -.town-store-item.vendor-traded-caps { grid-area: vendor-traded-caps; } - -.town-store-caps { - padding-top: 4px; - padding-bottom: 8px; -} -.town-store-caps[data-caps="0"] { - color: var(--fg03); -} - -#town-store-player-kept-items { grid-area: player-kept-items; } -#town-store-player-traded-items { grid-area: player-traded-items; } -#town-store-vendor-kept-items { grid-area: vendor-kept-items; } -#town-store-vendor-traded-items { grid-area: vendor-traded-items; } - -#town-store-player-traded-value { grid-area: player-traded-value; } -#town-store-vendor-traded-value { grid-area: vendor-traded-value; } - -#town-store-barter-message { - margin-top: 40px; - color: var(--fg-highlight); -} - -.town-store-transfer-n-area { - display: flex; -} -.town-store-transfer-n-area .after-hover { display: none; } -.town-store-transfer-n-area:hover .after-hover { display: block; } -.town-store-transfer-n-area .before-hover { display: block; } -.town-store-transfer-n-area:hover .before-hover { display: none; } -.town-store-transfer-n-input { - width: 5.5ch; - background-color: var(--bg02); - padding-left: 6px; -} - -.character-skills-skill { - display: flex; - flex-direction: row; - justify-content: space-between; -} -.character-skills-skill:hover, -.character-skills-skill:hover .character-skill-tag-btn, -.character-skills-skill:hover .character-skill-inc-btn { - color: var(--fg01); -} -.character-skills-skill.is-taggable { - cursor: pointer; -} -.character-skills-skill.not-useful { - opacity: 0.5; -} -.character-skills-skill.is-tagged, -.character-skills-skill.is-tagged .character-skill-tag-btn , -.character-skills-skill.is-tagged .character-skill-inc-btn { - color: var(--fg-highlight); -} -.character-skill-tag-btn { - white-space: pre; - margin-right: 1ch; -} -.character-skill-inc-btn { - white-space: pre; - margin-left: 1ch; -} -#character-skills.cannot-inc .character-skill-inc-btn { - opacity: 0.5; -} -.character-skill-value { - display: flex; -} -.character-skill-percent { - padding-left: 2ch; - width: 4ch; - text-align: right; -} -#character-skills-list { - width: max-content; - padding: 0; -} - -.new-character-traits-trait { - display: flex; - flex-direction: row; - justify-content: flex-start; - cursor: pointer; -} -.new-character-traits-trait:hover, -.new-character-traits-trait:hover .new-character-trait-tag-btn { - color: var(--fg01); -} -.new-character-traits-trait.is-toggled, -.new-character-traits-trait.is-toggled .new-character-trait-tag-btn { - color: var(--fg-highlight); -} -.new-character-trait-tag-btn { - white-space: pre; - margin-right: 1ch; -} -#new-character-traits-list { - width: max-content; - padding: 0; - display: grid; - grid-template-columns: repeat(2, 1fr); -} - -#new-character-grid, -#character-grid { - display: grid; - grid-template-columns: repeat(3, 1fr); - grid-gap: 20px; -} - -#new-character-traits, -#character-traits, -#character-perks { - margin-top: 40px; -} - -#new-character-notes p { - max-width: none; - color: var(--fg03); -} - -#new-character-create-btn { - margin-top: 40px; -} - -.new-character-section-title, -.character-section-title { - color: var(--fg03); - margin-top: 0; -} -.new-character-section-available-number, -.character-section-available-number { - color: var(--fg-highlight); -} - -#new-character-special p, -#new-character-traits p, -#new-character-skills p { - color: var(--fg03); -} - -#new-character-error { - color: var(--fg-highlight); - margin-top: 20px; -} - -#new-character-help, -#character-help { - margin-top: 20px; -} - -.inventory-item button { - margin-right: 1ch; -} -.inventory-item button:last-child { - margin-right: 2ch; -} -.inventory-item-use-btn:disabled { - color: var(--fg03); -} -.inventory-equipment-unequip-btn { - margin-left: 1ch; -} - -.character-choose-perk-item { - cursor: pointer; -} - -.character-choose-perk-item:hover { - color: var(--fg-highlight); -} - -#character-choose-perk { - flex: 1; - display: flex; - flex-direction: column; - align-self: stretch; -} - -#character-choose-perk-columns { - flex: 1; - display: grid; - grid-template-columns: repeat(2, 1fr); -} - -.hovered-item-title { - margin-top: 0; - color: var(--fg-highlight); -} - -#about-content strong { - color: var(--fg-highlight); -} - -#about-content p { - margin-top: 0; -} - -#fight-stats-table th, -#fight-stats-table td { - text-align: right; -} - -.fight-strategy-grid { - display: grid; - grid-template-areas: - "examples info" - "textarea info"; - --textarea-margin-top: 16px; - --textarea-padding: 16px; - --textarea-line-height: 18px; -} -.fight-strategy-examples { - grid-area: examples; -} -.fight-strategy-example { - text-transform: none; -} -.fight-strategy-example:before { - content: '['; -} -.fight-strategy-example:after { - content: ']'; -} -.fight-strategy-textarea { - background-color: var(--bg02); - grid-area: textarea; - width: 70ch; - height: 25em; - margin-top: var(--textarea-margin-top); - margin-bottom: 16px; - padding: var(--textarea-padding); - border-radius: 4px; - font-size: 16px; - line-height: var(--textarea-line-height); - white-space: pre; - font-family: "PixelOperatorMono"; -} -.fight-strategy-hovered-error { - pointer-events: none; - user-select: none; - border-bottom: 2px; - width: 3ch; - height: 1em; - background-color: var(--fg-highlight-transparent); - margin-left: -2px; - padding-left: 2px; - border-left: 2px solid var(--fg-highlight); - background: var(--fg-highlight); - background: linear-gradient(90deg, var(--fg-highlight-transparent) 0%, var(--fg-highlight-fully-transparent) 100%); - grid-area: textarea; - font-size: 16px; - line-height: var(--textarea-line-height); - transform: translate( - calc((var(--error-col) - 1) * 1ch + var(--textarea-padding)), - calc((var(--error-row) - 1) * var(--textarea-line-height) + var(--textarea-padding) + var(--textarea-margin-top)) - ); - -} -.fight-strategy-info { - grid-area: info; - margin-left: 16px; -} -.fight-strategy-info-paragraph { - margin-top: 16px; -} -.fight-strategy-info-link { - color: var(--fg01); -} -.fight-strategy-info-link:hover { - color: var(--fg-highlight); -} -.fight-strategy-help-btn { - margin-left: 1ch; -} - -.fight-strategy-reset-btn { - margin-left: 1ch; -} -.fight-strategy-dead-ends { - margin: 0; - padding: 0; - list-style: none; -} -.fight-strategy-dead-end:hover { - color: var(--fg01); -} -.fight-strategy-warnings { - margin: 0; - padding: 0; - list-style: none; -} -.fight-strategy-warning:hover { - color: var(--fg01); -} -.fight-strategy-syntax-help { -} -.fight-strategy-syntax-help-reference { - color: var(--fg-highlight); - font-family: "PixelOperatorMono"; -} -.fight-strategy-syntax-help-grid { - display: grid; - grid-template-areas: 'cheatsheet hover'; -} -.fight-strategy-syntax-help-cheatsheet { - grid-area: cheatsheet; - font-family: "PixelOperatorMono"; -} -.fight-strategy-syntax-help-hover { - grid-area: hover; - margin-left: 2ch; -} -.fight-strategy-syntax-help-hover-description { - white-space: pre-wrap; -} -#admin-new-world-form { - margin-top: 1em; - display: flex; - flex-direction: column; - align-items: flex-start; -} -#admin-new-world-form label input[type="checkbox"] { - margin-right: 1ch; -} -.quests { - list-style: none; -} -.quest { - padding-left: 16px; -} -.quest:before { - content: '[+]'; - padding-right: 8px; - color: var(--fg02); -} -.quest:not(.expanded) { - cursor: pointer; -} -.quest:not(.expanded):hover, -.quest:not(.expanded):hover:before { - color: var(--fg01); -} -.quest.expanded:before { - content: '[-]'; -} -.quest-inner { - display: inline-block; - vertical-align: top; -} -.quest.expanded:not(:last-child) { - margin-bottom: 20px; -} -.quest-players { - color: var(--fg03); -} -.quest-number { - color: var(--fg02); -} -.quest-name { - cursor: pointer; -} -.quest-name:hover { - color: var(--fg01); -} -.quest-progressbar { - color: var(--fg03); - margin-top: 20px; -} -.quest-progressbar-text { - margin-left: 1ch; -} -.quest-toggle-btn { - margin-left: 1ch; -} -.quest-toggle-btn:hover { - color: var(--fg-highlight); -} -.quest-requirements-title { - margin-top: 20px; -} -.quest-requirements-list { - padding-inline-start: 4ch; -} -.quest-requirements-none { - margin-left: 4ch; - color: var(--fg03); -} -.quest-xp-per-tick { - color: var(--fg03); -} diff --git a/public/styles/defaults.css b/public/styles/defaults.css new file mode 100644 index 00000000..83d05b73 --- /dev/null +++ b/public/styles/defaults.css @@ -0,0 +1,116 @@ +:root { + --green-900: #111810; + --green-800: #10240C; + + --green-300: #007C00; + --green-200: #00C000; + --green-100: #3CF800; + + + --orange: #FCFF2F; + --red: #FC0001; + + --green-800-half-transparent: rgba(16, 36, 12, 0.5); + --green-300-half-transparent: rgba(0, 124, 0, 0.5); + + --green-100-half-transparent: rgba(60, 248, 0, 0.5); + --green-100-fully-transparent: rgba(60, 248, 0, 0); + + --orange-transparent: rgba(252, 253, 125, 0.25); + --orange-fully-transparent: rgba(252, 253, 125, 0); + --black-transparent: rgba(0, 0, 0, 0.25); + /* + Greens: + Fallout 2 character select screen: #5BF523 + Fallout Tactics custom campaign: #4AFC24 + + Oranges: + Fallout Tactics custom campaign: #FCFF2F + */ +} + +body { + background-color: var(--green-900); + color: var(--green-200); + display: flex; + height: 100vh; + width: 100vw; +} + +* { + font-family: "PixelOperator"; + line-height: 17px; + font-size: 16px; + font-weight: normal; + + font-smooth: never; + -webkit-font-smoothing: none; + -moz-osx-font-smoothing: none; + + text-wrap: pretty; +} + +/* VIGNETTE CORNERS */ +body:after { + position: fixed; + content: ''; + left: 0; + right: 0; + top: 0; + bottom: 0; + z-index: 1; + border-style: solid; + border-width: 128px; + border-color: transparent; + border-image: url('../images/border-image.webp') 50% repeat; + box-sizing: border-box; + pointer-events: none; +} + +::placeholder { + color: var(--green-300) !important; +} + +/* To remove this style we'd have to use Dillon's Markdown package. Too lazy right now */ +strong { + font-weight: 400 !important; + color: var(--orange) !important; +} + +/* Tables */ +table { + text-align: left; + border-collapse: collapse; +} + +thead { + border-bottom: 3px solid var(--green-300-half-transparent); + color: var(--green-300); +} + +th { + padding-left: 8px; + padding-right: 8px; + padding-top: 4px; + padding-bottom: 4px; + font-weight: 400; +} + +th:not(:first-child) { + border-left: 3px solid var(--green-300-half-transparent); +} + +td { + padding-left: 8px; + padding-right: 8px; + padding-top: 2px; + padding-bottom: 2px; +} + +td:not(:first-child) { + border-left: 1px solid var(--green-300-half-transparent); +} + +tr:hover td { + background-color: var(--green-800); +} \ No newline at end of file diff --git a/public/styles/fonts.css b/public/styles/fonts.css new file mode 100644 index 00000000..14c39c47 --- /dev/null +++ b/public/styles/fonts.css @@ -0,0 +1,22 @@ +@font-face { + font-family: "PixelOperator"; + font-weight: 400; + src: url("../fonts/PixelOperator.ttf") format('truetype'); +} + +@font-face { + font-family: "PixelOperator"; + font-weight: 700; + src: url("../fonts/PixelOperatorHB.ttf") format('truetype'); +} + +@font-face { + font-family: "PixelOperator"; + font-weight: 900; + src: url("../fonts/PixelOperatorHBSC.ttf") format('truetype'); +} + +@font-face { + font-family: "PixelOperatorMono"; + src: url("../fonts/PixelOperatorMonoHB.ttf") format('truetype'); +} \ No newline at end of file diff --git a/public/styles/links.css b/public/styles/links.css new file mode 100644 index 00000000..52222160 --- /dev/null +++ b/public/styles/links.css @@ -0,0 +1,39 @@ +.link { + color: var(--green-300); + cursor: pointer; + text-decoration: none; + display: block; + text-align: left; +} + +.link-label { + color: var(--green-100); + text-transform: uppercase; + width: 9ch; + min-width: 9ch; + display: inline-block; + margin: 0 1ch; + white-space: pre; +} + +.link[target="_blank"] .link-right-bracket::before { + content: "-> "; + color: var(--green-300); + margin-left: -2ch; +} + +.link.active .link-label, +.link:hover, +.link:hover .link-label { + color: var(--orange); +} + +.link.dimmed:not(:hover):not(.active) .link-label { + color: var(--green-300); +} + +.link:disabled .link-left-bracket, +.link:disabled .link-right-bracket, +.link:disabled .link-label { + color: var(--green-300); +} \ No newline at end of file diff --git a/public/styles/loading-cursor.css b/public/styles/loading-cursor.css new file mode 100644 index 00000000..482d9d57 --- /dev/null +++ b/public/styles/loading-cursor.css @@ -0,0 +1,18 @@ +.loading-cursor { + animation: cursor-blink 1.5s linear infinite; +} + +@keyframes cursor-blink { + + 0%, + 10%, + 90%, + 100% { + background: var(--green-200); + } + + 30%, + 70% { + background: transparent; + } +} \ No newline at end of file diff --git a/public/styles/logo-filter.css b/public/styles/logo-filter.css new file mode 100644 index 00000000..4b17663a --- /dev/null +++ b/public/styles/logo-filter.css @@ -0,0 +1,54 @@ +:root { + /* Calculated with https://codepen.io/sosuke/pen/Pjoqqp */ + --filter-logo-inactive: invert(42%) sepia(85%) saturate(1707%) hue-rotate(88deg) brightness(102%) contrast(112%); + --filter-logo-active: invert(71%) sepia(54%) saturate(3327%) hue-rotate(60deg) brightness(106%) contrast(118%) drop-shadow(0px 0px 8px var(--green-300)); +} + +/* Safari hack courtesy https://browserstrangeness.github.io/ + +Disable the flicker animation in Safari, since it behaves very weird and +doesn't look as nice as in Chrome/Firefox. +*/ +_::-webkit-full-page-media, +_:future, +:root .filter-logo-active { + animation: none; +} + +@keyframes flicker { + + 0%, + 19%, + 26%, + 46%, + 65%, + 82%, + 86%, + 87%, + 90%, + 95% { + filter: var(--filter-logo-inactive); + } + + 20%, + 25%, + 47%, + 64%, + 83%, + 85%, + 88%, + 89%, + 96%, + 100% { + filter: var(--filter-logo-active); + } +} + +.filter-logo-inactive { + filter: var(--filter-logo-inactive); +} + +.filter-logo-active { + filter: var(--filter-logo-active); + animation: flicker 2s linear 1; +} \ No newline at end of file diff --git a/public/styles/select.css b/public/styles/select.css new file mode 100644 index 00000000..1b451f84 --- /dev/null +++ b/public/styles/select.css @@ -0,0 +1,20 @@ +/* select+option taken mainly from https://codepen.io/5t3ph/pen/MWyyYNz */ +.select-wrapper { + grid-template-areas: "select"; +} + +.select-wrapper::after { + grid-area: select; + content: "^" !important; +} + +.select { + grid-area: select; + font-size: inherit; + cursor: inherit; + line-height: inherit; +} + +.select::-ms-expand { + display: none; +} \ No newline at end of file diff --git a/public/styles/town-store.css b/public/styles/town-store.css new file mode 100644 index 00000000..f920b82b --- /dev/null +++ b/public/styles/town-store.css @@ -0,0 +1,7 @@ +.town-store-grid { + grid-template-areas: + "player-name player-name vendor-name vendor-name" + "player-kept-caps player-traded-caps vendor-traded-caps vendor-kept-caps" + "player-kept-items player-traded-items vendor-traded-items vendor-kept-items" + "barter-reset-btn player-traded-value vendor-traded-value barter-confirm-btn"; +} \ No newline at end of file diff --git a/src/Admin.elm b/src/Admin.elm index 58a4fc65..a5cf9722 100644 --- a/src/Admin.elm +++ b/src/Admin.elm @@ -4,6 +4,7 @@ module Admin exposing , encodeToBackendMsg ) +import BiDict import Data.Auth as Auth import Data.Barter as Barter import Data.FightStrategy as FightStrategy @@ -44,11 +45,12 @@ backendModelDecoderV1 seed = JD.map (\world -> { worlds = Dict.singleton Logic.mainWorldName world - , loggedInPlayers = Dict.empty + , loggedInPlayers = BiDict.empty , time = Time.millisToPosix 0 , adminLoggedIn = Nothing , lastTenToBackendMsgs = Queue.empty , randomSeed = seed + , playerDataCache = Dict.empty } ) World.decoder @@ -60,11 +62,12 @@ backendModelDecoderV2 seed = JD.map (\worlds -> { worlds = worlds - , loggedInPlayers = Dict.empty + , loggedInPlayers = BiDict.empty , time = Time.millisToPosix 0 , adminLoggedIn = Nothing , lastTenToBackendMsgs = Queue.empty , randomSeed = seed + , playerDataCache = Dict.empty } ) (JD.field "worlds" (Dict.decoder JD.string World.decoder)) diff --git a/src/Backend.elm b/src/Backend.elm index 89ad10bd..90f5deb4 100644 --- a/src/Backend.elm +++ b/src/Backend.elm @@ -3,6 +3,7 @@ module Backend exposing (..) import Admin import AssocList as Dict_ import AssocSet as Set_ +import BiDict import Cmd.Extra as Cmd import Data.Auth as Auth exposing @@ -52,6 +53,7 @@ import Http import Json.Decode as JD import Json.Encode as JE import Lamdera exposing (ClientId, SessionId) +import Lamdera.Hash import List.Extra as List import Logic import Queue @@ -81,10 +83,11 @@ init : ( Model, Cmd BackendMsg ) init = ( { worlds = Dict.singleton Logic.mainWorldName (World.init { fast = False }) , time = Time.millisToPosix 0 - , loggedInPlayers = Dict.empty + , loggedInPlayers = BiDict.empty , adminLoggedIn = Nothing , lastTenToBackendMsgs = Queue.empty , randomSeed = Random.initialSeed 0 + , playerDataCache = Dict.empty } , Task.perform FirstTick Time.now ) @@ -138,13 +141,13 @@ getAdminData model = getLoggedInPlayers : Model -> Dict World.Name (List PlayerName) getLoggedInPlayers model = model.loggedInPlayers - |> Dict.values - |> List.gatherEqualsBy .worldName + |> BiDict.values + |> List.gatherEqualsBy Tuple.first |> List.map - (\( first, rest ) -> - ( first.worldName + (\( ( worldName, _ ) as first, rest ) -> + ( worldName , (first :: rest) - |> List.map .playerName + |> List.map Tuple.second ) ) |> Dict.fromList @@ -305,7 +308,7 @@ update msg model = ) Disconnected _ clientId -> - ( { model | loggedInPlayers = Dict.remove clientId model.loggedInPlayers } + ( { model | loggedInPlayers = BiDict.remove clientId model.loggedInPlayers } , Cmd.none ) @@ -389,17 +392,38 @@ update msg model = ) |> Cmd.andThen (\m -> - ( m - , model.loggedInPlayers - |> Dict.toList - |> List.filter (\( _, r ) -> r.worldName == worldName) - |> List.filterMap - (\( clientId, { playerName } ) -> - getPlayerData worldName playerName m - |> Maybe.map (Lamdera.sendToFrontend clientId << CurrentPlayer) + model.loggedInPlayers + |> BiDict.toReverseList + |> List.filter (\( ( wn, _ ), _ ) -> wn == worldName) + |> List.foldl + (\( ( wn, pn ), clientIds ) accOuter -> + case getPlayerData wn pn m of + Nothing -> + accOuter + + Just playerData_ -> + let + newHash : Int + newHash = + Lamdera.Hash.hash + Types.w3_encode_PlayerData_ + playerData_ + in + clientIds + |> Set.toList + |> List.foldl + (\clientId accInner -> + if Lamdera.Hash.hasChanged newHash clientId model.playerDataCache then + accInner + |> Tuple.mapFirst (saveToPlayerDataCache clientId newHash) + |> Cmd.withCmd (Lamdera.sendToFrontend clientId (CurrentPlayer playerData_)) + + else + accInner + ) + accOuter ) - |> Cmd.batch - ) + ( m, Cmd.none ) ) in ( newModel, Cmd.batch [ cmd, newCmd ] ) @@ -413,6 +437,11 @@ update msg model = ( model, Cmd.none ) +saveToPlayerDataCache : ClientId -> Int -> Model -> Model +saveToPlayerDataCache clientId newHash model = + { model | playerDataCache = Dict.insert clientId newHash model.playerDataCache } + + processGameTick : World.Name -> Model -> ( Model, Cmd BackendMsg ) processGameTick worldName model = -- TODO refresh the affected users that are logged-in? @@ -480,9 +509,9 @@ withLoggedInPlayer_ : -> (ClientId -> World -> World.Name -> Player SPlayer -> Model -> ( Model, Cmd BackendMsg )) -> ( Model, Cmd BackendMsg ) withLoggedInPlayer_ model clientId fn = - Dict.get clientId model.loggedInPlayers + BiDict.get clientId model.loggedInPlayers |> Maybe.andThen - (\{ worldName, playerName } -> + (\( worldName, playerName ) -> Dict.get worldName model.worlds |> Maybe.map (\world -> ( world, worldName, playerName )) ) @@ -518,9 +547,10 @@ logAndUpdateFromFrontend_ : SessionId -> ClientId -> ToBackend -> Model -> ( Mod logAndUpdateFromFrontend_ sessionId clientId msg model = let logMsgCmd = - Dict.get clientId model.loggedInPlayers + -- TODO rethink this, something something Event Sourcing? Or maybe indeed just log all *Msgs somewhere and build tooling on being able to play it back + BiDict.get clientId model.loggedInPlayers |> Maybe.map - (\{ playerName, worldName } -> + (\( worldName, playerName ) -> Http.request { method = "POST" , url = "https://janiczek-nuashworld.builtwithdark.com/log-backend" @@ -541,15 +571,9 @@ logAndUpdateFromFrontend_ sessionId clientId msg model = ) |> Maybe.withDefault Cmd.none - playerName_ = - Dict.get clientId model.loggedInPlayers - |> Maybe.map .playerName - |> Maybe.withDefault "anonymous" - - worldName_ = - Dict.get clientId model.loggedInPlayers - |> Maybe.map .worldName - |> Maybe.withDefault "-" + ( worldName_, playerName_ ) = + BiDict.get clientId model.loggedInPlayers + |> Maybe.withDefault ( "-", "anonymous" ) modelWithLoggedMsg = if isAdminMsg msg then @@ -623,9 +647,9 @@ updateFromFrontend sessionId clientId msg model = (ClientId -> World -> World.Name -> SPlayer -> Model -> ( Model, Cmd BackendMsg )) -> ( Model, Cmd BackendMsg ) withLoggedInCreatedPlayer fn = - Dict.get clientId model.loggedInPlayers + BiDict.get clientId model.loggedInPlayers |> Maybe.andThen - (\{ worldName, playerName } -> + (\( worldName, playerName ) -> Dict.get worldName model.worlds |> Maybe.andThen (\world -> @@ -703,11 +727,12 @@ updateFromFrontend sessionId clientId msg model = |> Maybe.map (\data -> let - ( loggedOutPlayers, otherPlayers ) = - -- We log this clientId in, but we log their other browser out. - Dict.partition - (\_ names -> names.worldName == auth.worldName && names.playerName == auth.name) - model.loggedInPlayers + names = + ( auth.worldName, auth.name ) + + clientIdsToLogout : Set ClientId + clientIdsToLogout = + BiDict.getReverse names model.loggedInPlayers loggedOutData = getWorlds model @@ -715,20 +740,18 @@ updateFromFrontend sessionId clientId msg model = newModel = { model | loggedInPlayers = - Dict.insert - clientId - { worldName = auth.worldName - , playerName = auth.name - } - otherPlayers + model.loggedInPlayers + |> -- TODO: BiDict.removeReverse would be nice + BiDict.filter (\_ names_ -> names_ /= names) + |> BiDict.insert clientId names } in ( newModel , Cmd.batch <| (Lamdera.sendToFrontend clientId <| YoureLoggedIn data) :: refreshAdminLoggedInPlayers newModel - :: (loggedOutPlayers - |> Dict.keys + :: (clientIdsToLogout + |> Set.toList |> List.map (\cId -> Lamdera.sendToFrontend cId <| YoureLoggedOut loggedOutData) ) ) @@ -777,13 +800,7 @@ updateFromFrontend sessionId clientId msg model = newModel = { model - | loggedInPlayers = - Dict.insert - clientId - { worldName = auth.worldName - , playerName = auth.name - } - model.loggedInPlayers + | loggedInPlayers = BiDict.insert clientId ( auth.worldName, auth.name ) model.loggedInPlayers , worlds = model.worlds |> Dict.insert auth.worldName newWorld } @@ -807,7 +824,7 @@ updateFromFrontend sessionId clientId msg model = { model | adminLoggedIn = Nothing } else - { model | loggedInPlayers = Dict.remove clientId model.loggedInPlayers } + { model | loggedInPlayers = BiDict.remove clientId model.loggedInPlayers } world = getWorlds newModel @@ -860,16 +877,24 @@ updateFromFrontend sessionId clientId msg model = ) else - case Dict.get clientId model.loggedInPlayers of + case BiDict.get clientId model.loggedInPlayers of Nothing -> loggedOut () - Just { worldName, playerName } -> + Just (( worldName, playerName ) as worldAndPlayer) -> + let + clientIds : Set ClientId + clientIds = + BiDict.getReverse worldAndPlayer model.loggedInPlayers + in getPlayerData worldName playerName model |> Maybe.map (\data -> ( model - , Lamdera.sendToFrontend clientId <| CurrentPlayer data + , clientIds + |> Set.toList + |> List.map (\cId -> Lamdera.sendToFrontend cId <| CurrentPlayer data) + |> Cmd.batch ) ) |> Maybe.withDefault (loggedOut ()) diff --git a/src/Calculator/BarterPrice.elm b/src/Calculator/BarterPrice.elm index 000172b3..611c4fa9 100644 --- a/src/Calculator/BarterPrice.elm +++ b/src/Calculator/BarterPrice.elm @@ -139,7 +139,9 @@ view model = , H.text "Do you have the Master Trader perk?" ] , H.div [ HA.id "final-price" ] - [ H.strong [] [ H.text "Final price: " ] + [ H.span + [ HA.class "text-orange" ] + [ H.text "Final price: " ] , H.text <| case maybePrice of Nothing -> diff --git a/src/Cmd/Extra.elm b/src/Cmd/Extra.elm index 6b578739..44e43228 100644 --- a/src/Cmd/Extra.elm +++ b/src/Cmd/Extra.elm @@ -1,4 +1,4 @@ -module Cmd.Extra exposing (andThen) +module Cmd.Extra exposing (andThen, withCmd) andThen : (model -> ( model, Cmd msg )) -> ( model, Cmd msg ) -> ( model, Cmd msg ) @@ -10,3 +10,10 @@ andThen fn ( model, oldCmd ) = ( newModel , Cmd.batch [ oldCmd, newCmd ] ) + + +withCmd : Cmd msg -> ( model, Cmd msg ) -> ( model, Cmd msg ) +withCmd newCmd ( model, oldCmd ) = + ( model + , Cmd.batch [ newCmd, oldCmd ] + ) diff --git a/src/Data/Auth.elm b/src/Data/Auth.elm index c452777e..b76b291c 100644 --- a/src/Data/Auth.elm +++ b/src/Data/Auth.elm @@ -210,6 +210,14 @@ selectDefaultWorld worlds auth = { auth | worldName = worlds + |> List.sortBy + (\world -> + if world.name == Logic.mainWorldName then + 0 + + else + 1 + ) |> List.head |> Maybe.map .name |> Maybe.withDefault auth.worldName diff --git a/src/Data/Fight.elm b/src/Data/Fight.elm index dec1fa1d..7ec0fc94 100644 --- a/src/Data/Fight.elm +++ b/src/Data/Fight.elm @@ -12,6 +12,7 @@ module Data.Fight exposing , isAttack , isCriticalAttack , isMiss + , isNPC , isPlayer , opponentName , opponentXp @@ -566,6 +567,16 @@ isPlayer opponentType = True +isNPC : OpponentType -> Bool +isNPC opponentType = + case opponentType of + Npc _ -> + True + + Player _ -> + False + + attackDamage : Action -> Int attackDamage action = case action of diff --git a/src/Data/Fight/Generator.elm b/src/Data/Fight/Generator.elm index cf70f1d7..f246e5da 100644 --- a/src/Data/Fight/Generator.elm +++ b/src/Data/Fight/Generator.elm @@ -1045,6 +1045,9 @@ evalCondition state condition = OpponentIsPlayer -> Fight.isPlayer state.them.type_ + OpponentIsNPC -> + Fight.isNPC state.them.type_ + Operator { op, value, number_ } -> operatorFn op diff --git a/src/Data/Fight/View.elm b/src/Data/Fight/View.elm index 396b93e0..e49f068c 100644 --- a/src/Data/Fight/View.elm +++ b/src/Data/Fight/View.elm @@ -159,7 +159,7 @@ view perceptionLevel fight yourName = Fight.Npc enemyType -> Enemy.aimedShotName enemyType aimedShot in - H.div [ HA.class "fight-info" ] + H.div [ HA.class "flex flex-col gap-4" ] [ fight.log |> List.Extra.groupWhile (\( a, _ ) ( b, _ ) -> a == b) |> List.map @@ -169,147 +169,187 @@ view perceptionLevel fight yourName = names_ = getNames who - name : String -> String - name n = - -- This is then picked up by the CSS - "**" ++ n ++ "**" + highlight : String -> Html msg + highlight n = + H.span + [ HA.class "text-orange" ] + [ H.text n ] other : Who other = Fight.theOther who in H.li [] - [ H.text <| names_.subject.namePossCap ++ " turn" + [ H.span + [ HA.class "text-green-300" ] + [ H.text <| names_.subject.namePossCap ++ " turn" ] , (first :: rest) |> List.map (\( currentActionWho, action ) -> let - action_ : String + action_ : Html msg action_ = case action of Fight.Start { distanceHexes } -> if Perception.atLeast Perception.Great perceptionLevel then - names_.subject.verbPresent "initiate" - ++ " the fight from " - ++ String.fromInt distanceHexes - ++ " hexes away." + H.span [] + [ H.text <| + names_.subject.verbPresent "initiate" + ++ " the fight from " + , highlight <| String.fromInt distanceHexes + , H.text " hexes away." + ] else - names_.subject.verbPresent "initiate" - ++ " the fight." + H.text <| + names_.subject.verbPresent "initiate" + ++ " the fight." Fight.ComeCloser { hexes, remainingDistanceHexes } -> if Perception.atLeast Perception.Great perceptionLevel then - names_.subject.verbPresent "come" - ++ " closer " - ++ String.fromInt hexes - ++ " hexes. Remaining distance: " - ++ String.fromInt remainingDistanceHexes - ++ " hexes." + H.span [] + [ H.text <| + names_.subject.verbPresent "come" + ++ " closer " + , highlight <| String.fromInt hexes + , H.text " hexes. Remaining distance: " + , highlight <| String.fromInt remainingDistanceHexes + , H.text " hexes." + ] else - names_.subject.verbPresent "come" - ++ " closer." + H.text <| + names_.subject.verbPresent "come" + ++ " closer." Fight.Attack { damage, remainingHp, shotType, isCritical } -> - (case shotType of - NormalShot -> - "" - - AimedShot aimed -> - names_.subject.verbPresent "aim" - ++ " for " - ++ aimedShotName other aimed - ++ " and " - ) - ++ (if isCritical then - "critically " - - else - "" - ) - ++ names_.subject.verbPresent "attack" - ++ " " - ++ name names_.object.name - ++ " for " - ++ String.fromInt damage - ++ " damage." - ++ (if currentActionWho /= you || Perception.atLeast Perception.Great perceptionLevel then - " Remaining HP: " - ++ String.fromInt remainingHp - ++ "." - - else - "" - ) + H.span [] + [ H.text <| + (case shotType of + NormalShot -> + "" + + AimedShot aimed -> + names_.subject.verbPresent "aim" + ++ " for " + ++ aimedShotName other aimed + ++ " and " + ) + ++ (if isCritical then + "critically " + + else + "" + ) + ++ names_.subject.verbPresent "attack" + ++ " " + , highlight names_.object.name + , H.text " for " + , highlight <| String.fromInt damage + , H.text " damage." + , if currentActionWho /= you || Perception.atLeast Perception.Great perceptionLevel then + H.span [] + [ H.text " Remaining HP: " + , highlight <| String.fromInt remainingHp + , H.text "." + ] + + else + H.text "" + ] Fight.Miss { shotType } -> - (case shotType of - NormalShot -> - "" - - AimedShot aimed -> - names_.subject.verbPresent "aim" - ++ " for " - ++ aimedShotName other aimed - ++ " and " - ) - ++ names_.subject.verbPresent "attack" - ++ " " - ++ name names_.object.name - ++ " but " - ++ names_.subject.verbPresent "miss" - ++ "." + H.span [] + [ H.text <| + (case shotType of + NormalShot -> + "" + + AimedShot aimed -> + names_.subject.verbPresent "aim" + ++ " for " + ++ aimedShotName other aimed + ++ " and " + ) + ++ names_.subject.verbPresent "attack" + ++ " " + , highlight names_.object.name + , H.text <| + " but " + ++ names_.subject.verbPresent "miss" + ++ "." + ] Fight.Heal r -> - names_.subject.verbPresent "heal" - ++ " with " - ++ Item.name r.itemKind - ++ " for " - ++ String.fromInt r.healedHp - ++ " HP." - ++ (if currentActionWho == you || Perception.atLeast Perception.Great perceptionLevel then - " Current HP: " - ++ String.fromInt r.newHp - ++ "." - - else - "" - ) + H.text <| + names_.subject.verbPresent "heal" + ++ " with " + ++ Item.name r.itemKind + ++ " for " + ++ String.fromInt r.healedHp + ++ " HP." + ++ (if currentActionWho == you || Perception.atLeast Perception.Great perceptionLevel then + " Current HP: " + ++ String.fromInt r.newHp + ++ "." + + else + "" + ) in - H.li [] - [ Markdown.toHtml [ HA.class "fight-log-action" ] <| - name names_.subject.nameCap - ++ " " - ++ action_ + H.li + [ HA.class "ps-[2ch]" ] + [ highlight names_.subject.nameCap + , H.text " " + , action_ ] ) |> H.ul [] ] ) - |> H.ul [] + |> H.ul [ HA.class "flex flex-col gap-4" ] , H.div [] - [ H.text <| - "Result: " - ++ (case fight.result of - Fight.AttackerWon { xpGained, capsGained, itemsGained } -> - if youAreAttacker then - "You won! You gained " - ++ String.fromInt xpGained - ++ " XP and looted " - ++ String.fromInt capsGained - ++ " caps." - ++ (if List.isEmpty itemsGained then - "" - - else - " You also looted " - ++ viewLoot itemsGained - ++ "." - ) - - else - "You lost! Your attacker gained " + [ H.span + [ HA.class "text-green-300" ] + [ H.text "Result: " ] + , H.span [ HA.class "text-green-100" ] + [ H.text <| + case fight.result of + Fight.AttackerWon { xpGained, capsGained, itemsGained } -> + if youAreAttacker then + "You won! You gained " + ++ String.fromInt xpGained + ++ " XP and looted " + ++ String.fromInt capsGained + ++ " caps." + ++ (if List.isEmpty itemsGained then + "" + + else + " You also looted " + ++ viewLoot itemsGained + ++ "." + ) + + else + "You lost! Your attacker gained " + ++ String.fromInt xpGained + ++ " XP and looted " + ++ String.fromInt capsGained + ++ " caps." + ++ (if List.isEmpty itemsGained then + "" + + else + " They also looted " + ++ viewLoot itemsGained + ++ "." + ) + + Fight.TargetWon { xpGained, capsGained, itemsGained } -> + if youAreAttacker then + if Fight.isPlayer fight.target then + "You lost! Your target gained " ++ String.fromInt xpGained ++ " XP and looted " ++ String.fromInt capsGained @@ -323,59 +363,42 @@ view perceptionLevel fight yourName = ++ "." ) - Fight.TargetWon { xpGained, capsGained, itemsGained } -> - if youAreAttacker then - if Fight.isPlayer fight.target then - "You lost! Your target gained " - ++ String.fromInt xpGained - ++ " XP and looted " - ++ String.fromInt capsGained - ++ " caps." - ++ (if List.isEmpty itemsGained then - "" - - else - " They also looted " - ++ viewLoot itemsGained - ++ "." - ) - - else - "You lost!" - - else - "You won! You gained " - ++ String.fromInt xpGained - ++ " XP and looted " - ++ String.fromInt capsGained - ++ " caps." - ++ (if List.isEmpty itemsGained then - "" - - else - " You also looted " - ++ viewLoot itemsGained - ++ "." - ) - - Fight.TargetAlreadyDead -> - if youAreAttacker then - "You wanted to fight them but then realized they're already dead. You feel slightly dumb. (Higher Perception will help you see more info about your opponents.)" - else - attackerName ++ " wanted to fight you but due to their low Perception didn't realize you're already dead. Ashamed, they quickly ran away and will deny this ever happened." - - Fight.BothDead -> - "You both end up dead." - - Fight.NobodyDead -> - "You both get out of the fight alive." - - Fight.NobodyDeadGivenUp -> - "You're both so exhausted by this long fight that you agree to finish this some other time." - ) + "You lost!" + + else + "You won! You gained " + ++ String.fromInt xpGained + ++ " XP and looted " + ++ String.fromInt capsGained + ++ " caps." + ++ (if List.isEmpty itemsGained then + "" + + else + " You also looted " + ++ viewLoot itemsGained + ++ "." + ) + + Fight.TargetAlreadyDead -> + if youAreAttacker then + "You wanted to fight them but then realized they're already dead. You feel slightly dumb. (Higher Perception will help you see more info about your opponents.)" + + else + attackerName ++ " wanted to fight you but due to their low Perception didn't realize you're already dead. Ashamed, they quickly ran away and will deny this ever happened." + + Fight.BothDead -> + "You both end up dead." + + Fight.NobodyDead -> + "You both get out of the fight alive." + + Fight.NobodyDeadGivenUp -> + "You're both so exhausted by this long fight that you agree to finish this some other time." + ] ] - , H.p [] [ H.text "Stats:" ] + , H.span [ HA.class "text-green-300" ] [ H.text "Stats:" ] , let ( yourActions, theirActions ) = List.partition (\( who, _ ) -> who == you) fight.log @@ -455,40 +478,46 @@ view perceptionLevel fight yourName = else (String.fromFloat <| (\x -> x / 100) <| toFloat <| round <| pct * 10000) ++ "%" + + th attrs children = + H.th (HA.class "text-right" :: attrs) children + + td attrs children = + H.td (HA.class "text-right" :: attrs) children in - H.table [ HA.id "fight-stats-table" ] + H.table [ HA.class "w-max" ] [ H.thead [] [ H.tr [] - [ H.td [] [] - , H.th [] [ H.text "You" ] - , H.th [] [ H.text yourOpponentName ] + [ td [] [] + , th [] [ H.text "You" ] + , th [] [ H.text yourOpponentName ] ] ] , H.tbody [] [ H.tr [] - [ H.td [] [ H.text "Total damage" ] - , H.td [] [ H.text <| String.fromInt yourTotalDamage ] - , H.td [] [ H.text <| String.fromInt theirTotalDamage ] + [ td [] [ H.text "Total damage" ] + , td [] [ H.text <| String.fromInt yourTotalDamage ] + , td [] [ H.text <| String.fromInt theirTotalDamage ] ] , H.tr [] - [ H.td [] [ H.text "Hit rate" ] - , H.td [] [ H.text <| formatPercentage yourHitRate ] - , H.td [] [ H.text <| formatPercentage theirHitRate ] + [ td [] [ H.text "Hit rate" ] + , td [] [ H.text <| formatPercentage yourHitRate ] + , td [] [ H.text <| formatPercentage theirHitRate ] ] , H.tr [] - [ H.td [] [ H.text "Critical hit rate" ] - , H.td [] [ H.text <| formatPercentage yourCritRate ] - , H.td [] [ H.text <| formatPercentage theirCritRate ] + [ td [] [ H.text "Critical hit rate" ] + , td [] [ H.text <| formatPercentage yourCritRate ] + , td [] [ H.text <| formatPercentage theirCritRate ] ] , H.tr [] - [ H.td [] [ H.text "Average damage" ] - , H.td [] [ H.text <| formatFloat yourAvgDamage ] - , H.td [] [ H.text <| formatFloat theirAvgDamage ] + [ td [] [ H.text "Average damage" ] + , td [] [ H.text <| formatFloat yourAvgDamage ] + , td [] [ H.text <| formatFloat theirAvgDamage ] ] , H.tr [] - [ H.td [] [ H.text "Max hit" ] - , H.td [] [ H.text <| String.fromInt yourMaxHit ] - , H.td [] [ H.text <| String.fromInt theirMaxHit ] + [ td [] [ H.text "Max hit" ] + , td [] [ H.text <| String.fromInt yourMaxHit ] + , td [] [ H.text <| String.fromInt theirMaxHit ] ] ] ] diff --git a/src/Data/FightStrategy.elm b/src/Data/FightStrategy.elm index 35c0786c..4597130c 100644 --- a/src/Data/FightStrategy.elm +++ b/src/Data/FightStrategy.elm @@ -47,6 +47,7 @@ type Condition | And Condition Condition | Operator OperatorData | OpponentIsPlayer + | OpponentIsNPC type alias OperatorData = @@ -130,6 +131,9 @@ conditionToString condition = OpponentIsPlayer -> "opponent is player" + OpponentIsNPC -> + "opponent is NPC" + Operator { op, value, number_ } -> valueToString value ++ " " @@ -290,6 +294,11 @@ encodeCondition condition = [ ( "type", JE.string "OpponentIsPlayer" ) ] + OpponentIsNPC -> + JE.object + [ ( "type", JE.string "OpponentIsNPC" ) + ] + Operator { op, value, number_ } -> JE.object [ ( "type", JE.string "Operator" ) @@ -400,6 +409,9 @@ conditionDecoder = "OpponentIsPlayer" -> JD.succeed OpponentIsPlayer + "OpponentIsNPC" -> + JD.succeed OpponentIsNPC + "Operator" -> JD.succeed OperatorData |> JD.andMap (JD.field "value" valueDecoder) @@ -576,6 +588,9 @@ extractItems strategy = OpponentIsPlayer -> [] + OpponentIsNPC -> + [] + Operator { value } -> fromValue value in diff --git a/src/Data/FightStrategy/Help.elm b/src/Data/FightStrategy/Help.elm index 1a6bcbd9..e32964cd 100644 --- a/src/Data/FightStrategy/Help.elm +++ b/src/Data/FightStrategy/Help.elm @@ -18,28 +18,29 @@ help = - if [CONDITION] then [STRATEGY] else [STRATEGY] -[COMMAND] [VALUE] - - attack randomly - my HP - - attack ([SHOT TYPE]) - my AP - - heal ([ITEM]) - number of available [ITEM] - - move forward - number of used [ITEM] - - do whatever - opponent's level - - chance to hit ([SHOT TYPE]) - - distance +[COMMAND] [VALUE] + - attack randomly - my HP + - attack ([SHOT TYPE]) - my AP + - heal ([ITEM]) - number of available [ITEM] + - move forward - number of used [ITEM] + - do whatever - opponent's level + - chance to hit ([SHOT TYPE]) + - distance [CONDITION] - opponent is player - - [VALUE] [OPERATOR] [NUMBER] [SHOT TYPE] - - ([CONDITION] or [CONDITION]) - unaimed - - ([CONDITION] and [CONDITION]) - head - - eyes + - opponent is NPC [SHOT TYPE] + - [VALUE] [OPERATOR] [NUMBER] - unaimed + - ([CONDITION] or [CONDITION]) - head + - ([CONDITION] and [CONDITION]) - eyes - torso -[OPERATOR] - groin - - < - left arm - - <= - right arm - - == - left leg - - != - right leg - - >= - - > + - groin +[OPERATOR] - left arm + - < (less than) - right arm + - <= (less than or equal) - left leg + - == (equals) - right leg + - != (doesn't equal) + - >= (greater than or equal) + - > (greater than) """ |> P.run parser |> Result.withDefault [ Text "BUG: couldn't parse the syntax help!" ] @@ -148,7 +149,7 @@ referenceDescription : Reference -> String referenceDescription ref = case ref of Strategy -> - """The main building block of your strategy. + """The entrypoint to your fight strategy. Examples: - do whatever @@ -157,7 +158,7 @@ Examples: else do whatever""" Command -> - """The result of applying your strategy to your current situation. + """The end result of applying your strategy to your current situation. Examples: - heal (Stimpak) @@ -198,9 +199,7 @@ Example usage: - number of available Stimpak""" Operator -> - """The != operator means 'is not equal to'. - -Example usage: + """Example usage: - distance > 0 - my HP <= 80 - my AP == 3 diff --git a/src/Data/FightStrategy/Parser.elm b/src/Data/FightStrategy/Parser.elm index 828b28d9..a5e36d2d 100644 --- a/src/Data/FightStrategy/Parser.elm +++ b/src/Data/FightStrategy/Parser.elm @@ -123,6 +123,7 @@ condition = P.oneOf [ binary , P.map (\_ -> OpponentIsPlayer) (P.keyword "opponent is player") + , P.map (\_ -> OpponentIsNPC) (P.keyword "opponent is NPC") , operatorCondition ] diff --git a/src/Data/Special/Perception.elm b/src/Data/Special/Perception.elm index 1c51a490..33991360 100644 --- a/src/Data/Special/Perception.elm +++ b/src/Data/Special/Perception.elm @@ -95,10 +95,12 @@ healthPerceptionTooltip level_ = "You see everybody's exact HP and max HP." Great -> - "You see others' HP in range of (Unhurt, Slightly Wounded, Wounded, Severely Wounded, Almost Dead, Dead)." + """You see others' HP in range of (Unhurt, Slightly Wounded, + Wounded, Severely Wounded, Almost Dead, Dead).""" Good -> - "You see others' HP in range of (Unhurt, Wounded, Severely Wounded, Almost Dead, Dead)." + """You see others' HP in range of (Unhurt, Wounded, Severely + Wounded, Almost Dead, Dead).""" Bad -> "You see others' HP in range of (Alive, Dead)." @@ -112,15 +114,22 @@ mapMovementTooltip level_ = let terrainAwareOptimalMovement : String terrainAwareOptimalMovement = - "When planning longer route on the map you always go in the most efficient line, taking into consideration the terrain like mountains etc. You also see the AP cost of your route." + """When planning longer route on the map you always go in the most + efficient line, taking into consideration the terrain like mountains + etc. You also see the AP cost of your route and are able to see + which areas are more dangerous than others.""" okayMovement : String okayMovement = - "When planning longer route on the map you always go in a mostly efficient straight line but ignore terrain like mountains etc. You also see the AP cost of your route." + """When planning longer route on the map you always go in a mostly + efficient straight line but ignore terrain like mountains etc. You + also see the AP cost of your route.""" inefficientMovement : String inefficientMovement = - "When planning longer route on the map you always go in a (not very efficient) straight line but ignore terrain like mountains etc." + """When planning longer route on the map you always go in a (not + very efficient) straight line but ignore terrain like mountains + etc.""" in case level_ of Perfect -> diff --git a/src/Data/Version.elm b/src/Data/Version.elm index d1c63853..bdb90322 100644 --- a/src/Data/Version.elm +++ b/src/Data/Version.elm @@ -3,4 +3,4 @@ module Data.Version exposing (version) version : String version = - "2021.11.30::001" + "2024.09.22::001" diff --git a/src/Evergreen/Migrate/V100.elm b/src/Evergreen/Migrate/V100.elm deleted file mode 100644 index 332f066e..00000000 --- a/src/Evergreen/Migrate/V100.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.Migrate.V100 exposing (..) - -import Evergreen.V100.Types as New -import Evergreen.V97.Types as Old -import Lamdera.Migrations exposing (..) - - -frontendModel : Old.FrontendModel -> ModelMigration New.FrontendModel New.FrontendMsg -frontendModel old = - ModelUnchanged - - -backendModel : Old.BackendModel -> ModelMigration New.BackendModel New.BackendMsg -backendModel old = - ModelUnchanged - - -frontendMsg : Old.FrontendMsg -> MsgMigration New.FrontendMsg New.FrontendMsg -frontendMsg old = - MsgUnchanged - - -toBackend : Old.ToBackend -> MsgMigration New.ToBackend New.BackendMsg -toBackend old = - MsgUnchanged - - -backendMsg : Old.BackendMsg -> MsgMigration New.BackendMsg New.BackendMsg -backendMsg old = - MsgUnchanged - - -toFrontend : Old.ToFrontend -> MsgMigration New.ToFrontend New.FrontendMsg -toFrontend old = - MsgUnchanged diff --git a/src/Evergreen/Migrate/V77.elm b/src/Evergreen/Migrate/V77.elm deleted file mode 100644 index d348b54e..00000000 --- a/src/Evergreen/Migrate/V77.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.Migrate.V77 exposing (..) - -import Evergreen.V75.Types as Old -import Evergreen.V77.Types as New -import Lamdera.Migrations exposing (..) - - -frontendModel : Old.FrontendModel -> ModelMigration New.FrontendModel New.FrontendMsg -frontendModel old = - ModelUnchanged - - -backendModel : Old.BackendModel -> ModelMigration New.BackendModel New.BackendMsg -backendModel old = - ModelUnchanged - - -frontendMsg : Old.FrontendMsg -> MsgMigration New.FrontendMsg New.FrontendMsg -frontendMsg old = - MsgUnchanged - - -toBackend : Old.ToBackend -> MsgMigration New.ToBackend New.BackendMsg -toBackend old = - MsgUnchanged - - -backendMsg : Old.BackendMsg -> MsgMigration New.BackendMsg New.BackendMsg -backendMsg old = - MsgUnchanged - - -toFrontend : Old.ToFrontend -> MsgMigration New.ToFrontend New.FrontendMsg -toFrontend old = - MsgUnchanged diff --git a/src/Evergreen/Migrate/V78.elm b/src/Evergreen/Migrate/V78.elm deleted file mode 100644 index 97f8eb26..00000000 --- a/src/Evergreen/Migrate/V78.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.Migrate.V78 exposing (..) - -import Evergreen.V77.Types as Old -import Evergreen.V78.Types as New -import Lamdera.Migrations exposing (..) - - -frontendModel : Old.FrontendModel -> ModelMigration New.FrontendModel New.FrontendMsg -frontendModel old = - ModelUnchanged - - -backendModel : Old.BackendModel -> ModelMigration New.BackendModel New.BackendMsg -backendModel old = - ModelUnchanged - - -frontendMsg : Old.FrontendMsg -> MsgMigration New.FrontendMsg New.FrontendMsg -frontendMsg old = - MsgUnchanged - - -toBackend : Old.ToBackend -> MsgMigration New.ToBackend New.BackendMsg -toBackend old = - MsgUnchanged - - -backendMsg : Old.BackendMsg -> MsgMigration New.BackendMsg New.BackendMsg -backendMsg old = - MsgUnchanged - - -toFrontend : Old.ToFrontend -> MsgMigration New.ToFrontend New.FrontendMsg -toFrontend old = - MsgUnchanged diff --git a/src/Evergreen/Migrate/V79.elm b/src/Evergreen/Migrate/V79.elm deleted file mode 100644 index e7ba5ce0..00000000 --- a/src/Evergreen/Migrate/V79.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.Migrate.V79 exposing (..) - -import Evergreen.V78.Types as Old -import Evergreen.V79.Types as New -import Lamdera.Migrations exposing (..) - - -frontendModel : Old.FrontendModel -> ModelMigration New.FrontendModel New.FrontendMsg -frontendModel old = - ModelUnchanged - - -backendModel : Old.BackendModel -> ModelMigration New.BackendModel New.BackendMsg -backendModel old = - ModelUnchanged - - -frontendMsg : Old.FrontendMsg -> MsgMigration New.FrontendMsg New.FrontendMsg -frontendMsg old = - MsgUnchanged - - -toBackend : Old.ToBackend -> MsgMigration New.ToBackend New.BackendMsg -toBackend old = - MsgUnchanged - - -backendMsg : Old.BackendMsg -> MsgMigration New.BackendMsg New.BackendMsg -backendMsg old = - MsgUnchanged - - -toFrontend : Old.ToFrontend -> MsgMigration New.ToFrontend New.FrontendMsg -toFrontend old = - MsgUnchanged diff --git a/src/Evergreen/Migrate/V81.elm b/src/Evergreen/Migrate/V81.elm deleted file mode 100644 index b04c2c9b..00000000 --- a/src/Evergreen/Migrate/V81.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.Migrate.V81 exposing (..) - -import Evergreen.V79.Types as Old -import Evergreen.V81.Types as New -import Lamdera.Migrations exposing (..) - - -frontendModel : Old.FrontendModel -> ModelMigration New.FrontendModel New.FrontendMsg -frontendModel old = - ModelUnchanged - - -backendModel : Old.BackendModel -> ModelMigration New.BackendModel New.BackendMsg -backendModel old = - ModelUnchanged - - -frontendMsg : Old.FrontendMsg -> MsgMigration New.FrontendMsg New.FrontendMsg -frontendMsg old = - MsgUnchanged - - -toBackend : Old.ToBackend -> MsgMigration New.ToBackend New.BackendMsg -toBackend old = - MsgUnchanged - - -backendMsg : Old.BackendMsg -> MsgMigration New.BackendMsg New.BackendMsg -backendMsg old = - MsgUnchanged - - -toFrontend : Old.ToFrontend -> MsgMigration New.ToFrontend New.FrontendMsg -toFrontend old = - MsgUnchanged diff --git a/src/Evergreen/Migrate/V83.elm b/src/Evergreen/Migrate/V83.elm deleted file mode 100644 index b92934cb..00000000 --- a/src/Evergreen/Migrate/V83.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.Migrate.V83 exposing (..) - -import Evergreen.V81.Types as Old -import Evergreen.V83.Types as New -import Lamdera.Migrations exposing (..) - - -frontendModel : Old.FrontendModel -> ModelMigration New.FrontendModel New.FrontendMsg -frontendModel old = - ModelUnchanged - - -backendModel : Old.BackendModel -> ModelMigration New.BackendModel New.BackendMsg -backendModel old = - ModelUnchanged - - -frontendMsg : Old.FrontendMsg -> MsgMigration New.FrontendMsg New.FrontendMsg -frontendMsg old = - MsgUnchanged - - -toBackend : Old.ToBackend -> MsgMigration New.ToBackend New.BackendMsg -toBackend old = - MsgUnchanged - - -backendMsg : Old.BackendMsg -> MsgMigration New.BackendMsg New.BackendMsg -backendMsg old = - MsgUnchanged - - -toFrontend : Old.ToFrontend -> MsgMigration New.ToFrontend New.FrontendMsg -toFrontend old = - MsgUnchanged diff --git a/src/Evergreen/Migrate/V85.elm b/src/Evergreen/Migrate/V85.elm deleted file mode 100644 index e56b7f82..00000000 --- a/src/Evergreen/Migrate/V85.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.Migrate.V85 exposing (..) - -import Evergreen.V83.Types as Old -import Evergreen.V85.Types as New -import Lamdera.Migrations exposing (..) - - -frontendModel : Old.FrontendModel -> ModelMigration New.FrontendModel New.FrontendMsg -frontendModel old = - ModelUnchanged - - -backendModel : Old.BackendModel -> ModelMigration New.BackendModel New.BackendMsg -backendModel old = - ModelUnchanged - - -frontendMsg : Old.FrontendMsg -> MsgMigration New.FrontendMsg New.FrontendMsg -frontendMsg old = - MsgUnchanged - - -toBackend : Old.ToBackend -> MsgMigration New.ToBackend New.BackendMsg -toBackend old = - MsgUnchanged - - -backendMsg : Old.BackendMsg -> MsgMigration New.BackendMsg New.BackendMsg -backendMsg old = - MsgUnchanged - - -toFrontend : Old.ToFrontend -> MsgMigration New.ToFrontend New.FrontendMsg -toFrontend old = - MsgUnchanged diff --git a/src/Evergreen/Migrate/V87.elm b/src/Evergreen/Migrate/V87.elm deleted file mode 100644 index b7b1cf77..00000000 --- a/src/Evergreen/Migrate/V87.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.Migrate.V87 exposing (..) - -import Evergreen.V85.Types as Old -import Evergreen.V87.Types as New -import Lamdera.Migrations exposing (..) - - -frontendModel : Old.FrontendModel -> ModelMigration New.FrontendModel New.FrontendMsg -frontendModel old = - ModelUnchanged - - -backendModel : Old.BackendModel -> ModelMigration New.BackendModel New.BackendMsg -backendModel old = - ModelUnchanged - - -frontendMsg : Old.FrontendMsg -> MsgMigration New.FrontendMsg New.FrontendMsg -frontendMsg old = - MsgUnchanged - - -toBackend : Old.ToBackend -> MsgMigration New.ToBackend New.BackendMsg -toBackend old = - MsgUnchanged - - -backendMsg : Old.BackendMsg -> MsgMigration New.BackendMsg New.BackendMsg -backendMsg old = - MsgUnchanged - - -toFrontend : Old.ToFrontend -> MsgMigration New.ToFrontend New.FrontendMsg -toFrontend old = - MsgUnchanged diff --git a/src/Evergreen/Migrate/V88.elm b/src/Evergreen/Migrate/V88.elm deleted file mode 100644 index 7564025f..00000000 --- a/src/Evergreen/Migrate/V88.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.Migrate.V88 exposing (..) - -import Evergreen.V87.Types as Old -import Evergreen.V88.Types as New -import Lamdera.Migrations exposing (..) - - -frontendModel : Old.FrontendModel -> ModelMigration New.FrontendModel New.FrontendMsg -frontendModel old = - ModelUnchanged - - -backendModel : Old.BackendModel -> ModelMigration New.BackendModel New.BackendMsg -backendModel old = - ModelUnchanged - - -frontendMsg : Old.FrontendMsg -> MsgMigration New.FrontendMsg New.FrontendMsg -frontendMsg old = - MsgUnchanged - - -toBackend : Old.ToBackend -> MsgMigration New.ToBackend New.BackendMsg -toBackend old = - MsgUnchanged - - -backendMsg : Old.BackendMsg -> MsgMigration New.BackendMsg New.BackendMsg -backendMsg old = - MsgUnchanged - - -toFrontend : Old.ToFrontend -> MsgMigration New.ToFrontend New.FrontendMsg -toFrontend old = - MsgUnchanged diff --git a/src/Evergreen/Migrate/V89.elm b/src/Evergreen/Migrate/V89.elm deleted file mode 100644 index 8b95ce06..00000000 --- a/src/Evergreen/Migrate/V89.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.Migrate.V89 exposing (..) - -import Evergreen.V88.Types as Old -import Evergreen.V89.Types as New -import Lamdera.Migrations exposing (..) - - -frontendModel : Old.FrontendModel -> ModelMigration New.FrontendModel New.FrontendMsg -frontendModel old = - ModelUnchanged - - -backendModel : Old.BackendModel -> ModelMigration New.BackendModel New.BackendMsg -backendModel old = - ModelUnchanged - - -frontendMsg : Old.FrontendMsg -> MsgMigration New.FrontendMsg New.FrontendMsg -frontendMsg old = - MsgUnchanged - - -toBackend : Old.ToBackend -> MsgMigration New.ToBackend New.BackendMsg -toBackend old = - MsgUnchanged - - -backendMsg : Old.BackendMsg -> MsgMigration New.BackendMsg New.BackendMsg -backendMsg old = - MsgUnchanged - - -toFrontend : Old.ToFrontend -> MsgMigration New.ToFrontend New.FrontendMsg -toFrontend old = - MsgUnchanged diff --git a/src/Evergreen/Migrate/V96.elm b/src/Evergreen/Migrate/V96.elm deleted file mode 100644 index cb88724e..00000000 --- a/src/Evergreen/Migrate/V96.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.Migrate.V96 exposing (..) - -import Evergreen.V89.Types as Old -import Evergreen.V96.Types as New -import Lamdera.Migrations exposing (..) - - -frontendModel : Old.FrontendModel -> ModelMigration New.FrontendModel New.FrontendMsg -frontendModel old = - ModelUnchanged - - -backendModel : Old.BackendModel -> ModelMigration New.BackendModel New.BackendMsg -backendModel old = - ModelUnchanged - - -frontendMsg : Old.FrontendMsg -> MsgMigration New.FrontendMsg New.FrontendMsg -frontendMsg old = - MsgUnchanged - - -toBackend : Old.ToBackend -> MsgMigration New.ToBackend New.BackendMsg -toBackend old = - MsgUnchanged - - -backendMsg : Old.BackendMsg -> MsgMigration New.BackendMsg New.BackendMsg -backendMsg old = - MsgUnchanged - - -toFrontend : Old.ToFrontend -> MsgMigration New.ToFrontend New.FrontendMsg -toFrontend old = - MsgUnchanged diff --git a/src/Evergreen/Migrate/V97.elm b/src/Evergreen/Migrate/V97.elm deleted file mode 100644 index 779aa866..00000000 --- a/src/Evergreen/Migrate/V97.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.Migrate.V97 exposing (..) - -import Evergreen.V96.Types as Old -import Evergreen.V97.Types as New -import Lamdera.Migrations exposing (..) - - -frontendModel : Old.FrontendModel -> ModelMigration New.FrontendModel New.FrontendMsg -frontendModel old = - ModelUnchanged - - -backendModel : Old.BackendModel -> ModelMigration New.BackendModel New.BackendMsg -backendModel old = - ModelUnchanged - - -frontendMsg : Old.FrontendMsg -> MsgMigration New.FrontendMsg New.FrontendMsg -frontendMsg old = - MsgUnchanged - - -toBackend : Old.ToBackend -> MsgMigration New.ToBackend New.BackendMsg -toBackend old = - MsgUnchanged - - -backendMsg : Old.BackendMsg -> MsgMigration New.BackendMsg New.BackendMsg -backendMsg old = - MsgUnchanged - - -toFrontend : Old.ToFrontend -> MsgMigration New.ToFrontend New.FrontendMsg -toFrontend old = - MsgUnchanged diff --git a/src/Evergreen/V100/Data/Auth.elm b/src/Evergreen/V100/Data/Auth.elm deleted file mode 100644 index fd088a61..00000000 --- a/src/Evergreen/V100/Data/Auth.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V100.Data.Auth exposing (..) - - -type Plaintext - = Plaintext - - -type Password a - = Password String - - -type alias Auth a = - { name : String - , password : Password a - } - - -type Verified - = Verified - - -type Hashed - = Hashed diff --git a/src/Evergreen/V100/Data/Barter.elm b/src/Evergreen/V100/Data/Barter.elm deleted file mode 100644 index ff398bdf..00000000 --- a/src/Evergreen/V100/Data/Barter.elm +++ /dev/null @@ -1,33 +0,0 @@ -module Evergreen.V100.Data.Barter exposing (..) - -import AssocList -import Dict -import Evergreen.V100.Data.Item - - -type Message - = BarterIsEmpty - | PlayerOfferNotValuableEnough - | YouGaveStuffForFree - - -type TransferNPosition - = PlayerKeptItem Evergreen.V100.Data.Item.Id - | VendorKeptItem Evergreen.V100.Data.Item.Id - | PlayerTradedItem Evergreen.V100.Data.Item.Id - | VendorTradedItem Evergreen.V100.Data.Item.Id - | PlayerKeptCaps - | VendorKeptCaps - | PlayerTradedCaps - | VendorTradedCaps - - -type alias State = - { playerItems : Dict.Dict Evergreen.V100.Data.Item.Id Int - , vendorItems : Dict.Dict Evergreen.V100.Data.Item.Id Int - , playerCaps : Int - , vendorCaps : Int - , lastMessage : Maybe Message - , transferNInputs : AssocList.Dict TransferNPosition String - , transferNHover : Maybe TransferNPosition - } diff --git a/src/Evergreen/V100/Data/Enemy.elm b/src/Evergreen/V100/Data/Enemy.elm deleted file mode 100644 index 6977529e..00000000 --- a/src/Evergreen/V100/Data/Enemy.elm +++ /dev/null @@ -1,14 +0,0 @@ -module Evergreen.V100.Data.Enemy exposing (..) - - -type Type - = Brahmin - | AngryBrahmin - | WeakBrahmin - | WildBrahmin - | GiantAnt - | ToughGiantAnt - | BlackRadscorpion - | LesserBlackRadscorpion - | LesserRadscorpion - | Radscorpion diff --git a/src/Evergreen/V100/Data/Fight.elm b/src/Evergreen/V100/Data/Fight.elm deleted file mode 100644 index d22241a7..00000000 --- a/src/Evergreen/V100/Data/Fight.elm +++ /dev/null @@ -1,99 +0,0 @@ -module Evergreen.V100.Data.Fight exposing (..) - -import AssocList -import AssocSet -import Dict -import Evergreen.V100.Data.Enemy -import Evergreen.V100.Data.Fight.ShotType -import Evergreen.V100.Data.FightStrategy -import Evergreen.V100.Data.Item -import Evergreen.V100.Data.Perk -import Evergreen.V100.Data.Player.PlayerName -import Evergreen.V100.Data.Skill -import Evergreen.V100.Data.Special -import Evergreen.V100.Data.Trait -import Evergreen.V100.Logic - - -type alias PlayerOpponent = - { name : Evergreen.V100.Data.Player.PlayerName.PlayerName - , xp : Int - } - - -type OpponentType - = Npc Evergreen.V100.Data.Enemy.Type - | Player PlayerOpponent - - -type Who - = Attacker - | Target - - -type Action - = Start - { distanceHexes : Int - } - | ComeCloser - { hexes : Int - , remainingDistanceHexes : Int - } - | Attack - { damage : Int - , shotType : Evergreen.V100.Data.Fight.ShotType.ShotType - , remainingHp : Int - , isCritical : Bool - } - | Miss - { shotType : Evergreen.V100.Data.Fight.ShotType.ShotType - } - | Heal - { itemKind : Evergreen.V100.Data.Item.Kind - , healedHp : Int - , newHp : Int - } - - -type Result - = AttackerWon - { xpGained : Int - , capsGained : Int - , itemsGained : List Evergreen.V100.Data.Item.Item - } - | TargetWon - { xpGained : Int - , capsGained : Int - , itemsGained : List Evergreen.V100.Data.Item.Item - } - | TargetAlreadyDead - | BothDead - | NobodyDead - - -type alias Info = - { attacker : OpponentType - , target : OpponentType - , log : List ( Who, Action ) - , result : Result - } - - -type alias Opponent = - { type_ : OpponentType - , hp : Int - , maxHp : Int - , maxAp : Int - , sequence : Int - , traits : AssocSet.Set Evergreen.V100.Data.Trait.Trait - , perks : AssocList.Dict Evergreen.V100.Data.Perk.Perk Int - , caps : Int - , items : Dict.Dict Evergreen.V100.Data.Item.Id Evergreen.V100.Data.Item.Item - , drops : List Evergreen.V100.Data.Item.Item - , equippedArmor : Maybe Evergreen.V100.Data.Item.Kind - , naturalArmorClass : Int - , attackStats : Evergreen.V100.Logic.AttackStats - , addedSkillPercentages : AssocList.Dict Evergreen.V100.Data.Skill.Skill Int - , special : Evergreen.V100.Data.Special.Special - , fightStrategy : Evergreen.V100.Data.FightStrategy.FightStrategy - } diff --git a/src/Evergreen/V100/Data/Fight/Generator.elm b/src/Evergreen/V100/Data/Fight/Generator.elm deleted file mode 100644 index 9334c999..00000000 --- a/src/Evergreen/V100/Data/Fight/Generator.elm +++ /dev/null @@ -1,13 +0,0 @@ -module Evergreen.V100.Data.Fight.Generator exposing (..) - -import Evergreen.V100.Data.Fight -import Evergreen.V100.Data.Message - - -type alias Fight = - { finalAttacker : Evergreen.V100.Data.Fight.Opponent - , finalTarget : Evergreen.V100.Data.Fight.Opponent - , fightInfo : Evergreen.V100.Data.Fight.Info - , messageForTarget : Evergreen.V100.Data.Message.Message - , messageForAttacker : Evergreen.V100.Data.Message.Message - } diff --git a/src/Evergreen/V100/Data/Fight/ShotType.elm b/src/Evergreen/V100/Data/Fight/ShotType.elm deleted file mode 100644 index c292ed0f..00000000 --- a/src/Evergreen/V100/Data/Fight/ShotType.elm +++ /dev/null @@ -1,17 +0,0 @@ -module Evergreen.V100.Data.Fight.ShotType exposing (..) - - -type AimedShot - = Head - | Torso - | Eyes - | Groin - | LeftArm - | RightArm - | LeftLeg - | RightLeg - - -type ShotType - = NormalShot - | AimedShot AimedShot diff --git a/src/Evergreen/V100/Data/FightStrategy.elm b/src/Evergreen/V100/Data/FightStrategy.elm deleted file mode 100644 index 8f74be3f..00000000 --- a/src/Evergreen/V100/Data/FightStrategy.elm +++ /dev/null @@ -1,57 +0,0 @@ -module Evergreen.V100.Data.FightStrategy exposing (..) - -import Evergreen.V100.Data.Fight.ShotType -import Evergreen.V100.Data.Item - - -type Operator - = LT_ - | LTE - | EQ_ - | NE - | GTE - | GT_ - - -type Value - = MyHP - | MyAP - | MyItemCount Evergreen.V100.Data.Item.Kind - | ItemsUsed Evergreen.V100.Data.Item.Kind - | TheirLevel - | ChanceToHit Evergreen.V100.Data.Fight.ShotType.ShotType - | Distance - - -type alias OperatorData = - { op : Operator - , value : Value - , number_ : Float - } - - -type Condition - = Or Condition Condition - | And Condition Condition - | Not Condition - | Operator OperatorData - - -type alias IfData = - { condition : Condition - , then_ : FightStrategy - , else_ : FightStrategy - } - - -type Command - = Attack Evergreen.V100.Data.Fight.ShotType.ShotType - | AttackRandomly - | Heal Evergreen.V100.Data.Item.Kind - | MoveForward - | DoWhatever - - -type FightStrategy - = If IfData - | Command Command diff --git a/src/Evergreen/V100/Data/HealthStatus.elm b/src/Evergreen/V100/Data/HealthStatus.elm deleted file mode 100644 index 70d3c111..00000000 --- a/src/Evergreen/V100/Data/HealthStatus.elm +++ /dev/null @@ -1,16 +0,0 @@ -module Evergreen.V100.Data.HealthStatus exposing (..) - - -type HealthStatus - = ExactHp - { current : Int - , max : Int - } - | Unhurt - | SlightlyWounded - | Wounded - | SeverelyWounded - | AlmostDead - | Dead - | Alive - | Unknown diff --git a/src/Evergreen/V100/Data/Item.elm b/src/Evergreen/V100/Data/Item.elm deleted file mode 100644 index 45605d12..00000000 --- a/src/Evergreen/V100/Data/Item.elm +++ /dev/null @@ -1,27 +0,0 @@ -module Evergreen.V100.Data.Item exposing (..) - - -type alias Id = - Int - - -type Kind - = Fruit - | HealingPowder - | Stimpak - | BigBookOfScience - | DeansElectronics - | FirstAidBook - | GunsAndBullets - | ScoutHandbook - | Robes - | LeatherJacket - | LeatherArmor - | MetalArmor - - -type alias Item = - { id : Id - , kind : Kind - , count : Int - } diff --git a/src/Evergreen/V100/Data/Map.elm b/src/Evergreen/V100/Data/Map.elm deleted file mode 100644 index 4b895632..00000000 --- a/src/Evergreen/V100/Data/Map.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V100.Data.Map exposing (..) - - -type alias TileNum = - Int - - -type alias TileCoords = - ( Int, Int ) diff --git a/src/Evergreen/V100/Data/Message.elm b/src/Evergreen/V100/Data/Message.elm deleted file mode 100644 index 4715ad90..00000000 --- a/src/Evergreen/V100/Data/Message.elm +++ /dev/null @@ -1,27 +0,0 @@ -module Evergreen.V100.Data.Message exposing (..) - -import Evergreen.V100.Data.Fight -import Evergreen.V100.Data.Player.PlayerName -import Time - - -type Type - = Welcome - | YouAdvancedLevel - { newLevel : Int - } - | YouWereAttacked - { attacker : Evergreen.V100.Data.Player.PlayerName.PlayerName - , fightInfo : Evergreen.V100.Data.Fight.Info - } - | YouAttacked - { target : Evergreen.V100.Data.Player.PlayerName.PlayerName - , fightInfo : Evergreen.V100.Data.Fight.Info - } - - -type alias Message = - { type_ : Type - , hasBeenRead : Bool - , date : Time.Posix - } diff --git a/src/Evergreen/V100/Data/NewChar.elm b/src/Evergreen/V100/Data/NewChar.elm deleted file mode 100644 index 1e7575a1..00000000 --- a/src/Evergreen/V100/Data/NewChar.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V100.Data.NewChar exposing (..) - -import AssocSet -import Evergreen.V100.Data.Skill -import Evergreen.V100.Data.Special -import Evergreen.V100.Data.Trait - - -type CreationError - = DoesNotHaveThreeTaggedSkills - | HasSpecialPointsLeft - | UsedMoreSpecialPointsThanAvailable - | HasSpecialOutOfRange - | HasMoreThanTwoTraits - - -type alias NewChar = - { baseSpecial : Evergreen.V100.Data.Special.Special - , availableSpecial : Int - , taggedSkills : AssocSet.Set Evergreen.V100.Data.Skill.Skill - , traits : AssocSet.Set Evergreen.V100.Data.Trait.Trait - , error : Maybe CreationError - } diff --git a/src/Evergreen/V100/Data/Perk.elm b/src/Evergreen/V100/Data/Perk.elm deleted file mode 100644 index e8a81b8d..00000000 --- a/src/Evergreen/V100/Data/Perk.elm +++ /dev/null @@ -1,45 +0,0 @@ -module Evergreen.V100.Data.Perk exposing (..) - - -type Perk - = BonusHthDamage - | Awareness - | CautiousNature - | Comprehension - | EarlierSequence - | FasterHealing - | HereAndNow - | Survivalist - | SwiftLearner - | Thief - | Toughness - | AdrenalineRush - | Educated - | FortuneFinder - | Gambler - | MoreCriticals - | Negotiator - | Pathfinder - | Ranger - | Salesman - | BetterCriticals - | Dodger - | Speaker - | ActionBoy - | GainStrength - | GainPerception - | GainEndurance - | GainCharisma - | GainIntelligence - | GainAgility - | GainLuck - | HthEvade - | Lifegiver - | LivingAnatomy - | MasterThief - | MasterTrader - | Medic - | MrFixit - | Tag - | BonusHthAttacks - | Slayer diff --git a/src/Evergreen/V100/Data/Player.elm b/src/Evergreen/V100/Data/Player.elm deleted file mode 100644 index f7486290..00000000 --- a/src/Evergreen/V100/Data/Player.elm +++ /dev/null @@ -1,80 +0,0 @@ -module Evergreen.V100.Data.Player exposing (..) - -import AssocList -import AssocSet -import Dict -import Evergreen.V100.Data.Auth -import Evergreen.V100.Data.FightStrategy -import Evergreen.V100.Data.HealthStatus -import Evergreen.V100.Data.Item -import Evergreen.V100.Data.Map -import Evergreen.V100.Data.Message -import Evergreen.V100.Data.Perk -import Evergreen.V100.Data.Player.PlayerName -import Evergreen.V100.Data.Skill -import Evergreen.V100.Data.Special -import Evergreen.V100.Data.Trait -import Evergreen.V100.Data.Xp - - -type alias COtherPlayer = - { level : Evergreen.V100.Data.Xp.Level - , name : Evergreen.V100.Data.Player.PlayerName.PlayerName - , wins : Int - , losses : Int - , healthStatus : Evergreen.V100.Data.HealthStatus.HealthStatus - } - - -type alias CPlayer = - { hp : Int - , maxHp : Int - , xp : Evergreen.V100.Data.Xp.Xp - , name : Evergreen.V100.Data.Player.PlayerName.PlayerName - , special : Evergreen.V100.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V100.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V100.Data.Perk.Perk Int - , messages : List Evergreen.V100.Data.Message.Message - , items : Dict.Dict Evergreen.V100.Data.Item.Id Evergreen.V100.Data.Item.Item - , traits : AssocSet.Set Evergreen.V100.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V100.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V100.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - , equippedArmor : Maybe Evergreen.V100.Data.Item.Item - , fightStrategy : Evergreen.V100.Data.FightStrategy.FightStrategy - } - - -type Player a - = NeedsCharCreated (Evergreen.V100.Data.Auth.Auth Evergreen.V100.Data.Auth.Verified) - | Player a - - -type alias SPlayer = - { name : Evergreen.V100.Data.Player.PlayerName.PlayerName - , password : Evergreen.V100.Data.Auth.Password Evergreen.V100.Data.Auth.Verified - , hp : Int - , maxHp : Int - , xp : Int - , special : Evergreen.V100.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V100.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V100.Data.Perk.Perk Int - , messages : List Evergreen.V100.Data.Message.Message - , items : Dict.Dict Evergreen.V100.Data.Item.Id Evergreen.V100.Data.Item.Item - , traits : AssocSet.Set Evergreen.V100.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V100.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V100.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - , equippedArmor : Maybe Evergreen.V100.Data.Item.Item - , fightStrategy : Evergreen.V100.Data.FightStrategy.FightStrategy - } diff --git a/src/Evergreen/V100/Data/Player/PlayerName.elm b/src/Evergreen/V100/Data/Player/PlayerName.elm deleted file mode 100644 index 6529089a..00000000 --- a/src/Evergreen/V100/Data/Player/PlayerName.elm +++ /dev/null @@ -1,5 +0,0 @@ -module Evergreen.V100.Data.Player.PlayerName exposing (..) - - -type alias PlayerName = - String diff --git a/src/Evergreen/V100/Data/Skill.elm b/src/Evergreen/V100/Data/Skill.elm deleted file mode 100644 index c88c1c3a..00000000 --- a/src/Evergreen/V100/Data/Skill.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V100.Data.Skill exposing (..) - - -type Skill - = SmallGuns - | BigGuns - | EnergyWeapons - | Unarmed - | MeleeWeapons - | Throwing - | FirstAid - | Doctor - | Sneak - | Lockpick - | Steal - | Traps - | Science - | Repair - | Speech - | Barter - | Gambling - | Outdoorsman diff --git a/src/Evergreen/V100/Data/Special.elm b/src/Evergreen/V100/Data/Special.elm deleted file mode 100644 index 72dd141d..00000000 --- a/src/Evergreen/V100/Data/Special.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V100.Data.Special exposing (..) - - -type alias Special = - { strength : Int - , perception : Int - , endurance : Int - , charisma : Int - , intelligence : Int - , agility : Int - , luck : Int - } - - -type Type - = Strength - | Perception - | Endurance - | Charisma - | Intelligence - | Agility - | Luck diff --git a/src/Evergreen/V100/Data/Trait.elm b/src/Evergreen/V100/Data/Trait.elm deleted file mode 100644 index e94910a9..00000000 --- a/src/Evergreen/V100/Data/Trait.elm +++ /dev/null @@ -1,11 +0,0 @@ -module Evergreen.V100.Data.Trait exposing (..) - - -type Trait - = Kamikaze - | Bruiser - | Gifted - | SmallFrame - | Skilled - | HeavyHanded - | Finesse diff --git a/src/Evergreen/V100/Data/Vendor.elm b/src/Evergreen/V100/Data/Vendor.elm deleted file mode 100644 index f2188b5c..00000000 --- a/src/Evergreen/V100/Data/Vendor.elm +++ /dev/null @@ -1,20 +0,0 @@ -module Evergreen.V100.Data.Vendor exposing (..) - -import Dict -import Evergreen.V100.Data.Item - - -type Name - = ArroyoHakunin - | KlamathMaidaBuckner - | DenFlick - | ModocJo - | VaultCityHappyHarry - - -type alias Vendor = - { name : Name - , items : Dict.Dict Evergreen.V100.Data.Item.Id Evergreen.V100.Data.Item.Item - , caps : Int - , barterSkill : Int - } diff --git a/src/Evergreen/V100/Data/World.elm b/src/Evergreen/V100/Data/World.elm deleted file mode 100644 index 784c963e..00000000 --- a/src/Evergreen/V100/Data/World.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.V100.Data.World exposing (..) - -import AssocList -import Evergreen.V100.Data.Auth -import Evergreen.V100.Data.Player -import Evergreen.V100.Data.Player.PlayerName -import Evergreen.V100.Data.Vendor -import Time - - -type alias WorldLoggedOutData = - { players : List Evergreen.V100.Data.Player.COtherPlayer - } - - -type alias WorldLoggedInData = - { player : Evergreen.V100.Data.Player.Player Evergreen.V100.Data.Player.CPlayer - , otherPlayers : List Evergreen.V100.Data.Player.COtherPlayer - , playerRank : Int - , vendors : AssocList.Dict Evergreen.V100.Data.Vendor.Name Evergreen.V100.Data.Vendor.Vendor - } - - -type alias AdminData = - { players : List (Evergreen.V100.Data.Player.Player Evergreen.V100.Data.Player.SPlayer) - , loggedInPlayers : List Evergreen.V100.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - } - - -type World - = WorldNotInitialized (Evergreen.V100.Data.Auth.Auth Evergreen.V100.Data.Auth.Plaintext) - | WorldLoggedOut (Evergreen.V100.Data.Auth.Auth Evergreen.V100.Data.Auth.Plaintext) WorldLoggedOutData - | WorldLoggedIn WorldLoggedInData - | WorldAdmin AdminData diff --git a/src/Evergreen/V100/Data/Xp.elm b/src/Evergreen/V100/Data/Xp.elm deleted file mode 100644 index 1dfa3294..00000000 --- a/src/Evergreen/V100/Data/Xp.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V100.Data.Xp exposing (..) - - -type alias Level = - Int - - -type alias Xp = - Int diff --git a/src/Evergreen/V100/Frontend/HoveredItem.elm b/src/Evergreen/V100/Frontend/HoveredItem.elm deleted file mode 100644 index 14bed1d7..00000000 --- a/src/Evergreen/V100/Frontend/HoveredItem.elm +++ /dev/null @@ -1,13 +0,0 @@ -module Evergreen.V100.Frontend.HoveredItem exposing (..) - -import Evergreen.V100.Data.Perk -import Evergreen.V100.Data.Skill -import Evergreen.V100.Data.Special -import Evergreen.V100.Data.Trait - - -type HoveredItem - = HoveredPerk Evergreen.V100.Data.Perk.Perk - | HoveredTrait Evergreen.V100.Data.Trait.Trait - | HoveredSpecial Evergreen.V100.Data.Special.Type - | HoveredSkill Evergreen.V100.Data.Skill.Skill diff --git a/src/Evergreen/V100/Frontend/Route.elm b/src/Evergreen/V100/Frontend/Route.elm deleted file mode 100644 index 2153d480..00000000 --- a/src/Evergreen/V100/Frontend/Route.elm +++ /dev/null @@ -1,32 +0,0 @@ -module Evergreen.V100.Frontend.Route exposing (..) - -import Evergreen.V100.Data.Barter -import Evergreen.V100.Data.Fight -import Evergreen.V100.Data.Message - - -type TownRoute - = MainSquare - | Store - { barter : Evergreen.V100.Data.Barter.State - } - - -type AdminRoute - = LoggedIn - - -type Route - = Character - | Inventory - | Map - | Ladder - | Town TownRoute - | About - | News - | Fight Evergreen.V100.Data.Fight.Info - | Messages - | Message Evergreen.V100.Data.Message.Message - | CharCreation - | Admin AdminRoute - | Settings diff --git a/src/Evergreen/V100/Logic.elm b/src/Evergreen/V100/Logic.elm deleted file mode 100644 index 21c367ae..00000000 --- a/src/Evergreen/V100/Logic.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V100.Logic exposing (..) - - -type alias AttackStats = - { minDamage : Int - , maxDamage : Int - , criticalChanceBonus : Int - } diff --git a/src/Evergreen/V100/Types.elm b/src/Evergreen/V100/Types.elm deleted file mode 100644 index e30db5ac..00000000 --- a/src/Evergreen/V100/Types.elm +++ /dev/null @@ -1,167 +0,0 @@ -module Evergreen.V100.Types exposing (..) - -import AssocList -import Browser -import Browser.Navigation -import Dict -import Evergreen.V100.Data.Auth -import Evergreen.V100.Data.Barter -import Evergreen.V100.Data.Fight -import Evergreen.V100.Data.Fight.Generator -import Evergreen.V100.Data.FightStrategy -import Evergreen.V100.Data.Item -import Evergreen.V100.Data.Map -import Evergreen.V100.Data.Message -import Evergreen.V100.Data.NewChar -import Evergreen.V100.Data.Perk -import Evergreen.V100.Data.Player -import Evergreen.V100.Data.Player.PlayerName -import Evergreen.V100.Data.Skill -import Evergreen.V100.Data.Special -import Evergreen.V100.Data.Trait -import Evergreen.V100.Data.Vendor -import Evergreen.V100.Data.World -import Evergreen.V100.Frontend.HoveredItem -import Evergreen.V100.Frontend.Route -import File exposing (File) -import Lamdera -import Set -import Time -import Url - - -type alias FrontendModel = - { key : Browser.Navigation.Key - , time : Time.Posix - , zone : Time.Zone - , route : Evergreen.V100.Frontend.Route.Route - , world : Evergreen.V100.Data.World.World - , newChar : Evergreen.V100.Data.NewChar.NewChar - , alertMessage : Maybe String - , mapMouseCoords : Maybe ( Evergreen.V100.Data.Map.TileCoords, Set.Set Evergreen.V100.Data.Map.TileCoords ) - , hoveredItem : Maybe Evergreen.V100.Frontend.HoveredItem.HoveredItem - } - - -type alias BackendModel = - { players : Dict.Dict Evergreen.V100.Data.Player.PlayerName.PlayerName (Evergreen.V100.Data.Player.Player Evergreen.V100.Data.Player.SPlayer) - , loggedInPlayers : Dict.Dict Lamdera.ClientId Evergreen.V100.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - , adminLoggedIn : Maybe ( Lamdera.ClientId, Lamdera.SessionId ) - , time : Time.Posix - , vendors : AssocList.Dict Evergreen.V100.Data.Vendor.Name Evergreen.V100.Data.Vendor.Vendor - , lastItemId : Int - } - - -type BarterMsg - = AddPlayerItem Evergreen.V100.Data.Item.Id Int - | AddVendorItem Evergreen.V100.Data.Item.Id Int - | AddPlayerCaps Int - | AddVendorCaps Int - | RemovePlayerItem Evergreen.V100.Data.Item.Id Int - | RemoveVendorItem Evergreen.V100.Data.Item.Id Int - | RemovePlayerCaps Int - | RemoveVendorCaps Int - | ResetBarter - | ConfirmBarter - | SetTransferNInput Evergreen.V100.Data.Barter.TransferNPosition String - | SetTransferNHover Evergreen.V100.Data.Barter.TransferNPosition - | UnsetTransferNHover - - -type FrontendMsg - = UrlClicked Browser.UrlRequest - | UrlChanged Url.Url - | GoToRoute Evergreen.V100.Frontend.Route.Route - | Logout - | Login - | Register - | GotZone Time.Zone - | GotTime Time.Posix - | AskToFight Evergreen.V100.Data.Player.PlayerName.PlayerName - | AskToHeal - | AskToUseItem Evergreen.V100.Data.Item.Id - | AskToWander - | AskToChoosePerk Evergreen.V100.Data.Perk.Perk - | AskToEquipItem Evergreen.V100.Data.Item.Id - | AskToUnequipArmor - | AskToSetFightStrategy Evergreen.V100.Data.FightStrategy.FightStrategy - | AskForExport - | ImportButtonClicked - | ImportFileSelected File - | AskToImport String - | Refresh - | AskToTagSkill Evergreen.V100.Data.Skill.Skill - | AskToUseSkillPoints Evergreen.V100.Data.Skill.Skill - | SetAuthName String - | SetAuthPassword String - | CreateChar - | NewCharIncSpecial Evergreen.V100.Data.Special.Type - | NewCharDecSpecial Evergreen.V100.Data.Special.Type - | NewCharToggleTaggedSkill Evergreen.V100.Data.Skill.Skill - | NewCharToggleTrait Evergreen.V100.Data.Trait.Trait - | MapMouseAtCoords Evergreen.V100.Data.Map.TileCoords - | MapMouseOut - | MapMouseClick - | OpenMessage Evergreen.V100.Data.Message.Message - | AskToRemoveMessage Evergreen.V100.Data.Message.Message - | BarterMsg BarterMsg - | HoverItem Evergreen.V100.Frontend.HoveredItem.HoveredItem - | StopHoveringItem - - -type AdminToBackend - = ExportJson - | ImportJson String - - -type ToBackend - = LogMeIn (Evergreen.V100.Data.Auth.Auth Evergreen.V100.Data.Auth.Hashed) - | RegisterMe (Evergreen.V100.Data.Auth.Auth Evergreen.V100.Data.Auth.Hashed) - | CreateNewChar Evergreen.V100.Data.NewChar.NewChar - | LogMeOut - | Fight Evergreen.V100.Data.Player.PlayerName.PlayerName - | HealMe - | UseItem Evergreen.V100.Data.Item.Id - | Wander - | EquipItem Evergreen.V100.Data.Item.Id - | SetFightStrategy Evergreen.V100.Data.FightStrategy.FightStrategy - | UnequipArmor - | RefreshPlease - | TagSkill Evergreen.V100.Data.Skill.Skill - | UseSkillPoints Evergreen.V100.Data.Skill.Skill - | ChoosePerk Evergreen.V100.Data.Perk.Perk - | MoveTo Evergreen.V100.Data.Map.TileCoords (Set.Set Evergreen.V100.Data.Map.TileCoords) - | MessageWasRead Evergreen.V100.Data.Message.Message - | RemoveMessage Evergreen.V100.Data.Message.Message - | Barter Evergreen.V100.Data.Barter.State - | AdminToBackend AdminToBackend - - -type BackendMsg - = Connected Lamdera.SessionId Lamdera.ClientId - | Disconnected Lamdera.SessionId Lamdera.ClientId - | GeneratedFight Lamdera.ClientId Evergreen.V100.Data.Player.SPlayer ( Evergreen.V100.Data.Fight.Generator.Fight, Int ) - | GeneratedNewVendorsStock ( AssocList.Dict Evergreen.V100.Data.Vendor.Name Evergreen.V100.Data.Vendor.Vendor, Int ) - | Tick Time.Posix - | CreateNewCharWithTime Lamdera.ClientId Evergreen.V100.Data.NewChar.NewChar Time.Posix - | LoggedToBackendMsg - - -type ToFrontend - = YourCurrentWorld Evergreen.V100.Data.World.WorldLoggedInData - | InitWorld Evergreen.V100.Data.World.WorldLoggedOutData - | RefreshedLoggedOut Evergreen.V100.Data.World.WorldLoggedOutData - | CurrentAdminData Evergreen.V100.Data.World.AdminData - | YourFightResult ( Evergreen.V100.Data.Fight.Info, Evergreen.V100.Data.World.WorldLoggedInData ) - | YoureLoggedIn Evergreen.V100.Data.World.WorldLoggedInData - | YoureRegistered Evergreen.V100.Data.World.WorldLoggedInData - | CharCreationError Evergreen.V100.Data.NewChar.CreationError - | YouHaveCreatedChar Evergreen.V100.Data.World.WorldLoggedInData - | YoureLoggedOut Evergreen.V100.Data.World.WorldLoggedOutData - | AlertMessage String - | YoureLoggedInAsAdmin Evergreen.V100.Data.World.AdminData - | JsonExportDone String - | BarterDone ( Evergreen.V100.Data.World.WorldLoggedInData, Maybe Evergreen.V100.Data.Barter.Message ) - | BarterMessage Evergreen.V100.Data.Barter.Message diff --git a/src/Evergreen/V75/Data/Auth.elm b/src/Evergreen/V75/Data/Auth.elm deleted file mode 100644 index afa53874..00000000 --- a/src/Evergreen/V75/Data/Auth.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V75.Data.Auth exposing (..) - - -type Plaintext - = Plaintext - - -type Password a - = Password String - - -type alias Auth a = - { name : String - , password : Password a - } - - -type Verified - = Verified - - -type Hashed - = Hashed diff --git a/src/Evergreen/V75/Data/Barter.elm b/src/Evergreen/V75/Data/Barter.elm deleted file mode 100644 index c6a4950b..00000000 --- a/src/Evergreen/V75/Data/Barter.elm +++ /dev/null @@ -1,33 +0,0 @@ -module Evergreen.V75.Data.Barter exposing (..) - -import AssocList -import Dict -import Evergreen.V75.Data.Item - - -type Message - = BarterIsEmpty - | PlayerOfferNotValuableEnough - | YouGaveStuffForFree - - -type TransferNPosition - = PlayerKeptItem Evergreen.V75.Data.Item.Id - | VendorKeptItem Evergreen.V75.Data.Item.Id - | PlayerTradedItem Evergreen.V75.Data.Item.Id - | VendorTradedItem Evergreen.V75.Data.Item.Id - | PlayerKeptCaps - | VendorKeptCaps - | PlayerTradedCaps - | VendorTradedCaps - - -type alias State = - { playerItems : Dict.Dict Evergreen.V75.Data.Item.Id Int - , vendorItems : Dict.Dict Evergreen.V75.Data.Item.Id Int - , playerCaps : Int - , vendorCaps : Int - , lastMessage : Maybe Message - , transferNInputs : AssocList.Dict TransferNPosition String - , transferNHover : Maybe TransferNPosition - } diff --git a/src/Evergreen/V75/Data/Enemy.elm b/src/Evergreen/V75/Data/Enemy.elm deleted file mode 100644 index 9f01ee28..00000000 --- a/src/Evergreen/V75/Data/Enemy.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V75.Data.Enemy exposing (..) - - -type Type - = GiantAnt - | ToughGiantAnt - | LesserRadscorpion - | Radscorpion diff --git a/src/Evergreen/V75/Data/Fight.elm b/src/Evergreen/V75/Data/Fight.elm deleted file mode 100644 index e5b759d7..00000000 --- a/src/Evergreen/V75/Data/Fight.elm +++ /dev/null @@ -1,78 +0,0 @@ -module Evergreen.V75.Data.Fight exposing (..) - -import AssocList -import AssocSet -import Evergreen.V75.Data.Enemy -import Evergreen.V75.Data.Fight.ShotType -import Evergreen.V75.Data.Perk -import Evergreen.V75.Data.Player.PlayerName -import Evergreen.V75.Data.Skill -import Evergreen.V75.Data.Special -import Evergreen.V75.Data.Trait -import Evergreen.V75.Logic - - -type OpponentType - = Npc Evergreen.V75.Data.Enemy.Type - | Player Evergreen.V75.Data.Player.PlayerName.PlayerName - - -type Who - = Attacker - | Target - - -type FightAction - = Start - { distanceHexes : Int - } - | ComeCloser - { hexes : Int - , remainingDistanceHexes : Int - } - | Attack - { damage : Int - , shotType : Evergreen.V75.Data.Fight.ShotType.ShotType - , remainingHp : Int - } - | Miss - { shotType : Evergreen.V75.Data.Fight.ShotType.ShotType - } - - -type FightResult - = AttackerWon - { xpGained : Int - , capsGained : Int - } - | TargetWon - { xpGained : Int - , capsGained : Int - } - | TargetAlreadyDead - | BothDead - | NobodyDead - - -type alias FightInfo = - { attacker : OpponentType - , target : OpponentType - , log : List ( Who, FightAction ) - , result : FightResult - } - - -type alias Opponent = - { type_ : OpponentType - , hp : Int - , maxHp : Int - , maxAp : Int - , sequence : Int - , traits : AssocSet.Set Evergreen.V75.Data.Trait.Trait - , perks : AssocList.Dict Evergreen.V75.Data.Perk.Perk Int - , caps : Int - , armorClass : Int - , attackStats : Evergreen.V75.Logic.AttackStats - , addedSkillPercentages : AssocList.Dict Evergreen.V75.Data.Skill.Skill Int - , baseSpecial : Evergreen.V75.Data.Special.Special - } diff --git a/src/Evergreen/V75/Data/Fight/Generator.elm b/src/Evergreen/V75/Data/Fight/Generator.elm deleted file mode 100644 index 42270c5c..00000000 --- a/src/Evergreen/V75/Data/Fight/Generator.elm +++ /dev/null @@ -1,12 +0,0 @@ -module Evergreen.V75.Data.Fight.Generator exposing (..) - -import Evergreen.V75.Data.Fight -import Evergreen.V75.Data.Message - - -type alias Fight = - { finalAttacker : Evergreen.V75.Data.Fight.Opponent - , finalTarget : Evergreen.V75.Data.Fight.Opponent - , fightInfo : Evergreen.V75.Data.Fight.FightInfo - , messageForTarget : Evergreen.V75.Data.Message.Message - } diff --git a/src/Evergreen/V75/Data/Fight/ShotType.elm b/src/Evergreen/V75/Data/Fight/ShotType.elm deleted file mode 100644 index 455f4f5b..00000000 --- a/src/Evergreen/V75/Data/Fight/ShotType.elm +++ /dev/null @@ -1,17 +0,0 @@ -module Evergreen.V75.Data.Fight.ShotType exposing (..) - - -type AimedShot - = Head - | Torso - | Eyes - | Groin - | LeftArm - | RightArm - | LeftLeg - | RightLeg - - -type ShotType - = NormalShot - | AimedShot AimedShot diff --git a/src/Evergreen/V75/Data/HealthStatus.elm b/src/Evergreen/V75/Data/HealthStatus.elm deleted file mode 100644 index 9f1c6588..00000000 --- a/src/Evergreen/V75/Data/HealthStatus.elm +++ /dev/null @@ -1,16 +0,0 @@ -module Evergreen.V75.Data.HealthStatus exposing (..) - - -type HealthStatus - = ExactHp - { current : Int - , max : Int - } - | Unhurt - | SlightlyWounded - | Wounded - | SeverelyWounded - | AlmostDead - | Dead - | Alive - | Unknown diff --git a/src/Evergreen/V75/Data/Item.elm b/src/Evergreen/V75/Data/Item.elm deleted file mode 100644 index d93b8b09..00000000 --- a/src/Evergreen/V75/Data/Item.elm +++ /dev/null @@ -1,21 +0,0 @@ -module Evergreen.V75.Data.Item exposing (..) - - -type alias Id = - Int - - -type Kind - = Stimpak - | BigBookOfScience - | DeansElectronics - | FirstAidBook - | GunsAndBullets - | ScoutHandbook - - -type alias Item = - { id : Id - , kind : Kind - , count : Int - } diff --git a/src/Evergreen/V75/Data/Map.elm b/src/Evergreen/V75/Data/Map.elm deleted file mode 100644 index 3cd524a0..00000000 --- a/src/Evergreen/V75/Data/Map.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V75.Data.Map exposing (..) - - -type alias TileNum = - Int - - -type alias TileCoords = - ( Int, Int ) diff --git a/src/Evergreen/V75/Data/Message.elm b/src/Evergreen/V75/Data/Message.elm deleted file mode 100644 index 3b719a9c..00000000 --- a/src/Evergreen/V75/Data/Message.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V75.Data.Message exposing (..) - -import Evergreen.V75.Data.Fight -import Evergreen.V75.Data.Player.PlayerName -import Time - - -type Type - = Welcome - | YouAdvancedLevel - { newLevel : Int - } - | YouWereAttacked - { attacker : Evergreen.V75.Data.Player.PlayerName.PlayerName - , fightInfo : Evergreen.V75.Data.Fight.FightInfo - } - - -type alias Message = - { type_ : Type - , hasBeenRead : Bool - , date : Time.Posix - } diff --git a/src/Evergreen/V75/Data/NewChar.elm b/src/Evergreen/V75/Data/NewChar.elm deleted file mode 100644 index 7dbe52e5..00000000 --- a/src/Evergreen/V75/Data/NewChar.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V75.Data.NewChar exposing (..) - -import AssocSet -import Evergreen.V75.Data.Skill -import Evergreen.V75.Data.Special -import Evergreen.V75.Data.Trait - - -type CreationError - = DoesNotHaveThreeTaggedSkills - | HasSpecialPointsLeft - | UsedMoreSpecialPointsThanAvailable - | HasSpecialOutOfRange - | HasMoreThanTwoTraits - - -type alias NewChar = - { baseSpecial : Evergreen.V75.Data.Special.Special - , availableSpecial : Int - , taggedSkills : AssocSet.Set Evergreen.V75.Data.Skill.Skill - , traits : AssocSet.Set Evergreen.V75.Data.Trait.Trait - , error : Maybe CreationError - } diff --git a/src/Evergreen/V75/Data/Perk.elm b/src/Evergreen/V75/Data/Perk.elm deleted file mode 100644 index 588fd3b5..00000000 --- a/src/Evergreen/V75/Data/Perk.elm +++ /dev/null @@ -1,12 +0,0 @@ -module Evergreen.V75.Data.Perk exposing (..) - - -type Perk - = EarlierSequence - | Tag - | Educated - | BonusHthDamage - | MasterTrader - | Awareness - | CautiousNature - | Comprehension diff --git a/src/Evergreen/V75/Data/Player.elm b/src/Evergreen/V75/Data/Player.elm deleted file mode 100644 index 6a1e8d2d..00000000 --- a/src/Evergreen/V75/Data/Player.elm +++ /dev/null @@ -1,75 +0,0 @@ -module Evergreen.V75.Data.Player exposing (..) - -import AssocList -import AssocSet -import Dict -import Evergreen.V75.Data.Auth -import Evergreen.V75.Data.HealthStatus -import Evergreen.V75.Data.Item -import Evergreen.V75.Data.Map -import Evergreen.V75.Data.Message -import Evergreen.V75.Data.Perk -import Evergreen.V75.Data.Player.PlayerName -import Evergreen.V75.Data.Skill -import Evergreen.V75.Data.Special -import Evergreen.V75.Data.Trait -import Evergreen.V75.Data.Xp - - -type alias COtherPlayer = - { level : Evergreen.V75.Data.Xp.Level - , name : Evergreen.V75.Data.Player.PlayerName.PlayerName - , wins : Int - , losses : Int - , healthStatus : Evergreen.V75.Data.HealthStatus.HealthStatus - } - - -type alias CPlayer = - { hp : Int - , maxHp : Int - , xp : Evergreen.V75.Data.Xp.Xp - , name : Evergreen.V75.Data.Player.PlayerName.PlayerName - , baseSpecial : Evergreen.V75.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V75.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V75.Data.Perk.Perk Int - , messages : List Evergreen.V75.Data.Message.Message - , items : Dict.Dict Evergreen.V75.Data.Item.Id Evergreen.V75.Data.Item.Item - , traits : AssocSet.Set Evergreen.V75.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V75.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V75.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - } - - -type Player a - = NeedsCharCreated (Evergreen.V75.Data.Auth.Auth Evergreen.V75.Data.Auth.Verified) - | Player a - - -type alias SPlayer = - { name : Evergreen.V75.Data.Player.PlayerName.PlayerName - , password : Evergreen.V75.Data.Auth.Password Evergreen.V75.Data.Auth.Verified - , hp : Int - , maxHp : Int - , xp : Int - , baseSpecial : Evergreen.V75.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V75.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V75.Data.Perk.Perk Int - , messages : List Evergreen.V75.Data.Message.Message - , items : Dict.Dict Evergreen.V75.Data.Item.Id Evergreen.V75.Data.Item.Item - , traits : AssocSet.Set Evergreen.V75.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V75.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V75.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - } diff --git a/src/Evergreen/V75/Data/Player/PlayerName.elm b/src/Evergreen/V75/Data/Player/PlayerName.elm deleted file mode 100644 index 31b80ce9..00000000 --- a/src/Evergreen/V75/Data/Player/PlayerName.elm +++ /dev/null @@ -1,5 +0,0 @@ -module Evergreen.V75.Data.Player.PlayerName exposing (..) - - -type alias PlayerName = - String diff --git a/src/Evergreen/V75/Data/Skill.elm b/src/Evergreen/V75/Data/Skill.elm deleted file mode 100644 index 3e30a885..00000000 --- a/src/Evergreen/V75/Data/Skill.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V75.Data.Skill exposing (..) - - -type Skill - = SmallGuns - | BigGuns - | EnergyWeapons - | Unarmed - | MeleeWeapons - | Throwing - | FirstAid - | Doctor - | Sneak - | Lockpick - | Steal - | Traps - | Science - | Repair - | Speech - | Barter - | Gambling - | Outdoorsman diff --git a/src/Evergreen/V75/Data/Special.elm b/src/Evergreen/V75/Data/Special.elm deleted file mode 100644 index 35bb92e5..00000000 --- a/src/Evergreen/V75/Data/Special.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V75.Data.Special exposing (..) - - -type alias Special = - { strength : Int - , perception : Int - , endurance : Int - , charisma : Int - , intelligence : Int - , agility : Int - , luck : Int - } - - -type SpecialType - = Strength - | Perception - | Endurance - | Charisma - | Intelligence - | Agility - | Luck diff --git a/src/Evergreen/V75/Data/Trait.elm b/src/Evergreen/V75/Data/Trait.elm deleted file mode 100644 index 4e7b22f5..00000000 --- a/src/Evergreen/V75/Data/Trait.elm +++ /dev/null @@ -1,10 +0,0 @@ -module Evergreen.V75.Data.Trait exposing (..) - - -type Trait - = Kamikaze - | Bruiser - | Gifted - | SmallFrame - | Skilled - | HeavyHanded diff --git a/src/Evergreen/V75/Data/Vendor.elm b/src/Evergreen/V75/Data/Vendor.elm deleted file mode 100644 index 363ef284..00000000 --- a/src/Evergreen/V75/Data/Vendor.elm +++ /dev/null @@ -1,17 +0,0 @@ -module Evergreen.V75.Data.Vendor exposing (..) - -import Dict -import Evergreen.V75.Data.Item - - -type Name - = KlamathMaidaBuckner - | DenFlick - - -type alias Vendor = - { name : Name - , items : Dict.Dict Evergreen.V75.Data.Item.Id Evergreen.V75.Data.Item.Item - , caps : Int - , barterSkill : Int - } diff --git a/src/Evergreen/V75/Data/World.elm b/src/Evergreen/V75/Data/World.elm deleted file mode 100644 index 64da069f..00000000 --- a/src/Evergreen/V75/Data/World.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.V75.Data.World exposing (..) - -import AssocList -import Evergreen.V75.Data.Auth -import Evergreen.V75.Data.Player -import Evergreen.V75.Data.Player.PlayerName -import Evergreen.V75.Data.Vendor -import Time - - -type alias WorldLoggedOutData = - { players : List Evergreen.V75.Data.Player.COtherPlayer - } - - -type alias WorldLoggedInData = - { player : Evergreen.V75.Data.Player.Player Evergreen.V75.Data.Player.CPlayer - , otherPlayers : List Evergreen.V75.Data.Player.COtherPlayer - , playerRank : Int - , vendors : AssocList.Dict Evergreen.V75.Data.Vendor.Name Evergreen.V75.Data.Vendor.Vendor - } - - -type alias AdminData = - { players : List (Evergreen.V75.Data.Player.Player Evergreen.V75.Data.Player.SPlayer) - , loggedInPlayers : List Evergreen.V75.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - } - - -type World - = WorldNotInitialized (Evergreen.V75.Data.Auth.Auth Evergreen.V75.Data.Auth.Plaintext) - | WorldLoggedOut (Evergreen.V75.Data.Auth.Auth Evergreen.V75.Data.Auth.Plaintext) WorldLoggedOutData - | WorldLoggedIn WorldLoggedInData - | WorldAdmin AdminData diff --git a/src/Evergreen/V75/Data/Xp.elm b/src/Evergreen/V75/Data/Xp.elm deleted file mode 100644 index 7314db8a..00000000 --- a/src/Evergreen/V75/Data/Xp.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V75.Data.Xp exposing (..) - - -type alias Level = - Int - - -type alias Xp = - Int diff --git a/src/Evergreen/V75/Frontend/Route.elm b/src/Evergreen/V75/Frontend/Route.elm deleted file mode 100644 index 99287107..00000000 --- a/src/Evergreen/V75/Frontend/Route.elm +++ /dev/null @@ -1,32 +0,0 @@ -module Evergreen.V75.Frontend.Route exposing (..) - -import Evergreen.V75.Data.Barter -import Evergreen.V75.Data.Fight -import Evergreen.V75.Data.Message - - -type TownRoute - = MainSquare - | Store - { barter : Evergreen.V75.Data.Barter.State - } - - -type AdminRoute - = Players - | LoggedIn - - -type Route - = Character - | Inventory - | Map - | Ladder - | Town TownRoute - | About - | News - | Fight Evergreen.V75.Data.Fight.FightInfo - | Messages - | Message Evergreen.V75.Data.Message.Message - | CharCreation - | Admin AdminRoute diff --git a/src/Evergreen/V75/Logic.elm b/src/Evergreen/V75/Logic.elm deleted file mode 100644 index 42b8b981..00000000 --- a/src/Evergreen/V75/Logic.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V75.Logic exposing (..) - - -type alias AttackStats = - { minDamage : Int - , maxDamage : Int - , criticalChanceBonus : Int - } diff --git a/src/Evergreen/V75/Types.elm b/src/Evergreen/V75/Types.elm deleted file mode 100644 index 95ed7e58..00000000 --- a/src/Evergreen/V75/Types.elm +++ /dev/null @@ -1,156 +0,0 @@ -module Evergreen.V75.Types exposing (..) - -import AssocList -import Browser -import Browser.Navigation -import Dict -import Evergreen.V75.Data.Auth -import Evergreen.V75.Data.Barter -import Evergreen.V75.Data.Fight -import Evergreen.V75.Data.Fight.Generator -import Evergreen.V75.Data.Item -import Evergreen.V75.Data.Map -import Evergreen.V75.Data.Message -import Evergreen.V75.Data.NewChar -import Evergreen.V75.Data.Perk -import Evergreen.V75.Data.Player -import Evergreen.V75.Data.Player.PlayerName -import Evergreen.V75.Data.Skill -import Evergreen.V75.Data.Special -import Evergreen.V75.Data.Trait -import Evergreen.V75.Data.Vendor -import Evergreen.V75.Data.World -import Evergreen.V75.Frontend.Route -import File exposing (File) -import Lamdera -import Set -import Time -import Url - - -type alias FrontendModel = - { key : Browser.Navigation.Key - , time : Time.Posix - , zone : Time.Zone - , route : Evergreen.V75.Frontend.Route.Route - , world : Evergreen.V75.Data.World.World - , newChar : Evergreen.V75.Data.NewChar.NewChar - , alertMessage : Maybe String - , mapMouseCoords : Maybe ( Evergreen.V75.Data.Map.TileCoords, Set.Set Evergreen.V75.Data.Map.TileCoords ) - } - - -type alias BackendModel = - { players : Dict.Dict Evergreen.V75.Data.Player.PlayerName.PlayerName (Evergreen.V75.Data.Player.Player Evergreen.V75.Data.Player.SPlayer) - , loggedInPlayers : Dict.Dict Lamdera.ClientId Evergreen.V75.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - , adminLoggedIn : Maybe ( Lamdera.ClientId, Lamdera.SessionId ) - , time : Time.Posix - , vendors : AssocList.Dict Evergreen.V75.Data.Vendor.Name Evergreen.V75.Data.Vendor.Vendor - , lastItemId : Int - } - - -type BarterMsg - = AddPlayerItem Evergreen.V75.Data.Item.Id Int - | AddVendorItem Evergreen.V75.Data.Item.Id Int - | AddPlayerCaps Int - | AddVendorCaps Int - | RemovePlayerItem Evergreen.V75.Data.Item.Id Int - | RemoveVendorItem Evergreen.V75.Data.Item.Id Int - | RemovePlayerCaps Int - | RemoveVendorCaps Int - | ResetBarter - | ConfirmBarter - | SetTransferNInput Evergreen.V75.Data.Barter.TransferNPosition String - | SetTransferNHover Evergreen.V75.Data.Barter.TransferNPosition - | UnsetTransferNHover - - -type FrontendMsg - = UrlClicked Browser.UrlRequest - | UrlChanged Url.Url - | GoToRoute Evergreen.V75.Frontend.Route.Route - | Logout - | Login - | Register - | GotZone Time.Zone - | GotTime Time.Posix - | AskToFight Evergreen.V75.Data.Player.PlayerName.PlayerName - | AskToHeal - | AskToUseItem Evergreen.V75.Data.Item.Id - | AskToWander - | AskToChoosePerk Evergreen.V75.Data.Perk.Perk - | AskForExport - | ImportButtonClicked - | ImportFileSelected File - | AskToImport String - | Refresh - | AskToTagSkill Evergreen.V75.Data.Skill.Skill - | AskToUseSkillPoints Evergreen.V75.Data.Skill.Skill - | SetAuthName String - | SetAuthPassword String - | CreateChar - | NewCharIncSpecial Evergreen.V75.Data.Special.SpecialType - | NewCharDecSpecial Evergreen.V75.Data.Special.SpecialType - | NewCharToggleTaggedSkill Evergreen.V75.Data.Skill.Skill - | NewCharToggleTrait Evergreen.V75.Data.Trait.Trait - | MapMouseAtCoords Evergreen.V75.Data.Map.TileCoords - | MapMouseOut - | MapMouseClick - | OpenMessage Evergreen.V75.Data.Message.Message - | AskToRemoveMessage Evergreen.V75.Data.Message.Message - | BarterMsg BarterMsg - - -type AdminToBackend - = ExportJson - | ImportJson String - - -type ToBackend - = LogMeIn (Evergreen.V75.Data.Auth.Auth Evergreen.V75.Data.Auth.Hashed) - | RegisterMe (Evergreen.V75.Data.Auth.Auth Evergreen.V75.Data.Auth.Hashed) - | CreateNewChar Evergreen.V75.Data.NewChar.NewChar - | LogMeOut - | Fight Evergreen.V75.Data.Player.PlayerName.PlayerName - | HealMe - | UseItem Evergreen.V75.Data.Item.Id - | Wander - | RefreshPlease - | TagSkill Evergreen.V75.Data.Skill.Skill - | UseSkillPoints Evergreen.V75.Data.Skill.Skill - | ChoosePerk Evergreen.V75.Data.Perk.Perk - | MoveTo Evergreen.V75.Data.Map.TileCoords (Set.Set Evergreen.V75.Data.Map.TileCoords) - | MessageWasRead Evergreen.V75.Data.Message.Message - | RemoveMessage Evergreen.V75.Data.Message.Message - | Barter Evergreen.V75.Data.Barter.State - | AdminToBackend AdminToBackend - - -type BackendMsg - = Connected Lamdera.SessionId Lamdera.ClientId - | Disconnected Lamdera.SessionId Lamdera.ClientId - | GeneratedFight Lamdera.ClientId Evergreen.V75.Data.Player.SPlayer Evergreen.V75.Data.Fight.Generator.Fight - | GeneratedNewVendorsStock ( AssocList.Dict Evergreen.V75.Data.Vendor.Name Evergreen.V75.Data.Vendor.Vendor, Int ) - | Tick Time.Posix - | CreateNewCharWithTime Lamdera.ClientId Evergreen.V75.Data.NewChar.NewChar Time.Posix - | LoggedToBackendMsg - - -type ToFrontend - = YourCurrentWorld Evergreen.V75.Data.World.WorldLoggedInData - | InitWorld Evergreen.V75.Data.World.WorldLoggedOutData - | RefreshedLoggedOut Evergreen.V75.Data.World.WorldLoggedOutData - | CurrentAdminData Evergreen.V75.Data.World.AdminData - | YourFightResult ( Evergreen.V75.Data.Fight.FightInfo, Evergreen.V75.Data.World.WorldLoggedInData ) - | YoureLoggedIn Evergreen.V75.Data.World.WorldLoggedInData - | YoureRegistered Evergreen.V75.Data.World.WorldLoggedInData - | CharCreationError Evergreen.V75.Data.NewChar.CreationError - | YouHaveCreatedChar Evergreen.V75.Data.World.WorldLoggedInData - | YoureLoggedOut Evergreen.V75.Data.World.WorldLoggedOutData - | AlertMessage String - | YoureLoggedInAsAdmin Evergreen.V75.Data.World.AdminData - | JsonExportDone String - | BarterDone ( Evergreen.V75.Data.World.WorldLoggedInData, Maybe Evergreen.V75.Data.Barter.Message ) - | BarterMessage Evergreen.V75.Data.Barter.Message diff --git a/src/Evergreen/V77/Data/Auth.elm b/src/Evergreen/V77/Data/Auth.elm deleted file mode 100644 index 37461670..00000000 --- a/src/Evergreen/V77/Data/Auth.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V77.Data.Auth exposing (..) - - -type Plaintext - = Plaintext - - -type Password a - = Password String - - -type alias Auth a = - { name : String - , password : Password a - } - - -type Verified - = Verified - - -type Hashed - = Hashed diff --git a/src/Evergreen/V77/Data/Barter.elm b/src/Evergreen/V77/Data/Barter.elm deleted file mode 100644 index 0dded15d..00000000 --- a/src/Evergreen/V77/Data/Barter.elm +++ /dev/null @@ -1,33 +0,0 @@ -module Evergreen.V77.Data.Barter exposing (..) - -import AssocList -import Dict -import Evergreen.V77.Data.Item - - -type Message - = BarterIsEmpty - | PlayerOfferNotValuableEnough - | YouGaveStuffForFree - - -type TransferNPosition - = PlayerKeptItem Evergreen.V77.Data.Item.Id - | VendorKeptItem Evergreen.V77.Data.Item.Id - | PlayerTradedItem Evergreen.V77.Data.Item.Id - | VendorTradedItem Evergreen.V77.Data.Item.Id - | PlayerKeptCaps - | VendorKeptCaps - | PlayerTradedCaps - | VendorTradedCaps - - -type alias State = - { playerItems : Dict.Dict Evergreen.V77.Data.Item.Id Int - , vendorItems : Dict.Dict Evergreen.V77.Data.Item.Id Int - , playerCaps : Int - , vendorCaps : Int - , lastMessage : Maybe Message - , transferNInputs : AssocList.Dict TransferNPosition String - , transferNHover : Maybe TransferNPosition - } diff --git a/src/Evergreen/V77/Data/Enemy.elm b/src/Evergreen/V77/Data/Enemy.elm deleted file mode 100644 index 09c2e146..00000000 --- a/src/Evergreen/V77/Data/Enemy.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V77.Data.Enemy exposing (..) - - -type Type - = GiantAnt - | ToughGiantAnt - | LesserRadscorpion - | Radscorpion diff --git a/src/Evergreen/V77/Data/Fight.elm b/src/Evergreen/V77/Data/Fight.elm deleted file mode 100644 index a5e6b6ab..00000000 --- a/src/Evergreen/V77/Data/Fight.elm +++ /dev/null @@ -1,78 +0,0 @@ -module Evergreen.V77.Data.Fight exposing (..) - -import AssocList -import AssocSet -import Evergreen.V77.Data.Enemy -import Evergreen.V77.Data.Fight.ShotType -import Evergreen.V77.Data.Perk -import Evergreen.V77.Data.Player.PlayerName -import Evergreen.V77.Data.Skill -import Evergreen.V77.Data.Special -import Evergreen.V77.Data.Trait -import Evergreen.V77.Logic - - -type OpponentType - = Npc Evergreen.V77.Data.Enemy.Type - | Player Evergreen.V77.Data.Player.PlayerName.PlayerName - - -type Who - = Attacker - | Target - - -type FightAction - = Start - { distanceHexes : Int - } - | ComeCloser - { hexes : Int - , remainingDistanceHexes : Int - } - | Attack - { damage : Int - , shotType : Evergreen.V77.Data.Fight.ShotType.ShotType - , remainingHp : Int - } - | Miss - { shotType : Evergreen.V77.Data.Fight.ShotType.ShotType - } - - -type FightResult - = AttackerWon - { xpGained : Int - , capsGained : Int - } - | TargetWon - { xpGained : Int - , capsGained : Int - } - | TargetAlreadyDead - | BothDead - | NobodyDead - - -type alias FightInfo = - { attacker : OpponentType - , target : OpponentType - , log : List ( Who, FightAction ) - , result : FightResult - } - - -type alias Opponent = - { type_ : OpponentType - , hp : Int - , maxHp : Int - , maxAp : Int - , sequence : Int - , traits : AssocSet.Set Evergreen.V77.Data.Trait.Trait - , perks : AssocList.Dict Evergreen.V77.Data.Perk.Perk Int - , caps : Int - , armorClass : Int - , attackStats : Evergreen.V77.Logic.AttackStats - , addedSkillPercentages : AssocList.Dict Evergreen.V77.Data.Skill.Skill Int - , baseSpecial : Evergreen.V77.Data.Special.Special - } diff --git a/src/Evergreen/V77/Data/Fight/Generator.elm b/src/Evergreen/V77/Data/Fight/Generator.elm deleted file mode 100644 index a701908f..00000000 --- a/src/Evergreen/V77/Data/Fight/Generator.elm +++ /dev/null @@ -1,12 +0,0 @@ -module Evergreen.V77.Data.Fight.Generator exposing (..) - -import Evergreen.V77.Data.Fight -import Evergreen.V77.Data.Message - - -type alias Fight = - { finalAttacker : Evergreen.V77.Data.Fight.Opponent - , finalTarget : Evergreen.V77.Data.Fight.Opponent - , fightInfo : Evergreen.V77.Data.Fight.FightInfo - , messageForTarget : Evergreen.V77.Data.Message.Message - } diff --git a/src/Evergreen/V77/Data/Fight/ShotType.elm b/src/Evergreen/V77/Data/Fight/ShotType.elm deleted file mode 100644 index e943cec4..00000000 --- a/src/Evergreen/V77/Data/Fight/ShotType.elm +++ /dev/null @@ -1,17 +0,0 @@ -module Evergreen.V77.Data.Fight.ShotType exposing (..) - - -type AimedShot - = Head - | Torso - | Eyes - | Groin - | LeftArm - | RightArm - | LeftLeg - | RightLeg - - -type ShotType - = NormalShot - | AimedShot AimedShot diff --git a/src/Evergreen/V77/Data/HealthStatus.elm b/src/Evergreen/V77/Data/HealthStatus.elm deleted file mode 100644 index 4a4e107e..00000000 --- a/src/Evergreen/V77/Data/HealthStatus.elm +++ /dev/null @@ -1,16 +0,0 @@ -module Evergreen.V77.Data.HealthStatus exposing (..) - - -type HealthStatus - = ExactHp - { current : Int - , max : Int - } - | Unhurt - | SlightlyWounded - | Wounded - | SeverelyWounded - | AlmostDead - | Dead - | Alive - | Unknown diff --git a/src/Evergreen/V77/Data/Item.elm b/src/Evergreen/V77/Data/Item.elm deleted file mode 100644 index 3dd88ea9..00000000 --- a/src/Evergreen/V77/Data/Item.elm +++ /dev/null @@ -1,21 +0,0 @@ -module Evergreen.V77.Data.Item exposing (..) - - -type alias Id = - Int - - -type Kind - = Stimpak - | BigBookOfScience - | DeansElectronics - | FirstAidBook - | GunsAndBullets - | ScoutHandbook - - -type alias Item = - { id : Id - , kind : Kind - , count : Int - } diff --git a/src/Evergreen/V77/Data/Map.elm b/src/Evergreen/V77/Data/Map.elm deleted file mode 100644 index 6727ec74..00000000 --- a/src/Evergreen/V77/Data/Map.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V77.Data.Map exposing (..) - - -type alias TileNum = - Int - - -type alias TileCoords = - ( Int, Int ) diff --git a/src/Evergreen/V77/Data/Message.elm b/src/Evergreen/V77/Data/Message.elm deleted file mode 100644 index 5bb4a683..00000000 --- a/src/Evergreen/V77/Data/Message.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V77.Data.Message exposing (..) - -import Evergreen.V77.Data.Fight -import Evergreen.V77.Data.Player.PlayerName -import Time - - -type Type - = Welcome - | YouAdvancedLevel - { newLevel : Int - } - | YouWereAttacked - { attacker : Evergreen.V77.Data.Player.PlayerName.PlayerName - , fightInfo : Evergreen.V77.Data.Fight.FightInfo - } - - -type alias Message = - { type_ : Type - , hasBeenRead : Bool - , date : Time.Posix - } diff --git a/src/Evergreen/V77/Data/NewChar.elm b/src/Evergreen/V77/Data/NewChar.elm deleted file mode 100644 index 41f799f2..00000000 --- a/src/Evergreen/V77/Data/NewChar.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V77.Data.NewChar exposing (..) - -import AssocSet -import Evergreen.V77.Data.Skill -import Evergreen.V77.Data.Special -import Evergreen.V77.Data.Trait - - -type CreationError - = DoesNotHaveThreeTaggedSkills - | HasSpecialPointsLeft - | UsedMoreSpecialPointsThanAvailable - | HasSpecialOutOfRange - | HasMoreThanTwoTraits - - -type alias NewChar = - { baseSpecial : Evergreen.V77.Data.Special.Special - , availableSpecial : Int - , taggedSkills : AssocSet.Set Evergreen.V77.Data.Skill.Skill - , traits : AssocSet.Set Evergreen.V77.Data.Trait.Trait - , error : Maybe CreationError - } diff --git a/src/Evergreen/V77/Data/Perk.elm b/src/Evergreen/V77/Data/Perk.elm deleted file mode 100644 index e1352649..00000000 --- a/src/Evergreen/V77/Data/Perk.elm +++ /dev/null @@ -1,13 +0,0 @@ -module Evergreen.V77.Data.Perk exposing (..) - - -type Perk - = BonusHthDamage - | MasterTrader - | Awareness - | CautiousNature - | Comprehension - | EarlierSequence - | FasterHealing - | Educated - | Tag diff --git a/src/Evergreen/V77/Data/Player.elm b/src/Evergreen/V77/Data/Player.elm deleted file mode 100644 index b453011b..00000000 --- a/src/Evergreen/V77/Data/Player.elm +++ /dev/null @@ -1,75 +0,0 @@ -module Evergreen.V77.Data.Player exposing (..) - -import AssocList -import AssocSet -import Dict -import Evergreen.V77.Data.Auth -import Evergreen.V77.Data.HealthStatus -import Evergreen.V77.Data.Item -import Evergreen.V77.Data.Map -import Evergreen.V77.Data.Message -import Evergreen.V77.Data.Perk -import Evergreen.V77.Data.Player.PlayerName -import Evergreen.V77.Data.Skill -import Evergreen.V77.Data.Special -import Evergreen.V77.Data.Trait -import Evergreen.V77.Data.Xp - - -type alias COtherPlayer = - { level : Evergreen.V77.Data.Xp.Level - , name : Evergreen.V77.Data.Player.PlayerName.PlayerName - , wins : Int - , losses : Int - , healthStatus : Evergreen.V77.Data.HealthStatus.HealthStatus - } - - -type alias CPlayer = - { hp : Int - , maxHp : Int - , xp : Evergreen.V77.Data.Xp.Xp - , name : Evergreen.V77.Data.Player.PlayerName.PlayerName - , baseSpecial : Evergreen.V77.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V77.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V77.Data.Perk.Perk Int - , messages : List Evergreen.V77.Data.Message.Message - , items : Dict.Dict Evergreen.V77.Data.Item.Id Evergreen.V77.Data.Item.Item - , traits : AssocSet.Set Evergreen.V77.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V77.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V77.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - } - - -type Player a - = NeedsCharCreated (Evergreen.V77.Data.Auth.Auth Evergreen.V77.Data.Auth.Verified) - | Player a - - -type alias SPlayer = - { name : Evergreen.V77.Data.Player.PlayerName.PlayerName - , password : Evergreen.V77.Data.Auth.Password Evergreen.V77.Data.Auth.Verified - , hp : Int - , maxHp : Int - , xp : Int - , baseSpecial : Evergreen.V77.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V77.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V77.Data.Perk.Perk Int - , messages : List Evergreen.V77.Data.Message.Message - , items : Dict.Dict Evergreen.V77.Data.Item.Id Evergreen.V77.Data.Item.Item - , traits : AssocSet.Set Evergreen.V77.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V77.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V77.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - } diff --git a/src/Evergreen/V77/Data/Player/PlayerName.elm b/src/Evergreen/V77/Data/Player/PlayerName.elm deleted file mode 100644 index 3ae101cb..00000000 --- a/src/Evergreen/V77/Data/Player/PlayerName.elm +++ /dev/null @@ -1,5 +0,0 @@ -module Evergreen.V77.Data.Player.PlayerName exposing (..) - - -type alias PlayerName = - String diff --git a/src/Evergreen/V77/Data/Skill.elm b/src/Evergreen/V77/Data/Skill.elm deleted file mode 100644 index 38b082f2..00000000 --- a/src/Evergreen/V77/Data/Skill.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V77.Data.Skill exposing (..) - - -type Skill - = SmallGuns - | BigGuns - | EnergyWeapons - | Unarmed - | MeleeWeapons - | Throwing - | FirstAid - | Doctor - | Sneak - | Lockpick - | Steal - | Traps - | Science - | Repair - | Speech - | Barter - | Gambling - | Outdoorsman diff --git a/src/Evergreen/V77/Data/Special.elm b/src/Evergreen/V77/Data/Special.elm deleted file mode 100644 index 9f802407..00000000 --- a/src/Evergreen/V77/Data/Special.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V77.Data.Special exposing (..) - - -type alias Special = - { strength : Int - , perception : Int - , endurance : Int - , charisma : Int - , intelligence : Int - , agility : Int - , luck : Int - } - - -type SpecialType - = Strength - | Perception - | Endurance - | Charisma - | Intelligence - | Agility - | Luck diff --git a/src/Evergreen/V77/Data/Trait.elm b/src/Evergreen/V77/Data/Trait.elm deleted file mode 100644 index 74a650f5..00000000 --- a/src/Evergreen/V77/Data/Trait.elm +++ /dev/null @@ -1,10 +0,0 @@ -module Evergreen.V77.Data.Trait exposing (..) - - -type Trait - = Kamikaze - | Bruiser - | Gifted - | SmallFrame - | Skilled - | HeavyHanded diff --git a/src/Evergreen/V77/Data/Vendor.elm b/src/Evergreen/V77/Data/Vendor.elm deleted file mode 100644 index 90ef9e80..00000000 --- a/src/Evergreen/V77/Data/Vendor.elm +++ /dev/null @@ -1,17 +0,0 @@ -module Evergreen.V77.Data.Vendor exposing (..) - -import Dict -import Evergreen.V77.Data.Item - - -type Name - = KlamathMaidaBuckner - | DenFlick - - -type alias Vendor = - { name : Name - , items : Dict.Dict Evergreen.V77.Data.Item.Id Evergreen.V77.Data.Item.Item - , caps : Int - , barterSkill : Int - } diff --git a/src/Evergreen/V77/Data/World.elm b/src/Evergreen/V77/Data/World.elm deleted file mode 100644 index 13da1b0f..00000000 --- a/src/Evergreen/V77/Data/World.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.V77.Data.World exposing (..) - -import AssocList -import Evergreen.V77.Data.Auth -import Evergreen.V77.Data.Player -import Evergreen.V77.Data.Player.PlayerName -import Evergreen.V77.Data.Vendor -import Time - - -type alias WorldLoggedOutData = - { players : List Evergreen.V77.Data.Player.COtherPlayer - } - - -type alias WorldLoggedInData = - { player : Evergreen.V77.Data.Player.Player Evergreen.V77.Data.Player.CPlayer - , otherPlayers : List Evergreen.V77.Data.Player.COtherPlayer - , playerRank : Int - , vendors : AssocList.Dict Evergreen.V77.Data.Vendor.Name Evergreen.V77.Data.Vendor.Vendor - } - - -type alias AdminData = - { players : List (Evergreen.V77.Data.Player.Player Evergreen.V77.Data.Player.SPlayer) - , loggedInPlayers : List Evergreen.V77.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - } - - -type World - = WorldNotInitialized (Evergreen.V77.Data.Auth.Auth Evergreen.V77.Data.Auth.Plaintext) - | WorldLoggedOut (Evergreen.V77.Data.Auth.Auth Evergreen.V77.Data.Auth.Plaintext) WorldLoggedOutData - | WorldLoggedIn WorldLoggedInData - | WorldAdmin AdminData diff --git a/src/Evergreen/V77/Data/Xp.elm b/src/Evergreen/V77/Data/Xp.elm deleted file mode 100644 index 1b7aa596..00000000 --- a/src/Evergreen/V77/Data/Xp.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V77.Data.Xp exposing (..) - - -type alias Level = - Int - - -type alias Xp = - Int diff --git a/src/Evergreen/V77/Frontend/Route.elm b/src/Evergreen/V77/Frontend/Route.elm deleted file mode 100644 index 46439fdd..00000000 --- a/src/Evergreen/V77/Frontend/Route.elm +++ /dev/null @@ -1,32 +0,0 @@ -module Evergreen.V77.Frontend.Route exposing (..) - -import Evergreen.V77.Data.Barter -import Evergreen.V77.Data.Fight -import Evergreen.V77.Data.Message - - -type TownRoute - = MainSquare - | Store - { barter : Evergreen.V77.Data.Barter.State - } - - -type AdminRoute - = Players - | LoggedIn - - -type Route - = Character - | Inventory - | Map - | Ladder - | Town TownRoute - | About - | News - | Fight Evergreen.V77.Data.Fight.FightInfo - | Messages - | Message Evergreen.V77.Data.Message.Message - | CharCreation - | Admin AdminRoute diff --git a/src/Evergreen/V77/Logic.elm b/src/Evergreen/V77/Logic.elm deleted file mode 100644 index 1cab94c2..00000000 --- a/src/Evergreen/V77/Logic.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V77.Logic exposing (..) - - -type alias AttackStats = - { minDamage : Int - , maxDamage : Int - , criticalChanceBonus : Int - } diff --git a/src/Evergreen/V77/Types.elm b/src/Evergreen/V77/Types.elm deleted file mode 100644 index b19138c9..00000000 --- a/src/Evergreen/V77/Types.elm +++ /dev/null @@ -1,156 +0,0 @@ -module Evergreen.V77.Types exposing (..) - -import AssocList -import Browser -import Browser.Navigation -import Dict -import Evergreen.V77.Data.Auth -import Evergreen.V77.Data.Barter -import Evergreen.V77.Data.Fight -import Evergreen.V77.Data.Fight.Generator -import Evergreen.V77.Data.Item -import Evergreen.V77.Data.Map -import Evergreen.V77.Data.Message -import Evergreen.V77.Data.NewChar -import Evergreen.V77.Data.Perk -import Evergreen.V77.Data.Player -import Evergreen.V77.Data.Player.PlayerName -import Evergreen.V77.Data.Skill -import Evergreen.V77.Data.Special -import Evergreen.V77.Data.Trait -import Evergreen.V77.Data.Vendor -import Evergreen.V77.Data.World -import Evergreen.V77.Frontend.Route -import File exposing (File) -import Lamdera -import Set -import Time -import Url - - -type alias FrontendModel = - { key : Browser.Navigation.Key - , time : Time.Posix - , zone : Time.Zone - , route : Evergreen.V77.Frontend.Route.Route - , world : Evergreen.V77.Data.World.World - , newChar : Evergreen.V77.Data.NewChar.NewChar - , alertMessage : Maybe String - , mapMouseCoords : Maybe ( Evergreen.V77.Data.Map.TileCoords, Set.Set Evergreen.V77.Data.Map.TileCoords ) - } - - -type alias BackendModel = - { players : Dict.Dict Evergreen.V77.Data.Player.PlayerName.PlayerName (Evergreen.V77.Data.Player.Player Evergreen.V77.Data.Player.SPlayer) - , loggedInPlayers : Dict.Dict Lamdera.ClientId Evergreen.V77.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - , adminLoggedIn : Maybe ( Lamdera.ClientId, Lamdera.SessionId ) - , time : Time.Posix - , vendors : AssocList.Dict Evergreen.V77.Data.Vendor.Name Evergreen.V77.Data.Vendor.Vendor - , lastItemId : Int - } - - -type BarterMsg - = AddPlayerItem Evergreen.V77.Data.Item.Id Int - | AddVendorItem Evergreen.V77.Data.Item.Id Int - | AddPlayerCaps Int - | AddVendorCaps Int - | RemovePlayerItem Evergreen.V77.Data.Item.Id Int - | RemoveVendorItem Evergreen.V77.Data.Item.Id Int - | RemovePlayerCaps Int - | RemoveVendorCaps Int - | ResetBarter - | ConfirmBarter - | SetTransferNInput Evergreen.V77.Data.Barter.TransferNPosition String - | SetTransferNHover Evergreen.V77.Data.Barter.TransferNPosition - | UnsetTransferNHover - - -type FrontendMsg - = UrlClicked Browser.UrlRequest - | UrlChanged Url.Url - | GoToRoute Evergreen.V77.Frontend.Route.Route - | Logout - | Login - | Register - | GotZone Time.Zone - | GotTime Time.Posix - | AskToFight Evergreen.V77.Data.Player.PlayerName.PlayerName - | AskToHeal - | AskToUseItem Evergreen.V77.Data.Item.Id - | AskToWander - | AskToChoosePerk Evergreen.V77.Data.Perk.Perk - | AskForExport - | ImportButtonClicked - | ImportFileSelected File - | AskToImport String - | Refresh - | AskToTagSkill Evergreen.V77.Data.Skill.Skill - | AskToUseSkillPoints Evergreen.V77.Data.Skill.Skill - | SetAuthName String - | SetAuthPassword String - | CreateChar - | NewCharIncSpecial Evergreen.V77.Data.Special.SpecialType - | NewCharDecSpecial Evergreen.V77.Data.Special.SpecialType - | NewCharToggleTaggedSkill Evergreen.V77.Data.Skill.Skill - | NewCharToggleTrait Evergreen.V77.Data.Trait.Trait - | MapMouseAtCoords Evergreen.V77.Data.Map.TileCoords - | MapMouseOut - | MapMouseClick - | OpenMessage Evergreen.V77.Data.Message.Message - | AskToRemoveMessage Evergreen.V77.Data.Message.Message - | BarterMsg BarterMsg - - -type AdminToBackend - = ExportJson - | ImportJson String - - -type ToBackend - = LogMeIn (Evergreen.V77.Data.Auth.Auth Evergreen.V77.Data.Auth.Hashed) - | RegisterMe (Evergreen.V77.Data.Auth.Auth Evergreen.V77.Data.Auth.Hashed) - | CreateNewChar Evergreen.V77.Data.NewChar.NewChar - | LogMeOut - | Fight Evergreen.V77.Data.Player.PlayerName.PlayerName - | HealMe - | UseItem Evergreen.V77.Data.Item.Id - | Wander - | RefreshPlease - | TagSkill Evergreen.V77.Data.Skill.Skill - | UseSkillPoints Evergreen.V77.Data.Skill.Skill - | ChoosePerk Evergreen.V77.Data.Perk.Perk - | MoveTo Evergreen.V77.Data.Map.TileCoords (Set.Set Evergreen.V77.Data.Map.TileCoords) - | MessageWasRead Evergreen.V77.Data.Message.Message - | RemoveMessage Evergreen.V77.Data.Message.Message - | Barter Evergreen.V77.Data.Barter.State - | AdminToBackend AdminToBackend - - -type BackendMsg - = Connected Lamdera.SessionId Lamdera.ClientId - | Disconnected Lamdera.SessionId Lamdera.ClientId - | GeneratedFight Lamdera.ClientId Evergreen.V77.Data.Player.SPlayer Evergreen.V77.Data.Fight.Generator.Fight - | GeneratedNewVendorsStock ( AssocList.Dict Evergreen.V77.Data.Vendor.Name Evergreen.V77.Data.Vendor.Vendor, Int ) - | Tick Time.Posix - | CreateNewCharWithTime Lamdera.ClientId Evergreen.V77.Data.NewChar.NewChar Time.Posix - | LoggedToBackendMsg - - -type ToFrontend - = YourCurrentWorld Evergreen.V77.Data.World.WorldLoggedInData - | InitWorld Evergreen.V77.Data.World.WorldLoggedOutData - | RefreshedLoggedOut Evergreen.V77.Data.World.WorldLoggedOutData - | CurrentAdminData Evergreen.V77.Data.World.AdminData - | YourFightResult ( Evergreen.V77.Data.Fight.FightInfo, Evergreen.V77.Data.World.WorldLoggedInData ) - | YoureLoggedIn Evergreen.V77.Data.World.WorldLoggedInData - | YoureRegistered Evergreen.V77.Data.World.WorldLoggedInData - | CharCreationError Evergreen.V77.Data.NewChar.CreationError - | YouHaveCreatedChar Evergreen.V77.Data.World.WorldLoggedInData - | YoureLoggedOut Evergreen.V77.Data.World.WorldLoggedOutData - | AlertMessage String - | YoureLoggedInAsAdmin Evergreen.V77.Data.World.AdminData - | JsonExportDone String - | BarterDone ( Evergreen.V77.Data.World.WorldLoggedInData, Maybe Evergreen.V77.Data.Barter.Message ) - | BarterMessage Evergreen.V77.Data.Barter.Message diff --git a/src/Evergreen/V78/Data/Auth.elm b/src/Evergreen/V78/Data/Auth.elm deleted file mode 100644 index 1d888c86..00000000 --- a/src/Evergreen/V78/Data/Auth.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V78.Data.Auth exposing (..) - - -type Plaintext - = Plaintext - - -type Password a - = Password String - - -type alias Auth a = - { name : String - , password : Password a - } - - -type Verified - = Verified - - -type Hashed - = Hashed diff --git a/src/Evergreen/V78/Data/Barter.elm b/src/Evergreen/V78/Data/Barter.elm deleted file mode 100644 index a2de5bc6..00000000 --- a/src/Evergreen/V78/Data/Barter.elm +++ /dev/null @@ -1,33 +0,0 @@ -module Evergreen.V78.Data.Barter exposing (..) - -import AssocList -import Dict -import Evergreen.V78.Data.Item - - -type Message - = BarterIsEmpty - | PlayerOfferNotValuableEnough - | YouGaveStuffForFree - - -type TransferNPosition - = PlayerKeptItem Evergreen.V78.Data.Item.Id - | VendorKeptItem Evergreen.V78.Data.Item.Id - | PlayerTradedItem Evergreen.V78.Data.Item.Id - | VendorTradedItem Evergreen.V78.Data.Item.Id - | PlayerKeptCaps - | VendorKeptCaps - | PlayerTradedCaps - | VendorTradedCaps - - -type alias State = - { playerItems : Dict.Dict Evergreen.V78.Data.Item.Id Int - , vendorItems : Dict.Dict Evergreen.V78.Data.Item.Id Int - , playerCaps : Int - , vendorCaps : Int - , lastMessage : Maybe Message - , transferNInputs : AssocList.Dict TransferNPosition String - , transferNHover : Maybe TransferNPosition - } diff --git a/src/Evergreen/V78/Data/Enemy.elm b/src/Evergreen/V78/Data/Enemy.elm deleted file mode 100644 index b27d27db..00000000 --- a/src/Evergreen/V78/Data/Enemy.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V78.Data.Enemy exposing (..) - - -type Type - = GiantAnt - | ToughGiantAnt - | LesserRadscorpion - | Radscorpion diff --git a/src/Evergreen/V78/Data/Fight.elm b/src/Evergreen/V78/Data/Fight.elm deleted file mode 100644 index 8930889c..00000000 --- a/src/Evergreen/V78/Data/Fight.elm +++ /dev/null @@ -1,78 +0,0 @@ -module Evergreen.V78.Data.Fight exposing (..) - -import AssocList -import AssocSet -import Evergreen.V78.Data.Enemy -import Evergreen.V78.Data.Fight.ShotType -import Evergreen.V78.Data.Perk -import Evergreen.V78.Data.Player.PlayerName -import Evergreen.V78.Data.Skill -import Evergreen.V78.Data.Special -import Evergreen.V78.Data.Trait -import Evergreen.V78.Logic - - -type OpponentType - = Npc Evergreen.V78.Data.Enemy.Type - | Player Evergreen.V78.Data.Player.PlayerName.PlayerName - - -type Who - = Attacker - | Target - - -type FightAction - = Start - { distanceHexes : Int - } - | ComeCloser - { hexes : Int - , remainingDistanceHexes : Int - } - | Attack - { damage : Int - , shotType : Evergreen.V78.Data.Fight.ShotType.ShotType - , remainingHp : Int - } - | Miss - { shotType : Evergreen.V78.Data.Fight.ShotType.ShotType - } - - -type FightResult - = AttackerWon - { xpGained : Int - , capsGained : Int - } - | TargetWon - { xpGained : Int - , capsGained : Int - } - | TargetAlreadyDead - | BothDead - | NobodyDead - - -type alias FightInfo = - { attacker : OpponentType - , target : OpponentType - , log : List ( Who, FightAction ) - , result : FightResult - } - - -type alias Opponent = - { type_ : OpponentType - , hp : Int - , maxHp : Int - , maxAp : Int - , sequence : Int - , traits : AssocSet.Set Evergreen.V78.Data.Trait.Trait - , perks : AssocList.Dict Evergreen.V78.Data.Perk.Perk Int - , caps : Int - , armorClass : Int - , attackStats : Evergreen.V78.Logic.AttackStats - , addedSkillPercentages : AssocList.Dict Evergreen.V78.Data.Skill.Skill Int - , baseSpecial : Evergreen.V78.Data.Special.Special - } diff --git a/src/Evergreen/V78/Data/Fight/Generator.elm b/src/Evergreen/V78/Data/Fight/Generator.elm deleted file mode 100644 index 846a7c72..00000000 --- a/src/Evergreen/V78/Data/Fight/Generator.elm +++ /dev/null @@ -1,12 +0,0 @@ -module Evergreen.V78.Data.Fight.Generator exposing (..) - -import Evergreen.V78.Data.Fight -import Evergreen.V78.Data.Message - - -type alias Fight = - { finalAttacker : Evergreen.V78.Data.Fight.Opponent - , finalTarget : Evergreen.V78.Data.Fight.Opponent - , fightInfo : Evergreen.V78.Data.Fight.FightInfo - , messageForTarget : Evergreen.V78.Data.Message.Message - } diff --git a/src/Evergreen/V78/Data/Fight/ShotType.elm b/src/Evergreen/V78/Data/Fight/ShotType.elm deleted file mode 100644 index 08f22020..00000000 --- a/src/Evergreen/V78/Data/Fight/ShotType.elm +++ /dev/null @@ -1,17 +0,0 @@ -module Evergreen.V78.Data.Fight.ShotType exposing (..) - - -type AimedShot - = Head - | Torso - | Eyes - | Groin - | LeftArm - | RightArm - | LeftLeg - | RightLeg - - -type ShotType - = NormalShot - | AimedShot AimedShot diff --git a/src/Evergreen/V78/Data/HealthStatus.elm b/src/Evergreen/V78/Data/HealthStatus.elm deleted file mode 100644 index 0e026f4b..00000000 --- a/src/Evergreen/V78/Data/HealthStatus.elm +++ /dev/null @@ -1,16 +0,0 @@ -module Evergreen.V78.Data.HealthStatus exposing (..) - - -type HealthStatus - = ExactHp - { current : Int - , max : Int - } - | Unhurt - | SlightlyWounded - | Wounded - | SeverelyWounded - | AlmostDead - | Dead - | Alive - | Unknown diff --git a/src/Evergreen/V78/Data/Item.elm b/src/Evergreen/V78/Data/Item.elm deleted file mode 100644 index b240df48..00000000 --- a/src/Evergreen/V78/Data/Item.elm +++ /dev/null @@ -1,21 +0,0 @@ -module Evergreen.V78.Data.Item exposing (..) - - -type alias Id = - Int - - -type Kind - = Stimpak - | BigBookOfScience - | DeansElectronics - | FirstAidBook - | GunsAndBullets - | ScoutHandbook - - -type alias Item = - { id : Id - , kind : Kind - , count : Int - } diff --git a/src/Evergreen/V78/Data/Map.elm b/src/Evergreen/V78/Data/Map.elm deleted file mode 100644 index 33847e3e..00000000 --- a/src/Evergreen/V78/Data/Map.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V78.Data.Map exposing (..) - - -type alias TileNum = - Int - - -type alias TileCoords = - ( Int, Int ) diff --git a/src/Evergreen/V78/Data/Message.elm b/src/Evergreen/V78/Data/Message.elm deleted file mode 100644 index 5e0df3e5..00000000 --- a/src/Evergreen/V78/Data/Message.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V78.Data.Message exposing (..) - -import Evergreen.V78.Data.Fight -import Evergreen.V78.Data.Player.PlayerName -import Time - - -type Type - = Welcome - | YouAdvancedLevel - { newLevel : Int - } - | YouWereAttacked - { attacker : Evergreen.V78.Data.Player.PlayerName.PlayerName - , fightInfo : Evergreen.V78.Data.Fight.FightInfo - } - - -type alias Message = - { type_ : Type - , hasBeenRead : Bool - , date : Time.Posix - } diff --git a/src/Evergreen/V78/Data/NewChar.elm b/src/Evergreen/V78/Data/NewChar.elm deleted file mode 100644 index dc972a17..00000000 --- a/src/Evergreen/V78/Data/NewChar.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V78.Data.NewChar exposing (..) - -import AssocSet -import Evergreen.V78.Data.Skill -import Evergreen.V78.Data.Special -import Evergreen.V78.Data.Trait - - -type CreationError - = DoesNotHaveThreeTaggedSkills - | HasSpecialPointsLeft - | UsedMoreSpecialPointsThanAvailable - | HasSpecialOutOfRange - | HasMoreThanTwoTraits - - -type alias NewChar = - { baseSpecial : Evergreen.V78.Data.Special.Special - , availableSpecial : Int - , taggedSkills : AssocSet.Set Evergreen.V78.Data.Skill.Skill - , traits : AssocSet.Set Evergreen.V78.Data.Trait.Trait - , error : Maybe CreationError - } diff --git a/src/Evergreen/V78/Data/Perk.elm b/src/Evergreen/V78/Data/Perk.elm deleted file mode 100644 index ec80ff6d..00000000 --- a/src/Evergreen/V78/Data/Perk.elm +++ /dev/null @@ -1,15 +0,0 @@ -module Evergreen.V78.Data.Perk exposing (..) - - -type Perk - = BonusHthDamage - | MasterTrader - | Awareness - | CautiousNature - | Comprehension - | EarlierSequence - | FasterHealing - | HereAndNow - | Survivalist - | Educated - | Tag diff --git a/src/Evergreen/V78/Data/Player.elm b/src/Evergreen/V78/Data/Player.elm deleted file mode 100644 index 4ceeceef..00000000 --- a/src/Evergreen/V78/Data/Player.elm +++ /dev/null @@ -1,75 +0,0 @@ -module Evergreen.V78.Data.Player exposing (..) - -import AssocList -import AssocSet -import Dict -import Evergreen.V78.Data.Auth -import Evergreen.V78.Data.HealthStatus -import Evergreen.V78.Data.Item -import Evergreen.V78.Data.Map -import Evergreen.V78.Data.Message -import Evergreen.V78.Data.Perk -import Evergreen.V78.Data.Player.PlayerName -import Evergreen.V78.Data.Skill -import Evergreen.V78.Data.Special -import Evergreen.V78.Data.Trait -import Evergreen.V78.Data.Xp - - -type alias COtherPlayer = - { level : Evergreen.V78.Data.Xp.Level - , name : Evergreen.V78.Data.Player.PlayerName.PlayerName - , wins : Int - , losses : Int - , healthStatus : Evergreen.V78.Data.HealthStatus.HealthStatus - } - - -type alias CPlayer = - { hp : Int - , maxHp : Int - , xp : Evergreen.V78.Data.Xp.Xp - , name : Evergreen.V78.Data.Player.PlayerName.PlayerName - , baseSpecial : Evergreen.V78.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V78.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V78.Data.Perk.Perk Int - , messages : List Evergreen.V78.Data.Message.Message - , items : Dict.Dict Evergreen.V78.Data.Item.Id Evergreen.V78.Data.Item.Item - , traits : AssocSet.Set Evergreen.V78.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V78.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V78.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - } - - -type Player a - = NeedsCharCreated (Evergreen.V78.Data.Auth.Auth Evergreen.V78.Data.Auth.Verified) - | Player a - - -type alias SPlayer = - { name : Evergreen.V78.Data.Player.PlayerName.PlayerName - , password : Evergreen.V78.Data.Auth.Password Evergreen.V78.Data.Auth.Verified - , hp : Int - , maxHp : Int - , xp : Int - , baseSpecial : Evergreen.V78.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V78.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V78.Data.Perk.Perk Int - , messages : List Evergreen.V78.Data.Message.Message - , items : Dict.Dict Evergreen.V78.Data.Item.Id Evergreen.V78.Data.Item.Item - , traits : AssocSet.Set Evergreen.V78.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V78.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V78.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - } diff --git a/src/Evergreen/V78/Data/Player/PlayerName.elm b/src/Evergreen/V78/Data/Player/PlayerName.elm deleted file mode 100644 index c542e358..00000000 --- a/src/Evergreen/V78/Data/Player/PlayerName.elm +++ /dev/null @@ -1,5 +0,0 @@ -module Evergreen.V78.Data.Player.PlayerName exposing (..) - - -type alias PlayerName = - String diff --git a/src/Evergreen/V78/Data/Skill.elm b/src/Evergreen/V78/Data/Skill.elm deleted file mode 100644 index 41d44e26..00000000 --- a/src/Evergreen/V78/Data/Skill.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V78.Data.Skill exposing (..) - - -type Skill - = SmallGuns - | BigGuns - | EnergyWeapons - | Unarmed - | MeleeWeapons - | Throwing - | FirstAid - | Doctor - | Sneak - | Lockpick - | Steal - | Traps - | Science - | Repair - | Speech - | Barter - | Gambling - | Outdoorsman diff --git a/src/Evergreen/V78/Data/Special.elm b/src/Evergreen/V78/Data/Special.elm deleted file mode 100644 index 7341108c..00000000 --- a/src/Evergreen/V78/Data/Special.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V78.Data.Special exposing (..) - - -type alias Special = - { strength : Int - , perception : Int - , endurance : Int - , charisma : Int - , intelligence : Int - , agility : Int - , luck : Int - } - - -type SpecialType - = Strength - | Perception - | Endurance - | Charisma - | Intelligence - | Agility - | Luck diff --git a/src/Evergreen/V78/Data/Trait.elm b/src/Evergreen/V78/Data/Trait.elm deleted file mode 100644 index 22293461..00000000 --- a/src/Evergreen/V78/Data/Trait.elm +++ /dev/null @@ -1,10 +0,0 @@ -module Evergreen.V78.Data.Trait exposing (..) - - -type Trait - = Kamikaze - | Bruiser - | Gifted - | SmallFrame - | Skilled - | HeavyHanded diff --git a/src/Evergreen/V78/Data/Vendor.elm b/src/Evergreen/V78/Data/Vendor.elm deleted file mode 100644 index 8df84da7..00000000 --- a/src/Evergreen/V78/Data/Vendor.elm +++ /dev/null @@ -1,17 +0,0 @@ -module Evergreen.V78.Data.Vendor exposing (..) - -import Dict -import Evergreen.V78.Data.Item - - -type Name - = KlamathMaidaBuckner - | DenFlick - - -type alias Vendor = - { name : Name - , items : Dict.Dict Evergreen.V78.Data.Item.Id Evergreen.V78.Data.Item.Item - , caps : Int - , barterSkill : Int - } diff --git a/src/Evergreen/V78/Data/World.elm b/src/Evergreen/V78/Data/World.elm deleted file mode 100644 index ef682238..00000000 --- a/src/Evergreen/V78/Data/World.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.V78.Data.World exposing (..) - -import AssocList -import Evergreen.V78.Data.Auth -import Evergreen.V78.Data.Player -import Evergreen.V78.Data.Player.PlayerName -import Evergreen.V78.Data.Vendor -import Time - - -type alias WorldLoggedOutData = - { players : List Evergreen.V78.Data.Player.COtherPlayer - } - - -type alias WorldLoggedInData = - { player : Evergreen.V78.Data.Player.Player Evergreen.V78.Data.Player.CPlayer - , otherPlayers : List Evergreen.V78.Data.Player.COtherPlayer - , playerRank : Int - , vendors : AssocList.Dict Evergreen.V78.Data.Vendor.Name Evergreen.V78.Data.Vendor.Vendor - } - - -type alias AdminData = - { players : List (Evergreen.V78.Data.Player.Player Evergreen.V78.Data.Player.SPlayer) - , loggedInPlayers : List Evergreen.V78.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - } - - -type World - = WorldNotInitialized (Evergreen.V78.Data.Auth.Auth Evergreen.V78.Data.Auth.Plaintext) - | WorldLoggedOut (Evergreen.V78.Data.Auth.Auth Evergreen.V78.Data.Auth.Plaintext) WorldLoggedOutData - | WorldLoggedIn WorldLoggedInData - | WorldAdmin AdminData diff --git a/src/Evergreen/V78/Data/Xp.elm b/src/Evergreen/V78/Data/Xp.elm deleted file mode 100644 index 8c67920d..00000000 --- a/src/Evergreen/V78/Data/Xp.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V78.Data.Xp exposing (..) - - -type alias Level = - Int - - -type alias Xp = - Int diff --git a/src/Evergreen/V78/Frontend/Route.elm b/src/Evergreen/V78/Frontend/Route.elm deleted file mode 100644 index eb28ef6c..00000000 --- a/src/Evergreen/V78/Frontend/Route.elm +++ /dev/null @@ -1,32 +0,0 @@ -module Evergreen.V78.Frontend.Route exposing (..) - -import Evergreen.V78.Data.Barter -import Evergreen.V78.Data.Fight -import Evergreen.V78.Data.Message - - -type TownRoute - = MainSquare - | Store - { barter : Evergreen.V78.Data.Barter.State - } - - -type AdminRoute - = Players - | LoggedIn - - -type Route - = Character - | Inventory - | Map - | Ladder - | Town TownRoute - | About - | News - | Fight Evergreen.V78.Data.Fight.FightInfo - | Messages - | Message Evergreen.V78.Data.Message.Message - | CharCreation - | Admin AdminRoute diff --git a/src/Evergreen/V78/Logic.elm b/src/Evergreen/V78/Logic.elm deleted file mode 100644 index ebb8ab7c..00000000 --- a/src/Evergreen/V78/Logic.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V78.Logic exposing (..) - - -type alias AttackStats = - { minDamage : Int - , maxDamage : Int - , criticalChanceBonus : Int - } diff --git a/src/Evergreen/V78/Types.elm b/src/Evergreen/V78/Types.elm deleted file mode 100644 index 37e3663c..00000000 --- a/src/Evergreen/V78/Types.elm +++ /dev/null @@ -1,156 +0,0 @@ -module Evergreen.V78.Types exposing (..) - -import AssocList -import Browser -import Browser.Navigation -import Dict -import Evergreen.V78.Data.Auth -import Evergreen.V78.Data.Barter -import Evergreen.V78.Data.Fight -import Evergreen.V78.Data.Fight.Generator -import Evergreen.V78.Data.Item -import Evergreen.V78.Data.Map -import Evergreen.V78.Data.Message -import Evergreen.V78.Data.NewChar -import Evergreen.V78.Data.Perk -import Evergreen.V78.Data.Player -import Evergreen.V78.Data.Player.PlayerName -import Evergreen.V78.Data.Skill -import Evergreen.V78.Data.Special -import Evergreen.V78.Data.Trait -import Evergreen.V78.Data.Vendor -import Evergreen.V78.Data.World -import Evergreen.V78.Frontend.Route -import File exposing (File) -import Lamdera -import Set -import Time -import Url - - -type alias FrontendModel = - { key : Browser.Navigation.Key - , time : Time.Posix - , zone : Time.Zone - , route : Evergreen.V78.Frontend.Route.Route - , world : Evergreen.V78.Data.World.World - , newChar : Evergreen.V78.Data.NewChar.NewChar - , alertMessage : Maybe String - , mapMouseCoords : Maybe ( Evergreen.V78.Data.Map.TileCoords, Set.Set Evergreen.V78.Data.Map.TileCoords ) - } - - -type alias BackendModel = - { players : Dict.Dict Evergreen.V78.Data.Player.PlayerName.PlayerName (Evergreen.V78.Data.Player.Player Evergreen.V78.Data.Player.SPlayer) - , loggedInPlayers : Dict.Dict Lamdera.ClientId Evergreen.V78.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - , adminLoggedIn : Maybe ( Lamdera.ClientId, Lamdera.SessionId ) - , time : Time.Posix - , vendors : AssocList.Dict Evergreen.V78.Data.Vendor.Name Evergreen.V78.Data.Vendor.Vendor - , lastItemId : Int - } - - -type BarterMsg - = AddPlayerItem Evergreen.V78.Data.Item.Id Int - | AddVendorItem Evergreen.V78.Data.Item.Id Int - | AddPlayerCaps Int - | AddVendorCaps Int - | RemovePlayerItem Evergreen.V78.Data.Item.Id Int - | RemoveVendorItem Evergreen.V78.Data.Item.Id Int - | RemovePlayerCaps Int - | RemoveVendorCaps Int - | ResetBarter - | ConfirmBarter - | SetTransferNInput Evergreen.V78.Data.Barter.TransferNPosition String - | SetTransferNHover Evergreen.V78.Data.Barter.TransferNPosition - | UnsetTransferNHover - - -type FrontendMsg - = UrlClicked Browser.UrlRequest - | UrlChanged Url.Url - | GoToRoute Evergreen.V78.Frontend.Route.Route - | Logout - | Login - | Register - | GotZone Time.Zone - | GotTime Time.Posix - | AskToFight Evergreen.V78.Data.Player.PlayerName.PlayerName - | AskToHeal - | AskToUseItem Evergreen.V78.Data.Item.Id - | AskToWander - | AskToChoosePerk Evergreen.V78.Data.Perk.Perk - | AskForExport - | ImportButtonClicked - | ImportFileSelected File - | AskToImport String - | Refresh - | AskToTagSkill Evergreen.V78.Data.Skill.Skill - | AskToUseSkillPoints Evergreen.V78.Data.Skill.Skill - | SetAuthName String - | SetAuthPassword String - | CreateChar - | NewCharIncSpecial Evergreen.V78.Data.Special.SpecialType - | NewCharDecSpecial Evergreen.V78.Data.Special.SpecialType - | NewCharToggleTaggedSkill Evergreen.V78.Data.Skill.Skill - | NewCharToggleTrait Evergreen.V78.Data.Trait.Trait - | MapMouseAtCoords Evergreen.V78.Data.Map.TileCoords - | MapMouseOut - | MapMouseClick - | OpenMessage Evergreen.V78.Data.Message.Message - | AskToRemoveMessage Evergreen.V78.Data.Message.Message - | BarterMsg BarterMsg - - -type AdminToBackend - = ExportJson - | ImportJson String - - -type ToBackend - = LogMeIn (Evergreen.V78.Data.Auth.Auth Evergreen.V78.Data.Auth.Hashed) - | RegisterMe (Evergreen.V78.Data.Auth.Auth Evergreen.V78.Data.Auth.Hashed) - | CreateNewChar Evergreen.V78.Data.NewChar.NewChar - | LogMeOut - | Fight Evergreen.V78.Data.Player.PlayerName.PlayerName - | HealMe - | UseItem Evergreen.V78.Data.Item.Id - | Wander - | RefreshPlease - | TagSkill Evergreen.V78.Data.Skill.Skill - | UseSkillPoints Evergreen.V78.Data.Skill.Skill - | ChoosePerk Evergreen.V78.Data.Perk.Perk - | MoveTo Evergreen.V78.Data.Map.TileCoords (Set.Set Evergreen.V78.Data.Map.TileCoords) - | MessageWasRead Evergreen.V78.Data.Message.Message - | RemoveMessage Evergreen.V78.Data.Message.Message - | Barter Evergreen.V78.Data.Barter.State - | AdminToBackend AdminToBackend - - -type BackendMsg - = Connected Lamdera.SessionId Lamdera.ClientId - | Disconnected Lamdera.SessionId Lamdera.ClientId - | GeneratedFight Lamdera.ClientId Evergreen.V78.Data.Player.SPlayer Evergreen.V78.Data.Fight.Generator.Fight - | GeneratedNewVendorsStock ( AssocList.Dict Evergreen.V78.Data.Vendor.Name Evergreen.V78.Data.Vendor.Vendor, Int ) - | Tick Time.Posix - | CreateNewCharWithTime Lamdera.ClientId Evergreen.V78.Data.NewChar.NewChar Time.Posix - | LoggedToBackendMsg - - -type ToFrontend - = YourCurrentWorld Evergreen.V78.Data.World.WorldLoggedInData - | InitWorld Evergreen.V78.Data.World.WorldLoggedOutData - | RefreshedLoggedOut Evergreen.V78.Data.World.WorldLoggedOutData - | CurrentAdminData Evergreen.V78.Data.World.AdminData - | YourFightResult ( Evergreen.V78.Data.Fight.FightInfo, Evergreen.V78.Data.World.WorldLoggedInData ) - | YoureLoggedIn Evergreen.V78.Data.World.WorldLoggedInData - | YoureRegistered Evergreen.V78.Data.World.WorldLoggedInData - | CharCreationError Evergreen.V78.Data.NewChar.CreationError - | YouHaveCreatedChar Evergreen.V78.Data.World.WorldLoggedInData - | YoureLoggedOut Evergreen.V78.Data.World.WorldLoggedOutData - | AlertMessage String - | YoureLoggedInAsAdmin Evergreen.V78.Data.World.AdminData - | JsonExportDone String - | BarterDone ( Evergreen.V78.Data.World.WorldLoggedInData, Maybe Evergreen.V78.Data.Barter.Message ) - | BarterMessage Evergreen.V78.Data.Barter.Message diff --git a/src/Evergreen/V79/Data/Auth.elm b/src/Evergreen/V79/Data/Auth.elm deleted file mode 100644 index 21d2670c..00000000 --- a/src/Evergreen/V79/Data/Auth.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V79.Data.Auth exposing (..) - - -type Plaintext - = Plaintext - - -type Password a - = Password String - - -type alias Auth a = - { name : String - , password : Password a - } - - -type Verified - = Verified - - -type Hashed - = Hashed diff --git a/src/Evergreen/V79/Data/Barter.elm b/src/Evergreen/V79/Data/Barter.elm deleted file mode 100644 index 9c77990e..00000000 --- a/src/Evergreen/V79/Data/Barter.elm +++ /dev/null @@ -1,33 +0,0 @@ -module Evergreen.V79.Data.Barter exposing (..) - -import AssocList -import Dict -import Evergreen.V79.Data.Item - - -type Message - = BarterIsEmpty - | PlayerOfferNotValuableEnough - | YouGaveStuffForFree - - -type TransferNPosition - = PlayerKeptItem Evergreen.V79.Data.Item.Id - | VendorKeptItem Evergreen.V79.Data.Item.Id - | PlayerTradedItem Evergreen.V79.Data.Item.Id - | VendorTradedItem Evergreen.V79.Data.Item.Id - | PlayerKeptCaps - | VendorKeptCaps - | PlayerTradedCaps - | VendorTradedCaps - - -type alias State = - { playerItems : Dict.Dict Evergreen.V79.Data.Item.Id Int - , vendorItems : Dict.Dict Evergreen.V79.Data.Item.Id Int - , playerCaps : Int - , vendorCaps : Int - , lastMessage : Maybe Message - , transferNInputs : AssocList.Dict TransferNPosition String - , transferNHover : Maybe TransferNPosition - } diff --git a/src/Evergreen/V79/Data/Enemy.elm b/src/Evergreen/V79/Data/Enemy.elm deleted file mode 100644 index 21a34ab4..00000000 --- a/src/Evergreen/V79/Data/Enemy.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V79.Data.Enemy exposing (..) - - -type Type - = GiantAnt - | ToughGiantAnt - | LesserRadscorpion - | Radscorpion diff --git a/src/Evergreen/V79/Data/Fight.elm b/src/Evergreen/V79/Data/Fight.elm deleted file mode 100644 index 037e4d4b..00000000 --- a/src/Evergreen/V79/Data/Fight.elm +++ /dev/null @@ -1,78 +0,0 @@ -module Evergreen.V79.Data.Fight exposing (..) - -import AssocList -import AssocSet -import Evergreen.V79.Data.Enemy -import Evergreen.V79.Data.Fight.ShotType -import Evergreen.V79.Data.Perk -import Evergreen.V79.Data.Player.PlayerName -import Evergreen.V79.Data.Skill -import Evergreen.V79.Data.Special -import Evergreen.V79.Data.Trait -import Evergreen.V79.Logic - - -type OpponentType - = Npc Evergreen.V79.Data.Enemy.Type - | Player Evergreen.V79.Data.Player.PlayerName.PlayerName - - -type Who - = Attacker - | Target - - -type FightAction - = Start - { distanceHexes : Int - } - | ComeCloser - { hexes : Int - , remainingDistanceHexes : Int - } - | Attack - { damage : Int - , shotType : Evergreen.V79.Data.Fight.ShotType.ShotType - , remainingHp : Int - } - | Miss - { shotType : Evergreen.V79.Data.Fight.ShotType.ShotType - } - - -type FightResult - = AttackerWon - { xpGained : Int - , capsGained : Int - } - | TargetWon - { xpGained : Int - , capsGained : Int - } - | TargetAlreadyDead - | BothDead - | NobodyDead - - -type alias FightInfo = - { attacker : OpponentType - , target : OpponentType - , log : List ( Who, FightAction ) - , result : FightResult - } - - -type alias Opponent = - { type_ : OpponentType - , hp : Int - , maxHp : Int - , maxAp : Int - , sequence : Int - , traits : AssocSet.Set Evergreen.V79.Data.Trait.Trait - , perks : AssocList.Dict Evergreen.V79.Data.Perk.Perk Int - , caps : Int - , armorClass : Int - , attackStats : Evergreen.V79.Logic.AttackStats - , addedSkillPercentages : AssocList.Dict Evergreen.V79.Data.Skill.Skill Int - , special : Evergreen.V79.Data.Special.Special - } diff --git a/src/Evergreen/V79/Data/Fight/Generator.elm b/src/Evergreen/V79/Data/Fight/Generator.elm deleted file mode 100644 index 08040bb8..00000000 --- a/src/Evergreen/V79/Data/Fight/Generator.elm +++ /dev/null @@ -1,12 +0,0 @@ -module Evergreen.V79.Data.Fight.Generator exposing (..) - -import Evergreen.V79.Data.Fight -import Evergreen.V79.Data.Message - - -type alias Fight = - { finalAttacker : Evergreen.V79.Data.Fight.Opponent - , finalTarget : Evergreen.V79.Data.Fight.Opponent - , fightInfo : Evergreen.V79.Data.Fight.FightInfo - , messageForTarget : Evergreen.V79.Data.Message.Message - } diff --git a/src/Evergreen/V79/Data/Fight/ShotType.elm b/src/Evergreen/V79/Data/Fight/ShotType.elm deleted file mode 100644 index 8f785b53..00000000 --- a/src/Evergreen/V79/Data/Fight/ShotType.elm +++ /dev/null @@ -1,17 +0,0 @@ -module Evergreen.V79.Data.Fight.ShotType exposing (..) - - -type AimedShot - = Head - | Torso - | Eyes - | Groin - | LeftArm - | RightArm - | LeftLeg - | RightLeg - - -type ShotType - = NormalShot - | AimedShot AimedShot diff --git a/src/Evergreen/V79/Data/HealthStatus.elm b/src/Evergreen/V79/Data/HealthStatus.elm deleted file mode 100644 index 0f648ea1..00000000 --- a/src/Evergreen/V79/Data/HealthStatus.elm +++ /dev/null @@ -1,16 +0,0 @@ -module Evergreen.V79.Data.HealthStatus exposing (..) - - -type HealthStatus - = ExactHp - { current : Int - , max : Int - } - | Unhurt - | SlightlyWounded - | Wounded - | SeverelyWounded - | AlmostDead - | Dead - | Alive - | Unknown diff --git a/src/Evergreen/V79/Data/Item.elm b/src/Evergreen/V79/Data/Item.elm deleted file mode 100644 index 1288aec3..00000000 --- a/src/Evergreen/V79/Data/Item.elm +++ /dev/null @@ -1,21 +0,0 @@ -module Evergreen.V79.Data.Item exposing (..) - - -type alias Id = - Int - - -type Kind - = Stimpak - | BigBookOfScience - | DeansElectronics - | FirstAidBook - | GunsAndBullets - | ScoutHandbook - - -type alias Item = - { id : Id - , kind : Kind - , count : Int - } diff --git a/src/Evergreen/V79/Data/Map.elm b/src/Evergreen/V79/Data/Map.elm deleted file mode 100644 index eb9ad4ff..00000000 --- a/src/Evergreen/V79/Data/Map.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V79.Data.Map exposing (..) - - -type alias TileNum = - Int - - -type alias TileCoords = - ( Int, Int ) diff --git a/src/Evergreen/V79/Data/Message.elm b/src/Evergreen/V79/Data/Message.elm deleted file mode 100644 index c0d19ffa..00000000 --- a/src/Evergreen/V79/Data/Message.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V79.Data.Message exposing (..) - -import Evergreen.V79.Data.Fight -import Evergreen.V79.Data.Player.PlayerName -import Time - - -type Type - = Welcome - | YouAdvancedLevel - { newLevel : Int - } - | YouWereAttacked - { attacker : Evergreen.V79.Data.Player.PlayerName.PlayerName - , fightInfo : Evergreen.V79.Data.Fight.FightInfo - } - - -type alias Message = - { type_ : Type - , hasBeenRead : Bool - , date : Time.Posix - } diff --git a/src/Evergreen/V79/Data/NewChar.elm b/src/Evergreen/V79/Data/NewChar.elm deleted file mode 100644 index f0e3454e..00000000 --- a/src/Evergreen/V79/Data/NewChar.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V79.Data.NewChar exposing (..) - -import AssocSet -import Evergreen.V79.Data.Skill -import Evergreen.V79.Data.Special -import Evergreen.V79.Data.Trait - - -type CreationError - = DoesNotHaveThreeTaggedSkills - | HasSpecialPointsLeft - | UsedMoreSpecialPointsThanAvailable - | HasSpecialOutOfRange - | HasMoreThanTwoTraits - - -type alias NewChar = - { baseSpecial : Evergreen.V79.Data.Special.Special - , availableSpecial : Int - , taggedSkills : AssocSet.Set Evergreen.V79.Data.Skill.Skill - , traits : AssocSet.Set Evergreen.V79.Data.Trait.Trait - , error : Maybe CreationError - } diff --git a/src/Evergreen/V79/Data/Perk.elm b/src/Evergreen/V79/Data/Perk.elm deleted file mode 100644 index f35e92d5..00000000 --- a/src/Evergreen/V79/Data/Perk.elm +++ /dev/null @@ -1,15 +0,0 @@ -module Evergreen.V79.Data.Perk exposing (..) - - -type Perk - = BonusHthDamage - | MasterTrader - | Awareness - | CautiousNature - | Comprehension - | EarlierSequence - | FasterHealing - | HereAndNow - | Survivalist - | Educated - | Tag diff --git a/src/Evergreen/V79/Data/Player.elm b/src/Evergreen/V79/Data/Player.elm deleted file mode 100644 index ba7106b8..00000000 --- a/src/Evergreen/V79/Data/Player.elm +++ /dev/null @@ -1,75 +0,0 @@ -module Evergreen.V79.Data.Player exposing (..) - -import AssocList -import AssocSet -import Dict -import Evergreen.V79.Data.Auth -import Evergreen.V79.Data.HealthStatus -import Evergreen.V79.Data.Item -import Evergreen.V79.Data.Map -import Evergreen.V79.Data.Message -import Evergreen.V79.Data.Perk -import Evergreen.V79.Data.Player.PlayerName -import Evergreen.V79.Data.Skill -import Evergreen.V79.Data.Special -import Evergreen.V79.Data.Trait -import Evergreen.V79.Data.Xp - - -type alias COtherPlayer = - { level : Evergreen.V79.Data.Xp.Level - , name : Evergreen.V79.Data.Player.PlayerName.PlayerName - , wins : Int - , losses : Int - , healthStatus : Evergreen.V79.Data.HealthStatus.HealthStatus - } - - -type alias CPlayer = - { hp : Int - , maxHp : Int - , xp : Evergreen.V79.Data.Xp.Xp - , name : Evergreen.V79.Data.Player.PlayerName.PlayerName - , special : Evergreen.V79.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V79.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V79.Data.Perk.Perk Int - , messages : List Evergreen.V79.Data.Message.Message - , items : Dict.Dict Evergreen.V79.Data.Item.Id Evergreen.V79.Data.Item.Item - , traits : AssocSet.Set Evergreen.V79.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V79.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V79.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - } - - -type Player a - = NeedsCharCreated (Evergreen.V79.Data.Auth.Auth Evergreen.V79.Data.Auth.Verified) - | Player a - - -type alias SPlayer = - { name : Evergreen.V79.Data.Player.PlayerName.PlayerName - , password : Evergreen.V79.Data.Auth.Password Evergreen.V79.Data.Auth.Verified - , hp : Int - , maxHp : Int - , xp : Int - , special : Evergreen.V79.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V79.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V79.Data.Perk.Perk Int - , messages : List Evergreen.V79.Data.Message.Message - , items : Dict.Dict Evergreen.V79.Data.Item.Id Evergreen.V79.Data.Item.Item - , traits : AssocSet.Set Evergreen.V79.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V79.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V79.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - } diff --git a/src/Evergreen/V79/Data/Player/PlayerName.elm b/src/Evergreen/V79/Data/Player/PlayerName.elm deleted file mode 100644 index 86a81386..00000000 --- a/src/Evergreen/V79/Data/Player/PlayerName.elm +++ /dev/null @@ -1,5 +0,0 @@ -module Evergreen.V79.Data.Player.PlayerName exposing (..) - - -type alias PlayerName = - String diff --git a/src/Evergreen/V79/Data/Skill.elm b/src/Evergreen/V79/Data/Skill.elm deleted file mode 100644 index a9fe157e..00000000 --- a/src/Evergreen/V79/Data/Skill.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V79.Data.Skill exposing (..) - - -type Skill - = SmallGuns - | BigGuns - | EnergyWeapons - | Unarmed - | MeleeWeapons - | Throwing - | FirstAid - | Doctor - | Sneak - | Lockpick - | Steal - | Traps - | Science - | Repair - | Speech - | Barter - | Gambling - | Outdoorsman diff --git a/src/Evergreen/V79/Data/Special.elm b/src/Evergreen/V79/Data/Special.elm deleted file mode 100644 index 10d28a31..00000000 --- a/src/Evergreen/V79/Data/Special.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V79.Data.Special exposing (..) - - -type alias Special = - { strength : Int - , perception : Int - , endurance : Int - , charisma : Int - , intelligence : Int - , agility : Int - , luck : Int - } - - -type SpecialType - = Strength - | Perception - | Endurance - | Charisma - | Intelligence - | Agility - | Luck diff --git a/src/Evergreen/V79/Data/Trait.elm b/src/Evergreen/V79/Data/Trait.elm deleted file mode 100644 index fcb6347d..00000000 --- a/src/Evergreen/V79/Data/Trait.elm +++ /dev/null @@ -1,10 +0,0 @@ -module Evergreen.V79.Data.Trait exposing (..) - - -type Trait - = Kamikaze - | Bruiser - | Gifted - | SmallFrame - | Skilled - | HeavyHanded diff --git a/src/Evergreen/V79/Data/Vendor.elm b/src/Evergreen/V79/Data/Vendor.elm deleted file mode 100644 index ea29df17..00000000 --- a/src/Evergreen/V79/Data/Vendor.elm +++ /dev/null @@ -1,17 +0,0 @@ -module Evergreen.V79.Data.Vendor exposing (..) - -import Dict -import Evergreen.V79.Data.Item - - -type Name - = KlamathMaidaBuckner - | DenFlick - - -type alias Vendor = - { name : Name - , items : Dict.Dict Evergreen.V79.Data.Item.Id Evergreen.V79.Data.Item.Item - , caps : Int - , barterSkill : Int - } diff --git a/src/Evergreen/V79/Data/World.elm b/src/Evergreen/V79/Data/World.elm deleted file mode 100644 index e896ba3e..00000000 --- a/src/Evergreen/V79/Data/World.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.V79.Data.World exposing (..) - -import AssocList -import Evergreen.V79.Data.Auth -import Evergreen.V79.Data.Player -import Evergreen.V79.Data.Player.PlayerName -import Evergreen.V79.Data.Vendor -import Time - - -type alias WorldLoggedOutData = - { players : List Evergreen.V79.Data.Player.COtherPlayer - } - - -type alias WorldLoggedInData = - { player : Evergreen.V79.Data.Player.Player Evergreen.V79.Data.Player.CPlayer - , otherPlayers : List Evergreen.V79.Data.Player.COtherPlayer - , playerRank : Int - , vendors : AssocList.Dict Evergreen.V79.Data.Vendor.Name Evergreen.V79.Data.Vendor.Vendor - } - - -type alias AdminData = - { players : List (Evergreen.V79.Data.Player.Player Evergreen.V79.Data.Player.SPlayer) - , loggedInPlayers : List Evergreen.V79.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - } - - -type World - = WorldNotInitialized (Evergreen.V79.Data.Auth.Auth Evergreen.V79.Data.Auth.Plaintext) - | WorldLoggedOut (Evergreen.V79.Data.Auth.Auth Evergreen.V79.Data.Auth.Plaintext) WorldLoggedOutData - | WorldLoggedIn WorldLoggedInData - | WorldAdmin AdminData diff --git a/src/Evergreen/V79/Data/Xp.elm b/src/Evergreen/V79/Data/Xp.elm deleted file mode 100644 index 0111bbe9..00000000 --- a/src/Evergreen/V79/Data/Xp.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V79.Data.Xp exposing (..) - - -type alias Level = - Int - - -type alias Xp = - Int diff --git a/src/Evergreen/V79/Frontend/Route.elm b/src/Evergreen/V79/Frontend/Route.elm deleted file mode 100644 index 7f2f9cc4..00000000 --- a/src/Evergreen/V79/Frontend/Route.elm +++ /dev/null @@ -1,32 +0,0 @@ -module Evergreen.V79.Frontend.Route exposing (..) - -import Evergreen.V79.Data.Barter -import Evergreen.V79.Data.Fight -import Evergreen.V79.Data.Message - - -type TownRoute - = MainSquare - | Store - { barter : Evergreen.V79.Data.Barter.State - } - - -type AdminRoute - = Players - | LoggedIn - - -type Route - = Character - | Inventory - | Map - | Ladder - | Town TownRoute - | About - | News - | Fight Evergreen.V79.Data.Fight.FightInfo - | Messages - | Message Evergreen.V79.Data.Message.Message - | CharCreation - | Admin AdminRoute diff --git a/src/Evergreen/V79/Logic.elm b/src/Evergreen/V79/Logic.elm deleted file mode 100644 index f4b5b023..00000000 --- a/src/Evergreen/V79/Logic.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V79.Logic exposing (..) - - -type alias AttackStats = - { minDamage : Int - , maxDamage : Int - , criticalChanceBonus : Int - } diff --git a/src/Evergreen/V79/Types.elm b/src/Evergreen/V79/Types.elm deleted file mode 100644 index 96830a1a..00000000 --- a/src/Evergreen/V79/Types.elm +++ /dev/null @@ -1,156 +0,0 @@ -module Evergreen.V79.Types exposing (..) - -import AssocList -import Browser -import Browser.Navigation -import Dict -import Evergreen.V79.Data.Auth -import Evergreen.V79.Data.Barter -import Evergreen.V79.Data.Fight -import Evergreen.V79.Data.Fight.Generator -import Evergreen.V79.Data.Item -import Evergreen.V79.Data.Map -import Evergreen.V79.Data.Message -import Evergreen.V79.Data.NewChar -import Evergreen.V79.Data.Perk -import Evergreen.V79.Data.Player -import Evergreen.V79.Data.Player.PlayerName -import Evergreen.V79.Data.Skill -import Evergreen.V79.Data.Special -import Evergreen.V79.Data.Trait -import Evergreen.V79.Data.Vendor -import Evergreen.V79.Data.World -import Evergreen.V79.Frontend.Route -import File exposing (File) -import Lamdera -import Set -import Time -import Url - - -type alias FrontendModel = - { key : Browser.Navigation.Key - , time : Time.Posix - , zone : Time.Zone - , route : Evergreen.V79.Frontend.Route.Route - , world : Evergreen.V79.Data.World.World - , newChar : Evergreen.V79.Data.NewChar.NewChar - , alertMessage : Maybe String - , mapMouseCoords : Maybe ( Evergreen.V79.Data.Map.TileCoords, Set.Set Evergreen.V79.Data.Map.TileCoords ) - } - - -type alias BackendModel = - { players : Dict.Dict Evergreen.V79.Data.Player.PlayerName.PlayerName (Evergreen.V79.Data.Player.Player Evergreen.V79.Data.Player.SPlayer) - , loggedInPlayers : Dict.Dict Lamdera.ClientId Evergreen.V79.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - , adminLoggedIn : Maybe ( Lamdera.ClientId, Lamdera.SessionId ) - , time : Time.Posix - , vendors : AssocList.Dict Evergreen.V79.Data.Vendor.Name Evergreen.V79.Data.Vendor.Vendor - , lastItemId : Int - } - - -type BarterMsg - = AddPlayerItem Evergreen.V79.Data.Item.Id Int - | AddVendorItem Evergreen.V79.Data.Item.Id Int - | AddPlayerCaps Int - | AddVendorCaps Int - | RemovePlayerItem Evergreen.V79.Data.Item.Id Int - | RemoveVendorItem Evergreen.V79.Data.Item.Id Int - | RemovePlayerCaps Int - | RemoveVendorCaps Int - | ResetBarter - | ConfirmBarter - | SetTransferNInput Evergreen.V79.Data.Barter.TransferNPosition String - | SetTransferNHover Evergreen.V79.Data.Barter.TransferNPosition - | UnsetTransferNHover - - -type FrontendMsg - = UrlClicked Browser.UrlRequest - | UrlChanged Url.Url - | GoToRoute Evergreen.V79.Frontend.Route.Route - | Logout - | Login - | Register - | GotZone Time.Zone - | GotTime Time.Posix - | AskToFight Evergreen.V79.Data.Player.PlayerName.PlayerName - | AskToHeal - | AskToUseItem Evergreen.V79.Data.Item.Id - | AskToWander - | AskToChoosePerk Evergreen.V79.Data.Perk.Perk - | AskForExport - | ImportButtonClicked - | ImportFileSelected File - | AskToImport String - | Refresh - | AskToTagSkill Evergreen.V79.Data.Skill.Skill - | AskToUseSkillPoints Evergreen.V79.Data.Skill.Skill - | SetAuthName String - | SetAuthPassword String - | CreateChar - | NewCharIncSpecial Evergreen.V79.Data.Special.SpecialType - | NewCharDecSpecial Evergreen.V79.Data.Special.SpecialType - | NewCharToggleTaggedSkill Evergreen.V79.Data.Skill.Skill - | NewCharToggleTrait Evergreen.V79.Data.Trait.Trait - | MapMouseAtCoords Evergreen.V79.Data.Map.TileCoords - | MapMouseOut - | MapMouseClick - | OpenMessage Evergreen.V79.Data.Message.Message - | AskToRemoveMessage Evergreen.V79.Data.Message.Message - | BarterMsg BarterMsg - - -type AdminToBackend - = ExportJson - | ImportJson String - - -type ToBackend - = LogMeIn (Evergreen.V79.Data.Auth.Auth Evergreen.V79.Data.Auth.Hashed) - | RegisterMe (Evergreen.V79.Data.Auth.Auth Evergreen.V79.Data.Auth.Hashed) - | CreateNewChar Evergreen.V79.Data.NewChar.NewChar - | LogMeOut - | Fight Evergreen.V79.Data.Player.PlayerName.PlayerName - | HealMe - | UseItem Evergreen.V79.Data.Item.Id - | Wander - | RefreshPlease - | TagSkill Evergreen.V79.Data.Skill.Skill - | UseSkillPoints Evergreen.V79.Data.Skill.Skill - | ChoosePerk Evergreen.V79.Data.Perk.Perk - | MoveTo Evergreen.V79.Data.Map.TileCoords (Set.Set Evergreen.V79.Data.Map.TileCoords) - | MessageWasRead Evergreen.V79.Data.Message.Message - | RemoveMessage Evergreen.V79.Data.Message.Message - | Barter Evergreen.V79.Data.Barter.State - | AdminToBackend AdminToBackend - - -type BackendMsg - = Connected Lamdera.SessionId Lamdera.ClientId - | Disconnected Lamdera.SessionId Lamdera.ClientId - | GeneratedFight Lamdera.ClientId Evergreen.V79.Data.Player.SPlayer Evergreen.V79.Data.Fight.Generator.Fight - | GeneratedNewVendorsStock ( AssocList.Dict Evergreen.V79.Data.Vendor.Name Evergreen.V79.Data.Vendor.Vendor, Int ) - | Tick Time.Posix - | CreateNewCharWithTime Lamdera.ClientId Evergreen.V79.Data.NewChar.NewChar Time.Posix - | LoggedToBackendMsg - - -type ToFrontend - = YourCurrentWorld Evergreen.V79.Data.World.WorldLoggedInData - | InitWorld Evergreen.V79.Data.World.WorldLoggedOutData - | RefreshedLoggedOut Evergreen.V79.Data.World.WorldLoggedOutData - | CurrentAdminData Evergreen.V79.Data.World.AdminData - | YourFightResult ( Evergreen.V79.Data.Fight.FightInfo, Evergreen.V79.Data.World.WorldLoggedInData ) - | YoureLoggedIn Evergreen.V79.Data.World.WorldLoggedInData - | YoureRegistered Evergreen.V79.Data.World.WorldLoggedInData - | CharCreationError Evergreen.V79.Data.NewChar.CreationError - | YouHaveCreatedChar Evergreen.V79.Data.World.WorldLoggedInData - | YoureLoggedOut Evergreen.V79.Data.World.WorldLoggedOutData - | AlertMessage String - | YoureLoggedInAsAdmin Evergreen.V79.Data.World.AdminData - | JsonExportDone String - | BarterDone ( Evergreen.V79.Data.World.WorldLoggedInData, Maybe Evergreen.V79.Data.Barter.Message ) - | BarterMessage Evergreen.V79.Data.Barter.Message diff --git a/src/Evergreen/V81/Data/Auth.elm b/src/Evergreen/V81/Data/Auth.elm deleted file mode 100644 index f2ace770..00000000 --- a/src/Evergreen/V81/Data/Auth.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V81.Data.Auth exposing (..) - - -type Plaintext - = Plaintext - - -type Password a - = Password String - - -type alias Auth a = - { name : String - , password : Password a - } - - -type Verified - = Verified - - -type Hashed - = Hashed diff --git a/src/Evergreen/V81/Data/Barter.elm b/src/Evergreen/V81/Data/Barter.elm deleted file mode 100644 index e468151d..00000000 --- a/src/Evergreen/V81/Data/Barter.elm +++ /dev/null @@ -1,33 +0,0 @@ -module Evergreen.V81.Data.Barter exposing (..) - -import AssocList -import Dict -import Evergreen.V81.Data.Item - - -type Message - = BarterIsEmpty - | PlayerOfferNotValuableEnough - | YouGaveStuffForFree - - -type TransferNPosition - = PlayerKeptItem Evergreen.V81.Data.Item.Id - | VendorKeptItem Evergreen.V81.Data.Item.Id - | PlayerTradedItem Evergreen.V81.Data.Item.Id - | VendorTradedItem Evergreen.V81.Data.Item.Id - | PlayerKeptCaps - | VendorKeptCaps - | PlayerTradedCaps - | VendorTradedCaps - - -type alias State = - { playerItems : Dict.Dict Evergreen.V81.Data.Item.Id Int - , vendorItems : Dict.Dict Evergreen.V81.Data.Item.Id Int - , playerCaps : Int - , vendorCaps : Int - , lastMessage : Maybe Message - , transferNInputs : AssocList.Dict TransferNPosition String - , transferNHover : Maybe TransferNPosition - } diff --git a/src/Evergreen/V81/Data/Enemy.elm b/src/Evergreen/V81/Data/Enemy.elm deleted file mode 100644 index 918e7299..00000000 --- a/src/Evergreen/V81/Data/Enemy.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V81.Data.Enemy exposing (..) - - -type Type - = GiantAnt - | ToughGiantAnt - | LesserRadscorpion - | Radscorpion diff --git a/src/Evergreen/V81/Data/Fight.elm b/src/Evergreen/V81/Data/Fight.elm deleted file mode 100644 index 62d81ad3..00000000 --- a/src/Evergreen/V81/Data/Fight.elm +++ /dev/null @@ -1,78 +0,0 @@ -module Evergreen.V81.Data.Fight exposing (..) - -import AssocList -import AssocSet -import Evergreen.V81.Data.Enemy -import Evergreen.V81.Data.Fight.ShotType -import Evergreen.V81.Data.Perk -import Evergreen.V81.Data.Player.PlayerName -import Evergreen.V81.Data.Skill -import Evergreen.V81.Data.Special -import Evergreen.V81.Data.Trait -import Evergreen.V81.Logic - - -type OpponentType - = Npc Evergreen.V81.Data.Enemy.Type - | Player Evergreen.V81.Data.Player.PlayerName.PlayerName - - -type Who - = Attacker - | Target - - -type FightAction - = Start - { distanceHexes : Int - } - | ComeCloser - { hexes : Int - , remainingDistanceHexes : Int - } - | Attack - { damage : Int - , shotType : Evergreen.V81.Data.Fight.ShotType.ShotType - , remainingHp : Int - } - | Miss - { shotType : Evergreen.V81.Data.Fight.ShotType.ShotType - } - - -type FightResult - = AttackerWon - { xpGained : Int - , capsGained : Int - } - | TargetWon - { xpGained : Int - , capsGained : Int - } - | TargetAlreadyDead - | BothDead - | NobodyDead - - -type alias FightInfo = - { attacker : OpponentType - , target : OpponentType - , log : List ( Who, FightAction ) - , result : FightResult - } - - -type alias Opponent = - { type_ : OpponentType - , hp : Int - , maxHp : Int - , maxAp : Int - , sequence : Int - , traits : AssocSet.Set Evergreen.V81.Data.Trait.Trait - , perks : AssocList.Dict Evergreen.V81.Data.Perk.Perk Int - , caps : Int - , armorClass : Int - , attackStats : Evergreen.V81.Logic.AttackStats - , addedSkillPercentages : AssocList.Dict Evergreen.V81.Data.Skill.Skill Int - , special : Evergreen.V81.Data.Special.Special - } diff --git a/src/Evergreen/V81/Data/Fight/Generator.elm b/src/Evergreen/V81/Data/Fight/Generator.elm deleted file mode 100644 index a5797728..00000000 --- a/src/Evergreen/V81/Data/Fight/Generator.elm +++ /dev/null @@ -1,12 +0,0 @@ -module Evergreen.V81.Data.Fight.Generator exposing (..) - -import Evergreen.V81.Data.Fight -import Evergreen.V81.Data.Message - - -type alias Fight = - { finalAttacker : Evergreen.V81.Data.Fight.Opponent - , finalTarget : Evergreen.V81.Data.Fight.Opponent - , fightInfo : Evergreen.V81.Data.Fight.FightInfo - , messageForTarget : Evergreen.V81.Data.Message.Message - } diff --git a/src/Evergreen/V81/Data/Fight/ShotType.elm b/src/Evergreen/V81/Data/Fight/ShotType.elm deleted file mode 100644 index 75722126..00000000 --- a/src/Evergreen/V81/Data/Fight/ShotType.elm +++ /dev/null @@ -1,17 +0,0 @@ -module Evergreen.V81.Data.Fight.ShotType exposing (..) - - -type AimedShot - = Head - | Torso - | Eyes - | Groin - | LeftArm - | RightArm - | LeftLeg - | RightLeg - - -type ShotType - = NormalShot - | AimedShot AimedShot diff --git a/src/Evergreen/V81/Data/HealthStatus.elm b/src/Evergreen/V81/Data/HealthStatus.elm deleted file mode 100644 index cec4786e..00000000 --- a/src/Evergreen/V81/Data/HealthStatus.elm +++ /dev/null @@ -1,16 +0,0 @@ -module Evergreen.V81.Data.HealthStatus exposing (..) - - -type HealthStatus - = ExactHp - { current : Int - , max : Int - } - | Unhurt - | SlightlyWounded - | Wounded - | SeverelyWounded - | AlmostDead - | Dead - | Alive - | Unknown diff --git a/src/Evergreen/V81/Data/Item.elm b/src/Evergreen/V81/Data/Item.elm deleted file mode 100644 index 3010fcbd..00000000 --- a/src/Evergreen/V81/Data/Item.elm +++ /dev/null @@ -1,21 +0,0 @@ -module Evergreen.V81.Data.Item exposing (..) - - -type alias Id = - Int - - -type Kind - = Stimpak - | BigBookOfScience - | DeansElectronics - | FirstAidBook - | GunsAndBullets - | ScoutHandbook - - -type alias Item = - { id : Id - , kind : Kind - , count : Int - } diff --git a/src/Evergreen/V81/Data/Map.elm b/src/Evergreen/V81/Data/Map.elm deleted file mode 100644 index c4b39914..00000000 --- a/src/Evergreen/V81/Data/Map.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V81.Data.Map exposing (..) - - -type alias TileNum = - Int - - -type alias TileCoords = - ( Int, Int ) diff --git a/src/Evergreen/V81/Data/Message.elm b/src/Evergreen/V81/Data/Message.elm deleted file mode 100644 index 5022dfc7..00000000 --- a/src/Evergreen/V81/Data/Message.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V81.Data.Message exposing (..) - -import Evergreen.V81.Data.Fight -import Evergreen.V81.Data.Player.PlayerName -import Time - - -type Type - = Welcome - | YouAdvancedLevel - { newLevel : Int - } - | YouWereAttacked - { attacker : Evergreen.V81.Data.Player.PlayerName.PlayerName - , fightInfo : Evergreen.V81.Data.Fight.FightInfo - } - - -type alias Message = - { type_ : Type - , hasBeenRead : Bool - , date : Time.Posix - } diff --git a/src/Evergreen/V81/Data/NewChar.elm b/src/Evergreen/V81/Data/NewChar.elm deleted file mode 100644 index d3a9079d..00000000 --- a/src/Evergreen/V81/Data/NewChar.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V81.Data.NewChar exposing (..) - -import AssocSet -import Evergreen.V81.Data.Skill -import Evergreen.V81.Data.Special -import Evergreen.V81.Data.Trait - - -type CreationError - = DoesNotHaveThreeTaggedSkills - | HasSpecialPointsLeft - | UsedMoreSpecialPointsThanAvailable - | HasSpecialOutOfRange - | HasMoreThanTwoTraits - - -type alias NewChar = - { baseSpecial : Evergreen.V81.Data.Special.Special - , availableSpecial : Int - , taggedSkills : AssocSet.Set Evergreen.V81.Data.Skill.Skill - , traits : AssocSet.Set Evergreen.V81.Data.Trait.Trait - , error : Maybe CreationError - } diff --git a/src/Evergreen/V81/Data/Perk.elm b/src/Evergreen/V81/Data/Perk.elm deleted file mode 100644 index bbc9aac9..00000000 --- a/src/Evergreen/V81/Data/Perk.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V81.Data.Perk exposing (..) - - -type Perk - = BonusHthDamage - | MasterTrader - | Awareness - | CautiousNature - | Comprehension - | EarlierSequence - | FasterHealing - | HereAndNow - | Survivalist - | Educated - | Tag - | GainStrength - | GainPerception - | GainEndurance - | GainCharisma - | GainIntelligence - | GainAgility - | GainLuck diff --git a/src/Evergreen/V81/Data/Player.elm b/src/Evergreen/V81/Data/Player.elm deleted file mode 100644 index 11d5a825..00000000 --- a/src/Evergreen/V81/Data/Player.elm +++ /dev/null @@ -1,75 +0,0 @@ -module Evergreen.V81.Data.Player exposing (..) - -import AssocList -import AssocSet -import Dict -import Evergreen.V81.Data.Auth -import Evergreen.V81.Data.HealthStatus -import Evergreen.V81.Data.Item -import Evergreen.V81.Data.Map -import Evergreen.V81.Data.Message -import Evergreen.V81.Data.Perk -import Evergreen.V81.Data.Player.PlayerName -import Evergreen.V81.Data.Skill -import Evergreen.V81.Data.Special -import Evergreen.V81.Data.Trait -import Evergreen.V81.Data.Xp - - -type alias COtherPlayer = - { level : Evergreen.V81.Data.Xp.Level - , name : Evergreen.V81.Data.Player.PlayerName.PlayerName - , wins : Int - , losses : Int - , healthStatus : Evergreen.V81.Data.HealthStatus.HealthStatus - } - - -type alias CPlayer = - { hp : Int - , maxHp : Int - , xp : Evergreen.V81.Data.Xp.Xp - , name : Evergreen.V81.Data.Player.PlayerName.PlayerName - , special : Evergreen.V81.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V81.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V81.Data.Perk.Perk Int - , messages : List Evergreen.V81.Data.Message.Message - , items : Dict.Dict Evergreen.V81.Data.Item.Id Evergreen.V81.Data.Item.Item - , traits : AssocSet.Set Evergreen.V81.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V81.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V81.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - } - - -type Player a - = NeedsCharCreated (Evergreen.V81.Data.Auth.Auth Evergreen.V81.Data.Auth.Verified) - | Player a - - -type alias SPlayer = - { name : Evergreen.V81.Data.Player.PlayerName.PlayerName - , password : Evergreen.V81.Data.Auth.Password Evergreen.V81.Data.Auth.Verified - , hp : Int - , maxHp : Int - , xp : Int - , special : Evergreen.V81.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V81.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V81.Data.Perk.Perk Int - , messages : List Evergreen.V81.Data.Message.Message - , items : Dict.Dict Evergreen.V81.Data.Item.Id Evergreen.V81.Data.Item.Item - , traits : AssocSet.Set Evergreen.V81.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V81.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V81.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - } diff --git a/src/Evergreen/V81/Data/Player/PlayerName.elm b/src/Evergreen/V81/Data/Player/PlayerName.elm deleted file mode 100644 index 01ff4e1d..00000000 --- a/src/Evergreen/V81/Data/Player/PlayerName.elm +++ /dev/null @@ -1,5 +0,0 @@ -module Evergreen.V81.Data.Player.PlayerName exposing (..) - - -type alias PlayerName = - String diff --git a/src/Evergreen/V81/Data/Skill.elm b/src/Evergreen/V81/Data/Skill.elm deleted file mode 100644 index 16264332..00000000 --- a/src/Evergreen/V81/Data/Skill.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V81.Data.Skill exposing (..) - - -type Skill - = SmallGuns - | BigGuns - | EnergyWeapons - | Unarmed - | MeleeWeapons - | Throwing - | FirstAid - | Doctor - | Sneak - | Lockpick - | Steal - | Traps - | Science - | Repair - | Speech - | Barter - | Gambling - | Outdoorsman diff --git a/src/Evergreen/V81/Data/Special.elm b/src/Evergreen/V81/Data/Special.elm deleted file mode 100644 index 84e2a4de..00000000 --- a/src/Evergreen/V81/Data/Special.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V81.Data.Special exposing (..) - - -type alias Special = - { strength : Int - , perception : Int - , endurance : Int - , charisma : Int - , intelligence : Int - , agility : Int - , luck : Int - } - - -type Type - = Strength - | Perception - | Endurance - | Charisma - | Intelligence - | Agility - | Luck diff --git a/src/Evergreen/V81/Data/Trait.elm b/src/Evergreen/V81/Data/Trait.elm deleted file mode 100644 index 4dcedfd2..00000000 --- a/src/Evergreen/V81/Data/Trait.elm +++ /dev/null @@ -1,10 +0,0 @@ -module Evergreen.V81.Data.Trait exposing (..) - - -type Trait - = Kamikaze - | Bruiser - | Gifted - | SmallFrame - | Skilled - | HeavyHanded diff --git a/src/Evergreen/V81/Data/Vendor.elm b/src/Evergreen/V81/Data/Vendor.elm deleted file mode 100644 index 042b7f60..00000000 --- a/src/Evergreen/V81/Data/Vendor.elm +++ /dev/null @@ -1,17 +0,0 @@ -module Evergreen.V81.Data.Vendor exposing (..) - -import Dict -import Evergreen.V81.Data.Item - - -type Name - = KlamathMaidaBuckner - | DenFlick - - -type alias Vendor = - { name : Name - , items : Dict.Dict Evergreen.V81.Data.Item.Id Evergreen.V81.Data.Item.Item - , caps : Int - , barterSkill : Int - } diff --git a/src/Evergreen/V81/Data/World.elm b/src/Evergreen/V81/Data/World.elm deleted file mode 100644 index 27e270b9..00000000 --- a/src/Evergreen/V81/Data/World.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.V81.Data.World exposing (..) - -import AssocList -import Evergreen.V81.Data.Auth -import Evergreen.V81.Data.Player -import Evergreen.V81.Data.Player.PlayerName -import Evergreen.V81.Data.Vendor -import Time - - -type alias WorldLoggedOutData = - { players : List Evergreen.V81.Data.Player.COtherPlayer - } - - -type alias WorldLoggedInData = - { player : Evergreen.V81.Data.Player.Player Evergreen.V81.Data.Player.CPlayer - , otherPlayers : List Evergreen.V81.Data.Player.COtherPlayer - , playerRank : Int - , vendors : AssocList.Dict Evergreen.V81.Data.Vendor.Name Evergreen.V81.Data.Vendor.Vendor - } - - -type alias AdminData = - { players : List (Evergreen.V81.Data.Player.Player Evergreen.V81.Data.Player.SPlayer) - , loggedInPlayers : List Evergreen.V81.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - } - - -type World - = WorldNotInitialized (Evergreen.V81.Data.Auth.Auth Evergreen.V81.Data.Auth.Plaintext) - | WorldLoggedOut (Evergreen.V81.Data.Auth.Auth Evergreen.V81.Data.Auth.Plaintext) WorldLoggedOutData - | WorldLoggedIn WorldLoggedInData - | WorldAdmin AdminData diff --git a/src/Evergreen/V81/Data/Xp.elm b/src/Evergreen/V81/Data/Xp.elm deleted file mode 100644 index 563fadb7..00000000 --- a/src/Evergreen/V81/Data/Xp.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V81.Data.Xp exposing (..) - - -type alias Level = - Int - - -type alias Xp = - Int diff --git a/src/Evergreen/V81/Frontend/Route.elm b/src/Evergreen/V81/Frontend/Route.elm deleted file mode 100644 index d166e76b..00000000 --- a/src/Evergreen/V81/Frontend/Route.elm +++ /dev/null @@ -1,32 +0,0 @@ -module Evergreen.V81.Frontend.Route exposing (..) - -import Evergreen.V81.Data.Barter -import Evergreen.V81.Data.Fight -import Evergreen.V81.Data.Message - - -type TownRoute - = MainSquare - | Store - { barter : Evergreen.V81.Data.Barter.State - } - - -type AdminRoute - = Players - | LoggedIn - - -type Route - = Character - | Inventory - | Map - | Ladder - | Town TownRoute - | About - | News - | Fight Evergreen.V81.Data.Fight.FightInfo - | Messages - | Message Evergreen.V81.Data.Message.Message - | CharCreation - | Admin AdminRoute diff --git a/src/Evergreen/V81/Logic.elm b/src/Evergreen/V81/Logic.elm deleted file mode 100644 index 8d8b5cd4..00000000 --- a/src/Evergreen/V81/Logic.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V81.Logic exposing (..) - - -type alias AttackStats = - { minDamage : Int - , maxDamage : Int - , criticalChanceBonus : Int - } diff --git a/src/Evergreen/V81/Types.elm b/src/Evergreen/V81/Types.elm deleted file mode 100644 index 95f6ce69..00000000 --- a/src/Evergreen/V81/Types.elm +++ /dev/null @@ -1,156 +0,0 @@ -module Evergreen.V81.Types exposing (..) - -import AssocList -import Browser -import Browser.Navigation -import Dict -import Evergreen.V81.Data.Auth -import Evergreen.V81.Data.Barter -import Evergreen.V81.Data.Fight -import Evergreen.V81.Data.Fight.Generator -import Evergreen.V81.Data.Item -import Evergreen.V81.Data.Map -import Evergreen.V81.Data.Message -import Evergreen.V81.Data.NewChar -import Evergreen.V81.Data.Perk -import Evergreen.V81.Data.Player -import Evergreen.V81.Data.Player.PlayerName -import Evergreen.V81.Data.Skill -import Evergreen.V81.Data.Special -import Evergreen.V81.Data.Trait -import Evergreen.V81.Data.Vendor -import Evergreen.V81.Data.World -import Evergreen.V81.Frontend.Route -import File exposing (File) -import Lamdera -import Set -import Time -import Url - - -type alias FrontendModel = - { key : Browser.Navigation.Key - , time : Time.Posix - , zone : Time.Zone - , route : Evergreen.V81.Frontend.Route.Route - , world : Evergreen.V81.Data.World.World - , newChar : Evergreen.V81.Data.NewChar.NewChar - , alertMessage : Maybe String - , mapMouseCoords : Maybe ( Evergreen.V81.Data.Map.TileCoords, Set.Set Evergreen.V81.Data.Map.TileCoords ) - } - - -type alias BackendModel = - { players : Dict.Dict Evergreen.V81.Data.Player.PlayerName.PlayerName (Evergreen.V81.Data.Player.Player Evergreen.V81.Data.Player.SPlayer) - , loggedInPlayers : Dict.Dict Lamdera.ClientId Evergreen.V81.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - , adminLoggedIn : Maybe ( Lamdera.ClientId, Lamdera.SessionId ) - , time : Time.Posix - , vendors : AssocList.Dict Evergreen.V81.Data.Vendor.Name Evergreen.V81.Data.Vendor.Vendor - , lastItemId : Int - } - - -type BarterMsg - = AddPlayerItem Evergreen.V81.Data.Item.Id Int - | AddVendorItem Evergreen.V81.Data.Item.Id Int - | AddPlayerCaps Int - | AddVendorCaps Int - | RemovePlayerItem Evergreen.V81.Data.Item.Id Int - | RemoveVendorItem Evergreen.V81.Data.Item.Id Int - | RemovePlayerCaps Int - | RemoveVendorCaps Int - | ResetBarter - | ConfirmBarter - | SetTransferNInput Evergreen.V81.Data.Barter.TransferNPosition String - | SetTransferNHover Evergreen.V81.Data.Barter.TransferNPosition - | UnsetTransferNHover - - -type FrontendMsg - = UrlClicked Browser.UrlRequest - | UrlChanged Url.Url - | GoToRoute Evergreen.V81.Frontend.Route.Route - | Logout - | Login - | Register - | GotZone Time.Zone - | GotTime Time.Posix - | AskToFight Evergreen.V81.Data.Player.PlayerName.PlayerName - | AskToHeal - | AskToUseItem Evergreen.V81.Data.Item.Id - | AskToWander - | AskToChoosePerk Evergreen.V81.Data.Perk.Perk - | AskForExport - | ImportButtonClicked - | ImportFileSelected File - | AskToImport String - | Refresh - | AskToTagSkill Evergreen.V81.Data.Skill.Skill - | AskToUseSkillPoints Evergreen.V81.Data.Skill.Skill - | SetAuthName String - | SetAuthPassword String - | CreateChar - | NewCharIncSpecial Evergreen.V81.Data.Special.Type - | NewCharDecSpecial Evergreen.V81.Data.Special.Type - | NewCharToggleTaggedSkill Evergreen.V81.Data.Skill.Skill - | NewCharToggleTrait Evergreen.V81.Data.Trait.Trait - | MapMouseAtCoords Evergreen.V81.Data.Map.TileCoords - | MapMouseOut - | MapMouseClick - | OpenMessage Evergreen.V81.Data.Message.Message - | AskToRemoveMessage Evergreen.V81.Data.Message.Message - | BarterMsg BarterMsg - - -type AdminToBackend - = ExportJson - | ImportJson String - - -type ToBackend - = LogMeIn (Evergreen.V81.Data.Auth.Auth Evergreen.V81.Data.Auth.Hashed) - | RegisterMe (Evergreen.V81.Data.Auth.Auth Evergreen.V81.Data.Auth.Hashed) - | CreateNewChar Evergreen.V81.Data.NewChar.NewChar - | LogMeOut - | Fight Evergreen.V81.Data.Player.PlayerName.PlayerName - | HealMe - | UseItem Evergreen.V81.Data.Item.Id - | Wander - | RefreshPlease - | TagSkill Evergreen.V81.Data.Skill.Skill - | UseSkillPoints Evergreen.V81.Data.Skill.Skill - | ChoosePerk Evergreen.V81.Data.Perk.Perk - | MoveTo Evergreen.V81.Data.Map.TileCoords (Set.Set Evergreen.V81.Data.Map.TileCoords) - | MessageWasRead Evergreen.V81.Data.Message.Message - | RemoveMessage Evergreen.V81.Data.Message.Message - | Barter Evergreen.V81.Data.Barter.State - | AdminToBackend AdminToBackend - - -type BackendMsg - = Connected Lamdera.SessionId Lamdera.ClientId - | Disconnected Lamdera.SessionId Lamdera.ClientId - | GeneratedFight Lamdera.ClientId Evergreen.V81.Data.Player.SPlayer Evergreen.V81.Data.Fight.Generator.Fight - | GeneratedNewVendorsStock ( AssocList.Dict Evergreen.V81.Data.Vendor.Name Evergreen.V81.Data.Vendor.Vendor, Int ) - | Tick Time.Posix - | CreateNewCharWithTime Lamdera.ClientId Evergreen.V81.Data.NewChar.NewChar Time.Posix - | LoggedToBackendMsg - - -type ToFrontend - = YourCurrentWorld Evergreen.V81.Data.World.WorldLoggedInData - | InitWorld Evergreen.V81.Data.World.WorldLoggedOutData - | RefreshedLoggedOut Evergreen.V81.Data.World.WorldLoggedOutData - | CurrentAdminData Evergreen.V81.Data.World.AdminData - | YourFightResult ( Evergreen.V81.Data.Fight.FightInfo, Evergreen.V81.Data.World.WorldLoggedInData ) - | YoureLoggedIn Evergreen.V81.Data.World.WorldLoggedInData - | YoureRegistered Evergreen.V81.Data.World.WorldLoggedInData - | CharCreationError Evergreen.V81.Data.NewChar.CreationError - | YouHaveCreatedChar Evergreen.V81.Data.World.WorldLoggedInData - | YoureLoggedOut Evergreen.V81.Data.World.WorldLoggedOutData - | AlertMessage String - | YoureLoggedInAsAdmin Evergreen.V81.Data.World.AdminData - | JsonExportDone String - | BarterDone ( Evergreen.V81.Data.World.WorldLoggedInData, Maybe Evergreen.V81.Data.Barter.Message ) - | BarterMessage Evergreen.V81.Data.Barter.Message diff --git a/src/Evergreen/V83/Data/Auth.elm b/src/Evergreen/V83/Data/Auth.elm deleted file mode 100644 index 920a4d42..00000000 --- a/src/Evergreen/V83/Data/Auth.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V83.Data.Auth exposing (..) - - -type Plaintext - = Plaintext - - -type Password a - = Password String - - -type alias Auth a = - { name : String - , password : Password a - } - - -type Verified - = Verified - - -type Hashed - = Hashed diff --git a/src/Evergreen/V83/Data/Barter.elm b/src/Evergreen/V83/Data/Barter.elm deleted file mode 100644 index f39d78b8..00000000 --- a/src/Evergreen/V83/Data/Barter.elm +++ /dev/null @@ -1,33 +0,0 @@ -module Evergreen.V83.Data.Barter exposing (..) - -import AssocList -import Dict -import Evergreen.V83.Data.Item - - -type Message - = BarterIsEmpty - | PlayerOfferNotValuableEnough - | YouGaveStuffForFree - - -type TransferNPosition - = PlayerKeptItem Evergreen.V83.Data.Item.Id - | VendorKeptItem Evergreen.V83.Data.Item.Id - | PlayerTradedItem Evergreen.V83.Data.Item.Id - | VendorTradedItem Evergreen.V83.Data.Item.Id - | PlayerKeptCaps - | VendorKeptCaps - | PlayerTradedCaps - | VendorTradedCaps - - -type alias State = - { playerItems : Dict.Dict Evergreen.V83.Data.Item.Id Int - , vendorItems : Dict.Dict Evergreen.V83.Data.Item.Id Int - , playerCaps : Int - , vendorCaps : Int - , lastMessage : Maybe Message - , transferNInputs : AssocList.Dict TransferNPosition String - , transferNHover : Maybe TransferNPosition - } diff --git a/src/Evergreen/V83/Data/Enemy.elm b/src/Evergreen/V83/Data/Enemy.elm deleted file mode 100644 index 16533f7e..00000000 --- a/src/Evergreen/V83/Data/Enemy.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V83.Data.Enemy exposing (..) - - -type Type - = GiantAnt - | ToughGiantAnt - | LesserRadscorpion - | Radscorpion diff --git a/src/Evergreen/V83/Data/Fight.elm b/src/Evergreen/V83/Data/Fight.elm deleted file mode 100644 index 3a0dacbb..00000000 --- a/src/Evergreen/V83/Data/Fight.elm +++ /dev/null @@ -1,80 +0,0 @@ -module Evergreen.V83.Data.Fight exposing (..) - -import AssocList -import AssocSet -import Evergreen.V83.Data.Enemy -import Evergreen.V83.Data.Fight.ShotType -import Evergreen.V83.Data.Item -import Evergreen.V83.Data.Perk -import Evergreen.V83.Data.Player.PlayerName -import Evergreen.V83.Data.Skill -import Evergreen.V83.Data.Special -import Evergreen.V83.Data.Trait -import Evergreen.V83.Logic - - -type OpponentType - = Npc Evergreen.V83.Data.Enemy.Type - | Player Evergreen.V83.Data.Player.PlayerName.PlayerName - - -type Who - = Attacker - | Target - - -type FightAction - = Start - { distanceHexes : Int - } - | ComeCloser - { hexes : Int - , remainingDistanceHexes : Int - } - | Attack - { damage : Int - , shotType : Evergreen.V83.Data.Fight.ShotType.ShotType - , remainingHp : Int - } - | Miss - { shotType : Evergreen.V83.Data.Fight.ShotType.ShotType - } - - -type FightResult - = AttackerWon - { xpGained : Int - , capsGained : Int - } - | TargetWon - { xpGained : Int - , capsGained : Int - } - | TargetAlreadyDead - | BothDead - | NobodyDead - - -type alias FightInfo = - { attacker : OpponentType - , target : OpponentType - , log : List ( Who, FightAction ) - , result : FightResult - } - - -type alias Opponent = - { type_ : OpponentType - , hp : Int - , maxHp : Int - , maxAp : Int - , sequence : Int - , traits : AssocSet.Set Evergreen.V83.Data.Trait.Trait - , perks : AssocList.Dict Evergreen.V83.Data.Perk.Perk Int - , caps : Int - , equippedArmor : Maybe Evergreen.V83.Data.Item.Kind - , naturalArmorClass : Int - , attackStats : Evergreen.V83.Logic.AttackStats - , addedSkillPercentages : AssocList.Dict Evergreen.V83.Data.Skill.Skill Int - , special : Evergreen.V83.Data.Special.Special - } diff --git a/src/Evergreen/V83/Data/Fight/Generator.elm b/src/Evergreen/V83/Data/Fight/Generator.elm deleted file mode 100644 index 635f3594..00000000 --- a/src/Evergreen/V83/Data/Fight/Generator.elm +++ /dev/null @@ -1,12 +0,0 @@ -module Evergreen.V83.Data.Fight.Generator exposing (..) - -import Evergreen.V83.Data.Fight -import Evergreen.V83.Data.Message - - -type alias Fight = - { finalAttacker : Evergreen.V83.Data.Fight.Opponent - , finalTarget : Evergreen.V83.Data.Fight.Opponent - , fightInfo : Evergreen.V83.Data.Fight.FightInfo - , messageForTarget : Evergreen.V83.Data.Message.Message - } diff --git a/src/Evergreen/V83/Data/Fight/ShotType.elm b/src/Evergreen/V83/Data/Fight/ShotType.elm deleted file mode 100644 index 7d6eb859..00000000 --- a/src/Evergreen/V83/Data/Fight/ShotType.elm +++ /dev/null @@ -1,17 +0,0 @@ -module Evergreen.V83.Data.Fight.ShotType exposing (..) - - -type AimedShot - = Head - | Torso - | Eyes - | Groin - | LeftArm - | RightArm - | LeftLeg - | RightLeg - - -type ShotType - = NormalShot - | AimedShot AimedShot diff --git a/src/Evergreen/V83/Data/HealthStatus.elm b/src/Evergreen/V83/Data/HealthStatus.elm deleted file mode 100644 index 0da41411..00000000 --- a/src/Evergreen/V83/Data/HealthStatus.elm +++ /dev/null @@ -1,16 +0,0 @@ -module Evergreen.V83.Data.HealthStatus exposing (..) - - -type HealthStatus - = ExactHp - { current : Int - , max : Int - } - | Unhurt - | SlightlyWounded - | Wounded - | SeverelyWounded - | AlmostDead - | Dead - | Alive - | Unknown diff --git a/src/Evergreen/V83/Data/Item.elm b/src/Evergreen/V83/Data/Item.elm deleted file mode 100644 index bdec673f..00000000 --- a/src/Evergreen/V83/Data/Item.elm +++ /dev/null @@ -1,26 +0,0 @@ -module Evergreen.V83.Data.Item exposing (..) - - -type alias Id = - Int - - -type Kind - = HealingPowder - | Stimpak - | BigBookOfScience - | DeansElectronics - | FirstAidBook - | GunsAndBullets - | ScoutHandbook - | Robes - | LeatherJacket - | LeatherArmor - | MetalArmor - - -type alias Item = - { id : Id - , kind : Kind - , count : Int - } diff --git a/src/Evergreen/V83/Data/Map.elm b/src/Evergreen/V83/Data/Map.elm deleted file mode 100644 index bbae59b0..00000000 --- a/src/Evergreen/V83/Data/Map.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V83.Data.Map exposing (..) - - -type alias TileNum = - Int - - -type alias TileCoords = - ( Int, Int ) diff --git a/src/Evergreen/V83/Data/Message.elm b/src/Evergreen/V83/Data/Message.elm deleted file mode 100644 index 052b481f..00000000 --- a/src/Evergreen/V83/Data/Message.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V83.Data.Message exposing (..) - -import Evergreen.V83.Data.Fight -import Evergreen.V83.Data.Player.PlayerName -import Time - - -type Type - = Welcome - | YouAdvancedLevel - { newLevel : Int - } - | YouWereAttacked - { attacker : Evergreen.V83.Data.Player.PlayerName.PlayerName - , fightInfo : Evergreen.V83.Data.Fight.FightInfo - } - - -type alias Message = - { type_ : Type - , hasBeenRead : Bool - , date : Time.Posix - } diff --git a/src/Evergreen/V83/Data/NewChar.elm b/src/Evergreen/V83/Data/NewChar.elm deleted file mode 100644 index 42d61db5..00000000 --- a/src/Evergreen/V83/Data/NewChar.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V83.Data.NewChar exposing (..) - -import AssocSet -import Evergreen.V83.Data.Skill -import Evergreen.V83.Data.Special -import Evergreen.V83.Data.Trait - - -type CreationError - = DoesNotHaveThreeTaggedSkills - | HasSpecialPointsLeft - | UsedMoreSpecialPointsThanAvailable - | HasSpecialOutOfRange - | HasMoreThanTwoTraits - - -type alias NewChar = - { baseSpecial : Evergreen.V83.Data.Special.Special - , availableSpecial : Int - , taggedSkills : AssocSet.Set Evergreen.V83.Data.Skill.Skill - , traits : AssocSet.Set Evergreen.V83.Data.Trait.Trait - , error : Maybe CreationError - } diff --git a/src/Evergreen/V83/Data/Perk.elm b/src/Evergreen/V83/Data/Perk.elm deleted file mode 100644 index 8d77f007..00000000 --- a/src/Evergreen/V83/Data/Perk.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V83.Data.Perk exposing (..) - - -type Perk - = BonusHthDamage - | MasterTrader - | Awareness - | CautiousNature - | Comprehension - | EarlierSequence - | FasterHealing - | HereAndNow - | Survivalist - | Educated - | Tag - | GainStrength - | GainPerception - | GainEndurance - | GainCharisma - | GainIntelligence - | GainAgility - | GainLuck diff --git a/src/Evergreen/V83/Data/Player.elm b/src/Evergreen/V83/Data/Player.elm deleted file mode 100644 index d58bc2e9..00000000 --- a/src/Evergreen/V83/Data/Player.elm +++ /dev/null @@ -1,77 +0,0 @@ -module Evergreen.V83.Data.Player exposing (..) - -import AssocList -import AssocSet -import Dict -import Evergreen.V83.Data.Auth -import Evergreen.V83.Data.HealthStatus -import Evergreen.V83.Data.Item -import Evergreen.V83.Data.Map -import Evergreen.V83.Data.Message -import Evergreen.V83.Data.Perk -import Evergreen.V83.Data.Player.PlayerName -import Evergreen.V83.Data.Skill -import Evergreen.V83.Data.Special -import Evergreen.V83.Data.Trait -import Evergreen.V83.Data.Xp - - -type alias COtherPlayer = - { level : Evergreen.V83.Data.Xp.Level - , name : Evergreen.V83.Data.Player.PlayerName.PlayerName - , wins : Int - , losses : Int - , healthStatus : Evergreen.V83.Data.HealthStatus.HealthStatus - } - - -type alias CPlayer = - { hp : Int - , maxHp : Int - , xp : Evergreen.V83.Data.Xp.Xp - , name : Evergreen.V83.Data.Player.PlayerName.PlayerName - , special : Evergreen.V83.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V83.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V83.Data.Perk.Perk Int - , messages : List Evergreen.V83.Data.Message.Message - , items : Dict.Dict Evergreen.V83.Data.Item.Id Evergreen.V83.Data.Item.Item - , traits : AssocSet.Set Evergreen.V83.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V83.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V83.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - , equippedArmor : Maybe Evergreen.V83.Data.Item.Item - } - - -type Player a - = NeedsCharCreated (Evergreen.V83.Data.Auth.Auth Evergreen.V83.Data.Auth.Verified) - | Player a - - -type alias SPlayer = - { name : Evergreen.V83.Data.Player.PlayerName.PlayerName - , password : Evergreen.V83.Data.Auth.Password Evergreen.V83.Data.Auth.Verified - , hp : Int - , maxHp : Int - , xp : Int - , special : Evergreen.V83.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V83.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V83.Data.Perk.Perk Int - , messages : List Evergreen.V83.Data.Message.Message - , items : Dict.Dict Evergreen.V83.Data.Item.Id Evergreen.V83.Data.Item.Item - , traits : AssocSet.Set Evergreen.V83.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V83.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V83.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - , equippedArmor : Maybe Evergreen.V83.Data.Item.Item - } diff --git a/src/Evergreen/V83/Data/Player/PlayerName.elm b/src/Evergreen/V83/Data/Player/PlayerName.elm deleted file mode 100644 index 700f65f1..00000000 --- a/src/Evergreen/V83/Data/Player/PlayerName.elm +++ /dev/null @@ -1,5 +0,0 @@ -module Evergreen.V83.Data.Player.PlayerName exposing (..) - - -type alias PlayerName = - String diff --git a/src/Evergreen/V83/Data/Skill.elm b/src/Evergreen/V83/Data/Skill.elm deleted file mode 100644 index 07dfe132..00000000 --- a/src/Evergreen/V83/Data/Skill.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V83.Data.Skill exposing (..) - - -type Skill - = SmallGuns - | BigGuns - | EnergyWeapons - | Unarmed - | MeleeWeapons - | Throwing - | FirstAid - | Doctor - | Sneak - | Lockpick - | Steal - | Traps - | Science - | Repair - | Speech - | Barter - | Gambling - | Outdoorsman diff --git a/src/Evergreen/V83/Data/Special.elm b/src/Evergreen/V83/Data/Special.elm deleted file mode 100644 index fc1c4bf6..00000000 --- a/src/Evergreen/V83/Data/Special.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V83.Data.Special exposing (..) - - -type alias Special = - { strength : Int - , perception : Int - , endurance : Int - , charisma : Int - , intelligence : Int - , agility : Int - , luck : Int - } - - -type Type - = Strength - | Perception - | Endurance - | Charisma - | Intelligence - | Agility - | Luck diff --git a/src/Evergreen/V83/Data/Trait.elm b/src/Evergreen/V83/Data/Trait.elm deleted file mode 100644 index 19b3fc5d..00000000 --- a/src/Evergreen/V83/Data/Trait.elm +++ /dev/null @@ -1,10 +0,0 @@ -module Evergreen.V83.Data.Trait exposing (..) - - -type Trait - = Kamikaze - | Bruiser - | Gifted - | SmallFrame - | Skilled - | HeavyHanded diff --git a/src/Evergreen/V83/Data/Vendor.elm b/src/Evergreen/V83/Data/Vendor.elm deleted file mode 100644 index 52b7764b..00000000 --- a/src/Evergreen/V83/Data/Vendor.elm +++ /dev/null @@ -1,20 +0,0 @@ -module Evergreen.V83.Data.Vendor exposing (..) - -import Dict -import Evergreen.V83.Data.Item - - -type Name - = ArroyoHakunin - | KlamathMaidaBuckner - | DenFlick - | ModocJo - | VaultCityHappyHarry - - -type alias Vendor = - { name : Name - , items : Dict.Dict Evergreen.V83.Data.Item.Id Evergreen.V83.Data.Item.Item - , caps : Int - , barterSkill : Int - } diff --git a/src/Evergreen/V83/Data/World.elm b/src/Evergreen/V83/Data/World.elm deleted file mode 100644 index c42f8f11..00000000 --- a/src/Evergreen/V83/Data/World.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.V83.Data.World exposing (..) - -import AssocList -import Evergreen.V83.Data.Auth -import Evergreen.V83.Data.Player -import Evergreen.V83.Data.Player.PlayerName -import Evergreen.V83.Data.Vendor -import Time - - -type alias WorldLoggedOutData = - { players : List Evergreen.V83.Data.Player.COtherPlayer - } - - -type alias WorldLoggedInData = - { player : Evergreen.V83.Data.Player.Player Evergreen.V83.Data.Player.CPlayer - , otherPlayers : List Evergreen.V83.Data.Player.COtherPlayer - , playerRank : Int - , vendors : AssocList.Dict Evergreen.V83.Data.Vendor.Name Evergreen.V83.Data.Vendor.Vendor - } - - -type alias AdminData = - { players : List (Evergreen.V83.Data.Player.Player Evergreen.V83.Data.Player.SPlayer) - , loggedInPlayers : List Evergreen.V83.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - } - - -type World - = WorldNotInitialized (Evergreen.V83.Data.Auth.Auth Evergreen.V83.Data.Auth.Plaintext) - | WorldLoggedOut (Evergreen.V83.Data.Auth.Auth Evergreen.V83.Data.Auth.Plaintext) WorldLoggedOutData - | WorldLoggedIn WorldLoggedInData - | WorldAdmin AdminData diff --git a/src/Evergreen/V83/Data/Xp.elm b/src/Evergreen/V83/Data/Xp.elm deleted file mode 100644 index 924449ab..00000000 --- a/src/Evergreen/V83/Data/Xp.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V83.Data.Xp exposing (..) - - -type alias Level = - Int - - -type alias Xp = - Int diff --git a/src/Evergreen/V83/Frontend/Route.elm b/src/Evergreen/V83/Frontend/Route.elm deleted file mode 100644 index 35c178a7..00000000 --- a/src/Evergreen/V83/Frontend/Route.elm +++ /dev/null @@ -1,32 +0,0 @@ -module Evergreen.V83.Frontend.Route exposing (..) - -import Evergreen.V83.Data.Barter -import Evergreen.V83.Data.Fight -import Evergreen.V83.Data.Message - - -type TownRoute - = MainSquare - | Store - { barter : Evergreen.V83.Data.Barter.State - } - - -type AdminRoute - = Players - | LoggedIn - - -type Route - = Character - | Inventory - | Map - | Ladder - | Town TownRoute - | About - | News - | Fight Evergreen.V83.Data.Fight.FightInfo - | Messages - | Message Evergreen.V83.Data.Message.Message - | CharCreation - | Admin AdminRoute diff --git a/src/Evergreen/V83/Logic.elm b/src/Evergreen/V83/Logic.elm deleted file mode 100644 index acad87be..00000000 --- a/src/Evergreen/V83/Logic.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V83.Logic exposing (..) - - -type alias AttackStats = - { minDamage : Int - , maxDamage : Int - , criticalChanceBonus : Int - } diff --git a/src/Evergreen/V83/Types.elm b/src/Evergreen/V83/Types.elm deleted file mode 100644 index df72e3bd..00000000 --- a/src/Evergreen/V83/Types.elm +++ /dev/null @@ -1,160 +0,0 @@ -module Evergreen.V83.Types exposing (..) - -import AssocList -import Browser -import Browser.Navigation -import Dict -import Evergreen.V83.Data.Auth -import Evergreen.V83.Data.Barter -import Evergreen.V83.Data.Fight -import Evergreen.V83.Data.Fight.Generator -import Evergreen.V83.Data.Item -import Evergreen.V83.Data.Map -import Evergreen.V83.Data.Message -import Evergreen.V83.Data.NewChar -import Evergreen.V83.Data.Perk -import Evergreen.V83.Data.Player -import Evergreen.V83.Data.Player.PlayerName -import Evergreen.V83.Data.Skill -import Evergreen.V83.Data.Special -import Evergreen.V83.Data.Trait -import Evergreen.V83.Data.Vendor -import Evergreen.V83.Data.World -import Evergreen.V83.Frontend.Route -import File exposing (File) -import Lamdera -import Set -import Time -import Url - - -type alias FrontendModel = - { key : Browser.Navigation.Key - , time : Time.Posix - , zone : Time.Zone - , route : Evergreen.V83.Frontend.Route.Route - , world : Evergreen.V83.Data.World.World - , newChar : Evergreen.V83.Data.NewChar.NewChar - , alertMessage : Maybe String - , mapMouseCoords : Maybe ( Evergreen.V83.Data.Map.TileCoords, Set.Set Evergreen.V83.Data.Map.TileCoords ) - } - - -type alias BackendModel = - { players : Dict.Dict Evergreen.V83.Data.Player.PlayerName.PlayerName (Evergreen.V83.Data.Player.Player Evergreen.V83.Data.Player.SPlayer) - , loggedInPlayers : Dict.Dict Lamdera.ClientId Evergreen.V83.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - , adminLoggedIn : Maybe ( Lamdera.ClientId, Lamdera.SessionId ) - , time : Time.Posix - , vendors : AssocList.Dict Evergreen.V83.Data.Vendor.Name Evergreen.V83.Data.Vendor.Vendor - , lastItemId : Int - } - - -type BarterMsg - = AddPlayerItem Evergreen.V83.Data.Item.Id Int - | AddVendorItem Evergreen.V83.Data.Item.Id Int - | AddPlayerCaps Int - | AddVendorCaps Int - | RemovePlayerItem Evergreen.V83.Data.Item.Id Int - | RemoveVendorItem Evergreen.V83.Data.Item.Id Int - | RemovePlayerCaps Int - | RemoveVendorCaps Int - | ResetBarter - | ConfirmBarter - | SetTransferNInput Evergreen.V83.Data.Barter.TransferNPosition String - | SetTransferNHover Evergreen.V83.Data.Barter.TransferNPosition - | UnsetTransferNHover - - -type FrontendMsg - = UrlClicked Browser.UrlRequest - | UrlChanged Url.Url - | GoToRoute Evergreen.V83.Frontend.Route.Route - | Logout - | Login - | Register - | GotZone Time.Zone - | GotTime Time.Posix - | AskToFight Evergreen.V83.Data.Player.PlayerName.PlayerName - | AskToHeal - | AskToUseItem Evergreen.V83.Data.Item.Id - | AskToWander - | AskToChoosePerk Evergreen.V83.Data.Perk.Perk - | AskToEquipItem Evergreen.V83.Data.Item.Id - | AskToUnequipArmor - | AskForExport - | ImportButtonClicked - | ImportFileSelected File - | AskToImport String - | Refresh - | AskToTagSkill Evergreen.V83.Data.Skill.Skill - | AskToUseSkillPoints Evergreen.V83.Data.Skill.Skill - | SetAuthName String - | SetAuthPassword String - | CreateChar - | NewCharIncSpecial Evergreen.V83.Data.Special.Type - | NewCharDecSpecial Evergreen.V83.Data.Special.Type - | NewCharToggleTaggedSkill Evergreen.V83.Data.Skill.Skill - | NewCharToggleTrait Evergreen.V83.Data.Trait.Trait - | MapMouseAtCoords Evergreen.V83.Data.Map.TileCoords - | MapMouseOut - | MapMouseClick - | OpenMessage Evergreen.V83.Data.Message.Message - | AskToRemoveMessage Evergreen.V83.Data.Message.Message - | BarterMsg BarterMsg - - -type AdminToBackend - = ExportJson - | ImportJson String - - -type ToBackend - = LogMeIn (Evergreen.V83.Data.Auth.Auth Evergreen.V83.Data.Auth.Hashed) - | RegisterMe (Evergreen.V83.Data.Auth.Auth Evergreen.V83.Data.Auth.Hashed) - | CreateNewChar Evergreen.V83.Data.NewChar.NewChar - | LogMeOut - | Fight Evergreen.V83.Data.Player.PlayerName.PlayerName - | HealMe - | UseItem Evergreen.V83.Data.Item.Id - | Wander - | EquipItem Evergreen.V83.Data.Item.Id - | UnequipArmor - | RefreshPlease - | TagSkill Evergreen.V83.Data.Skill.Skill - | UseSkillPoints Evergreen.V83.Data.Skill.Skill - | ChoosePerk Evergreen.V83.Data.Perk.Perk - | MoveTo Evergreen.V83.Data.Map.TileCoords (Set.Set Evergreen.V83.Data.Map.TileCoords) - | MessageWasRead Evergreen.V83.Data.Message.Message - | RemoveMessage Evergreen.V83.Data.Message.Message - | Barter Evergreen.V83.Data.Barter.State - | AdminToBackend AdminToBackend - - -type BackendMsg - = Connected Lamdera.SessionId Lamdera.ClientId - | Disconnected Lamdera.SessionId Lamdera.ClientId - | GeneratedFight Lamdera.ClientId Evergreen.V83.Data.Player.SPlayer Evergreen.V83.Data.Fight.Generator.Fight - | GeneratedNewVendorsStock ( AssocList.Dict Evergreen.V83.Data.Vendor.Name Evergreen.V83.Data.Vendor.Vendor, Int ) - | Tick Time.Posix - | CreateNewCharWithTime Lamdera.ClientId Evergreen.V83.Data.NewChar.NewChar Time.Posix - | LoggedToBackendMsg - - -type ToFrontend - = YourCurrentWorld Evergreen.V83.Data.World.WorldLoggedInData - | InitWorld Evergreen.V83.Data.World.WorldLoggedOutData - | RefreshedLoggedOut Evergreen.V83.Data.World.WorldLoggedOutData - | CurrentAdminData Evergreen.V83.Data.World.AdminData - | YourFightResult ( Evergreen.V83.Data.Fight.FightInfo, Evergreen.V83.Data.World.WorldLoggedInData ) - | YoureLoggedIn Evergreen.V83.Data.World.WorldLoggedInData - | YoureRegistered Evergreen.V83.Data.World.WorldLoggedInData - | CharCreationError Evergreen.V83.Data.NewChar.CreationError - | YouHaveCreatedChar Evergreen.V83.Data.World.WorldLoggedInData - | YoureLoggedOut Evergreen.V83.Data.World.WorldLoggedOutData - | AlertMessage String - | YoureLoggedInAsAdmin Evergreen.V83.Data.World.AdminData - | JsonExportDone String - | BarterDone ( Evergreen.V83.Data.World.WorldLoggedInData, Maybe Evergreen.V83.Data.Barter.Message ) - | BarterMessage Evergreen.V83.Data.Barter.Message diff --git a/src/Evergreen/V85/Data/Auth.elm b/src/Evergreen/V85/Data/Auth.elm deleted file mode 100644 index 689504c9..00000000 --- a/src/Evergreen/V85/Data/Auth.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V85.Data.Auth exposing (..) - - -type Plaintext - = Plaintext - - -type Password a - = Password String - - -type alias Auth a = - { name : String - , password : Password a - } - - -type Verified - = Verified - - -type Hashed - = Hashed diff --git a/src/Evergreen/V85/Data/Barter.elm b/src/Evergreen/V85/Data/Barter.elm deleted file mode 100644 index 2b00257a..00000000 --- a/src/Evergreen/V85/Data/Barter.elm +++ /dev/null @@ -1,33 +0,0 @@ -module Evergreen.V85.Data.Barter exposing (..) - -import AssocList -import Dict -import Evergreen.V85.Data.Item - - -type Message - = BarterIsEmpty - | PlayerOfferNotValuableEnough - | YouGaveStuffForFree - - -type TransferNPosition - = PlayerKeptItem Evergreen.V85.Data.Item.Id - | VendorKeptItem Evergreen.V85.Data.Item.Id - | PlayerTradedItem Evergreen.V85.Data.Item.Id - | VendorTradedItem Evergreen.V85.Data.Item.Id - | PlayerKeptCaps - | VendorKeptCaps - | PlayerTradedCaps - | VendorTradedCaps - - -type alias State = - { playerItems : Dict.Dict Evergreen.V85.Data.Item.Id Int - , vendorItems : Dict.Dict Evergreen.V85.Data.Item.Id Int - , playerCaps : Int - , vendorCaps : Int - , lastMessage : Maybe Message - , transferNInputs : AssocList.Dict TransferNPosition String - , transferNHover : Maybe TransferNPosition - } diff --git a/src/Evergreen/V85/Data/Enemy.elm b/src/Evergreen/V85/Data/Enemy.elm deleted file mode 100644 index afd5af7a..00000000 --- a/src/Evergreen/V85/Data/Enemy.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V85.Data.Enemy exposing (..) - - -type Type - = GiantAnt - | ToughGiantAnt - | LesserRadscorpion - | Radscorpion diff --git a/src/Evergreen/V85/Data/Fight.elm b/src/Evergreen/V85/Data/Fight.elm deleted file mode 100644 index 73f4b8aa..00000000 --- a/src/Evergreen/V85/Data/Fight.elm +++ /dev/null @@ -1,81 +0,0 @@ -module Evergreen.V85.Data.Fight exposing (..) - -import AssocList -import AssocSet -import Evergreen.V85.Data.Enemy -import Evergreen.V85.Data.Fight.ShotType -import Evergreen.V85.Data.Item -import Evergreen.V85.Data.Perk -import Evergreen.V85.Data.Player.PlayerName -import Evergreen.V85.Data.Skill -import Evergreen.V85.Data.Special -import Evergreen.V85.Data.Trait -import Evergreen.V85.Logic - - -type OpponentType - = Npc Evergreen.V85.Data.Enemy.Type - | Player Evergreen.V85.Data.Player.PlayerName.PlayerName - - -type Who - = Attacker - | Target - - -type Action - = Start - { distanceHexes : Int - } - | ComeCloser - { hexes : Int - , remainingDistanceHexes : Int - } - | Attack - { damage : Int - , shotType : Evergreen.V85.Data.Fight.ShotType.ShotType - , remainingHp : Int - , isCritical : Bool - } - | Miss - { shotType : Evergreen.V85.Data.Fight.ShotType.ShotType - } - - -type Result - = AttackerWon - { xpGained : Int - , capsGained : Int - } - | TargetWon - { xpGained : Int - , capsGained : Int - } - | TargetAlreadyDead - | BothDead - | NobodyDead - - -type alias Info = - { attacker : OpponentType - , target : OpponentType - , log : List ( Who, Action ) - , result : Result - } - - -type alias Opponent = - { type_ : OpponentType - , hp : Int - , maxHp : Int - , maxAp : Int - , sequence : Int - , traits : AssocSet.Set Evergreen.V85.Data.Trait.Trait - , perks : AssocList.Dict Evergreen.V85.Data.Perk.Perk Int - , caps : Int - , equippedArmor : Maybe Evergreen.V85.Data.Item.Kind - , naturalArmorClass : Int - , attackStats : Evergreen.V85.Logic.AttackStats - , addedSkillPercentages : AssocList.Dict Evergreen.V85.Data.Skill.Skill Int - , special : Evergreen.V85.Data.Special.Special - } diff --git a/src/Evergreen/V85/Data/Fight/Generator.elm b/src/Evergreen/V85/Data/Fight/Generator.elm deleted file mode 100644 index 98acce20..00000000 --- a/src/Evergreen/V85/Data/Fight/Generator.elm +++ /dev/null @@ -1,12 +0,0 @@ -module Evergreen.V85.Data.Fight.Generator exposing (..) - -import Evergreen.V85.Data.Fight -import Evergreen.V85.Data.Message - - -type alias Fight = - { finalAttacker : Evergreen.V85.Data.Fight.Opponent - , finalTarget : Evergreen.V85.Data.Fight.Opponent - , fightInfo : Evergreen.V85.Data.Fight.Info - , messageForTarget : Evergreen.V85.Data.Message.Message - } diff --git a/src/Evergreen/V85/Data/Fight/ShotType.elm b/src/Evergreen/V85/Data/Fight/ShotType.elm deleted file mode 100644 index 4e4bf2a1..00000000 --- a/src/Evergreen/V85/Data/Fight/ShotType.elm +++ /dev/null @@ -1,17 +0,0 @@ -module Evergreen.V85.Data.Fight.ShotType exposing (..) - - -type AimedShot - = Head - | Torso - | Eyes - | Groin - | LeftArm - | RightArm - | LeftLeg - | RightLeg - - -type ShotType - = NormalShot - | AimedShot AimedShot diff --git a/src/Evergreen/V85/Data/HealthStatus.elm b/src/Evergreen/V85/Data/HealthStatus.elm deleted file mode 100644 index b57c0783..00000000 --- a/src/Evergreen/V85/Data/HealthStatus.elm +++ /dev/null @@ -1,16 +0,0 @@ -module Evergreen.V85.Data.HealthStatus exposing (..) - - -type HealthStatus - = ExactHp - { current : Int - , max : Int - } - | Unhurt - | SlightlyWounded - | Wounded - | SeverelyWounded - | AlmostDead - | Dead - | Alive - | Unknown diff --git a/src/Evergreen/V85/Data/Item.elm b/src/Evergreen/V85/Data/Item.elm deleted file mode 100644 index ce4e7c26..00000000 --- a/src/Evergreen/V85/Data/Item.elm +++ /dev/null @@ -1,26 +0,0 @@ -module Evergreen.V85.Data.Item exposing (..) - - -type alias Id = - Int - - -type Kind - = HealingPowder - | Stimpak - | BigBookOfScience - | DeansElectronics - | FirstAidBook - | GunsAndBullets - | ScoutHandbook - | Robes - | LeatherJacket - | LeatherArmor - | MetalArmor - - -type alias Item = - { id : Id - , kind : Kind - , count : Int - } diff --git a/src/Evergreen/V85/Data/Map.elm b/src/Evergreen/V85/Data/Map.elm deleted file mode 100644 index c874da98..00000000 --- a/src/Evergreen/V85/Data/Map.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V85.Data.Map exposing (..) - - -type alias TileNum = - Int - - -type alias TileCoords = - ( Int, Int ) diff --git a/src/Evergreen/V85/Data/Message.elm b/src/Evergreen/V85/Data/Message.elm deleted file mode 100644 index 53bd7c41..00000000 --- a/src/Evergreen/V85/Data/Message.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V85.Data.Message exposing (..) - -import Evergreen.V85.Data.Fight -import Evergreen.V85.Data.Player.PlayerName -import Time - - -type Type - = Welcome - | YouAdvancedLevel - { newLevel : Int - } - | YouWereAttacked - { attacker : Evergreen.V85.Data.Player.PlayerName.PlayerName - , fightInfo : Evergreen.V85.Data.Fight.Info - } - - -type alias Message = - { type_ : Type - , hasBeenRead : Bool - , date : Time.Posix - } diff --git a/src/Evergreen/V85/Data/NewChar.elm b/src/Evergreen/V85/Data/NewChar.elm deleted file mode 100644 index 27f3832e..00000000 --- a/src/Evergreen/V85/Data/NewChar.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V85.Data.NewChar exposing (..) - -import AssocSet -import Evergreen.V85.Data.Skill -import Evergreen.V85.Data.Special -import Evergreen.V85.Data.Trait - - -type CreationError - = DoesNotHaveThreeTaggedSkills - | HasSpecialPointsLeft - | UsedMoreSpecialPointsThanAvailable - | HasSpecialOutOfRange - | HasMoreThanTwoTraits - - -type alias NewChar = - { baseSpecial : Evergreen.V85.Data.Special.Special - , availableSpecial : Int - , taggedSkills : AssocSet.Set Evergreen.V85.Data.Skill.Skill - , traits : AssocSet.Set Evergreen.V85.Data.Trait.Trait - , error : Maybe CreationError - } diff --git a/src/Evergreen/V85/Data/Perk.elm b/src/Evergreen/V85/Data/Perk.elm deleted file mode 100644 index f4a92da8..00000000 --- a/src/Evergreen/V85/Data/Perk.elm +++ /dev/null @@ -1,25 +0,0 @@ -module Evergreen.V85.Data.Perk exposing (..) - - -type Perk - = BonusHthDamage - | MasterTrader - | Awareness - | CautiousNature - | Comprehension - | EarlierSequence - | FasterHealing - | HereAndNow - | Survivalist - | Educated - | MoreCriticals - | BetterCriticals - | Tag - | GainStrength - | GainPerception - | GainEndurance - | GainCharisma - | GainIntelligence - | GainAgility - | GainLuck - | Slayer diff --git a/src/Evergreen/V85/Data/Player.elm b/src/Evergreen/V85/Data/Player.elm deleted file mode 100644 index 4ad5e69b..00000000 --- a/src/Evergreen/V85/Data/Player.elm +++ /dev/null @@ -1,77 +0,0 @@ -module Evergreen.V85.Data.Player exposing (..) - -import AssocList -import AssocSet -import Dict -import Evergreen.V85.Data.Auth -import Evergreen.V85.Data.HealthStatus -import Evergreen.V85.Data.Item -import Evergreen.V85.Data.Map -import Evergreen.V85.Data.Message -import Evergreen.V85.Data.Perk -import Evergreen.V85.Data.Player.PlayerName -import Evergreen.V85.Data.Skill -import Evergreen.V85.Data.Special -import Evergreen.V85.Data.Trait -import Evergreen.V85.Data.Xp - - -type alias COtherPlayer = - { level : Evergreen.V85.Data.Xp.Level - , name : Evergreen.V85.Data.Player.PlayerName.PlayerName - , wins : Int - , losses : Int - , healthStatus : Evergreen.V85.Data.HealthStatus.HealthStatus - } - - -type alias CPlayer = - { hp : Int - , maxHp : Int - , xp : Evergreen.V85.Data.Xp.Xp - , name : Evergreen.V85.Data.Player.PlayerName.PlayerName - , special : Evergreen.V85.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V85.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V85.Data.Perk.Perk Int - , messages : List Evergreen.V85.Data.Message.Message - , items : Dict.Dict Evergreen.V85.Data.Item.Id Evergreen.V85.Data.Item.Item - , traits : AssocSet.Set Evergreen.V85.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V85.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V85.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - , equippedArmor : Maybe Evergreen.V85.Data.Item.Item - } - - -type Player a - = NeedsCharCreated (Evergreen.V85.Data.Auth.Auth Evergreen.V85.Data.Auth.Verified) - | Player a - - -type alias SPlayer = - { name : Evergreen.V85.Data.Player.PlayerName.PlayerName - , password : Evergreen.V85.Data.Auth.Password Evergreen.V85.Data.Auth.Verified - , hp : Int - , maxHp : Int - , xp : Int - , special : Evergreen.V85.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V85.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V85.Data.Perk.Perk Int - , messages : List Evergreen.V85.Data.Message.Message - , items : Dict.Dict Evergreen.V85.Data.Item.Id Evergreen.V85.Data.Item.Item - , traits : AssocSet.Set Evergreen.V85.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V85.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V85.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - , equippedArmor : Maybe Evergreen.V85.Data.Item.Item - } diff --git a/src/Evergreen/V85/Data/Player/PlayerName.elm b/src/Evergreen/V85/Data/Player/PlayerName.elm deleted file mode 100644 index e1367e48..00000000 --- a/src/Evergreen/V85/Data/Player/PlayerName.elm +++ /dev/null @@ -1,5 +0,0 @@ -module Evergreen.V85.Data.Player.PlayerName exposing (..) - - -type alias PlayerName = - String diff --git a/src/Evergreen/V85/Data/Skill.elm b/src/Evergreen/V85/Data/Skill.elm deleted file mode 100644 index faf4ce57..00000000 --- a/src/Evergreen/V85/Data/Skill.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V85.Data.Skill exposing (..) - - -type Skill - = SmallGuns - | BigGuns - | EnergyWeapons - | Unarmed - | MeleeWeapons - | Throwing - | FirstAid - | Doctor - | Sneak - | Lockpick - | Steal - | Traps - | Science - | Repair - | Speech - | Barter - | Gambling - | Outdoorsman diff --git a/src/Evergreen/V85/Data/Special.elm b/src/Evergreen/V85/Data/Special.elm deleted file mode 100644 index 619d394a..00000000 --- a/src/Evergreen/V85/Data/Special.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V85.Data.Special exposing (..) - - -type alias Special = - { strength : Int - , perception : Int - , endurance : Int - , charisma : Int - , intelligence : Int - , agility : Int - , luck : Int - } - - -type Type - = Strength - | Perception - | Endurance - | Charisma - | Intelligence - | Agility - | Luck diff --git a/src/Evergreen/V85/Data/Trait.elm b/src/Evergreen/V85/Data/Trait.elm deleted file mode 100644 index 57e8b256..00000000 --- a/src/Evergreen/V85/Data/Trait.elm +++ /dev/null @@ -1,11 +0,0 @@ -module Evergreen.V85.Data.Trait exposing (..) - - -type Trait - = Kamikaze - | Bruiser - | Gifted - | SmallFrame - | Skilled - | HeavyHanded - | Finesse diff --git a/src/Evergreen/V85/Data/Vendor.elm b/src/Evergreen/V85/Data/Vendor.elm deleted file mode 100644 index 830a1cec..00000000 --- a/src/Evergreen/V85/Data/Vendor.elm +++ /dev/null @@ -1,20 +0,0 @@ -module Evergreen.V85.Data.Vendor exposing (..) - -import Dict -import Evergreen.V85.Data.Item - - -type Name - = ArroyoHakunin - | KlamathMaidaBuckner - | DenFlick - | ModocJo - | VaultCityHappyHarry - - -type alias Vendor = - { name : Name - , items : Dict.Dict Evergreen.V85.Data.Item.Id Evergreen.V85.Data.Item.Item - , caps : Int - , barterSkill : Int - } diff --git a/src/Evergreen/V85/Data/World.elm b/src/Evergreen/V85/Data/World.elm deleted file mode 100644 index a9223d39..00000000 --- a/src/Evergreen/V85/Data/World.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.V85.Data.World exposing (..) - -import AssocList -import Evergreen.V85.Data.Auth -import Evergreen.V85.Data.Player -import Evergreen.V85.Data.Player.PlayerName -import Evergreen.V85.Data.Vendor -import Time - - -type alias WorldLoggedOutData = - { players : List Evergreen.V85.Data.Player.COtherPlayer - } - - -type alias WorldLoggedInData = - { player : Evergreen.V85.Data.Player.Player Evergreen.V85.Data.Player.CPlayer - , otherPlayers : List Evergreen.V85.Data.Player.COtherPlayer - , playerRank : Int - , vendors : AssocList.Dict Evergreen.V85.Data.Vendor.Name Evergreen.V85.Data.Vendor.Vendor - } - - -type alias AdminData = - { players : List (Evergreen.V85.Data.Player.Player Evergreen.V85.Data.Player.SPlayer) - , loggedInPlayers : List Evergreen.V85.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - } - - -type World - = WorldNotInitialized (Evergreen.V85.Data.Auth.Auth Evergreen.V85.Data.Auth.Plaintext) - | WorldLoggedOut (Evergreen.V85.Data.Auth.Auth Evergreen.V85.Data.Auth.Plaintext) WorldLoggedOutData - | WorldLoggedIn WorldLoggedInData - | WorldAdmin AdminData diff --git a/src/Evergreen/V85/Data/Xp.elm b/src/Evergreen/V85/Data/Xp.elm deleted file mode 100644 index ffb9124c..00000000 --- a/src/Evergreen/V85/Data/Xp.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V85.Data.Xp exposing (..) - - -type alias Level = - Int - - -type alias Xp = - Int diff --git a/src/Evergreen/V85/Frontend/Route.elm b/src/Evergreen/V85/Frontend/Route.elm deleted file mode 100644 index 1ef2e34a..00000000 --- a/src/Evergreen/V85/Frontend/Route.elm +++ /dev/null @@ -1,31 +0,0 @@ -module Evergreen.V85.Frontend.Route exposing (..) - -import Evergreen.V85.Data.Barter -import Evergreen.V85.Data.Fight -import Evergreen.V85.Data.Message - - -type TownRoute - = MainSquare - | Store - { barter : Evergreen.V85.Data.Barter.State - } - - -type AdminRoute - = LoggedIn - - -type Route - = Character - | Inventory - | Map - | Ladder - | Town TownRoute - | About - | News - | Fight Evergreen.V85.Data.Fight.Info - | Messages - | Message Evergreen.V85.Data.Message.Message - | CharCreation - | Admin AdminRoute diff --git a/src/Evergreen/V85/Logic.elm b/src/Evergreen/V85/Logic.elm deleted file mode 100644 index b17580c7..00000000 --- a/src/Evergreen/V85/Logic.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V85.Logic exposing (..) - - -type alias AttackStats = - { minDamage : Int - , maxDamage : Int - , criticalChanceBonus : Int - } diff --git a/src/Evergreen/V85/Types.elm b/src/Evergreen/V85/Types.elm deleted file mode 100644 index 9eba620f..00000000 --- a/src/Evergreen/V85/Types.elm +++ /dev/null @@ -1,160 +0,0 @@ -module Evergreen.V85.Types exposing (..) - -import AssocList -import Browser -import Browser.Navigation -import Dict -import Evergreen.V85.Data.Auth -import Evergreen.V85.Data.Barter -import Evergreen.V85.Data.Fight -import Evergreen.V85.Data.Fight.Generator -import Evergreen.V85.Data.Item -import Evergreen.V85.Data.Map -import Evergreen.V85.Data.Message -import Evergreen.V85.Data.NewChar -import Evergreen.V85.Data.Perk -import Evergreen.V85.Data.Player -import Evergreen.V85.Data.Player.PlayerName -import Evergreen.V85.Data.Skill -import Evergreen.V85.Data.Special -import Evergreen.V85.Data.Trait -import Evergreen.V85.Data.Vendor -import Evergreen.V85.Data.World -import Evergreen.V85.Frontend.Route -import File exposing (File) -import Lamdera -import Set -import Time -import Url - - -type alias FrontendModel = - { key : Browser.Navigation.Key - , time : Time.Posix - , zone : Time.Zone - , route : Evergreen.V85.Frontend.Route.Route - , world : Evergreen.V85.Data.World.World - , newChar : Evergreen.V85.Data.NewChar.NewChar - , alertMessage : Maybe String - , mapMouseCoords : Maybe ( Evergreen.V85.Data.Map.TileCoords, Set.Set Evergreen.V85.Data.Map.TileCoords ) - } - - -type alias BackendModel = - { players : Dict.Dict Evergreen.V85.Data.Player.PlayerName.PlayerName (Evergreen.V85.Data.Player.Player Evergreen.V85.Data.Player.SPlayer) - , loggedInPlayers : Dict.Dict Lamdera.ClientId Evergreen.V85.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - , adminLoggedIn : Maybe ( Lamdera.ClientId, Lamdera.SessionId ) - , time : Time.Posix - , vendors : AssocList.Dict Evergreen.V85.Data.Vendor.Name Evergreen.V85.Data.Vendor.Vendor - , lastItemId : Int - } - - -type BarterMsg - = AddPlayerItem Evergreen.V85.Data.Item.Id Int - | AddVendorItem Evergreen.V85.Data.Item.Id Int - | AddPlayerCaps Int - | AddVendorCaps Int - | RemovePlayerItem Evergreen.V85.Data.Item.Id Int - | RemoveVendorItem Evergreen.V85.Data.Item.Id Int - | RemovePlayerCaps Int - | RemoveVendorCaps Int - | ResetBarter - | ConfirmBarter - | SetTransferNInput Evergreen.V85.Data.Barter.TransferNPosition String - | SetTransferNHover Evergreen.V85.Data.Barter.TransferNPosition - | UnsetTransferNHover - - -type FrontendMsg - = UrlClicked Browser.UrlRequest - | UrlChanged Url.Url - | GoToRoute Evergreen.V85.Frontend.Route.Route - | Logout - | Login - | Register - | GotZone Time.Zone - | GotTime Time.Posix - | AskToFight Evergreen.V85.Data.Player.PlayerName.PlayerName - | AskToHeal - | AskToUseItem Evergreen.V85.Data.Item.Id - | AskToWander - | AskToChoosePerk Evergreen.V85.Data.Perk.Perk - | AskToEquipItem Evergreen.V85.Data.Item.Id - | AskToUnequipArmor - | AskForExport - | ImportButtonClicked - | ImportFileSelected File - | AskToImport String - | Refresh - | AskToTagSkill Evergreen.V85.Data.Skill.Skill - | AskToUseSkillPoints Evergreen.V85.Data.Skill.Skill - | SetAuthName String - | SetAuthPassword String - | CreateChar - | NewCharIncSpecial Evergreen.V85.Data.Special.Type - | NewCharDecSpecial Evergreen.V85.Data.Special.Type - | NewCharToggleTaggedSkill Evergreen.V85.Data.Skill.Skill - | NewCharToggleTrait Evergreen.V85.Data.Trait.Trait - | MapMouseAtCoords Evergreen.V85.Data.Map.TileCoords - | MapMouseOut - | MapMouseClick - | OpenMessage Evergreen.V85.Data.Message.Message - | AskToRemoveMessage Evergreen.V85.Data.Message.Message - | BarterMsg BarterMsg - - -type AdminToBackend - = ExportJson - | ImportJson String - - -type ToBackend - = LogMeIn (Evergreen.V85.Data.Auth.Auth Evergreen.V85.Data.Auth.Hashed) - | RegisterMe (Evergreen.V85.Data.Auth.Auth Evergreen.V85.Data.Auth.Hashed) - | CreateNewChar Evergreen.V85.Data.NewChar.NewChar - | LogMeOut - | Fight Evergreen.V85.Data.Player.PlayerName.PlayerName - | HealMe - | UseItem Evergreen.V85.Data.Item.Id - | Wander - | EquipItem Evergreen.V85.Data.Item.Id - | UnequipArmor - | RefreshPlease - | TagSkill Evergreen.V85.Data.Skill.Skill - | UseSkillPoints Evergreen.V85.Data.Skill.Skill - | ChoosePerk Evergreen.V85.Data.Perk.Perk - | MoveTo Evergreen.V85.Data.Map.TileCoords (Set.Set Evergreen.V85.Data.Map.TileCoords) - | MessageWasRead Evergreen.V85.Data.Message.Message - | RemoveMessage Evergreen.V85.Data.Message.Message - | Barter Evergreen.V85.Data.Barter.State - | AdminToBackend AdminToBackend - - -type BackendMsg - = Connected Lamdera.SessionId Lamdera.ClientId - | Disconnected Lamdera.SessionId Lamdera.ClientId - | GeneratedFight Lamdera.ClientId Evergreen.V85.Data.Player.SPlayer Evergreen.V85.Data.Fight.Generator.Fight - | GeneratedNewVendorsStock ( AssocList.Dict Evergreen.V85.Data.Vendor.Name Evergreen.V85.Data.Vendor.Vendor, Int ) - | Tick Time.Posix - | CreateNewCharWithTime Lamdera.ClientId Evergreen.V85.Data.NewChar.NewChar Time.Posix - | LoggedToBackendMsg - - -type ToFrontend - = YourCurrentWorld Evergreen.V85.Data.World.WorldLoggedInData - | InitWorld Evergreen.V85.Data.World.WorldLoggedOutData - | RefreshedLoggedOut Evergreen.V85.Data.World.WorldLoggedOutData - | CurrentAdminData Evergreen.V85.Data.World.AdminData - | YourFightResult ( Evergreen.V85.Data.Fight.Info, Evergreen.V85.Data.World.WorldLoggedInData ) - | YoureLoggedIn Evergreen.V85.Data.World.WorldLoggedInData - | YoureRegistered Evergreen.V85.Data.World.WorldLoggedInData - | CharCreationError Evergreen.V85.Data.NewChar.CreationError - | YouHaveCreatedChar Evergreen.V85.Data.World.WorldLoggedInData - | YoureLoggedOut Evergreen.V85.Data.World.WorldLoggedOutData - | AlertMessage String - | YoureLoggedInAsAdmin Evergreen.V85.Data.World.AdminData - | JsonExportDone String - | BarterDone ( Evergreen.V85.Data.World.WorldLoggedInData, Maybe Evergreen.V85.Data.Barter.Message ) - | BarterMessage Evergreen.V85.Data.Barter.Message diff --git a/src/Evergreen/V87/Data/Auth.elm b/src/Evergreen/V87/Data/Auth.elm deleted file mode 100644 index 16bd37c1..00000000 --- a/src/Evergreen/V87/Data/Auth.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V87.Data.Auth exposing (..) - - -type Plaintext - = Plaintext - - -type Password a - = Password String - - -type alias Auth a = - { name : String - , password : Password a - } - - -type Verified - = Verified - - -type Hashed - = Hashed diff --git a/src/Evergreen/V87/Data/Barter.elm b/src/Evergreen/V87/Data/Barter.elm deleted file mode 100644 index 9ab8d432..00000000 --- a/src/Evergreen/V87/Data/Barter.elm +++ /dev/null @@ -1,33 +0,0 @@ -module Evergreen.V87.Data.Barter exposing (..) - -import AssocList -import Dict -import Evergreen.V87.Data.Item - - -type Message - = BarterIsEmpty - | PlayerOfferNotValuableEnough - | YouGaveStuffForFree - - -type TransferNPosition - = PlayerKeptItem Evergreen.V87.Data.Item.Id - | VendorKeptItem Evergreen.V87.Data.Item.Id - | PlayerTradedItem Evergreen.V87.Data.Item.Id - | VendorTradedItem Evergreen.V87.Data.Item.Id - | PlayerKeptCaps - | VendorKeptCaps - | PlayerTradedCaps - | VendorTradedCaps - - -type alias State = - { playerItems : Dict.Dict Evergreen.V87.Data.Item.Id Int - , vendorItems : Dict.Dict Evergreen.V87.Data.Item.Id Int - , playerCaps : Int - , vendorCaps : Int - , lastMessage : Maybe Message - , transferNInputs : AssocList.Dict TransferNPosition String - , transferNHover : Maybe TransferNPosition - } diff --git a/src/Evergreen/V87/Data/Enemy.elm b/src/Evergreen/V87/Data/Enemy.elm deleted file mode 100644 index f294efbb..00000000 --- a/src/Evergreen/V87/Data/Enemy.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V87.Data.Enemy exposing (..) - - -type Type - = GiantAnt - | ToughGiantAnt - | LesserRadscorpion - | Radscorpion diff --git a/src/Evergreen/V87/Data/Fight.elm b/src/Evergreen/V87/Data/Fight.elm deleted file mode 100644 index 11231bc0..00000000 --- a/src/Evergreen/V87/Data/Fight.elm +++ /dev/null @@ -1,81 +0,0 @@ -module Evergreen.V87.Data.Fight exposing (..) - -import AssocList -import AssocSet -import Evergreen.V87.Data.Enemy -import Evergreen.V87.Data.Fight.ShotType -import Evergreen.V87.Data.Item -import Evergreen.V87.Data.Perk -import Evergreen.V87.Data.Player.PlayerName -import Evergreen.V87.Data.Skill -import Evergreen.V87.Data.Special -import Evergreen.V87.Data.Trait -import Evergreen.V87.Logic - - -type OpponentType - = Npc Evergreen.V87.Data.Enemy.Type - | Player Evergreen.V87.Data.Player.PlayerName.PlayerName - - -type Who - = Attacker - | Target - - -type Action - = Start - { distanceHexes : Int - } - | ComeCloser - { hexes : Int - , remainingDistanceHexes : Int - } - | Attack - { damage : Int - , shotType : Evergreen.V87.Data.Fight.ShotType.ShotType - , remainingHp : Int - , isCritical : Bool - } - | Miss - { shotType : Evergreen.V87.Data.Fight.ShotType.ShotType - } - - -type Result - = AttackerWon - { xpGained : Int - , capsGained : Int - } - | TargetWon - { xpGained : Int - , capsGained : Int - } - | TargetAlreadyDead - | BothDead - | NobodyDead - - -type alias Info = - { attacker : OpponentType - , target : OpponentType - , log : List ( Who, Action ) - , result : Result - } - - -type alias Opponent = - { type_ : OpponentType - , hp : Int - , maxHp : Int - , maxAp : Int - , sequence : Int - , traits : AssocSet.Set Evergreen.V87.Data.Trait.Trait - , perks : AssocList.Dict Evergreen.V87.Data.Perk.Perk Int - , caps : Int - , equippedArmor : Maybe Evergreen.V87.Data.Item.Kind - , naturalArmorClass : Int - , attackStats : Evergreen.V87.Logic.AttackStats - , addedSkillPercentages : AssocList.Dict Evergreen.V87.Data.Skill.Skill Int - , special : Evergreen.V87.Data.Special.Special - } diff --git a/src/Evergreen/V87/Data/Fight/Generator.elm b/src/Evergreen/V87/Data/Fight/Generator.elm deleted file mode 100644 index 68d0932a..00000000 --- a/src/Evergreen/V87/Data/Fight/Generator.elm +++ /dev/null @@ -1,12 +0,0 @@ -module Evergreen.V87.Data.Fight.Generator exposing (..) - -import Evergreen.V87.Data.Fight -import Evergreen.V87.Data.Message - - -type alias Fight = - { finalAttacker : Evergreen.V87.Data.Fight.Opponent - , finalTarget : Evergreen.V87.Data.Fight.Opponent - , fightInfo : Evergreen.V87.Data.Fight.Info - , messageForTarget : Evergreen.V87.Data.Message.Message - } diff --git a/src/Evergreen/V87/Data/Fight/ShotType.elm b/src/Evergreen/V87/Data/Fight/ShotType.elm deleted file mode 100644 index 672b0aee..00000000 --- a/src/Evergreen/V87/Data/Fight/ShotType.elm +++ /dev/null @@ -1,17 +0,0 @@ -module Evergreen.V87.Data.Fight.ShotType exposing (..) - - -type AimedShot - = Head - | Torso - | Eyes - | Groin - | LeftArm - | RightArm - | LeftLeg - | RightLeg - - -type ShotType - = NormalShot - | AimedShot AimedShot diff --git a/src/Evergreen/V87/Data/HealthStatus.elm b/src/Evergreen/V87/Data/HealthStatus.elm deleted file mode 100644 index d6c98af1..00000000 --- a/src/Evergreen/V87/Data/HealthStatus.elm +++ /dev/null @@ -1,16 +0,0 @@ -module Evergreen.V87.Data.HealthStatus exposing (..) - - -type HealthStatus - = ExactHp - { current : Int - , max : Int - } - | Unhurt - | SlightlyWounded - | Wounded - | SeverelyWounded - | AlmostDead - | Dead - | Alive - | Unknown diff --git a/src/Evergreen/V87/Data/Item.elm b/src/Evergreen/V87/Data/Item.elm deleted file mode 100644 index ed824a48..00000000 --- a/src/Evergreen/V87/Data/Item.elm +++ /dev/null @@ -1,26 +0,0 @@ -module Evergreen.V87.Data.Item exposing (..) - - -type alias Id = - Int - - -type Kind - = HealingPowder - | Stimpak - | BigBookOfScience - | DeansElectronics - | FirstAidBook - | GunsAndBullets - | ScoutHandbook - | Robes - | LeatherJacket - | LeatherArmor - | MetalArmor - - -type alias Item = - { id : Id - , kind : Kind - , count : Int - } diff --git a/src/Evergreen/V87/Data/Map.elm b/src/Evergreen/V87/Data/Map.elm deleted file mode 100644 index cfe63130..00000000 --- a/src/Evergreen/V87/Data/Map.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V87.Data.Map exposing (..) - - -type alias TileNum = - Int - - -type alias TileCoords = - ( Int, Int ) diff --git a/src/Evergreen/V87/Data/Message.elm b/src/Evergreen/V87/Data/Message.elm deleted file mode 100644 index d77aea33..00000000 --- a/src/Evergreen/V87/Data/Message.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V87.Data.Message exposing (..) - -import Evergreen.V87.Data.Fight -import Evergreen.V87.Data.Player.PlayerName -import Time - - -type Type - = Welcome - | YouAdvancedLevel - { newLevel : Int - } - | YouWereAttacked - { attacker : Evergreen.V87.Data.Player.PlayerName.PlayerName - , fightInfo : Evergreen.V87.Data.Fight.Info - } - - -type alias Message = - { type_ : Type - , hasBeenRead : Bool - , date : Time.Posix - } diff --git a/src/Evergreen/V87/Data/NewChar.elm b/src/Evergreen/V87/Data/NewChar.elm deleted file mode 100644 index 8167182b..00000000 --- a/src/Evergreen/V87/Data/NewChar.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V87.Data.NewChar exposing (..) - -import AssocSet -import Evergreen.V87.Data.Skill -import Evergreen.V87.Data.Special -import Evergreen.V87.Data.Trait - - -type CreationError - = DoesNotHaveThreeTaggedSkills - | HasSpecialPointsLeft - | UsedMoreSpecialPointsThanAvailable - | HasSpecialOutOfRange - | HasMoreThanTwoTraits - - -type alias NewChar = - { baseSpecial : Evergreen.V87.Data.Special.Special - , availableSpecial : Int - , taggedSkills : AssocSet.Set Evergreen.V87.Data.Skill.Skill - , traits : AssocSet.Set Evergreen.V87.Data.Trait.Trait - , error : Maybe CreationError - } diff --git a/src/Evergreen/V87/Data/Perk.elm b/src/Evergreen/V87/Data/Perk.elm deleted file mode 100644 index e632325b..00000000 --- a/src/Evergreen/V87/Data/Perk.elm +++ /dev/null @@ -1,45 +0,0 @@ -module Evergreen.V87.Data.Perk exposing (..) - - -type Perk - = BonusHthDamage - | Awareness - | CautiousNature - | Comprehension - | EarlierSequence - | FasterHealing - | HereAndNow - | Survivalist - | SwiftLearner - | Thief - | Toughness - | AdrenalineRush - | Educated - | FortuneFinder - | Gambler - | MoreCriticals - | Negotiator - | Pathfinder - | Ranger - | Salesman - | BetterCriticals - | Dodger - | Speaker - | ActionBoy - | GainStrength - | GainPerception - | GainEndurance - | GainCharisma - | GainIntelligence - | GainAgility - | GainLuck - | HthEvade - | Lifegiver - | LivingAnatomy - | MasterThief - | MasterTrader - | Medic - | MrFixit - | Tag - | BonusHthAttacks - | Slayer diff --git a/src/Evergreen/V87/Data/Player.elm b/src/Evergreen/V87/Data/Player.elm deleted file mode 100644 index 492c39de..00000000 --- a/src/Evergreen/V87/Data/Player.elm +++ /dev/null @@ -1,77 +0,0 @@ -module Evergreen.V87.Data.Player exposing (..) - -import AssocList -import AssocSet -import Dict -import Evergreen.V87.Data.Auth -import Evergreen.V87.Data.HealthStatus -import Evergreen.V87.Data.Item -import Evergreen.V87.Data.Map -import Evergreen.V87.Data.Message -import Evergreen.V87.Data.Perk -import Evergreen.V87.Data.Player.PlayerName -import Evergreen.V87.Data.Skill -import Evergreen.V87.Data.Special -import Evergreen.V87.Data.Trait -import Evergreen.V87.Data.Xp - - -type alias COtherPlayer = - { level : Evergreen.V87.Data.Xp.Level - , name : Evergreen.V87.Data.Player.PlayerName.PlayerName - , wins : Int - , losses : Int - , healthStatus : Evergreen.V87.Data.HealthStatus.HealthStatus - } - - -type alias CPlayer = - { hp : Int - , maxHp : Int - , xp : Evergreen.V87.Data.Xp.Xp - , name : Evergreen.V87.Data.Player.PlayerName.PlayerName - , special : Evergreen.V87.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V87.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V87.Data.Perk.Perk Int - , messages : List Evergreen.V87.Data.Message.Message - , items : Dict.Dict Evergreen.V87.Data.Item.Id Evergreen.V87.Data.Item.Item - , traits : AssocSet.Set Evergreen.V87.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V87.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V87.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - , equippedArmor : Maybe Evergreen.V87.Data.Item.Item - } - - -type Player a - = NeedsCharCreated (Evergreen.V87.Data.Auth.Auth Evergreen.V87.Data.Auth.Verified) - | Player a - - -type alias SPlayer = - { name : Evergreen.V87.Data.Player.PlayerName.PlayerName - , password : Evergreen.V87.Data.Auth.Password Evergreen.V87.Data.Auth.Verified - , hp : Int - , maxHp : Int - , xp : Int - , special : Evergreen.V87.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V87.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V87.Data.Perk.Perk Int - , messages : List Evergreen.V87.Data.Message.Message - , items : Dict.Dict Evergreen.V87.Data.Item.Id Evergreen.V87.Data.Item.Item - , traits : AssocSet.Set Evergreen.V87.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V87.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V87.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - , equippedArmor : Maybe Evergreen.V87.Data.Item.Item - } diff --git a/src/Evergreen/V87/Data/Player/PlayerName.elm b/src/Evergreen/V87/Data/Player/PlayerName.elm deleted file mode 100644 index c876b162..00000000 --- a/src/Evergreen/V87/Data/Player/PlayerName.elm +++ /dev/null @@ -1,5 +0,0 @@ -module Evergreen.V87.Data.Player.PlayerName exposing (..) - - -type alias PlayerName = - String diff --git a/src/Evergreen/V87/Data/Skill.elm b/src/Evergreen/V87/Data/Skill.elm deleted file mode 100644 index 35e3da74..00000000 --- a/src/Evergreen/V87/Data/Skill.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V87.Data.Skill exposing (..) - - -type Skill - = SmallGuns - | BigGuns - | EnergyWeapons - | Unarmed - | MeleeWeapons - | Throwing - | FirstAid - | Doctor - | Sneak - | Lockpick - | Steal - | Traps - | Science - | Repair - | Speech - | Barter - | Gambling - | Outdoorsman diff --git a/src/Evergreen/V87/Data/Special.elm b/src/Evergreen/V87/Data/Special.elm deleted file mode 100644 index 8b7d7f75..00000000 --- a/src/Evergreen/V87/Data/Special.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V87.Data.Special exposing (..) - - -type alias Special = - { strength : Int - , perception : Int - , endurance : Int - , charisma : Int - , intelligence : Int - , agility : Int - , luck : Int - } - - -type Type - = Strength - | Perception - | Endurance - | Charisma - | Intelligence - | Agility - | Luck diff --git a/src/Evergreen/V87/Data/Trait.elm b/src/Evergreen/V87/Data/Trait.elm deleted file mode 100644 index 2448cd20..00000000 --- a/src/Evergreen/V87/Data/Trait.elm +++ /dev/null @@ -1,11 +0,0 @@ -module Evergreen.V87.Data.Trait exposing (..) - - -type Trait - = Kamikaze - | Bruiser - | Gifted - | SmallFrame - | Skilled - | HeavyHanded - | Finesse diff --git a/src/Evergreen/V87/Data/Vendor.elm b/src/Evergreen/V87/Data/Vendor.elm deleted file mode 100644 index bb353e71..00000000 --- a/src/Evergreen/V87/Data/Vendor.elm +++ /dev/null @@ -1,20 +0,0 @@ -module Evergreen.V87.Data.Vendor exposing (..) - -import Dict -import Evergreen.V87.Data.Item - - -type Name - = ArroyoHakunin - | KlamathMaidaBuckner - | DenFlick - | ModocJo - | VaultCityHappyHarry - - -type alias Vendor = - { name : Name - , items : Dict.Dict Evergreen.V87.Data.Item.Id Evergreen.V87.Data.Item.Item - , caps : Int - , barterSkill : Int - } diff --git a/src/Evergreen/V87/Data/World.elm b/src/Evergreen/V87/Data/World.elm deleted file mode 100644 index 2f2492ba..00000000 --- a/src/Evergreen/V87/Data/World.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.V87.Data.World exposing (..) - -import AssocList -import Evergreen.V87.Data.Auth -import Evergreen.V87.Data.Player -import Evergreen.V87.Data.Player.PlayerName -import Evergreen.V87.Data.Vendor -import Time - - -type alias WorldLoggedOutData = - { players : List Evergreen.V87.Data.Player.COtherPlayer - } - - -type alias WorldLoggedInData = - { player : Evergreen.V87.Data.Player.Player Evergreen.V87.Data.Player.CPlayer - , otherPlayers : List Evergreen.V87.Data.Player.COtherPlayer - , playerRank : Int - , vendors : AssocList.Dict Evergreen.V87.Data.Vendor.Name Evergreen.V87.Data.Vendor.Vendor - } - - -type alias AdminData = - { players : List (Evergreen.V87.Data.Player.Player Evergreen.V87.Data.Player.SPlayer) - , loggedInPlayers : List Evergreen.V87.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - } - - -type World - = WorldNotInitialized (Evergreen.V87.Data.Auth.Auth Evergreen.V87.Data.Auth.Plaintext) - | WorldLoggedOut (Evergreen.V87.Data.Auth.Auth Evergreen.V87.Data.Auth.Plaintext) WorldLoggedOutData - | WorldLoggedIn WorldLoggedInData - | WorldAdmin AdminData diff --git a/src/Evergreen/V87/Data/Xp.elm b/src/Evergreen/V87/Data/Xp.elm deleted file mode 100644 index b931cc73..00000000 --- a/src/Evergreen/V87/Data/Xp.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V87.Data.Xp exposing (..) - - -type alias Level = - Int - - -type alias Xp = - Int diff --git a/src/Evergreen/V87/Frontend/Route.elm b/src/Evergreen/V87/Frontend/Route.elm deleted file mode 100644 index 58e8b751..00000000 --- a/src/Evergreen/V87/Frontend/Route.elm +++ /dev/null @@ -1,31 +0,0 @@ -module Evergreen.V87.Frontend.Route exposing (..) - -import Evergreen.V87.Data.Barter -import Evergreen.V87.Data.Fight -import Evergreen.V87.Data.Message - - -type TownRoute - = MainSquare - | Store - { barter : Evergreen.V87.Data.Barter.State - } - - -type AdminRoute - = LoggedIn - - -type Route - = Character - | Inventory - | Map - | Ladder - | Town TownRoute - | About - | News - | Fight Evergreen.V87.Data.Fight.Info - | Messages - | Message Evergreen.V87.Data.Message.Message - | CharCreation - | Admin AdminRoute diff --git a/src/Evergreen/V87/Logic.elm b/src/Evergreen/V87/Logic.elm deleted file mode 100644 index b53ce033..00000000 --- a/src/Evergreen/V87/Logic.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V87.Logic exposing (..) - - -type alias AttackStats = - { minDamage : Int - , maxDamage : Int - , criticalChanceBonus : Int - } diff --git a/src/Evergreen/V87/Types.elm b/src/Evergreen/V87/Types.elm deleted file mode 100644 index 29b17310..00000000 --- a/src/Evergreen/V87/Types.elm +++ /dev/null @@ -1,163 +0,0 @@ -module Evergreen.V87.Types exposing (..) - -import AssocList -import Browser -import Browser.Navigation -import Dict -import Evergreen.V87.Data.Auth -import Evergreen.V87.Data.Barter -import Evergreen.V87.Data.Fight -import Evergreen.V87.Data.Fight.Generator -import Evergreen.V87.Data.Item -import Evergreen.V87.Data.Map -import Evergreen.V87.Data.Message -import Evergreen.V87.Data.NewChar -import Evergreen.V87.Data.Perk -import Evergreen.V87.Data.Player -import Evergreen.V87.Data.Player.PlayerName -import Evergreen.V87.Data.Skill -import Evergreen.V87.Data.Special -import Evergreen.V87.Data.Trait -import Evergreen.V87.Data.Vendor -import Evergreen.V87.Data.World -import Evergreen.V87.Frontend.Route -import File exposing (File) -import Lamdera -import Set -import Time -import Url - - -type alias FrontendModel = - { key : Browser.Navigation.Key - , time : Time.Posix - , zone : Time.Zone - , route : Evergreen.V87.Frontend.Route.Route - , world : Evergreen.V87.Data.World.World - , newChar : Evergreen.V87.Data.NewChar.NewChar - , alertMessage : Maybe String - , mapMouseCoords : Maybe ( Evergreen.V87.Data.Map.TileCoords, Set.Set Evergreen.V87.Data.Map.TileCoords ) - , hoveredPerk : Maybe Evergreen.V87.Data.Perk.Perk - } - - -type alias BackendModel = - { players : Dict.Dict Evergreen.V87.Data.Player.PlayerName.PlayerName (Evergreen.V87.Data.Player.Player Evergreen.V87.Data.Player.SPlayer) - , loggedInPlayers : Dict.Dict Lamdera.ClientId Evergreen.V87.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - , adminLoggedIn : Maybe ( Lamdera.ClientId, Lamdera.SessionId ) - , time : Time.Posix - , vendors : AssocList.Dict Evergreen.V87.Data.Vendor.Name Evergreen.V87.Data.Vendor.Vendor - , lastItemId : Int - } - - -type BarterMsg - = AddPlayerItem Evergreen.V87.Data.Item.Id Int - | AddVendorItem Evergreen.V87.Data.Item.Id Int - | AddPlayerCaps Int - | AddVendorCaps Int - | RemovePlayerItem Evergreen.V87.Data.Item.Id Int - | RemoveVendorItem Evergreen.V87.Data.Item.Id Int - | RemovePlayerCaps Int - | RemoveVendorCaps Int - | ResetBarter - | ConfirmBarter - | SetTransferNInput Evergreen.V87.Data.Barter.TransferNPosition String - | SetTransferNHover Evergreen.V87.Data.Barter.TransferNPosition - | UnsetTransferNHover - - -type FrontendMsg - = UrlClicked Browser.UrlRequest - | UrlChanged Url.Url - | GoToRoute Evergreen.V87.Frontend.Route.Route - | Logout - | Login - | Register - | GotZone Time.Zone - | GotTime Time.Posix - | AskToFight Evergreen.V87.Data.Player.PlayerName.PlayerName - | AskToHeal - | AskToUseItem Evergreen.V87.Data.Item.Id - | AskToWander - | AskToChoosePerk Evergreen.V87.Data.Perk.Perk - | AskToEquipItem Evergreen.V87.Data.Item.Id - | AskToUnequipArmor - | AskForExport - | ImportButtonClicked - | ImportFileSelected File - | AskToImport String - | Refresh - | AskToTagSkill Evergreen.V87.Data.Skill.Skill - | AskToUseSkillPoints Evergreen.V87.Data.Skill.Skill - | SetAuthName String - | SetAuthPassword String - | CreateChar - | NewCharIncSpecial Evergreen.V87.Data.Special.Type - | NewCharDecSpecial Evergreen.V87.Data.Special.Type - | NewCharToggleTaggedSkill Evergreen.V87.Data.Skill.Skill - | NewCharToggleTrait Evergreen.V87.Data.Trait.Trait - | MapMouseAtCoords Evergreen.V87.Data.Map.TileCoords - | MapMouseOut - | MapMouseClick - | OpenMessage Evergreen.V87.Data.Message.Message - | AskToRemoveMessage Evergreen.V87.Data.Message.Message - | BarterMsg BarterMsg - | HoverPerk Evergreen.V87.Data.Perk.Perk - | StopHoveringPerk - - -type AdminToBackend - = ExportJson - | ImportJson String - - -type ToBackend - = LogMeIn (Evergreen.V87.Data.Auth.Auth Evergreen.V87.Data.Auth.Hashed) - | RegisterMe (Evergreen.V87.Data.Auth.Auth Evergreen.V87.Data.Auth.Hashed) - | CreateNewChar Evergreen.V87.Data.NewChar.NewChar - | LogMeOut - | Fight Evergreen.V87.Data.Player.PlayerName.PlayerName - | HealMe - | UseItem Evergreen.V87.Data.Item.Id - | Wander - | EquipItem Evergreen.V87.Data.Item.Id - | UnequipArmor - | RefreshPlease - | TagSkill Evergreen.V87.Data.Skill.Skill - | UseSkillPoints Evergreen.V87.Data.Skill.Skill - | ChoosePerk Evergreen.V87.Data.Perk.Perk - | MoveTo Evergreen.V87.Data.Map.TileCoords (Set.Set Evergreen.V87.Data.Map.TileCoords) - | MessageWasRead Evergreen.V87.Data.Message.Message - | RemoveMessage Evergreen.V87.Data.Message.Message - | Barter Evergreen.V87.Data.Barter.State - | AdminToBackend AdminToBackend - - -type BackendMsg - = Connected Lamdera.SessionId Lamdera.ClientId - | Disconnected Lamdera.SessionId Lamdera.ClientId - | GeneratedFight Lamdera.ClientId Evergreen.V87.Data.Player.SPlayer Evergreen.V87.Data.Fight.Generator.Fight - | GeneratedNewVendorsStock ( AssocList.Dict Evergreen.V87.Data.Vendor.Name Evergreen.V87.Data.Vendor.Vendor, Int ) - | Tick Time.Posix - | CreateNewCharWithTime Lamdera.ClientId Evergreen.V87.Data.NewChar.NewChar Time.Posix - | LoggedToBackendMsg - - -type ToFrontend - = YourCurrentWorld Evergreen.V87.Data.World.WorldLoggedInData - | InitWorld Evergreen.V87.Data.World.WorldLoggedOutData - | RefreshedLoggedOut Evergreen.V87.Data.World.WorldLoggedOutData - | CurrentAdminData Evergreen.V87.Data.World.AdminData - | YourFightResult ( Evergreen.V87.Data.Fight.Info, Evergreen.V87.Data.World.WorldLoggedInData ) - | YoureLoggedIn Evergreen.V87.Data.World.WorldLoggedInData - | YoureRegistered Evergreen.V87.Data.World.WorldLoggedInData - | CharCreationError Evergreen.V87.Data.NewChar.CreationError - | YouHaveCreatedChar Evergreen.V87.Data.World.WorldLoggedInData - | YoureLoggedOut Evergreen.V87.Data.World.WorldLoggedOutData - | AlertMessage String - | YoureLoggedInAsAdmin Evergreen.V87.Data.World.AdminData - | JsonExportDone String - | BarterDone ( Evergreen.V87.Data.World.WorldLoggedInData, Maybe Evergreen.V87.Data.Barter.Message ) - | BarterMessage Evergreen.V87.Data.Barter.Message diff --git a/src/Evergreen/V88/Data/Auth.elm b/src/Evergreen/V88/Data/Auth.elm deleted file mode 100644 index a67bc62e..00000000 --- a/src/Evergreen/V88/Data/Auth.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V88.Data.Auth exposing (..) - - -type Plaintext - = Plaintext - - -type Password a - = Password String - - -type alias Auth a = - { name : String - , password : Password a - } - - -type Verified - = Verified - - -type Hashed - = Hashed diff --git a/src/Evergreen/V88/Data/Barter.elm b/src/Evergreen/V88/Data/Barter.elm deleted file mode 100644 index 40f02082..00000000 --- a/src/Evergreen/V88/Data/Barter.elm +++ /dev/null @@ -1,33 +0,0 @@ -module Evergreen.V88.Data.Barter exposing (..) - -import AssocList -import Dict -import Evergreen.V88.Data.Item - - -type Message - = BarterIsEmpty - | PlayerOfferNotValuableEnough - | YouGaveStuffForFree - - -type TransferNPosition - = PlayerKeptItem Evergreen.V88.Data.Item.Id - | VendorKeptItem Evergreen.V88.Data.Item.Id - | PlayerTradedItem Evergreen.V88.Data.Item.Id - | VendorTradedItem Evergreen.V88.Data.Item.Id - | PlayerKeptCaps - | VendorKeptCaps - | PlayerTradedCaps - | VendorTradedCaps - - -type alias State = - { playerItems : Dict.Dict Evergreen.V88.Data.Item.Id Int - , vendorItems : Dict.Dict Evergreen.V88.Data.Item.Id Int - , playerCaps : Int - , vendorCaps : Int - , lastMessage : Maybe Message - , transferNInputs : AssocList.Dict TransferNPosition String - , transferNHover : Maybe TransferNPosition - } diff --git a/src/Evergreen/V88/Data/Enemy.elm b/src/Evergreen/V88/Data/Enemy.elm deleted file mode 100644 index b0109fc4..00000000 --- a/src/Evergreen/V88/Data/Enemy.elm +++ /dev/null @@ -1,14 +0,0 @@ -module Evergreen.V88.Data.Enemy exposing (..) - - -type Type - = Brahmin - | AngryBrahmin - | WeakBrahmin - | WildBrahmin - | GiantAnt - | ToughGiantAnt - | BlackRadscorpion - | LesserBlackRadscorpion - | LesserRadscorpion - | Radscorpion diff --git a/src/Evergreen/V88/Data/Fight.elm b/src/Evergreen/V88/Data/Fight.elm deleted file mode 100644 index 4e4c9f18..00000000 --- a/src/Evergreen/V88/Data/Fight.elm +++ /dev/null @@ -1,84 +0,0 @@ -module Evergreen.V88.Data.Fight exposing (..) - -import AssocList -import AssocSet -import Evergreen.V88.Data.Enemy -import Evergreen.V88.Data.Fight.ShotType -import Evergreen.V88.Data.Item -import Evergreen.V88.Data.Perk -import Evergreen.V88.Data.Player.PlayerName -import Evergreen.V88.Data.Skill -import Evergreen.V88.Data.Special -import Evergreen.V88.Data.Trait -import Evergreen.V88.Logic - - -type OpponentType - = Npc Evergreen.V88.Data.Enemy.Type - | Player Evergreen.V88.Data.Player.PlayerName.PlayerName - - -type Who - = Attacker - | Target - - -type Action - = Start - { distanceHexes : Int - } - | ComeCloser - { hexes : Int - , remainingDistanceHexes : Int - } - | Attack - { damage : Int - , shotType : Evergreen.V88.Data.Fight.ShotType.ShotType - , remainingHp : Int - , isCritical : Bool - } - | Miss - { shotType : Evergreen.V88.Data.Fight.ShotType.ShotType - } - - -type Result - = AttackerWon - { xpGained : Int - , capsGained : Int - , itemsGained : List Evergreen.V88.Data.Item.Item - } - | TargetWon - { xpGained : Int - , capsGained : Int - , itemsGained : List Evergreen.V88.Data.Item.Item - } - | TargetAlreadyDead - | BothDead - | NobodyDead - - -type alias Info = - { attacker : OpponentType - , target : OpponentType - , log : List ( Who, Action ) - , result : Result - } - - -type alias Opponent = - { type_ : OpponentType - , hp : Int - , maxHp : Int - , maxAp : Int - , sequence : Int - , traits : AssocSet.Set Evergreen.V88.Data.Trait.Trait - , perks : AssocList.Dict Evergreen.V88.Data.Perk.Perk Int - , caps : Int - , drops : List Evergreen.V88.Data.Item.Item - , equippedArmor : Maybe Evergreen.V88.Data.Item.Kind - , naturalArmorClass : Int - , attackStats : Evergreen.V88.Logic.AttackStats - , addedSkillPercentages : AssocList.Dict Evergreen.V88.Data.Skill.Skill Int - , special : Evergreen.V88.Data.Special.Special - } diff --git a/src/Evergreen/V88/Data/Fight/Generator.elm b/src/Evergreen/V88/Data/Fight/Generator.elm deleted file mode 100644 index fc336a97..00000000 --- a/src/Evergreen/V88/Data/Fight/Generator.elm +++ /dev/null @@ -1,12 +0,0 @@ -module Evergreen.V88.Data.Fight.Generator exposing (..) - -import Evergreen.V88.Data.Fight -import Evergreen.V88.Data.Message - - -type alias Fight = - { finalAttacker : Evergreen.V88.Data.Fight.Opponent - , finalTarget : Evergreen.V88.Data.Fight.Opponent - , fightInfo : Evergreen.V88.Data.Fight.Info - , messageForTarget : Evergreen.V88.Data.Message.Message - } diff --git a/src/Evergreen/V88/Data/Fight/ShotType.elm b/src/Evergreen/V88/Data/Fight/ShotType.elm deleted file mode 100644 index 76b79dc8e..00000000 --- a/src/Evergreen/V88/Data/Fight/ShotType.elm +++ /dev/null @@ -1,17 +0,0 @@ -module Evergreen.V88.Data.Fight.ShotType exposing (..) - - -type AimedShot - = Head - | Torso - | Eyes - | Groin - | LeftArm - | RightArm - | LeftLeg - | RightLeg - - -type ShotType - = NormalShot - | AimedShot AimedShot diff --git a/src/Evergreen/V88/Data/HealthStatus.elm b/src/Evergreen/V88/Data/HealthStatus.elm deleted file mode 100644 index af600994..00000000 --- a/src/Evergreen/V88/Data/HealthStatus.elm +++ /dev/null @@ -1,16 +0,0 @@ -module Evergreen.V88.Data.HealthStatus exposing (..) - - -type HealthStatus - = ExactHp - { current : Int - , max : Int - } - | Unhurt - | SlightlyWounded - | Wounded - | SeverelyWounded - | AlmostDead - | Dead - | Alive - | Unknown diff --git a/src/Evergreen/V88/Data/Item.elm b/src/Evergreen/V88/Data/Item.elm deleted file mode 100644 index 30258c24..00000000 --- a/src/Evergreen/V88/Data/Item.elm +++ /dev/null @@ -1,27 +0,0 @@ -module Evergreen.V88.Data.Item exposing (..) - - -type alias Id = - Int - - -type Kind - = Fruit - | HealingPowder - | Stimpak - | BigBookOfScience - | DeansElectronics - | FirstAidBook - | GunsAndBullets - | ScoutHandbook - | Robes - | LeatherJacket - | LeatherArmor - | MetalArmor - - -type alias Item = - { id : Id - , kind : Kind - , count : Int - } diff --git a/src/Evergreen/V88/Data/Map.elm b/src/Evergreen/V88/Data/Map.elm deleted file mode 100644 index 1324a31c..00000000 --- a/src/Evergreen/V88/Data/Map.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V88.Data.Map exposing (..) - - -type alias TileNum = - Int - - -type alias TileCoords = - ( Int, Int ) diff --git a/src/Evergreen/V88/Data/Message.elm b/src/Evergreen/V88/Data/Message.elm deleted file mode 100644 index a01e4634..00000000 --- a/src/Evergreen/V88/Data/Message.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V88.Data.Message exposing (..) - -import Evergreen.V88.Data.Fight -import Evergreen.V88.Data.Player.PlayerName -import Time - - -type Type - = Welcome - | YouAdvancedLevel - { newLevel : Int - } - | YouWereAttacked - { attacker : Evergreen.V88.Data.Player.PlayerName.PlayerName - , fightInfo : Evergreen.V88.Data.Fight.Info - } - - -type alias Message = - { type_ : Type - , hasBeenRead : Bool - , date : Time.Posix - } diff --git a/src/Evergreen/V88/Data/NewChar.elm b/src/Evergreen/V88/Data/NewChar.elm deleted file mode 100644 index b0f46b29..00000000 --- a/src/Evergreen/V88/Data/NewChar.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V88.Data.NewChar exposing (..) - -import AssocSet -import Evergreen.V88.Data.Skill -import Evergreen.V88.Data.Special -import Evergreen.V88.Data.Trait - - -type CreationError - = DoesNotHaveThreeTaggedSkills - | HasSpecialPointsLeft - | UsedMoreSpecialPointsThanAvailable - | HasSpecialOutOfRange - | HasMoreThanTwoTraits - - -type alias NewChar = - { baseSpecial : Evergreen.V88.Data.Special.Special - , availableSpecial : Int - , taggedSkills : AssocSet.Set Evergreen.V88.Data.Skill.Skill - , traits : AssocSet.Set Evergreen.V88.Data.Trait.Trait - , error : Maybe CreationError - } diff --git a/src/Evergreen/V88/Data/Perk.elm b/src/Evergreen/V88/Data/Perk.elm deleted file mode 100644 index 7b129b49..00000000 --- a/src/Evergreen/V88/Data/Perk.elm +++ /dev/null @@ -1,45 +0,0 @@ -module Evergreen.V88.Data.Perk exposing (..) - - -type Perk - = BonusHthDamage - | Awareness - | CautiousNature - | Comprehension - | EarlierSequence - | FasterHealing - | HereAndNow - | Survivalist - | SwiftLearner - | Thief - | Toughness - | AdrenalineRush - | Educated - | FortuneFinder - | Gambler - | MoreCriticals - | Negotiator - | Pathfinder - | Ranger - | Salesman - | BetterCriticals - | Dodger - | Speaker - | ActionBoy - | GainStrength - | GainPerception - | GainEndurance - | GainCharisma - | GainIntelligence - | GainAgility - | GainLuck - | HthEvade - | Lifegiver - | LivingAnatomy - | MasterThief - | MasterTrader - | Medic - | MrFixit - | Tag - | BonusHthAttacks - | Slayer diff --git a/src/Evergreen/V88/Data/Player.elm b/src/Evergreen/V88/Data/Player.elm deleted file mode 100644 index 5065ffd4..00000000 --- a/src/Evergreen/V88/Data/Player.elm +++ /dev/null @@ -1,77 +0,0 @@ -module Evergreen.V88.Data.Player exposing (..) - -import AssocList -import AssocSet -import Dict -import Evergreen.V88.Data.Auth -import Evergreen.V88.Data.HealthStatus -import Evergreen.V88.Data.Item -import Evergreen.V88.Data.Map -import Evergreen.V88.Data.Message -import Evergreen.V88.Data.Perk -import Evergreen.V88.Data.Player.PlayerName -import Evergreen.V88.Data.Skill -import Evergreen.V88.Data.Special -import Evergreen.V88.Data.Trait -import Evergreen.V88.Data.Xp - - -type alias COtherPlayer = - { level : Evergreen.V88.Data.Xp.Level - , name : Evergreen.V88.Data.Player.PlayerName.PlayerName - , wins : Int - , losses : Int - , healthStatus : Evergreen.V88.Data.HealthStatus.HealthStatus - } - - -type alias CPlayer = - { hp : Int - , maxHp : Int - , xp : Evergreen.V88.Data.Xp.Xp - , name : Evergreen.V88.Data.Player.PlayerName.PlayerName - , special : Evergreen.V88.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V88.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V88.Data.Perk.Perk Int - , messages : List Evergreen.V88.Data.Message.Message - , items : Dict.Dict Evergreen.V88.Data.Item.Id Evergreen.V88.Data.Item.Item - , traits : AssocSet.Set Evergreen.V88.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V88.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V88.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - , equippedArmor : Maybe Evergreen.V88.Data.Item.Item - } - - -type Player a - = NeedsCharCreated (Evergreen.V88.Data.Auth.Auth Evergreen.V88.Data.Auth.Verified) - | Player a - - -type alias SPlayer = - { name : Evergreen.V88.Data.Player.PlayerName.PlayerName - , password : Evergreen.V88.Data.Auth.Password Evergreen.V88.Data.Auth.Verified - , hp : Int - , maxHp : Int - , xp : Int - , special : Evergreen.V88.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V88.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V88.Data.Perk.Perk Int - , messages : List Evergreen.V88.Data.Message.Message - , items : Dict.Dict Evergreen.V88.Data.Item.Id Evergreen.V88.Data.Item.Item - , traits : AssocSet.Set Evergreen.V88.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V88.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V88.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - , equippedArmor : Maybe Evergreen.V88.Data.Item.Item - } diff --git a/src/Evergreen/V88/Data/Player/PlayerName.elm b/src/Evergreen/V88/Data/Player/PlayerName.elm deleted file mode 100644 index f1886f28..00000000 --- a/src/Evergreen/V88/Data/Player/PlayerName.elm +++ /dev/null @@ -1,5 +0,0 @@ -module Evergreen.V88.Data.Player.PlayerName exposing (..) - - -type alias PlayerName = - String diff --git a/src/Evergreen/V88/Data/Skill.elm b/src/Evergreen/V88/Data/Skill.elm deleted file mode 100644 index 3c3d82d9..00000000 --- a/src/Evergreen/V88/Data/Skill.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V88.Data.Skill exposing (..) - - -type Skill - = SmallGuns - | BigGuns - | EnergyWeapons - | Unarmed - | MeleeWeapons - | Throwing - | FirstAid - | Doctor - | Sneak - | Lockpick - | Steal - | Traps - | Science - | Repair - | Speech - | Barter - | Gambling - | Outdoorsman diff --git a/src/Evergreen/V88/Data/Special.elm b/src/Evergreen/V88/Data/Special.elm deleted file mode 100644 index 144abc91..00000000 --- a/src/Evergreen/V88/Data/Special.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V88.Data.Special exposing (..) - - -type alias Special = - { strength : Int - , perception : Int - , endurance : Int - , charisma : Int - , intelligence : Int - , agility : Int - , luck : Int - } - - -type Type - = Strength - | Perception - | Endurance - | Charisma - | Intelligence - | Agility - | Luck diff --git a/src/Evergreen/V88/Data/Trait.elm b/src/Evergreen/V88/Data/Trait.elm deleted file mode 100644 index ae7aad9e..00000000 --- a/src/Evergreen/V88/Data/Trait.elm +++ /dev/null @@ -1,11 +0,0 @@ -module Evergreen.V88.Data.Trait exposing (..) - - -type Trait - = Kamikaze - | Bruiser - | Gifted - | SmallFrame - | Skilled - | HeavyHanded - | Finesse diff --git a/src/Evergreen/V88/Data/Vendor.elm b/src/Evergreen/V88/Data/Vendor.elm deleted file mode 100644 index e5b1ed5b..00000000 --- a/src/Evergreen/V88/Data/Vendor.elm +++ /dev/null @@ -1,20 +0,0 @@ -module Evergreen.V88.Data.Vendor exposing (..) - -import Dict -import Evergreen.V88.Data.Item - - -type Name - = ArroyoHakunin - | KlamathMaidaBuckner - | DenFlick - | ModocJo - | VaultCityHappyHarry - - -type alias Vendor = - { name : Name - , items : Dict.Dict Evergreen.V88.Data.Item.Id Evergreen.V88.Data.Item.Item - , caps : Int - , barterSkill : Int - } diff --git a/src/Evergreen/V88/Data/World.elm b/src/Evergreen/V88/Data/World.elm deleted file mode 100644 index 8c6cb942..00000000 --- a/src/Evergreen/V88/Data/World.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.V88.Data.World exposing (..) - -import AssocList -import Evergreen.V88.Data.Auth -import Evergreen.V88.Data.Player -import Evergreen.V88.Data.Player.PlayerName -import Evergreen.V88.Data.Vendor -import Time - - -type alias WorldLoggedOutData = - { players : List Evergreen.V88.Data.Player.COtherPlayer - } - - -type alias WorldLoggedInData = - { player : Evergreen.V88.Data.Player.Player Evergreen.V88.Data.Player.CPlayer - , otherPlayers : List Evergreen.V88.Data.Player.COtherPlayer - , playerRank : Int - , vendors : AssocList.Dict Evergreen.V88.Data.Vendor.Name Evergreen.V88.Data.Vendor.Vendor - } - - -type alias AdminData = - { players : List (Evergreen.V88.Data.Player.Player Evergreen.V88.Data.Player.SPlayer) - , loggedInPlayers : List Evergreen.V88.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - } - - -type World - = WorldNotInitialized (Evergreen.V88.Data.Auth.Auth Evergreen.V88.Data.Auth.Plaintext) - | WorldLoggedOut (Evergreen.V88.Data.Auth.Auth Evergreen.V88.Data.Auth.Plaintext) WorldLoggedOutData - | WorldLoggedIn WorldLoggedInData - | WorldAdmin AdminData diff --git a/src/Evergreen/V88/Data/Xp.elm b/src/Evergreen/V88/Data/Xp.elm deleted file mode 100644 index be826deb..00000000 --- a/src/Evergreen/V88/Data/Xp.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V88.Data.Xp exposing (..) - - -type alias Level = - Int - - -type alias Xp = - Int diff --git a/src/Evergreen/V88/Frontend/Route.elm b/src/Evergreen/V88/Frontend/Route.elm deleted file mode 100644 index cdf041cb..00000000 --- a/src/Evergreen/V88/Frontend/Route.elm +++ /dev/null @@ -1,31 +0,0 @@ -module Evergreen.V88.Frontend.Route exposing (..) - -import Evergreen.V88.Data.Barter -import Evergreen.V88.Data.Fight -import Evergreen.V88.Data.Message - - -type TownRoute - = MainSquare - | Store - { barter : Evergreen.V88.Data.Barter.State - } - - -type AdminRoute - = LoggedIn - - -type Route - = Character - | Inventory - | Map - | Ladder - | Town TownRoute - | About - | News - | Fight Evergreen.V88.Data.Fight.Info - | Messages - | Message Evergreen.V88.Data.Message.Message - | CharCreation - | Admin AdminRoute diff --git a/src/Evergreen/V88/Logic.elm b/src/Evergreen/V88/Logic.elm deleted file mode 100644 index d017a918..00000000 --- a/src/Evergreen/V88/Logic.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V88.Logic exposing (..) - - -type alias AttackStats = - { minDamage : Int - , maxDamage : Int - , criticalChanceBonus : Int - } diff --git a/src/Evergreen/V88/Types.elm b/src/Evergreen/V88/Types.elm deleted file mode 100644 index 4d06a426..00000000 --- a/src/Evergreen/V88/Types.elm +++ /dev/null @@ -1,163 +0,0 @@ -module Evergreen.V88.Types exposing (..) - -import AssocList -import Browser -import Browser.Navigation -import Dict -import Evergreen.V88.Data.Auth -import Evergreen.V88.Data.Barter -import Evergreen.V88.Data.Fight -import Evergreen.V88.Data.Fight.Generator -import Evergreen.V88.Data.Item -import Evergreen.V88.Data.Map -import Evergreen.V88.Data.Message -import Evergreen.V88.Data.NewChar -import Evergreen.V88.Data.Perk -import Evergreen.V88.Data.Player -import Evergreen.V88.Data.Player.PlayerName -import Evergreen.V88.Data.Skill -import Evergreen.V88.Data.Special -import Evergreen.V88.Data.Trait -import Evergreen.V88.Data.Vendor -import Evergreen.V88.Data.World -import Evergreen.V88.Frontend.Route -import File exposing (File) -import Lamdera -import Set -import Time -import Url - - -type alias FrontendModel = - { key : Browser.Navigation.Key - , time : Time.Posix - , zone : Time.Zone - , route : Evergreen.V88.Frontend.Route.Route - , world : Evergreen.V88.Data.World.World - , newChar : Evergreen.V88.Data.NewChar.NewChar - , alertMessage : Maybe String - , mapMouseCoords : Maybe ( Evergreen.V88.Data.Map.TileCoords, Set.Set Evergreen.V88.Data.Map.TileCoords ) - , hoveredPerk : Maybe Evergreen.V88.Data.Perk.Perk - } - - -type alias BackendModel = - { players : Dict.Dict Evergreen.V88.Data.Player.PlayerName.PlayerName (Evergreen.V88.Data.Player.Player Evergreen.V88.Data.Player.SPlayer) - , loggedInPlayers : Dict.Dict Lamdera.ClientId Evergreen.V88.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - , adminLoggedIn : Maybe ( Lamdera.ClientId, Lamdera.SessionId ) - , time : Time.Posix - , vendors : AssocList.Dict Evergreen.V88.Data.Vendor.Name Evergreen.V88.Data.Vendor.Vendor - , lastItemId : Int - } - - -type BarterMsg - = AddPlayerItem Evergreen.V88.Data.Item.Id Int - | AddVendorItem Evergreen.V88.Data.Item.Id Int - | AddPlayerCaps Int - | AddVendorCaps Int - | RemovePlayerItem Evergreen.V88.Data.Item.Id Int - | RemoveVendorItem Evergreen.V88.Data.Item.Id Int - | RemovePlayerCaps Int - | RemoveVendorCaps Int - | ResetBarter - | ConfirmBarter - | SetTransferNInput Evergreen.V88.Data.Barter.TransferNPosition String - | SetTransferNHover Evergreen.V88.Data.Barter.TransferNPosition - | UnsetTransferNHover - - -type FrontendMsg - = UrlClicked Browser.UrlRequest - | UrlChanged Url.Url - | GoToRoute Evergreen.V88.Frontend.Route.Route - | Logout - | Login - | Register - | GotZone Time.Zone - | GotTime Time.Posix - | AskToFight Evergreen.V88.Data.Player.PlayerName.PlayerName - | AskToHeal - | AskToUseItem Evergreen.V88.Data.Item.Id - | AskToWander - | AskToChoosePerk Evergreen.V88.Data.Perk.Perk - | AskToEquipItem Evergreen.V88.Data.Item.Id - | AskToUnequipArmor - | AskForExport - | ImportButtonClicked - | ImportFileSelected File - | AskToImport String - | Refresh - | AskToTagSkill Evergreen.V88.Data.Skill.Skill - | AskToUseSkillPoints Evergreen.V88.Data.Skill.Skill - | SetAuthName String - | SetAuthPassword String - | CreateChar - | NewCharIncSpecial Evergreen.V88.Data.Special.Type - | NewCharDecSpecial Evergreen.V88.Data.Special.Type - | NewCharToggleTaggedSkill Evergreen.V88.Data.Skill.Skill - | NewCharToggleTrait Evergreen.V88.Data.Trait.Trait - | MapMouseAtCoords Evergreen.V88.Data.Map.TileCoords - | MapMouseOut - | MapMouseClick - | OpenMessage Evergreen.V88.Data.Message.Message - | AskToRemoveMessage Evergreen.V88.Data.Message.Message - | BarterMsg BarterMsg - | HoverPerk Evergreen.V88.Data.Perk.Perk - | StopHoveringPerk - - -type AdminToBackend - = ExportJson - | ImportJson String - - -type ToBackend - = LogMeIn (Evergreen.V88.Data.Auth.Auth Evergreen.V88.Data.Auth.Hashed) - | RegisterMe (Evergreen.V88.Data.Auth.Auth Evergreen.V88.Data.Auth.Hashed) - | CreateNewChar Evergreen.V88.Data.NewChar.NewChar - | LogMeOut - | Fight Evergreen.V88.Data.Player.PlayerName.PlayerName - | HealMe - | UseItem Evergreen.V88.Data.Item.Id - | Wander - | EquipItem Evergreen.V88.Data.Item.Id - | UnequipArmor - | RefreshPlease - | TagSkill Evergreen.V88.Data.Skill.Skill - | UseSkillPoints Evergreen.V88.Data.Skill.Skill - | ChoosePerk Evergreen.V88.Data.Perk.Perk - | MoveTo Evergreen.V88.Data.Map.TileCoords (Set.Set Evergreen.V88.Data.Map.TileCoords) - | MessageWasRead Evergreen.V88.Data.Message.Message - | RemoveMessage Evergreen.V88.Data.Message.Message - | Barter Evergreen.V88.Data.Barter.State - | AdminToBackend AdminToBackend - - -type BackendMsg - = Connected Lamdera.SessionId Lamdera.ClientId - | Disconnected Lamdera.SessionId Lamdera.ClientId - | GeneratedFight Lamdera.ClientId Evergreen.V88.Data.Player.SPlayer ( Evergreen.V88.Data.Fight.Generator.Fight, Int ) - | GeneratedNewVendorsStock ( AssocList.Dict Evergreen.V88.Data.Vendor.Name Evergreen.V88.Data.Vendor.Vendor, Int ) - | Tick Time.Posix - | CreateNewCharWithTime Lamdera.ClientId Evergreen.V88.Data.NewChar.NewChar Time.Posix - | LoggedToBackendMsg - - -type ToFrontend - = YourCurrentWorld Evergreen.V88.Data.World.WorldLoggedInData - | InitWorld Evergreen.V88.Data.World.WorldLoggedOutData - | RefreshedLoggedOut Evergreen.V88.Data.World.WorldLoggedOutData - | CurrentAdminData Evergreen.V88.Data.World.AdminData - | YourFightResult ( Evergreen.V88.Data.Fight.Info, Evergreen.V88.Data.World.WorldLoggedInData ) - | YoureLoggedIn Evergreen.V88.Data.World.WorldLoggedInData - | YoureRegistered Evergreen.V88.Data.World.WorldLoggedInData - | CharCreationError Evergreen.V88.Data.NewChar.CreationError - | YouHaveCreatedChar Evergreen.V88.Data.World.WorldLoggedInData - | YoureLoggedOut Evergreen.V88.Data.World.WorldLoggedOutData - | AlertMessage String - | YoureLoggedInAsAdmin Evergreen.V88.Data.World.AdminData - | JsonExportDone String - | BarterDone ( Evergreen.V88.Data.World.WorldLoggedInData, Maybe Evergreen.V88.Data.Barter.Message ) - | BarterMessage Evergreen.V88.Data.Barter.Message diff --git a/src/Evergreen/V89/Data/Auth.elm b/src/Evergreen/V89/Data/Auth.elm deleted file mode 100644 index b236dd4a..00000000 --- a/src/Evergreen/V89/Data/Auth.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V89.Data.Auth exposing (..) - - -type Plaintext - = Plaintext - - -type Password a - = Password String - - -type alias Auth a = - { name : String - , password : Password a - } - - -type Verified - = Verified - - -type Hashed - = Hashed diff --git a/src/Evergreen/V89/Data/Barter.elm b/src/Evergreen/V89/Data/Barter.elm deleted file mode 100644 index eaf90db7..00000000 --- a/src/Evergreen/V89/Data/Barter.elm +++ /dev/null @@ -1,33 +0,0 @@ -module Evergreen.V89.Data.Barter exposing (..) - -import AssocList -import Dict -import Evergreen.V89.Data.Item - - -type Message - = BarterIsEmpty - | PlayerOfferNotValuableEnough - | YouGaveStuffForFree - - -type TransferNPosition - = PlayerKeptItem Evergreen.V89.Data.Item.Id - | VendorKeptItem Evergreen.V89.Data.Item.Id - | PlayerTradedItem Evergreen.V89.Data.Item.Id - | VendorTradedItem Evergreen.V89.Data.Item.Id - | PlayerKeptCaps - | VendorKeptCaps - | PlayerTradedCaps - | VendorTradedCaps - - -type alias State = - { playerItems : Dict.Dict Evergreen.V89.Data.Item.Id Int - , vendorItems : Dict.Dict Evergreen.V89.Data.Item.Id Int - , playerCaps : Int - , vendorCaps : Int - , lastMessage : Maybe Message - , transferNInputs : AssocList.Dict TransferNPosition String - , transferNHover : Maybe TransferNPosition - } diff --git a/src/Evergreen/V89/Data/Enemy.elm b/src/Evergreen/V89/Data/Enemy.elm deleted file mode 100644 index bbce463f..00000000 --- a/src/Evergreen/V89/Data/Enemy.elm +++ /dev/null @@ -1,14 +0,0 @@ -module Evergreen.V89.Data.Enemy exposing (..) - - -type Type - = Brahmin - | AngryBrahmin - | WeakBrahmin - | WildBrahmin - | GiantAnt - | ToughGiantAnt - | BlackRadscorpion - | LesserBlackRadscorpion - | LesserRadscorpion - | Radscorpion diff --git a/src/Evergreen/V89/Data/Fight.elm b/src/Evergreen/V89/Data/Fight.elm deleted file mode 100644 index 813f4834..00000000 --- a/src/Evergreen/V89/Data/Fight.elm +++ /dev/null @@ -1,84 +0,0 @@ -module Evergreen.V89.Data.Fight exposing (..) - -import AssocList -import AssocSet -import Evergreen.V89.Data.Enemy -import Evergreen.V89.Data.Fight.ShotType -import Evergreen.V89.Data.Item -import Evergreen.V89.Data.Perk -import Evergreen.V89.Data.Player.PlayerName -import Evergreen.V89.Data.Skill -import Evergreen.V89.Data.Special -import Evergreen.V89.Data.Trait -import Evergreen.V89.Logic - - -type OpponentType - = Npc Evergreen.V89.Data.Enemy.Type - | Player Evergreen.V89.Data.Player.PlayerName.PlayerName - - -type Who - = Attacker - | Target - - -type Action - = Start - { distanceHexes : Int - } - | ComeCloser - { hexes : Int - , remainingDistanceHexes : Int - } - | Attack - { damage : Int - , shotType : Evergreen.V89.Data.Fight.ShotType.ShotType - , remainingHp : Int - , isCritical : Bool - } - | Miss - { shotType : Evergreen.V89.Data.Fight.ShotType.ShotType - } - - -type Result - = AttackerWon - { xpGained : Int - , capsGained : Int - , itemsGained : List Evergreen.V89.Data.Item.Item - } - | TargetWon - { xpGained : Int - , capsGained : Int - , itemsGained : List Evergreen.V89.Data.Item.Item - } - | TargetAlreadyDead - | BothDead - | NobodyDead - - -type alias Info = - { attacker : OpponentType - , target : OpponentType - , log : List ( Who, Action ) - , result : Result - } - - -type alias Opponent = - { type_ : OpponentType - , hp : Int - , maxHp : Int - , maxAp : Int - , sequence : Int - , traits : AssocSet.Set Evergreen.V89.Data.Trait.Trait - , perks : AssocList.Dict Evergreen.V89.Data.Perk.Perk Int - , caps : Int - , drops : List Evergreen.V89.Data.Item.Item - , equippedArmor : Maybe Evergreen.V89.Data.Item.Kind - , naturalArmorClass : Int - , attackStats : Evergreen.V89.Logic.AttackStats - , addedSkillPercentages : AssocList.Dict Evergreen.V89.Data.Skill.Skill Int - , special : Evergreen.V89.Data.Special.Special - } diff --git a/src/Evergreen/V89/Data/Fight/Generator.elm b/src/Evergreen/V89/Data/Fight/Generator.elm deleted file mode 100644 index 331040b6..00000000 --- a/src/Evergreen/V89/Data/Fight/Generator.elm +++ /dev/null @@ -1,12 +0,0 @@ -module Evergreen.V89.Data.Fight.Generator exposing (..) - -import Evergreen.V89.Data.Fight -import Evergreen.V89.Data.Message - - -type alias Fight = - { finalAttacker : Evergreen.V89.Data.Fight.Opponent - , finalTarget : Evergreen.V89.Data.Fight.Opponent - , fightInfo : Evergreen.V89.Data.Fight.Info - , messageForTarget : Evergreen.V89.Data.Message.Message - } diff --git a/src/Evergreen/V89/Data/Fight/ShotType.elm b/src/Evergreen/V89/Data/Fight/ShotType.elm deleted file mode 100644 index d7605f8e..00000000 --- a/src/Evergreen/V89/Data/Fight/ShotType.elm +++ /dev/null @@ -1,17 +0,0 @@ -module Evergreen.V89.Data.Fight.ShotType exposing (..) - - -type AimedShot - = Head - | Torso - | Eyes - | Groin - | LeftArm - | RightArm - | LeftLeg - | RightLeg - - -type ShotType - = NormalShot - | AimedShot AimedShot diff --git a/src/Evergreen/V89/Data/HealthStatus.elm b/src/Evergreen/V89/Data/HealthStatus.elm deleted file mode 100644 index 24315a9f..00000000 --- a/src/Evergreen/V89/Data/HealthStatus.elm +++ /dev/null @@ -1,16 +0,0 @@ -module Evergreen.V89.Data.HealthStatus exposing (..) - - -type HealthStatus - = ExactHp - { current : Int - , max : Int - } - | Unhurt - | SlightlyWounded - | Wounded - | SeverelyWounded - | AlmostDead - | Dead - | Alive - | Unknown diff --git a/src/Evergreen/V89/Data/Item.elm b/src/Evergreen/V89/Data/Item.elm deleted file mode 100644 index a93d8e59..00000000 --- a/src/Evergreen/V89/Data/Item.elm +++ /dev/null @@ -1,27 +0,0 @@ -module Evergreen.V89.Data.Item exposing (..) - - -type alias Id = - Int - - -type Kind - = Fruit - | HealingPowder - | Stimpak - | BigBookOfScience - | DeansElectronics - | FirstAidBook - | GunsAndBullets - | ScoutHandbook - | Robes - | LeatherJacket - | LeatherArmor - | MetalArmor - - -type alias Item = - { id : Id - , kind : Kind - , count : Int - } diff --git a/src/Evergreen/V89/Data/Map.elm b/src/Evergreen/V89/Data/Map.elm deleted file mode 100644 index a609d516..00000000 --- a/src/Evergreen/V89/Data/Map.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V89.Data.Map exposing (..) - - -type alias TileNum = - Int - - -type alias TileCoords = - ( Int, Int ) diff --git a/src/Evergreen/V89/Data/Message.elm b/src/Evergreen/V89/Data/Message.elm deleted file mode 100644 index 542279eb..00000000 --- a/src/Evergreen/V89/Data/Message.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V89.Data.Message exposing (..) - -import Evergreen.V89.Data.Fight -import Evergreen.V89.Data.Player.PlayerName -import Time - - -type Type - = Welcome - | YouAdvancedLevel - { newLevel : Int - } - | YouWereAttacked - { attacker : Evergreen.V89.Data.Player.PlayerName.PlayerName - , fightInfo : Evergreen.V89.Data.Fight.Info - } - - -type alias Message = - { type_ : Type - , hasBeenRead : Bool - , date : Time.Posix - } diff --git a/src/Evergreen/V89/Data/NewChar.elm b/src/Evergreen/V89/Data/NewChar.elm deleted file mode 100644 index eee9669a..00000000 --- a/src/Evergreen/V89/Data/NewChar.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V89.Data.NewChar exposing (..) - -import AssocSet -import Evergreen.V89.Data.Skill -import Evergreen.V89.Data.Special -import Evergreen.V89.Data.Trait - - -type CreationError - = DoesNotHaveThreeTaggedSkills - | HasSpecialPointsLeft - | UsedMoreSpecialPointsThanAvailable - | HasSpecialOutOfRange - | HasMoreThanTwoTraits - - -type alias NewChar = - { baseSpecial : Evergreen.V89.Data.Special.Special - , availableSpecial : Int - , taggedSkills : AssocSet.Set Evergreen.V89.Data.Skill.Skill - , traits : AssocSet.Set Evergreen.V89.Data.Trait.Trait - , error : Maybe CreationError - } diff --git a/src/Evergreen/V89/Data/Perk.elm b/src/Evergreen/V89/Data/Perk.elm deleted file mode 100644 index 3b74b8b1..00000000 --- a/src/Evergreen/V89/Data/Perk.elm +++ /dev/null @@ -1,45 +0,0 @@ -module Evergreen.V89.Data.Perk exposing (..) - - -type Perk - = BonusHthDamage - | Awareness - | CautiousNature - | Comprehension - | EarlierSequence - | FasterHealing - | HereAndNow - | Survivalist - | SwiftLearner - | Thief - | Toughness - | AdrenalineRush - | Educated - | FortuneFinder - | Gambler - | MoreCriticals - | Negotiator - | Pathfinder - | Ranger - | Salesman - | BetterCriticals - | Dodger - | Speaker - | ActionBoy - | GainStrength - | GainPerception - | GainEndurance - | GainCharisma - | GainIntelligence - | GainAgility - | GainLuck - | HthEvade - | Lifegiver - | LivingAnatomy - | MasterThief - | MasterTrader - | Medic - | MrFixit - | Tag - | BonusHthAttacks - | Slayer diff --git a/src/Evergreen/V89/Data/Player.elm b/src/Evergreen/V89/Data/Player.elm deleted file mode 100644 index a5b3fcc2..00000000 --- a/src/Evergreen/V89/Data/Player.elm +++ /dev/null @@ -1,77 +0,0 @@ -module Evergreen.V89.Data.Player exposing (..) - -import AssocList -import AssocSet -import Dict -import Evergreen.V89.Data.Auth -import Evergreen.V89.Data.HealthStatus -import Evergreen.V89.Data.Item -import Evergreen.V89.Data.Map -import Evergreen.V89.Data.Message -import Evergreen.V89.Data.Perk -import Evergreen.V89.Data.Player.PlayerName -import Evergreen.V89.Data.Skill -import Evergreen.V89.Data.Special -import Evergreen.V89.Data.Trait -import Evergreen.V89.Data.Xp - - -type alias COtherPlayer = - { level : Evergreen.V89.Data.Xp.Level - , name : Evergreen.V89.Data.Player.PlayerName.PlayerName - , wins : Int - , losses : Int - , healthStatus : Evergreen.V89.Data.HealthStatus.HealthStatus - } - - -type alias CPlayer = - { hp : Int - , maxHp : Int - , xp : Evergreen.V89.Data.Xp.Xp - , name : Evergreen.V89.Data.Player.PlayerName.PlayerName - , special : Evergreen.V89.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V89.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V89.Data.Perk.Perk Int - , messages : List Evergreen.V89.Data.Message.Message - , items : Dict.Dict Evergreen.V89.Data.Item.Id Evergreen.V89.Data.Item.Item - , traits : AssocSet.Set Evergreen.V89.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V89.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V89.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - , equippedArmor : Maybe Evergreen.V89.Data.Item.Item - } - - -type Player a - = NeedsCharCreated (Evergreen.V89.Data.Auth.Auth Evergreen.V89.Data.Auth.Verified) - | Player a - - -type alias SPlayer = - { name : Evergreen.V89.Data.Player.PlayerName.PlayerName - , password : Evergreen.V89.Data.Auth.Password Evergreen.V89.Data.Auth.Verified - , hp : Int - , maxHp : Int - , xp : Int - , special : Evergreen.V89.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V89.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V89.Data.Perk.Perk Int - , messages : List Evergreen.V89.Data.Message.Message - , items : Dict.Dict Evergreen.V89.Data.Item.Id Evergreen.V89.Data.Item.Item - , traits : AssocSet.Set Evergreen.V89.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V89.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V89.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - , equippedArmor : Maybe Evergreen.V89.Data.Item.Item - } diff --git a/src/Evergreen/V89/Data/Player/PlayerName.elm b/src/Evergreen/V89/Data/Player/PlayerName.elm deleted file mode 100644 index 85265ab7..00000000 --- a/src/Evergreen/V89/Data/Player/PlayerName.elm +++ /dev/null @@ -1,5 +0,0 @@ -module Evergreen.V89.Data.Player.PlayerName exposing (..) - - -type alias PlayerName = - String diff --git a/src/Evergreen/V89/Data/Skill.elm b/src/Evergreen/V89/Data/Skill.elm deleted file mode 100644 index 1cd43fc9..00000000 --- a/src/Evergreen/V89/Data/Skill.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V89.Data.Skill exposing (..) - - -type Skill - = SmallGuns - | BigGuns - | EnergyWeapons - | Unarmed - | MeleeWeapons - | Throwing - | FirstAid - | Doctor - | Sneak - | Lockpick - | Steal - | Traps - | Science - | Repair - | Speech - | Barter - | Gambling - | Outdoorsman diff --git a/src/Evergreen/V89/Data/Special.elm b/src/Evergreen/V89/Data/Special.elm deleted file mode 100644 index 71882ea1..00000000 --- a/src/Evergreen/V89/Data/Special.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V89.Data.Special exposing (..) - - -type alias Special = - { strength : Int - , perception : Int - , endurance : Int - , charisma : Int - , intelligence : Int - , agility : Int - , luck : Int - } - - -type Type - = Strength - | Perception - | Endurance - | Charisma - | Intelligence - | Agility - | Luck diff --git a/src/Evergreen/V89/Data/Trait.elm b/src/Evergreen/V89/Data/Trait.elm deleted file mode 100644 index 11816d0f..00000000 --- a/src/Evergreen/V89/Data/Trait.elm +++ /dev/null @@ -1,11 +0,0 @@ -module Evergreen.V89.Data.Trait exposing (..) - - -type Trait - = Kamikaze - | Bruiser - | Gifted - | SmallFrame - | Skilled - | HeavyHanded - | Finesse diff --git a/src/Evergreen/V89/Data/Vendor.elm b/src/Evergreen/V89/Data/Vendor.elm deleted file mode 100644 index 596bda9b..00000000 --- a/src/Evergreen/V89/Data/Vendor.elm +++ /dev/null @@ -1,20 +0,0 @@ -module Evergreen.V89.Data.Vendor exposing (..) - -import Dict -import Evergreen.V89.Data.Item - - -type Name - = ArroyoHakunin - | KlamathMaidaBuckner - | DenFlick - | ModocJo - | VaultCityHappyHarry - - -type alias Vendor = - { name : Name - , items : Dict.Dict Evergreen.V89.Data.Item.Id Evergreen.V89.Data.Item.Item - , caps : Int - , barterSkill : Int - } diff --git a/src/Evergreen/V89/Data/World.elm b/src/Evergreen/V89/Data/World.elm deleted file mode 100644 index 4e0602c2..00000000 --- a/src/Evergreen/V89/Data/World.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.V89.Data.World exposing (..) - -import AssocList -import Evergreen.V89.Data.Auth -import Evergreen.V89.Data.Player -import Evergreen.V89.Data.Player.PlayerName -import Evergreen.V89.Data.Vendor -import Time - - -type alias WorldLoggedOutData = - { players : List Evergreen.V89.Data.Player.COtherPlayer - } - - -type alias WorldLoggedInData = - { player : Evergreen.V89.Data.Player.Player Evergreen.V89.Data.Player.CPlayer - , otherPlayers : List Evergreen.V89.Data.Player.COtherPlayer - , playerRank : Int - , vendors : AssocList.Dict Evergreen.V89.Data.Vendor.Name Evergreen.V89.Data.Vendor.Vendor - } - - -type alias AdminData = - { players : List (Evergreen.V89.Data.Player.Player Evergreen.V89.Data.Player.SPlayer) - , loggedInPlayers : List Evergreen.V89.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - } - - -type World - = WorldNotInitialized (Evergreen.V89.Data.Auth.Auth Evergreen.V89.Data.Auth.Plaintext) - | WorldLoggedOut (Evergreen.V89.Data.Auth.Auth Evergreen.V89.Data.Auth.Plaintext) WorldLoggedOutData - | WorldLoggedIn WorldLoggedInData - | WorldAdmin AdminData diff --git a/src/Evergreen/V89/Data/Xp.elm b/src/Evergreen/V89/Data/Xp.elm deleted file mode 100644 index 9051bc44..00000000 --- a/src/Evergreen/V89/Data/Xp.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V89.Data.Xp exposing (..) - - -type alias Level = - Int - - -type alias Xp = - Int diff --git a/src/Evergreen/V89/Frontend/HoveredItem.elm b/src/Evergreen/V89/Frontend/HoveredItem.elm deleted file mode 100644 index a30da247..00000000 --- a/src/Evergreen/V89/Frontend/HoveredItem.elm +++ /dev/null @@ -1,13 +0,0 @@ -module Evergreen.V89.Frontend.HoveredItem exposing (..) - -import Evergreen.V89.Data.Perk -import Evergreen.V89.Data.Skill -import Evergreen.V89.Data.Special -import Evergreen.V89.Data.Trait - - -type HoveredItem - = HoveredPerk Evergreen.V89.Data.Perk.Perk - | HoveredTrait Evergreen.V89.Data.Trait.Trait - | HoveredSpecial Evergreen.V89.Data.Special.Type - | HoveredSkill Evergreen.V89.Data.Skill.Skill diff --git a/src/Evergreen/V89/Frontend/Route.elm b/src/Evergreen/V89/Frontend/Route.elm deleted file mode 100644 index c0af1776..00000000 --- a/src/Evergreen/V89/Frontend/Route.elm +++ /dev/null @@ -1,31 +0,0 @@ -module Evergreen.V89.Frontend.Route exposing (..) - -import Evergreen.V89.Data.Barter -import Evergreen.V89.Data.Fight -import Evergreen.V89.Data.Message - - -type TownRoute - = MainSquare - | Store - { barter : Evergreen.V89.Data.Barter.State - } - - -type AdminRoute - = LoggedIn - - -type Route - = Character - | Inventory - | Map - | Ladder - | Town TownRoute - | About - | News - | Fight Evergreen.V89.Data.Fight.Info - | Messages - | Message Evergreen.V89.Data.Message.Message - | CharCreation - | Admin AdminRoute diff --git a/src/Evergreen/V89/Logic.elm b/src/Evergreen/V89/Logic.elm deleted file mode 100644 index 8aae8204..00000000 --- a/src/Evergreen/V89/Logic.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V89.Logic exposing (..) - - -type alias AttackStats = - { minDamage : Int - , maxDamage : Int - , criticalChanceBonus : Int - } diff --git a/src/Evergreen/V89/Types.elm b/src/Evergreen/V89/Types.elm deleted file mode 100644 index 9cd432e3..00000000 --- a/src/Evergreen/V89/Types.elm +++ /dev/null @@ -1,164 +0,0 @@ -module Evergreen.V89.Types exposing (..) - -import AssocList -import Browser -import Browser.Navigation -import Dict -import Evergreen.V89.Data.Auth -import Evergreen.V89.Data.Barter -import Evergreen.V89.Data.Fight -import Evergreen.V89.Data.Fight.Generator -import Evergreen.V89.Data.Item -import Evergreen.V89.Data.Map -import Evergreen.V89.Data.Message -import Evergreen.V89.Data.NewChar -import Evergreen.V89.Data.Perk -import Evergreen.V89.Data.Player -import Evergreen.V89.Data.Player.PlayerName -import Evergreen.V89.Data.Skill -import Evergreen.V89.Data.Special -import Evergreen.V89.Data.Trait -import Evergreen.V89.Data.Vendor -import Evergreen.V89.Data.World -import Evergreen.V89.Frontend.HoveredItem -import Evergreen.V89.Frontend.Route -import File exposing (File) -import Lamdera -import Set -import Time -import Url - - -type alias FrontendModel = - { key : Browser.Navigation.Key - , time : Time.Posix - , zone : Time.Zone - , route : Evergreen.V89.Frontend.Route.Route - , world : Evergreen.V89.Data.World.World - , newChar : Evergreen.V89.Data.NewChar.NewChar - , alertMessage : Maybe String - , mapMouseCoords : Maybe ( Evergreen.V89.Data.Map.TileCoords, Set.Set Evergreen.V89.Data.Map.TileCoords ) - , hoveredItem : Maybe Evergreen.V89.Frontend.HoveredItem.HoveredItem - } - - -type alias BackendModel = - { players : Dict.Dict Evergreen.V89.Data.Player.PlayerName.PlayerName (Evergreen.V89.Data.Player.Player Evergreen.V89.Data.Player.SPlayer) - , loggedInPlayers : Dict.Dict Lamdera.ClientId Evergreen.V89.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - , adminLoggedIn : Maybe ( Lamdera.ClientId, Lamdera.SessionId ) - , time : Time.Posix - , vendors : AssocList.Dict Evergreen.V89.Data.Vendor.Name Evergreen.V89.Data.Vendor.Vendor - , lastItemId : Int - } - - -type BarterMsg - = AddPlayerItem Evergreen.V89.Data.Item.Id Int - | AddVendorItem Evergreen.V89.Data.Item.Id Int - | AddPlayerCaps Int - | AddVendorCaps Int - | RemovePlayerItem Evergreen.V89.Data.Item.Id Int - | RemoveVendorItem Evergreen.V89.Data.Item.Id Int - | RemovePlayerCaps Int - | RemoveVendorCaps Int - | ResetBarter - | ConfirmBarter - | SetTransferNInput Evergreen.V89.Data.Barter.TransferNPosition String - | SetTransferNHover Evergreen.V89.Data.Barter.TransferNPosition - | UnsetTransferNHover - - -type FrontendMsg - = UrlClicked Browser.UrlRequest - | UrlChanged Url.Url - | GoToRoute Evergreen.V89.Frontend.Route.Route - | Logout - | Login - | Register - | GotZone Time.Zone - | GotTime Time.Posix - | AskToFight Evergreen.V89.Data.Player.PlayerName.PlayerName - | AskToHeal - | AskToUseItem Evergreen.V89.Data.Item.Id - | AskToWander - | AskToChoosePerk Evergreen.V89.Data.Perk.Perk - | AskToEquipItem Evergreen.V89.Data.Item.Id - | AskToUnequipArmor - | AskForExport - | ImportButtonClicked - | ImportFileSelected File - | AskToImport String - | Refresh - | AskToTagSkill Evergreen.V89.Data.Skill.Skill - | AskToUseSkillPoints Evergreen.V89.Data.Skill.Skill - | SetAuthName String - | SetAuthPassword String - | CreateChar - | NewCharIncSpecial Evergreen.V89.Data.Special.Type - | NewCharDecSpecial Evergreen.V89.Data.Special.Type - | NewCharToggleTaggedSkill Evergreen.V89.Data.Skill.Skill - | NewCharToggleTrait Evergreen.V89.Data.Trait.Trait - | MapMouseAtCoords Evergreen.V89.Data.Map.TileCoords - | MapMouseOut - | MapMouseClick - | OpenMessage Evergreen.V89.Data.Message.Message - | AskToRemoveMessage Evergreen.V89.Data.Message.Message - | BarterMsg BarterMsg - | HoverItem Evergreen.V89.Frontend.HoveredItem.HoveredItem - | StopHoveringItem - - -type AdminToBackend - = ExportJson - | ImportJson String - - -type ToBackend - = LogMeIn (Evergreen.V89.Data.Auth.Auth Evergreen.V89.Data.Auth.Hashed) - | RegisterMe (Evergreen.V89.Data.Auth.Auth Evergreen.V89.Data.Auth.Hashed) - | CreateNewChar Evergreen.V89.Data.NewChar.NewChar - | LogMeOut - | Fight Evergreen.V89.Data.Player.PlayerName.PlayerName - | HealMe - | UseItem Evergreen.V89.Data.Item.Id - | Wander - | EquipItem Evergreen.V89.Data.Item.Id - | UnequipArmor - | RefreshPlease - | TagSkill Evergreen.V89.Data.Skill.Skill - | UseSkillPoints Evergreen.V89.Data.Skill.Skill - | ChoosePerk Evergreen.V89.Data.Perk.Perk - | MoveTo Evergreen.V89.Data.Map.TileCoords (Set.Set Evergreen.V89.Data.Map.TileCoords) - | MessageWasRead Evergreen.V89.Data.Message.Message - | RemoveMessage Evergreen.V89.Data.Message.Message - | Barter Evergreen.V89.Data.Barter.State - | AdminToBackend AdminToBackend - - -type BackendMsg - = Connected Lamdera.SessionId Lamdera.ClientId - | Disconnected Lamdera.SessionId Lamdera.ClientId - | GeneratedFight Lamdera.ClientId Evergreen.V89.Data.Player.SPlayer ( Evergreen.V89.Data.Fight.Generator.Fight, Int ) - | GeneratedNewVendorsStock ( AssocList.Dict Evergreen.V89.Data.Vendor.Name Evergreen.V89.Data.Vendor.Vendor, Int ) - | Tick Time.Posix - | CreateNewCharWithTime Lamdera.ClientId Evergreen.V89.Data.NewChar.NewChar Time.Posix - | LoggedToBackendMsg - - -type ToFrontend - = YourCurrentWorld Evergreen.V89.Data.World.WorldLoggedInData - | InitWorld Evergreen.V89.Data.World.WorldLoggedOutData - | RefreshedLoggedOut Evergreen.V89.Data.World.WorldLoggedOutData - | CurrentAdminData Evergreen.V89.Data.World.AdminData - | YourFightResult ( Evergreen.V89.Data.Fight.Info, Evergreen.V89.Data.World.WorldLoggedInData ) - | YoureLoggedIn Evergreen.V89.Data.World.WorldLoggedInData - | YoureRegistered Evergreen.V89.Data.World.WorldLoggedInData - | CharCreationError Evergreen.V89.Data.NewChar.CreationError - | YouHaveCreatedChar Evergreen.V89.Data.World.WorldLoggedInData - | YoureLoggedOut Evergreen.V89.Data.World.WorldLoggedOutData - | AlertMessage String - | YoureLoggedInAsAdmin Evergreen.V89.Data.World.AdminData - | JsonExportDone String - | BarterDone ( Evergreen.V89.Data.World.WorldLoggedInData, Maybe Evergreen.V89.Data.Barter.Message ) - | BarterMessage Evergreen.V89.Data.Barter.Message diff --git a/src/Evergreen/V96/Data/Auth.elm b/src/Evergreen/V96/Data/Auth.elm deleted file mode 100644 index 98c1b310..00000000 --- a/src/Evergreen/V96/Data/Auth.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V96.Data.Auth exposing (..) - - -type Plaintext - = Plaintext - - -type Password a - = Password String - - -type alias Auth a = - { name : String - , password : Password a - } - - -type Verified - = Verified - - -type Hashed - = Hashed diff --git a/src/Evergreen/V96/Data/Barter.elm b/src/Evergreen/V96/Data/Barter.elm deleted file mode 100644 index 58e97d4c..00000000 --- a/src/Evergreen/V96/Data/Barter.elm +++ /dev/null @@ -1,33 +0,0 @@ -module Evergreen.V96.Data.Barter exposing (..) - -import AssocList -import Dict -import Evergreen.V96.Data.Item - - -type Message - = BarterIsEmpty - | PlayerOfferNotValuableEnough - | YouGaveStuffForFree - - -type TransferNPosition - = PlayerKeptItem Evergreen.V96.Data.Item.Id - | VendorKeptItem Evergreen.V96.Data.Item.Id - | PlayerTradedItem Evergreen.V96.Data.Item.Id - | VendorTradedItem Evergreen.V96.Data.Item.Id - | PlayerKeptCaps - | VendorKeptCaps - | PlayerTradedCaps - | VendorTradedCaps - - -type alias State = - { playerItems : Dict.Dict Evergreen.V96.Data.Item.Id Int - , vendorItems : Dict.Dict Evergreen.V96.Data.Item.Id Int - , playerCaps : Int - , vendorCaps : Int - , lastMessage : Maybe Message - , transferNInputs : AssocList.Dict TransferNPosition String - , transferNHover : Maybe TransferNPosition - } diff --git a/src/Evergreen/V96/Data/Enemy.elm b/src/Evergreen/V96/Data/Enemy.elm deleted file mode 100644 index e8a798c0..00000000 --- a/src/Evergreen/V96/Data/Enemy.elm +++ /dev/null @@ -1,14 +0,0 @@ -module Evergreen.V96.Data.Enemy exposing (..) - - -type Type - = Brahmin - | AngryBrahmin - | WeakBrahmin - | WildBrahmin - | GiantAnt - | ToughGiantAnt - | BlackRadscorpion - | LesserBlackRadscorpion - | LesserRadscorpion - | Radscorpion diff --git a/src/Evergreen/V96/Data/Fight.elm b/src/Evergreen/V96/Data/Fight.elm deleted file mode 100644 index 6bf7b2ef..00000000 --- a/src/Evergreen/V96/Data/Fight.elm +++ /dev/null @@ -1,90 +0,0 @@ -module Evergreen.V96.Data.Fight exposing (..) - -import AssocList -import AssocSet -import Evergreen.V96.Data.Enemy -import Evergreen.V96.Data.Fight.ShotType -import Evergreen.V96.Data.Item -import Evergreen.V96.Data.Perk -import Evergreen.V96.Data.Player.PlayerName -import Evergreen.V96.Data.Skill -import Evergreen.V96.Data.Special -import Evergreen.V96.Data.Trait -import Evergreen.V96.Logic - - -type alias PlayerOpponent = - { name : Evergreen.V96.Data.Player.PlayerName.PlayerName - , xp : Int - } - - -type OpponentType - = Npc Evergreen.V96.Data.Enemy.Type - | Player PlayerOpponent - - -type Who - = Attacker - | Target - - -type Action - = Start - { distanceHexes : Int - } - | ComeCloser - { hexes : Int - , remainingDistanceHexes : Int - } - | Attack - { damage : Int - , shotType : Evergreen.V96.Data.Fight.ShotType.ShotType - , remainingHp : Int - , isCritical : Bool - } - | Miss - { shotType : Evergreen.V96.Data.Fight.ShotType.ShotType - } - - -type Result - = AttackerWon - { xpGained : Int - , capsGained : Int - , itemsGained : List Evergreen.V96.Data.Item.Item - } - | TargetWon - { xpGained : Int - , capsGained : Int - , itemsGained : List Evergreen.V96.Data.Item.Item - } - | TargetAlreadyDead - | BothDead - | NobodyDead - - -type alias Info = - { attacker : OpponentType - , target : OpponentType - , log : List ( Who, Action ) - , result : Result - } - - -type alias Opponent = - { type_ : OpponentType - , hp : Int - , maxHp : Int - , maxAp : Int - , sequence : Int - , traits : AssocSet.Set Evergreen.V96.Data.Trait.Trait - , perks : AssocList.Dict Evergreen.V96.Data.Perk.Perk Int - , caps : Int - , drops : List Evergreen.V96.Data.Item.Item - , equippedArmor : Maybe Evergreen.V96.Data.Item.Kind - , naturalArmorClass : Int - , attackStats : Evergreen.V96.Logic.AttackStats - , addedSkillPercentages : AssocList.Dict Evergreen.V96.Data.Skill.Skill Int - , special : Evergreen.V96.Data.Special.Special - } diff --git a/src/Evergreen/V96/Data/Fight/Generator.elm b/src/Evergreen/V96/Data/Fight/Generator.elm deleted file mode 100644 index 4b5c386d..00000000 --- a/src/Evergreen/V96/Data/Fight/Generator.elm +++ /dev/null @@ -1,12 +0,0 @@ -module Evergreen.V96.Data.Fight.Generator exposing (..) - -import Evergreen.V96.Data.Fight -import Evergreen.V96.Data.Message - - -type alias Fight = - { finalAttacker : Evergreen.V96.Data.Fight.Opponent - , finalTarget : Evergreen.V96.Data.Fight.Opponent - , fightInfo : Evergreen.V96.Data.Fight.Info - , messageForTarget : Evergreen.V96.Data.Message.Message - } diff --git a/src/Evergreen/V96/Data/Fight/ShotType.elm b/src/Evergreen/V96/Data/Fight/ShotType.elm deleted file mode 100644 index 89ee716e..00000000 --- a/src/Evergreen/V96/Data/Fight/ShotType.elm +++ /dev/null @@ -1,17 +0,0 @@ -module Evergreen.V96.Data.Fight.ShotType exposing (..) - - -type AimedShot - = Head - | Torso - | Eyes - | Groin - | LeftArm - | RightArm - | LeftLeg - | RightLeg - - -type ShotType - = NormalShot - | AimedShot AimedShot diff --git a/src/Evergreen/V96/Data/HealthStatus.elm b/src/Evergreen/V96/Data/HealthStatus.elm deleted file mode 100644 index b31e0579..00000000 --- a/src/Evergreen/V96/Data/HealthStatus.elm +++ /dev/null @@ -1,16 +0,0 @@ -module Evergreen.V96.Data.HealthStatus exposing (..) - - -type HealthStatus - = ExactHp - { current : Int - , max : Int - } - | Unhurt - | SlightlyWounded - | Wounded - | SeverelyWounded - | AlmostDead - | Dead - | Alive - | Unknown diff --git a/src/Evergreen/V96/Data/Item.elm b/src/Evergreen/V96/Data/Item.elm deleted file mode 100644 index 5ecf6c07..00000000 --- a/src/Evergreen/V96/Data/Item.elm +++ /dev/null @@ -1,27 +0,0 @@ -module Evergreen.V96.Data.Item exposing (..) - - -type alias Id = - Int - - -type Kind - = Fruit - | HealingPowder - | Stimpak - | BigBookOfScience - | DeansElectronics - | FirstAidBook - | GunsAndBullets - | ScoutHandbook - | Robes - | LeatherJacket - | LeatherArmor - | MetalArmor - - -type alias Item = - { id : Id - , kind : Kind - , count : Int - } diff --git a/src/Evergreen/V96/Data/Map.elm b/src/Evergreen/V96/Data/Map.elm deleted file mode 100644 index 93b36a8c..00000000 --- a/src/Evergreen/V96/Data/Map.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V96.Data.Map exposing (..) - - -type alias TileNum = - Int - - -type alias TileCoords = - ( Int, Int ) diff --git a/src/Evergreen/V96/Data/Message.elm b/src/Evergreen/V96/Data/Message.elm deleted file mode 100644 index b89d3b37..00000000 --- a/src/Evergreen/V96/Data/Message.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V96.Data.Message exposing (..) - -import Evergreen.V96.Data.Fight -import Evergreen.V96.Data.Player.PlayerName -import Time - - -type Type - = Welcome - | YouAdvancedLevel - { newLevel : Int - } - | YouWereAttacked - { attacker : Evergreen.V96.Data.Player.PlayerName.PlayerName - , fightInfo : Evergreen.V96.Data.Fight.Info - } - - -type alias Message = - { type_ : Type - , hasBeenRead : Bool - , date : Time.Posix - } diff --git a/src/Evergreen/V96/Data/NewChar.elm b/src/Evergreen/V96/Data/NewChar.elm deleted file mode 100644 index cba7412a..00000000 --- a/src/Evergreen/V96/Data/NewChar.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V96.Data.NewChar exposing (..) - -import AssocSet -import Evergreen.V96.Data.Skill -import Evergreen.V96.Data.Special -import Evergreen.V96.Data.Trait - - -type CreationError - = DoesNotHaveThreeTaggedSkills - | HasSpecialPointsLeft - | UsedMoreSpecialPointsThanAvailable - | HasSpecialOutOfRange - | HasMoreThanTwoTraits - - -type alias NewChar = - { baseSpecial : Evergreen.V96.Data.Special.Special - , availableSpecial : Int - , taggedSkills : AssocSet.Set Evergreen.V96.Data.Skill.Skill - , traits : AssocSet.Set Evergreen.V96.Data.Trait.Trait - , error : Maybe CreationError - } diff --git a/src/Evergreen/V96/Data/Perk.elm b/src/Evergreen/V96/Data/Perk.elm deleted file mode 100644 index fc435c05..00000000 --- a/src/Evergreen/V96/Data/Perk.elm +++ /dev/null @@ -1,45 +0,0 @@ -module Evergreen.V96.Data.Perk exposing (..) - - -type Perk - = BonusHthDamage - | Awareness - | CautiousNature - | Comprehension - | EarlierSequence - | FasterHealing - | HereAndNow - | Survivalist - | SwiftLearner - | Thief - | Toughness - | AdrenalineRush - | Educated - | FortuneFinder - | Gambler - | MoreCriticals - | Negotiator - | Pathfinder - | Ranger - | Salesman - | BetterCriticals - | Dodger - | Speaker - | ActionBoy - | GainStrength - | GainPerception - | GainEndurance - | GainCharisma - | GainIntelligence - | GainAgility - | GainLuck - | HthEvade - | Lifegiver - | LivingAnatomy - | MasterThief - | MasterTrader - | Medic - | MrFixit - | Tag - | BonusHthAttacks - | Slayer diff --git a/src/Evergreen/V96/Data/Player.elm b/src/Evergreen/V96/Data/Player.elm deleted file mode 100644 index 9378db0d..00000000 --- a/src/Evergreen/V96/Data/Player.elm +++ /dev/null @@ -1,77 +0,0 @@ -module Evergreen.V96.Data.Player exposing (..) - -import AssocList -import AssocSet -import Dict -import Evergreen.V96.Data.Auth -import Evergreen.V96.Data.HealthStatus -import Evergreen.V96.Data.Item -import Evergreen.V96.Data.Map -import Evergreen.V96.Data.Message -import Evergreen.V96.Data.Perk -import Evergreen.V96.Data.Player.PlayerName -import Evergreen.V96.Data.Skill -import Evergreen.V96.Data.Special -import Evergreen.V96.Data.Trait -import Evergreen.V96.Data.Xp - - -type alias COtherPlayer = - { level : Evergreen.V96.Data.Xp.Level - , name : Evergreen.V96.Data.Player.PlayerName.PlayerName - , wins : Int - , losses : Int - , healthStatus : Evergreen.V96.Data.HealthStatus.HealthStatus - } - - -type alias CPlayer = - { hp : Int - , maxHp : Int - , xp : Evergreen.V96.Data.Xp.Xp - , name : Evergreen.V96.Data.Player.PlayerName.PlayerName - , special : Evergreen.V96.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V96.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V96.Data.Perk.Perk Int - , messages : List Evergreen.V96.Data.Message.Message - , items : Dict.Dict Evergreen.V96.Data.Item.Id Evergreen.V96.Data.Item.Item - , traits : AssocSet.Set Evergreen.V96.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V96.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V96.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - , equippedArmor : Maybe Evergreen.V96.Data.Item.Item - } - - -type Player a - = NeedsCharCreated (Evergreen.V96.Data.Auth.Auth Evergreen.V96.Data.Auth.Verified) - | Player a - - -type alias SPlayer = - { name : Evergreen.V96.Data.Player.PlayerName.PlayerName - , password : Evergreen.V96.Data.Auth.Password Evergreen.V96.Data.Auth.Verified - , hp : Int - , maxHp : Int - , xp : Int - , special : Evergreen.V96.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V96.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V96.Data.Perk.Perk Int - , messages : List Evergreen.V96.Data.Message.Message - , items : Dict.Dict Evergreen.V96.Data.Item.Id Evergreen.V96.Data.Item.Item - , traits : AssocSet.Set Evergreen.V96.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V96.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V96.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - , equippedArmor : Maybe Evergreen.V96.Data.Item.Item - } diff --git a/src/Evergreen/V96/Data/Player/PlayerName.elm b/src/Evergreen/V96/Data/Player/PlayerName.elm deleted file mode 100644 index 09b23341..00000000 --- a/src/Evergreen/V96/Data/Player/PlayerName.elm +++ /dev/null @@ -1,5 +0,0 @@ -module Evergreen.V96.Data.Player.PlayerName exposing (..) - - -type alias PlayerName = - String diff --git a/src/Evergreen/V96/Data/Skill.elm b/src/Evergreen/V96/Data/Skill.elm deleted file mode 100644 index 8208224d..00000000 --- a/src/Evergreen/V96/Data/Skill.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V96.Data.Skill exposing (..) - - -type Skill - = SmallGuns - | BigGuns - | EnergyWeapons - | Unarmed - | MeleeWeapons - | Throwing - | FirstAid - | Doctor - | Sneak - | Lockpick - | Steal - | Traps - | Science - | Repair - | Speech - | Barter - | Gambling - | Outdoorsman diff --git a/src/Evergreen/V96/Data/Special.elm b/src/Evergreen/V96/Data/Special.elm deleted file mode 100644 index 6f26fc38..00000000 --- a/src/Evergreen/V96/Data/Special.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V96.Data.Special exposing (..) - - -type alias Special = - { strength : Int - , perception : Int - , endurance : Int - , charisma : Int - , intelligence : Int - , agility : Int - , luck : Int - } - - -type Type - = Strength - | Perception - | Endurance - | Charisma - | Intelligence - | Agility - | Luck diff --git a/src/Evergreen/V96/Data/Trait.elm b/src/Evergreen/V96/Data/Trait.elm deleted file mode 100644 index a1c330b6..00000000 --- a/src/Evergreen/V96/Data/Trait.elm +++ /dev/null @@ -1,11 +0,0 @@ -module Evergreen.V96.Data.Trait exposing (..) - - -type Trait - = Kamikaze - | Bruiser - | Gifted - | SmallFrame - | Skilled - | HeavyHanded - | Finesse diff --git a/src/Evergreen/V96/Data/Vendor.elm b/src/Evergreen/V96/Data/Vendor.elm deleted file mode 100644 index 5432962a..00000000 --- a/src/Evergreen/V96/Data/Vendor.elm +++ /dev/null @@ -1,20 +0,0 @@ -module Evergreen.V96.Data.Vendor exposing (..) - -import Dict -import Evergreen.V96.Data.Item - - -type Name - = ArroyoHakunin - | KlamathMaidaBuckner - | DenFlick - | ModocJo - | VaultCityHappyHarry - - -type alias Vendor = - { name : Name - , items : Dict.Dict Evergreen.V96.Data.Item.Id Evergreen.V96.Data.Item.Item - , caps : Int - , barterSkill : Int - } diff --git a/src/Evergreen/V96/Data/World.elm b/src/Evergreen/V96/Data/World.elm deleted file mode 100644 index 7e01daff..00000000 --- a/src/Evergreen/V96/Data/World.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.V96.Data.World exposing (..) - -import AssocList -import Evergreen.V96.Data.Auth -import Evergreen.V96.Data.Player -import Evergreen.V96.Data.Player.PlayerName -import Evergreen.V96.Data.Vendor -import Time - - -type alias WorldLoggedOutData = - { players : List Evergreen.V96.Data.Player.COtherPlayer - } - - -type alias WorldLoggedInData = - { player : Evergreen.V96.Data.Player.Player Evergreen.V96.Data.Player.CPlayer - , otherPlayers : List Evergreen.V96.Data.Player.COtherPlayer - , playerRank : Int - , vendors : AssocList.Dict Evergreen.V96.Data.Vendor.Name Evergreen.V96.Data.Vendor.Vendor - } - - -type alias AdminData = - { players : List (Evergreen.V96.Data.Player.Player Evergreen.V96.Data.Player.SPlayer) - , loggedInPlayers : List Evergreen.V96.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - } - - -type World - = WorldNotInitialized (Evergreen.V96.Data.Auth.Auth Evergreen.V96.Data.Auth.Plaintext) - | WorldLoggedOut (Evergreen.V96.Data.Auth.Auth Evergreen.V96.Data.Auth.Plaintext) WorldLoggedOutData - | WorldLoggedIn WorldLoggedInData - | WorldAdmin AdminData diff --git a/src/Evergreen/V96/Data/Xp.elm b/src/Evergreen/V96/Data/Xp.elm deleted file mode 100644 index 09928368..00000000 --- a/src/Evergreen/V96/Data/Xp.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V96.Data.Xp exposing (..) - - -type alias Level = - Int - - -type alias Xp = - Int diff --git a/src/Evergreen/V96/Frontend/HoveredItem.elm b/src/Evergreen/V96/Frontend/HoveredItem.elm deleted file mode 100644 index 28f29b78..00000000 --- a/src/Evergreen/V96/Frontend/HoveredItem.elm +++ /dev/null @@ -1,13 +0,0 @@ -module Evergreen.V96.Frontend.HoveredItem exposing (..) - -import Evergreen.V96.Data.Perk -import Evergreen.V96.Data.Skill -import Evergreen.V96.Data.Special -import Evergreen.V96.Data.Trait - - -type HoveredItem - = HoveredPerk Evergreen.V96.Data.Perk.Perk - | HoveredTrait Evergreen.V96.Data.Trait.Trait - | HoveredSpecial Evergreen.V96.Data.Special.Type - | HoveredSkill Evergreen.V96.Data.Skill.Skill diff --git a/src/Evergreen/V96/Frontend/Route.elm b/src/Evergreen/V96/Frontend/Route.elm deleted file mode 100644 index 9be72ee3..00000000 --- a/src/Evergreen/V96/Frontend/Route.elm +++ /dev/null @@ -1,31 +0,0 @@ -module Evergreen.V96.Frontend.Route exposing (..) - -import Evergreen.V96.Data.Barter -import Evergreen.V96.Data.Fight -import Evergreen.V96.Data.Message - - -type TownRoute - = MainSquare - | Store - { barter : Evergreen.V96.Data.Barter.State - } - - -type AdminRoute - = LoggedIn - - -type Route - = Character - | Inventory - | Map - | Ladder - | Town TownRoute - | About - | News - | Fight Evergreen.V96.Data.Fight.Info - | Messages - | Message Evergreen.V96.Data.Message.Message - | CharCreation - | Admin AdminRoute diff --git a/src/Evergreen/V96/Logic.elm b/src/Evergreen/V96/Logic.elm deleted file mode 100644 index 4c5372f2..00000000 --- a/src/Evergreen/V96/Logic.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V96.Logic exposing (..) - - -type alias AttackStats = - { minDamage : Int - , maxDamage : Int - , criticalChanceBonus : Int - } diff --git a/src/Evergreen/V96/Types.elm b/src/Evergreen/V96/Types.elm deleted file mode 100644 index e186a16f..00000000 --- a/src/Evergreen/V96/Types.elm +++ /dev/null @@ -1,164 +0,0 @@ -module Evergreen.V96.Types exposing (..) - -import AssocList -import Browser -import Browser.Navigation -import Dict -import Evergreen.V96.Data.Auth -import Evergreen.V96.Data.Barter -import Evergreen.V96.Data.Fight -import Evergreen.V96.Data.Fight.Generator -import Evergreen.V96.Data.Item -import Evergreen.V96.Data.Map -import Evergreen.V96.Data.Message -import Evergreen.V96.Data.NewChar -import Evergreen.V96.Data.Perk -import Evergreen.V96.Data.Player -import Evergreen.V96.Data.Player.PlayerName -import Evergreen.V96.Data.Skill -import Evergreen.V96.Data.Special -import Evergreen.V96.Data.Trait -import Evergreen.V96.Data.Vendor -import Evergreen.V96.Data.World -import Evergreen.V96.Frontend.HoveredItem -import Evergreen.V96.Frontend.Route -import File exposing (File) -import Lamdera -import Set -import Time -import Url - - -type alias FrontendModel = - { key : Browser.Navigation.Key - , time : Time.Posix - , zone : Time.Zone - , route : Evergreen.V96.Frontend.Route.Route - , world : Evergreen.V96.Data.World.World - , newChar : Evergreen.V96.Data.NewChar.NewChar - , alertMessage : Maybe String - , mapMouseCoords : Maybe ( Evergreen.V96.Data.Map.TileCoords, Set.Set Evergreen.V96.Data.Map.TileCoords ) - , hoveredItem : Maybe Evergreen.V96.Frontend.HoveredItem.HoveredItem - } - - -type alias BackendModel = - { players : Dict.Dict Evergreen.V96.Data.Player.PlayerName.PlayerName (Evergreen.V96.Data.Player.Player Evergreen.V96.Data.Player.SPlayer) - , loggedInPlayers : Dict.Dict Lamdera.ClientId Evergreen.V96.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - , adminLoggedIn : Maybe ( Lamdera.ClientId, Lamdera.SessionId ) - , time : Time.Posix - , vendors : AssocList.Dict Evergreen.V96.Data.Vendor.Name Evergreen.V96.Data.Vendor.Vendor - , lastItemId : Int - } - - -type BarterMsg - = AddPlayerItem Evergreen.V96.Data.Item.Id Int - | AddVendorItem Evergreen.V96.Data.Item.Id Int - | AddPlayerCaps Int - | AddVendorCaps Int - | RemovePlayerItem Evergreen.V96.Data.Item.Id Int - | RemoveVendorItem Evergreen.V96.Data.Item.Id Int - | RemovePlayerCaps Int - | RemoveVendorCaps Int - | ResetBarter - | ConfirmBarter - | SetTransferNInput Evergreen.V96.Data.Barter.TransferNPosition String - | SetTransferNHover Evergreen.V96.Data.Barter.TransferNPosition - | UnsetTransferNHover - - -type FrontendMsg - = UrlClicked Browser.UrlRequest - | UrlChanged Url.Url - | GoToRoute Evergreen.V96.Frontend.Route.Route - | Logout - | Login - | Register - | GotZone Time.Zone - | GotTime Time.Posix - | AskToFight Evergreen.V96.Data.Player.PlayerName.PlayerName - | AskToHeal - | AskToUseItem Evergreen.V96.Data.Item.Id - | AskToWander - | AskToChoosePerk Evergreen.V96.Data.Perk.Perk - | AskToEquipItem Evergreen.V96.Data.Item.Id - | AskToUnequipArmor - | AskForExport - | ImportButtonClicked - | ImportFileSelected File - | AskToImport String - | Refresh - | AskToTagSkill Evergreen.V96.Data.Skill.Skill - | AskToUseSkillPoints Evergreen.V96.Data.Skill.Skill - | SetAuthName String - | SetAuthPassword String - | CreateChar - | NewCharIncSpecial Evergreen.V96.Data.Special.Type - | NewCharDecSpecial Evergreen.V96.Data.Special.Type - | NewCharToggleTaggedSkill Evergreen.V96.Data.Skill.Skill - | NewCharToggleTrait Evergreen.V96.Data.Trait.Trait - | MapMouseAtCoords Evergreen.V96.Data.Map.TileCoords - | MapMouseOut - | MapMouseClick - | OpenMessage Evergreen.V96.Data.Message.Message - | AskToRemoveMessage Evergreen.V96.Data.Message.Message - | BarterMsg BarterMsg - | HoverItem Evergreen.V96.Frontend.HoveredItem.HoveredItem - | StopHoveringItem - - -type AdminToBackend - = ExportJson - | ImportJson String - - -type ToBackend - = LogMeIn (Evergreen.V96.Data.Auth.Auth Evergreen.V96.Data.Auth.Hashed) - | RegisterMe (Evergreen.V96.Data.Auth.Auth Evergreen.V96.Data.Auth.Hashed) - | CreateNewChar Evergreen.V96.Data.NewChar.NewChar - | LogMeOut - | Fight Evergreen.V96.Data.Player.PlayerName.PlayerName - | HealMe - | UseItem Evergreen.V96.Data.Item.Id - | Wander - | EquipItem Evergreen.V96.Data.Item.Id - | UnequipArmor - | RefreshPlease - | TagSkill Evergreen.V96.Data.Skill.Skill - | UseSkillPoints Evergreen.V96.Data.Skill.Skill - | ChoosePerk Evergreen.V96.Data.Perk.Perk - | MoveTo Evergreen.V96.Data.Map.TileCoords (Set.Set Evergreen.V96.Data.Map.TileCoords) - | MessageWasRead Evergreen.V96.Data.Message.Message - | RemoveMessage Evergreen.V96.Data.Message.Message - | Barter Evergreen.V96.Data.Barter.State - | AdminToBackend AdminToBackend - - -type BackendMsg - = Connected Lamdera.SessionId Lamdera.ClientId - | Disconnected Lamdera.SessionId Lamdera.ClientId - | GeneratedFight Lamdera.ClientId Evergreen.V96.Data.Player.SPlayer ( Evergreen.V96.Data.Fight.Generator.Fight, Int ) - | GeneratedNewVendorsStock ( AssocList.Dict Evergreen.V96.Data.Vendor.Name Evergreen.V96.Data.Vendor.Vendor, Int ) - | Tick Time.Posix - | CreateNewCharWithTime Lamdera.ClientId Evergreen.V96.Data.NewChar.NewChar Time.Posix - | LoggedToBackendMsg - - -type ToFrontend - = YourCurrentWorld Evergreen.V96.Data.World.WorldLoggedInData - | InitWorld Evergreen.V96.Data.World.WorldLoggedOutData - | RefreshedLoggedOut Evergreen.V96.Data.World.WorldLoggedOutData - | CurrentAdminData Evergreen.V96.Data.World.AdminData - | YourFightResult ( Evergreen.V96.Data.Fight.Info, Evergreen.V96.Data.World.WorldLoggedInData ) - | YoureLoggedIn Evergreen.V96.Data.World.WorldLoggedInData - | YoureRegistered Evergreen.V96.Data.World.WorldLoggedInData - | CharCreationError Evergreen.V96.Data.NewChar.CreationError - | YouHaveCreatedChar Evergreen.V96.Data.World.WorldLoggedInData - | YoureLoggedOut Evergreen.V96.Data.World.WorldLoggedOutData - | AlertMessage String - | YoureLoggedInAsAdmin Evergreen.V96.Data.World.AdminData - | JsonExportDone String - | BarterDone ( Evergreen.V96.Data.World.WorldLoggedInData, Maybe Evergreen.V96.Data.Barter.Message ) - | BarterMessage Evergreen.V96.Data.Barter.Message diff --git a/src/Evergreen/V97/Data/Auth.elm b/src/Evergreen/V97/Data/Auth.elm deleted file mode 100644 index 1c2a97c9..00000000 --- a/src/Evergreen/V97/Data/Auth.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V97.Data.Auth exposing (..) - - -type Plaintext - = Plaintext - - -type Password a - = Password String - - -type alias Auth a = - { name : String - , password : Password a - } - - -type Verified - = Verified - - -type Hashed - = Hashed diff --git a/src/Evergreen/V97/Data/Barter.elm b/src/Evergreen/V97/Data/Barter.elm deleted file mode 100644 index 17050058..00000000 --- a/src/Evergreen/V97/Data/Barter.elm +++ /dev/null @@ -1,33 +0,0 @@ -module Evergreen.V97.Data.Barter exposing (..) - -import AssocList -import Dict -import Evergreen.V97.Data.Item - - -type Message - = BarterIsEmpty - | PlayerOfferNotValuableEnough - | YouGaveStuffForFree - - -type TransferNPosition - = PlayerKeptItem Evergreen.V97.Data.Item.Id - | VendorKeptItem Evergreen.V97.Data.Item.Id - | PlayerTradedItem Evergreen.V97.Data.Item.Id - | VendorTradedItem Evergreen.V97.Data.Item.Id - | PlayerKeptCaps - | VendorKeptCaps - | PlayerTradedCaps - | VendorTradedCaps - - -type alias State = - { playerItems : Dict.Dict Evergreen.V97.Data.Item.Id Int - , vendorItems : Dict.Dict Evergreen.V97.Data.Item.Id Int - , playerCaps : Int - , vendorCaps : Int - , lastMessage : Maybe Message - , transferNInputs : AssocList.Dict TransferNPosition String - , transferNHover : Maybe TransferNPosition - } diff --git a/src/Evergreen/V97/Data/Enemy.elm b/src/Evergreen/V97/Data/Enemy.elm deleted file mode 100644 index 07a75933..00000000 --- a/src/Evergreen/V97/Data/Enemy.elm +++ /dev/null @@ -1,14 +0,0 @@ -module Evergreen.V97.Data.Enemy exposing (..) - - -type Type - = Brahmin - | AngryBrahmin - | WeakBrahmin - | WildBrahmin - | GiantAnt - | ToughGiantAnt - | BlackRadscorpion - | LesserBlackRadscorpion - | LesserRadscorpion - | Radscorpion diff --git a/src/Evergreen/V97/Data/Fight.elm b/src/Evergreen/V97/Data/Fight.elm deleted file mode 100644 index 8be30438..00000000 --- a/src/Evergreen/V97/Data/Fight.elm +++ /dev/null @@ -1,90 +0,0 @@ -module Evergreen.V97.Data.Fight exposing (..) - -import AssocList -import AssocSet -import Evergreen.V97.Data.Enemy -import Evergreen.V97.Data.Fight.ShotType -import Evergreen.V97.Data.Item -import Evergreen.V97.Data.Perk -import Evergreen.V97.Data.Player.PlayerName -import Evergreen.V97.Data.Skill -import Evergreen.V97.Data.Special -import Evergreen.V97.Data.Trait -import Evergreen.V97.Logic - - -type alias PlayerOpponent = - { name : Evergreen.V97.Data.Player.PlayerName.PlayerName - , xp : Int - } - - -type OpponentType - = Npc Evergreen.V97.Data.Enemy.Type - | Player PlayerOpponent - - -type Who - = Attacker - | Target - - -type Action - = Start - { distanceHexes : Int - } - | ComeCloser - { hexes : Int - , remainingDistanceHexes : Int - } - | Attack - { damage : Int - , shotType : Evergreen.V97.Data.Fight.ShotType.ShotType - , remainingHp : Int - , isCritical : Bool - } - | Miss - { shotType : Evergreen.V97.Data.Fight.ShotType.ShotType - } - - -type Result - = AttackerWon - { xpGained : Int - , capsGained : Int - , itemsGained : List Evergreen.V97.Data.Item.Item - } - | TargetWon - { xpGained : Int - , capsGained : Int - , itemsGained : List Evergreen.V97.Data.Item.Item - } - | TargetAlreadyDead - | BothDead - | NobodyDead - - -type alias Info = - { attacker : OpponentType - , target : OpponentType - , log : List ( Who, Action ) - , result : Result - } - - -type alias Opponent = - { type_ : OpponentType - , hp : Int - , maxHp : Int - , maxAp : Int - , sequence : Int - , traits : AssocSet.Set Evergreen.V97.Data.Trait.Trait - , perks : AssocList.Dict Evergreen.V97.Data.Perk.Perk Int - , caps : Int - , drops : List Evergreen.V97.Data.Item.Item - , equippedArmor : Maybe Evergreen.V97.Data.Item.Kind - , naturalArmorClass : Int - , attackStats : Evergreen.V97.Logic.AttackStats - , addedSkillPercentages : AssocList.Dict Evergreen.V97.Data.Skill.Skill Int - , special : Evergreen.V97.Data.Special.Special - } diff --git a/src/Evergreen/V97/Data/Fight/Generator.elm b/src/Evergreen/V97/Data/Fight/Generator.elm deleted file mode 100644 index 708d063b..00000000 --- a/src/Evergreen/V97/Data/Fight/Generator.elm +++ /dev/null @@ -1,13 +0,0 @@ -module Evergreen.V97.Data.Fight.Generator exposing (..) - -import Evergreen.V97.Data.Fight -import Evergreen.V97.Data.Message - - -type alias Fight = - { finalAttacker : Evergreen.V97.Data.Fight.Opponent - , finalTarget : Evergreen.V97.Data.Fight.Opponent - , fightInfo : Evergreen.V97.Data.Fight.Info - , messageForTarget : Evergreen.V97.Data.Message.Message - , messageForAttacker : Evergreen.V97.Data.Message.Message - } diff --git a/src/Evergreen/V97/Data/Fight/ShotType.elm b/src/Evergreen/V97/Data/Fight/ShotType.elm deleted file mode 100644 index 659bd163..00000000 --- a/src/Evergreen/V97/Data/Fight/ShotType.elm +++ /dev/null @@ -1,17 +0,0 @@ -module Evergreen.V97.Data.Fight.ShotType exposing (..) - - -type AimedShot - = Head - | Torso - | Eyes - | Groin - | LeftArm - | RightArm - | LeftLeg - | RightLeg - - -type ShotType - = NormalShot - | AimedShot AimedShot diff --git a/src/Evergreen/V97/Data/HealthStatus.elm b/src/Evergreen/V97/Data/HealthStatus.elm deleted file mode 100644 index 23617a10..00000000 --- a/src/Evergreen/V97/Data/HealthStatus.elm +++ /dev/null @@ -1,16 +0,0 @@ -module Evergreen.V97.Data.HealthStatus exposing (..) - - -type HealthStatus - = ExactHp - { current : Int - , max : Int - } - | Unhurt - | SlightlyWounded - | Wounded - | SeverelyWounded - | AlmostDead - | Dead - | Alive - | Unknown diff --git a/src/Evergreen/V97/Data/Item.elm b/src/Evergreen/V97/Data/Item.elm deleted file mode 100644 index dde92ba6..00000000 --- a/src/Evergreen/V97/Data/Item.elm +++ /dev/null @@ -1,27 +0,0 @@ -module Evergreen.V97.Data.Item exposing (..) - - -type alias Id = - Int - - -type Kind - = Fruit - | HealingPowder - | Stimpak - | BigBookOfScience - | DeansElectronics - | FirstAidBook - | GunsAndBullets - | ScoutHandbook - | Robes - | LeatherJacket - | LeatherArmor - | MetalArmor - - -type alias Item = - { id : Id - , kind : Kind - , count : Int - } diff --git a/src/Evergreen/V97/Data/Map.elm b/src/Evergreen/V97/Data/Map.elm deleted file mode 100644 index 80a5f6ec..00000000 --- a/src/Evergreen/V97/Data/Map.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V97.Data.Map exposing (..) - - -type alias TileNum = - Int - - -type alias TileCoords = - ( Int, Int ) diff --git a/src/Evergreen/V97/Data/Message.elm b/src/Evergreen/V97/Data/Message.elm deleted file mode 100644 index 6b57f2ef..00000000 --- a/src/Evergreen/V97/Data/Message.elm +++ /dev/null @@ -1,27 +0,0 @@ -module Evergreen.V97.Data.Message exposing (..) - -import Evergreen.V97.Data.Fight -import Evergreen.V97.Data.Player.PlayerName -import Time - - -type Type - = Welcome - | YouAdvancedLevel - { newLevel : Int - } - | YouWereAttacked - { attacker : Evergreen.V97.Data.Player.PlayerName.PlayerName - , fightInfo : Evergreen.V97.Data.Fight.Info - } - | YouAttacked - { target : Evergreen.V97.Data.Player.PlayerName.PlayerName - , fightInfo : Evergreen.V97.Data.Fight.Info - } - - -type alias Message = - { type_ : Type - , hasBeenRead : Bool - , date : Time.Posix - } diff --git a/src/Evergreen/V97/Data/NewChar.elm b/src/Evergreen/V97/Data/NewChar.elm deleted file mode 100644 index cb582f0b..00000000 --- a/src/Evergreen/V97/Data/NewChar.elm +++ /dev/null @@ -1,23 +0,0 @@ -module Evergreen.V97.Data.NewChar exposing (..) - -import AssocSet -import Evergreen.V97.Data.Skill -import Evergreen.V97.Data.Special -import Evergreen.V97.Data.Trait - - -type CreationError - = DoesNotHaveThreeTaggedSkills - | HasSpecialPointsLeft - | UsedMoreSpecialPointsThanAvailable - | HasSpecialOutOfRange - | HasMoreThanTwoTraits - - -type alias NewChar = - { baseSpecial : Evergreen.V97.Data.Special.Special - , availableSpecial : Int - , taggedSkills : AssocSet.Set Evergreen.V97.Data.Skill.Skill - , traits : AssocSet.Set Evergreen.V97.Data.Trait.Trait - , error : Maybe CreationError - } diff --git a/src/Evergreen/V97/Data/Perk.elm b/src/Evergreen/V97/Data/Perk.elm deleted file mode 100644 index 4d2b7ac5..00000000 --- a/src/Evergreen/V97/Data/Perk.elm +++ /dev/null @@ -1,45 +0,0 @@ -module Evergreen.V97.Data.Perk exposing (..) - - -type Perk - = BonusHthDamage - | Awareness - | CautiousNature - | Comprehension - | EarlierSequence - | FasterHealing - | HereAndNow - | Survivalist - | SwiftLearner - | Thief - | Toughness - | AdrenalineRush - | Educated - | FortuneFinder - | Gambler - | MoreCriticals - | Negotiator - | Pathfinder - | Ranger - | Salesman - | BetterCriticals - | Dodger - | Speaker - | ActionBoy - | GainStrength - | GainPerception - | GainEndurance - | GainCharisma - | GainIntelligence - | GainAgility - | GainLuck - | HthEvade - | Lifegiver - | LivingAnatomy - | MasterThief - | MasterTrader - | Medic - | MrFixit - | Tag - | BonusHthAttacks - | Slayer diff --git a/src/Evergreen/V97/Data/Player.elm b/src/Evergreen/V97/Data/Player.elm deleted file mode 100644 index be14f6a6..00000000 --- a/src/Evergreen/V97/Data/Player.elm +++ /dev/null @@ -1,77 +0,0 @@ -module Evergreen.V97.Data.Player exposing (..) - -import AssocList -import AssocSet -import Dict -import Evergreen.V97.Data.Auth -import Evergreen.V97.Data.HealthStatus -import Evergreen.V97.Data.Item -import Evergreen.V97.Data.Map -import Evergreen.V97.Data.Message -import Evergreen.V97.Data.Perk -import Evergreen.V97.Data.Player.PlayerName -import Evergreen.V97.Data.Skill -import Evergreen.V97.Data.Special -import Evergreen.V97.Data.Trait -import Evergreen.V97.Data.Xp - - -type alias COtherPlayer = - { level : Evergreen.V97.Data.Xp.Level - , name : Evergreen.V97.Data.Player.PlayerName.PlayerName - , wins : Int - , losses : Int - , healthStatus : Evergreen.V97.Data.HealthStatus.HealthStatus - } - - -type alias CPlayer = - { hp : Int - , maxHp : Int - , xp : Evergreen.V97.Data.Xp.Xp - , name : Evergreen.V97.Data.Player.PlayerName.PlayerName - , special : Evergreen.V97.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V97.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V97.Data.Perk.Perk Int - , messages : List Evergreen.V97.Data.Message.Message - , items : Dict.Dict Evergreen.V97.Data.Item.Id Evergreen.V97.Data.Item.Item - , traits : AssocSet.Set Evergreen.V97.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V97.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V97.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - , equippedArmor : Maybe Evergreen.V97.Data.Item.Item - } - - -type Player a - = NeedsCharCreated (Evergreen.V97.Data.Auth.Auth Evergreen.V97.Data.Auth.Verified) - | Player a - - -type alias SPlayer = - { name : Evergreen.V97.Data.Player.PlayerName.PlayerName - , password : Evergreen.V97.Data.Auth.Password Evergreen.V97.Data.Auth.Verified - , hp : Int - , maxHp : Int - , xp : Int - , special : Evergreen.V97.Data.Special.Special - , caps : Int - , ticks : Int - , wins : Int - , losses : Int - , location : Evergreen.V97.Data.Map.TileNum - , perks : AssocList.Dict Evergreen.V97.Data.Perk.Perk Int - , messages : List Evergreen.V97.Data.Message.Message - , items : Dict.Dict Evergreen.V97.Data.Item.Id Evergreen.V97.Data.Item.Item - , traits : AssocSet.Set Evergreen.V97.Data.Trait.Trait - , addedSkillPercentages : AssocList.Dict Evergreen.V97.Data.Skill.Skill Int - , taggedSkills : AssocSet.Set Evergreen.V97.Data.Skill.Skill - , availableSkillPoints : Int - , availablePerks : Int - , equippedArmor : Maybe Evergreen.V97.Data.Item.Item - } diff --git a/src/Evergreen/V97/Data/Player/PlayerName.elm b/src/Evergreen/V97/Data/Player/PlayerName.elm deleted file mode 100644 index 0c9e4ce1..00000000 --- a/src/Evergreen/V97/Data/Player/PlayerName.elm +++ /dev/null @@ -1,5 +0,0 @@ -module Evergreen.V97.Data.Player.PlayerName exposing (..) - - -type alias PlayerName = - String diff --git a/src/Evergreen/V97/Data/Skill.elm b/src/Evergreen/V97/Data/Skill.elm deleted file mode 100644 index 671ab397..00000000 --- a/src/Evergreen/V97/Data/Skill.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V97.Data.Skill exposing (..) - - -type Skill - = SmallGuns - | BigGuns - | EnergyWeapons - | Unarmed - | MeleeWeapons - | Throwing - | FirstAid - | Doctor - | Sneak - | Lockpick - | Steal - | Traps - | Science - | Repair - | Speech - | Barter - | Gambling - | Outdoorsman diff --git a/src/Evergreen/V97/Data/Special.elm b/src/Evergreen/V97/Data/Special.elm deleted file mode 100644 index 142cf4cf..00000000 --- a/src/Evergreen/V97/Data/Special.elm +++ /dev/null @@ -1,22 +0,0 @@ -module Evergreen.V97.Data.Special exposing (..) - - -type alias Special = - { strength : Int - , perception : Int - , endurance : Int - , charisma : Int - , intelligence : Int - , agility : Int - , luck : Int - } - - -type Type - = Strength - | Perception - | Endurance - | Charisma - | Intelligence - | Agility - | Luck diff --git a/src/Evergreen/V97/Data/Trait.elm b/src/Evergreen/V97/Data/Trait.elm deleted file mode 100644 index cd378be5..00000000 --- a/src/Evergreen/V97/Data/Trait.elm +++ /dev/null @@ -1,11 +0,0 @@ -module Evergreen.V97.Data.Trait exposing (..) - - -type Trait - = Kamikaze - | Bruiser - | Gifted - | SmallFrame - | Skilled - | HeavyHanded - | Finesse diff --git a/src/Evergreen/V97/Data/Vendor.elm b/src/Evergreen/V97/Data/Vendor.elm deleted file mode 100644 index 42fec890..00000000 --- a/src/Evergreen/V97/Data/Vendor.elm +++ /dev/null @@ -1,20 +0,0 @@ -module Evergreen.V97.Data.Vendor exposing (..) - -import Dict -import Evergreen.V97.Data.Item - - -type Name - = ArroyoHakunin - | KlamathMaidaBuckner - | DenFlick - | ModocJo - | VaultCityHappyHarry - - -type alias Vendor = - { name : Name - , items : Dict.Dict Evergreen.V97.Data.Item.Id Evergreen.V97.Data.Item.Item - , caps : Int - , barterSkill : Int - } diff --git a/src/Evergreen/V97/Data/World.elm b/src/Evergreen/V97/Data/World.elm deleted file mode 100644 index d546059e..00000000 --- a/src/Evergreen/V97/Data/World.elm +++ /dev/null @@ -1,35 +0,0 @@ -module Evergreen.V97.Data.World exposing (..) - -import AssocList -import Evergreen.V97.Data.Auth -import Evergreen.V97.Data.Player -import Evergreen.V97.Data.Player.PlayerName -import Evergreen.V97.Data.Vendor -import Time - - -type alias WorldLoggedOutData = - { players : List Evergreen.V97.Data.Player.COtherPlayer - } - - -type alias WorldLoggedInData = - { player : Evergreen.V97.Data.Player.Player Evergreen.V97.Data.Player.CPlayer - , otherPlayers : List Evergreen.V97.Data.Player.COtherPlayer - , playerRank : Int - , vendors : AssocList.Dict Evergreen.V97.Data.Vendor.Name Evergreen.V97.Data.Vendor.Vendor - } - - -type alias AdminData = - { players : List (Evergreen.V97.Data.Player.Player Evergreen.V97.Data.Player.SPlayer) - , loggedInPlayers : List Evergreen.V97.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - } - - -type World - = WorldNotInitialized (Evergreen.V97.Data.Auth.Auth Evergreen.V97.Data.Auth.Plaintext) - | WorldLoggedOut (Evergreen.V97.Data.Auth.Auth Evergreen.V97.Data.Auth.Plaintext) WorldLoggedOutData - | WorldLoggedIn WorldLoggedInData - | WorldAdmin AdminData diff --git a/src/Evergreen/V97/Data/Xp.elm b/src/Evergreen/V97/Data/Xp.elm deleted file mode 100644 index e0e866ae..00000000 --- a/src/Evergreen/V97/Data/Xp.elm +++ /dev/null @@ -1,9 +0,0 @@ -module Evergreen.V97.Data.Xp exposing (..) - - -type alias Level = - Int - - -type alias Xp = - Int diff --git a/src/Evergreen/V97/Frontend/HoveredItem.elm b/src/Evergreen/V97/Frontend/HoveredItem.elm deleted file mode 100644 index af489c6d..00000000 --- a/src/Evergreen/V97/Frontend/HoveredItem.elm +++ /dev/null @@ -1,13 +0,0 @@ -module Evergreen.V97.Frontend.HoveredItem exposing (..) - -import Evergreen.V97.Data.Perk -import Evergreen.V97.Data.Skill -import Evergreen.V97.Data.Special -import Evergreen.V97.Data.Trait - - -type HoveredItem - = HoveredPerk Evergreen.V97.Data.Perk.Perk - | HoveredTrait Evergreen.V97.Data.Trait.Trait - | HoveredSpecial Evergreen.V97.Data.Special.Type - | HoveredSkill Evergreen.V97.Data.Skill.Skill diff --git a/src/Evergreen/V97/Frontend/Route.elm b/src/Evergreen/V97/Frontend/Route.elm deleted file mode 100644 index 3f1264c6..00000000 --- a/src/Evergreen/V97/Frontend/Route.elm +++ /dev/null @@ -1,31 +0,0 @@ -module Evergreen.V97.Frontend.Route exposing (..) - -import Evergreen.V97.Data.Barter -import Evergreen.V97.Data.Fight -import Evergreen.V97.Data.Message - - -type TownRoute - = MainSquare - | Store - { barter : Evergreen.V97.Data.Barter.State - } - - -type AdminRoute - = LoggedIn - - -type Route - = Character - | Inventory - | Map - | Ladder - | Town TownRoute - | About - | News - | Fight Evergreen.V97.Data.Fight.Info - | Messages - | Message Evergreen.V97.Data.Message.Message - | CharCreation - | Admin AdminRoute diff --git a/src/Evergreen/V97/Logic.elm b/src/Evergreen/V97/Logic.elm deleted file mode 100644 index 57dab323..00000000 --- a/src/Evergreen/V97/Logic.elm +++ /dev/null @@ -1,8 +0,0 @@ -module Evergreen.V97.Logic exposing (..) - - -type alias AttackStats = - { minDamage : Int - , maxDamage : Int - , criticalChanceBonus : Int - } diff --git a/src/Evergreen/V97/Types.elm b/src/Evergreen/V97/Types.elm deleted file mode 100644 index 8ea0ef2b..00000000 --- a/src/Evergreen/V97/Types.elm +++ /dev/null @@ -1,164 +0,0 @@ -module Evergreen.V97.Types exposing (..) - -import AssocList -import Browser -import Browser.Navigation -import Dict -import Evergreen.V97.Data.Auth -import Evergreen.V97.Data.Barter -import Evergreen.V97.Data.Fight -import Evergreen.V97.Data.Fight.Generator -import Evergreen.V97.Data.Item -import Evergreen.V97.Data.Map -import Evergreen.V97.Data.Message -import Evergreen.V97.Data.NewChar -import Evergreen.V97.Data.Perk -import Evergreen.V97.Data.Player -import Evergreen.V97.Data.Player.PlayerName -import Evergreen.V97.Data.Skill -import Evergreen.V97.Data.Special -import Evergreen.V97.Data.Trait -import Evergreen.V97.Data.Vendor -import Evergreen.V97.Data.World -import Evergreen.V97.Frontend.HoveredItem -import Evergreen.V97.Frontend.Route -import File exposing (File) -import Lamdera -import Set -import Time -import Url - - -type alias FrontendModel = - { key : Browser.Navigation.Key - , time : Time.Posix - , zone : Time.Zone - , route : Evergreen.V97.Frontend.Route.Route - , world : Evergreen.V97.Data.World.World - , newChar : Evergreen.V97.Data.NewChar.NewChar - , alertMessage : Maybe String - , mapMouseCoords : Maybe ( Evergreen.V97.Data.Map.TileCoords, Set.Set Evergreen.V97.Data.Map.TileCoords ) - , hoveredItem : Maybe Evergreen.V97.Frontend.HoveredItem.HoveredItem - } - - -type alias BackendModel = - { players : Dict.Dict Evergreen.V97.Data.Player.PlayerName.PlayerName (Evergreen.V97.Data.Player.Player Evergreen.V97.Data.Player.SPlayer) - , loggedInPlayers : Dict.Dict Lamdera.ClientId Evergreen.V97.Data.Player.PlayerName.PlayerName - , nextWantedTick : Maybe Time.Posix - , adminLoggedIn : Maybe ( Lamdera.ClientId, Lamdera.SessionId ) - , time : Time.Posix - , vendors : AssocList.Dict Evergreen.V97.Data.Vendor.Name Evergreen.V97.Data.Vendor.Vendor - , lastItemId : Int - } - - -type BarterMsg - = AddPlayerItem Evergreen.V97.Data.Item.Id Int - | AddVendorItem Evergreen.V97.Data.Item.Id Int - | AddPlayerCaps Int - | AddVendorCaps Int - | RemovePlayerItem Evergreen.V97.Data.Item.Id Int - | RemoveVendorItem Evergreen.V97.Data.Item.Id Int - | RemovePlayerCaps Int - | RemoveVendorCaps Int - | ResetBarter - | ConfirmBarter - | SetTransferNInput Evergreen.V97.Data.Barter.TransferNPosition String - | SetTransferNHover Evergreen.V97.Data.Barter.TransferNPosition - | UnsetTransferNHover - - -type FrontendMsg - = UrlClicked Browser.UrlRequest - | UrlChanged Url.Url - | GoToRoute Evergreen.V97.Frontend.Route.Route - | Logout - | Login - | Register - | GotZone Time.Zone - | GotTime Time.Posix - | AskToFight Evergreen.V97.Data.Player.PlayerName.PlayerName - | AskToHeal - | AskToUseItem Evergreen.V97.Data.Item.Id - | AskToWander - | AskToChoosePerk Evergreen.V97.Data.Perk.Perk - | AskToEquipItem Evergreen.V97.Data.Item.Id - | AskToUnequipArmor - | AskForExport - | ImportButtonClicked - | ImportFileSelected File - | AskToImport String - | Refresh - | AskToTagSkill Evergreen.V97.Data.Skill.Skill - | AskToUseSkillPoints Evergreen.V97.Data.Skill.Skill - | SetAuthName String - | SetAuthPassword String - | CreateChar - | NewCharIncSpecial Evergreen.V97.Data.Special.Type - | NewCharDecSpecial Evergreen.V97.Data.Special.Type - | NewCharToggleTaggedSkill Evergreen.V97.Data.Skill.Skill - | NewCharToggleTrait Evergreen.V97.Data.Trait.Trait - | MapMouseAtCoords Evergreen.V97.Data.Map.TileCoords - | MapMouseOut - | MapMouseClick - | OpenMessage Evergreen.V97.Data.Message.Message - | AskToRemoveMessage Evergreen.V97.Data.Message.Message - | BarterMsg BarterMsg - | HoverItem Evergreen.V97.Frontend.HoveredItem.HoveredItem - | StopHoveringItem - - -type AdminToBackend - = ExportJson - | ImportJson String - - -type ToBackend - = LogMeIn (Evergreen.V97.Data.Auth.Auth Evergreen.V97.Data.Auth.Hashed) - | RegisterMe (Evergreen.V97.Data.Auth.Auth Evergreen.V97.Data.Auth.Hashed) - | CreateNewChar Evergreen.V97.Data.NewChar.NewChar - | LogMeOut - | Fight Evergreen.V97.Data.Player.PlayerName.PlayerName - | HealMe - | UseItem Evergreen.V97.Data.Item.Id - | Wander - | EquipItem Evergreen.V97.Data.Item.Id - | UnequipArmor - | RefreshPlease - | TagSkill Evergreen.V97.Data.Skill.Skill - | UseSkillPoints Evergreen.V97.Data.Skill.Skill - | ChoosePerk Evergreen.V97.Data.Perk.Perk - | MoveTo Evergreen.V97.Data.Map.TileCoords (Set.Set Evergreen.V97.Data.Map.TileCoords) - | MessageWasRead Evergreen.V97.Data.Message.Message - | RemoveMessage Evergreen.V97.Data.Message.Message - | Barter Evergreen.V97.Data.Barter.State - | AdminToBackend AdminToBackend - - -type BackendMsg - = Connected Lamdera.SessionId Lamdera.ClientId - | Disconnected Lamdera.SessionId Lamdera.ClientId - | GeneratedFight Lamdera.ClientId Evergreen.V97.Data.Player.SPlayer ( Evergreen.V97.Data.Fight.Generator.Fight, Int ) - | GeneratedNewVendorsStock ( AssocList.Dict Evergreen.V97.Data.Vendor.Name Evergreen.V97.Data.Vendor.Vendor, Int ) - | Tick Time.Posix - | CreateNewCharWithTime Lamdera.ClientId Evergreen.V97.Data.NewChar.NewChar Time.Posix - | LoggedToBackendMsg - - -type ToFrontend - = YourCurrentWorld Evergreen.V97.Data.World.WorldLoggedInData - | InitWorld Evergreen.V97.Data.World.WorldLoggedOutData - | RefreshedLoggedOut Evergreen.V97.Data.World.WorldLoggedOutData - | CurrentAdminData Evergreen.V97.Data.World.AdminData - | YourFightResult ( Evergreen.V97.Data.Fight.Info, Evergreen.V97.Data.World.WorldLoggedInData ) - | YoureLoggedIn Evergreen.V97.Data.World.WorldLoggedInData - | YoureRegistered Evergreen.V97.Data.World.WorldLoggedInData - | CharCreationError Evergreen.V97.Data.NewChar.CreationError - | YouHaveCreatedChar Evergreen.V97.Data.World.WorldLoggedInData - | YoureLoggedOut Evergreen.V97.Data.World.WorldLoggedOutData - | AlertMessage String - | YoureLoggedInAsAdmin Evergreen.V97.Data.World.AdminData - | JsonExportDone String - | BarterDone ( Evergreen.V97.Data.World.WorldLoggedInData, Maybe Evergreen.V97.Data.Barter.Message ) - | BarterMessage Evergreen.V97.Data.Barter.Message diff --git a/src/Frontend.elm b/src/Frontend.elm index 19c45976..2f264375 100644 --- a/src/Frontend.elm +++ b/src/Frontend.elm @@ -82,11 +82,13 @@ import Result.Extra as Result import Set exposing (Set) import Svg as S exposing (Svg) import Svg.Attributes as SA +import Tailwind as TW import Task import Time exposing (Posix) import Time.Extra as Time import Time.ExtraExtra as Time import Types exposing (..) +import UI import Url exposing (Url) @@ -134,6 +136,7 @@ init url key = , fightInfo = Nothing , fightStrategyText = "" , expandedQuests = Set_.empty + , userWantsToShowAreaDanger = False -- backend state , lastTenToBackendMsgs = [] @@ -144,6 +147,21 @@ init url key = [ Task.perform GotZone Time.here , Task.perform GotTime Time.now , Nav.pushUrl key (Route.toString route) + + -- TODO don't push this, only for developing styles + , let + initAuth = + Auth.init + in + Lamdera.sendToBackend <| + LogMeIn <| + Auth.hash + ({ initAuth + | name = "j2" + , worldName = "main" + } + |> Auth.setPlaintextPassword "j2" + ) ] ) @@ -480,6 +498,11 @@ update msg ({ loginForm } as model) = , Lamdera.sendToBackend <| MoveTo newCoords path ) + SetShowAreaDanger newShow -> + ( { model | userWantsToShowAreaDanger = newShow } + , Cmd.none + ) + OpenMessage messageId -> ( model , Lamdera.sendToBackend <| MessageWasRead messageId @@ -514,8 +537,8 @@ update msg ({ loginForm } as model) = , Cmd.none ) - ToggleAdminNewWorldFast -> - ( { model | adminNewWorldFast = not model.adminNewWorldFast } + SetAdminNewWorldFast new -> + ( { model | adminNewWorldFast = new } , Cmd.none ) @@ -685,7 +708,9 @@ updateFromBackend msg model = YoureLoggedOut worlds -> { model - | loginForm = Auth.init + | loginForm = + Auth.init + |> Auth.selectDefaultWorld worlds , alertMessage = Nothing , worlds = Just worlds , worldData = NotLoggedIn @@ -695,7 +720,9 @@ updateFromBackend msg model = CurrentWorlds worlds -> ( { model | worlds = Just worlds - , loginForm = Auth.selectDefaultWorld worlds model.loginForm + , loginForm = + model.loginForm + |> Auth.selectDefaultWorld worlds } , Cmd.none ) @@ -790,15 +817,43 @@ updateFromBackend msg model = view : Model -> Browser.Document FrontendMsg view model = + let + worldNames : List World.Name + worldNames = + model.worlds + |> Maybe.withDefault [] + |> List.map .name + + leftNav = + case model.worldData of + IsAdmin _ -> + [ alertMessageView model.alertMessage + , H.div [ HA.class "flex flex-col gap-4" ] + [ adminLinksView model.route + , commonLinksView model.route + ] + ] + + IsPlayer data -> + [ alertMessageView model.alertMessage + , playerInfoView data.player + , H.div [ HA.class "flex flex-col gap-4" ] + [ loggedInLinksView data.player model.route + , commonLinksView model.route + ] + ] + + NotLoggedIn -> + [ loginFormView worldNames model.loginForm + , alertMessageView model.alertMessage + , H.div [ HA.class "flex flex-col gap-4" ] + [ loggedOutLinksView model.route + , commonLinksView model.route + ] + ] + in { title = "NuAshworld " ++ Version.version - , body = - [ stylesLinkView - , favicon16View - , favicon32View - , genericFaviconView - , genericFavicon2View - , view_ model - ] + , body = [ appView { leftNav = leftNav } model ] } @@ -807,70 +862,90 @@ appView : -> Model -> Html FrontendMsg appView { leftNav } model = + H.div [ HA.class "flex flex-1 flex-row bg-green-900 max-w-vw max-h-vh overflow-hidden" ] + [ leftNavView leftNav model + , contentView model + ] + + +leftNavView : List (Html FrontendMsg) -> Model -> Html FrontendMsg +leftNavView leftNav model = let - tickFrequency : Maybe Time.Interval - tickFrequency = + tickData : + Maybe + { tickFrequency : Time.Interval + , worldName : String + } + tickData = case model.worldData of IsAdmin _ -> Nothing IsPlayer data -> - Just data.tickFrequency + Just + { tickFrequency = data.tickFrequency + , worldName = data.worldName + } NotLoggedIn -> Nothing in - H.div - [ HA.id "app" - , HA.classList - [ ( "player", isPlayer model ) - , ( "admin", isAdmin model ) - ] - ] - [ H.div [ HA.id "left-nav" ] - [ logoView - , H.div [ HA.id "left-nav-content" ] - ((tickFrequency - |> H.viewMaybe (\freq -> nextTickView freq model.zone model.time) - ) - :: leftNav - ++ [ commonLinksView model.route ] - ) - ] - , contentView model + H.div [ HA.class "bg-green-800 min-w-fit px-6 pb-10 pt-[26px] flex flex-col gap-10 items-center max-h-vh overflow-auto" ] + [ logoView model + , H.div [ HA.class "flex flex-col items-center gap-6" ] + ((tickData |> H.viewMaybe (nextTickView model.zone model.time)) + :: leftNav + ) ] -nextTickView : Time.Interval -> Time.Zone -> Posix -> Html FrontendMsg -nextTickView tickFrequency zone time = +nextTickView : + Time.Zone + -> Posix + -> + { tickFrequency : Time.Interval + , worldName : String + } + -> Html FrontendMsg +nextTickView zone time { tickFrequency, worldName } = let millis = Time.posixToMillis time in - H.div [ HA.id "next-tick" ] <| - if millis == 0 then - [] - - else - let - nextTick = - Tick.nextTick tickFrequency time + -- The -0.5px is a hack to prevent text on Windows from being blurry (basically aligning it back to the pixel grid) + H.div [ HA.class "grid grid-cols-2 gap-x-[1ch] -translate-x-[0.5px]" ] <| + List.concat + [ [ H.span + [ HA.class "text-green-300 text-right" ] + [ H.text "World:" ] + , H.span [] [ H.text worldName ] + ] + , if millis == 0 then + [] - nextTickString = - DateFormat.format - [ DateFormat.hourMilitaryFixed - , DateFormat.text ":" - , DateFormat.minuteFixed - , DateFormat.text ":" - , DateFormat.secondFixed - ] - zone - nextTick - in - [ H.text "Next tick: " - , H.span - [ HA.class "slightly-emphasized" ] - [ H.text nextTickString ] + else + let + nextTick = + Tick.nextTick tickFrequency time + + nextTickString = + DateFormat.format + [ DateFormat.hourMilitaryFixed + , DateFormat.text ":" + , DateFormat.minuteFixed + , DateFormat.text ":" + , DateFormat.secondFixed + ] + zone + nextTick + in + [ H.span + [ HA.class "text-green-300 text-right" ] + [ H.text "Next tick:" ] + , H.span + [ HA.class "text-green-100" ] + [ H.text nextTickString ] + ] ] @@ -900,7 +975,7 @@ contentView model = |> Maybe.map (\loc -> withCreatedPlayer data (fn loc)) |> Maybe.withDefault contentUnavailableWhenNotInTownView in - H.div [ HA.id "content" ] + H.div [ HA.class "pt-8 px-10 pb-10 flex flex-col flex-1 items-start overflow-auto max-h-vh" ] (case ( model.route, model.worldData ) of ( AdminRoute subroute, IsAdmin data ) -> case subroute of @@ -929,7 +1004,7 @@ contentView model = notFoundView url ( Map, IsPlayer data ) -> - withCreatedPlayer data (mapView model.mapMouseCoords) + withCreatedPlayer data (mapView model) ( Map, _ ) -> mapLoggedOutView @@ -995,27 +1070,27 @@ contentView model = pageTitleView : String -> Html FrontendMsg pageTitleView title = H.h2 - [ HA.id "page-title" ] + [ HA.class "text-lg font-extraBold mb-10" ] [ H.text title ] aboutView : List (Html FrontendMsg) aboutView = [ pageTitleView "About" - , Markdown.toHtml - [ HA.id "about-content" ] - """ -Welcome to **NuAshworld** - a multiplayer turn-based browser game set in the -universe of Fallout 2. - -Do you have what it takes to survive in the post-apocalyptic wasteland? Can you -shape the world for the better? - -What more, **can you stand up to the Enclave?** - -Many thanks to Patreons: -* DJetelina (iScrE4m) -""" + , H.div [ HA.class "flex flex-col gap-4 max-w-[60ch]" ] + [ H.p [] + [ H.text "Welcome to " + , H.span [ HA.class "text-green-100" ] [ H.text "NuAshworld" ] + , H.text " - a multiplayer turn-based browser game set in the universe of Fallout 2." + ] + , H.p [] + [ H.text "Do you have what it takes to survive in the post-apocalyptic wasteland? Can you shape the world for the better?" + ] + , H.p [] + [ H.text "What more, " + , H.span [ HA.class "text-green-100" ] [ H.text "can you stand up to the Enclave?" ] + ] + ] ] @@ -1027,11 +1102,19 @@ worldsListView worlds = Just worlds_ -> [ pageTitleView "Worlds" - , H.ul [] + , H.div [ HA.class "flex flex-row flex-wrap gap-4" ] (worlds_ + |> List.sortBy + (\w -> + if w.name == Logic.mainWorldName then + 0 + + else + 1 + ) |> List.map (\world -> - H.li [] + H.div [ HA.class "bg-green-800 p-[2ch]" ] [ worldInfoView { name = world.name , description = world.description @@ -1097,13 +1180,16 @@ adminMapView worldName adminData = |> List.map (.location >> Map.toTileCoords) in H.div - [ HA.id "map" - , HA.class "admin-map" - , cssVars + [ cssVars [ ( "--map-columns", String.fromInt Map.columns ) , ( "--map-rows", String.fromInt Map.rows ) , ( "--map-cell-size", String.fromInt Map.tileSize ++ "px" ) ] + , HA.class "relative bg-black bg-[url('/public/images/map_whole.webp')] bg-[0_0] bg-no-repeat select-none" + , HA.class "min-w-[calc(var(--map-columns)*var(--map-cell-size))]" + , HA.class "max-w-[calc(var(--map-columns)*var(--map-cell-size))]" + , HA.class "min-h-[calc(var(--map-rows)*var(--map-cell-size))]" + , HA.class "max-h-[calc(var(--map-rows)*var(--map-cell-size))]" ] (locationsView Nothing :: List.map mapMarkerView playerCoords @@ -1111,11 +1197,14 @@ adminMapView worldName adminData = mapView : - Maybe ( TileCoords, Set TileCoords ) + { model + | mapMouseCoords : Maybe ( TileCoords, Set TileCoords ) + , userWantsToShowAreaDanger : Bool + } -> PlayerData -> CPlayer -> List (Html FrontendMsg) -mapView mouseCoords _ player = +mapView { mapMouseCoords, userWantsToShowAreaDanger } _ player = let perceptionLevel : PerceptionLevel perceptionLevel = @@ -1129,13 +1218,16 @@ mapView mouseCoords _ player = Map.toTileCoords player.location mouseRelatedView : ( TileCoords, Set TileCoords ) -> Html FrontendMsg - mouseRelatedView ( ( x, y ) as mouseCoords_, pathTaken ) = + mouseRelatedView ( ( x, y ) as mouseCoords, pathTaken ) = let + impassableTiles : Set TileCoords + impassableTiles = + pathTaken + |> Set.filter (Terrain.forCoords >> Terrain.isPassable >> not) + notAllPassable : Bool notAllPassable = - pathTaken - |> Set.toList - |> List.any (Terrain.forCoords >> Terrain.isPassable >> not) + not (Set.isEmpty impassableTiles) cost : Int cost = @@ -1158,32 +1250,50 @@ mapView mouseCoords _ player = bigChunk : BigChunk bigChunk = - BigChunk.forCoords mouseCoords_ - in - H.div - [ HA.id "map-mouse-layer" - , HA.classList - [ ( "too-distant", tooDistant ) - , ( "not-all-passable", notAllPassable ) - ] - ] - [ H.div - [ HA.id "map-mouse-tile" - , HA.class "tile" - , cssVars - [ ( "--tile-coord-x", String.fromInt x ) - , ( "--tile-coord-y", String.fromInt y ) + BigChunk.forCoords mouseCoords + + impossiblePath : Bool + impossiblePath = + tooDistant || notAllPassable + + ( pathTextColor, pathBgColor ) = + if impossiblePath then + ( "text-orange", "bg-orange" ) + + else + ( "text-green-200", "bg-green-300" ) + + tileUnderCursor = + H.div + [ tileClass + , HA.class + (if Set.member mouseCoords impassableTiles then + "bg-red" + + else + pathBgColor + ) + , HA.class "opacity-75 pointer-events-none z-[1]" + , cssVars + [ ( "--tile-coord-x", String.fromInt x ) + , ( "--tile-coord-y", String.fromInt y ) + ] ] - ] - [] - , H.div - [ HA.id "map-path-tiles" ] - (List.map pathTileView - (Set.toList (Set.remove mouseCoords_ pathTaken)) - ) - , H.viewIf (Perception.atLeast Perception.Good perceptionLevel) <| + [] + + pathTiles = + H.div + [ HA.class "absolute inset-0" ] + (List.map (pathTileView pathBgColor impassableTiles) + (Set.toList (Set.remove mouseCoords pathTaken)) + ) + + tooltip = H.div - [ HA.id "map-cost-info" + [ HA.class "w-fit whitespace-nowrap p-5 bg-green-900 relative z-[3]" + , HA.class pathTextColor + , HA.class "translate-x-[calc(var(--map-cell-size)*(0.5+var(--tile-coord-x))-50%)]" + , HA.class "translate-y-[calc(var(--map-cell-size)*var(--tile-coord-y)-100%-10px)]" , cssVars [ ( "--tile-coord-x", String.fromInt x ) , ( "--tile-coord-y", String.fromInt y ) @@ -1197,19 +1307,31 @@ mapView mouseCoords _ player = [ H.div [] [ H.text <| "Path cost: " ++ String.fromInt cost ++ " " ++ ticksString ] , H.viewIf tooDistant <| H.div [] [ H.text "You don't have enough ticks." ] - , H.viewIf shouldShowBigChunks <| - H.div [] [ H.text <| "Map tile difficulty: " ++ BigChunk.difficulty bigChunk ] + , H.viewIf canShowAreaDanger <| + H.div [] [ H.text <| "Map area danger: " ++ BigChunk.difficulty bigChunk ] ] ] + in + H.div + [ HA.class "absolute inset-0" ] + [ tileUnderCursor + , pathTiles + , tooltip + |> H.viewIf (Perception.atLeast Perception.Good perceptionLevel) ] - pathTileView : TileCoords -> Html FrontendMsg - pathTileView ( x, y ) = + pathTileView : String -> Set TileCoords -> TileCoords -> Html FrontendMsg + pathTileView pathBgColor impassableTiles (( x, y ) as coord) = H.div - [ HA.classList - [ ( "tile", True ) - , ( "map-path-tile", True ) - ] + [ HA.class + (if Set.member coord impassableTiles then + "bg-red" + + else + pathBgColor + ) + , HA.class "opacity-50 pointer-events-none z-[1]" + , tileClass , cssVars [ ( "--tile-coord-x", String.fromInt x ) , ( "--tile-coord-y", String.fromInt y ) @@ -1219,12 +1341,12 @@ mapView mouseCoords _ player = mouseCoordsOnly : Maybe TileCoords mouseCoordsOnly = - Maybe.map Tuple.first mouseCoords + Maybe.map Tuple.first mapMouseCoords mouseEventCatcherView : Html FrontendMsg mouseEventCatcherView = H.div - [ HA.id "map-mouse-event-catcher" + [ HA.class "absolute inset-0 z-[4]" , HE.stopPropagationOn "mouseover" (JD.map (\c -> ( MapMouseAtCoords c, True )) <| changedCoordsDecoder mouseCoordsOnly @@ -1259,8 +1381,7 @@ mapView mouseCoords _ player = bigChunkLayerView : () -> Html FrontendMsg bigChunkLayerView () = S.svg - [ HA.id "map-fog" - , SA.viewBox <| "0 0 " ++ String.fromInt Map.columns ++ " " ++ String.fromInt Map.rows + [ SA.viewBox <| "0 0 " ++ String.fromInt Map.columns ++ " " ++ String.fromInt Map.rows ] (BigChunk.all |> List.map @@ -1274,24 +1395,41 @@ mapView mouseCoords _ player = ) ) - shouldShowBigChunks : Bool - shouldShowBigChunks = + canShowAreaDanger : Bool + canShowAreaDanger = Perception.atLeast Perception.Perfect perceptionLevel + + showAreaDanger : Bool + showAreaDanger = + canShowAreaDanger && userWantsToShowAreaDanger in [ pageTitleView "Map" - , H.div - [ HA.id "map" - , cssVars - [ ( "--map-columns", String.fromInt Map.columns ) - , ( "--map-rows", String.fromInt Map.rows ) - , ( "--map-cell-size", String.fromInt Map.tileSize ++ "px" ) + , H.div [ HA.class "flex flex-col items-start gap-4" ] + [ H.viewIf canShowAreaDanger <| + UI.checkbox + { isOn = userWantsToShowAreaDanger + , toggle = SetShowAreaDanger + , label = "Show area danger levels" + } + , H.div + [ cssVars + [ ( "--map-columns", String.fromInt Map.columns ) + , ( "--map-rows", String.fromInt Map.rows ) + , ( "--map-cell-size", String.fromInt Map.tileSize ++ "px" ) + ] + , HA.class "relative bg-black bg-[url('/public/images/map_whole.webp')] bg-[0_0] bg-no-repeat select-none" + , HA.class "min-w-[calc(var(--map-columns)*var(--map-cell-size))]" + , HA.class "max-w-[calc(var(--map-columns)*var(--map-cell-size))]" + , HA.class "min-h-[calc(var(--map-rows)*var(--map-cell-size))]" + , HA.class "max-h-[calc(var(--map-rows)*var(--map-cell-size))]" + ] + [ locationsView (Just playerCoords) + , mapMarkerView playerCoords + , bigChunkLayerView + |> H.viewIfLazy showAreaDanger + , mouseEventCatcherView + , H.viewMaybe mouseRelatedView mapMouseCoords ] - ] - [ locationsView (Just playerCoords) - , mapMarkerView playerCoords - , H.viewIfLazy shouldShowBigChunks bigChunkLayerView - , mouseEventCatcherView - , H.viewMaybe mouseRelatedView mouseCoords ] ] @@ -1330,6 +1468,11 @@ svgPolygonForTiles color coords = [] +tileClass : Attribute msg +tileClass = + HA.class "absolute left-0 top-0 w-[var(--map-cell-size)] h-[var(--map-cell-size)] translate-x-[calc(var(--map-cell-size)*var(--tile-coord-x))] translate-y-[calc(var(--map-cell-size)*var(--tile-coord-y))]" + + locationView : Maybe TileCoords -> Location -> Html FrontendMsg locationView maybePlayer location = let @@ -1351,22 +1494,52 @@ locationView maybePlayer location = isCurrent : Bool isCurrent = maybePlayer == Just ( x, y ) + + borderWidth : String + borderWidth = + case size of + Location.Small -> + "border" + + Location.Middle -> + "border" + + Location.Large -> + "border-2" in H.div - [ HA.classList - [ ( "tile", True ) - , ( "map-location", True ) - , ( "small", size == Location.Small ) - , ( "middle", size == Location.Middle ) - , ( "large", size == Location.Large ) - , ( "has-vendor", hasVendor ) - , ( "is-current", isCurrent ) - ] + [ tileClass + , HA.class "opacity-50 text-green-100 absolute inset-0" + , HA.classList + [ ( "!opacity-100", hasVendor || isCurrent ) ] , HA.attribute "data-location-name" name - , cssVars - [ ( "--tile-coord-x", String.fromInt x ) - , ( "--tile-coord-y", String.fromInt y ) - ] + , TW.mod "hover" "opacity-100" + , TW.mod "before" <| + "absolute top-1/2 left-1/2 content-[''] block w-[var(--location-size)] h-[var(--location-size)] border-green-100 rounded-full -translate-x-1/2 -translate-y-1/2 bg-[radial-gradient(circle,var(--green-100-fully-transparent)_0%,var(--green-100-half-transparent)_100%)] " + ++ borderWidth + , TW.mod "after" "content-[attr(data-location-name)] block top-[var(--location-name-top)] left-1/2 -translate-x-1/2 text-center absolute whitespace-nowrap bg-black-transparent p-x-1 leading-[13px]" + , HA.style "text-shadow" "2px 0 2px #000, 0 2px 2px #000, -2px 0 2px #000, 0 -2px 2px #000" + , cssVars <| + List.concat + [ [ ( "--tile-coord-x", String.fromInt x ) + , ( "--tile-coord-y", String.fromInt y ) + ] + , case size of + Location.Small -> + [ ( "--location-size", "11px" ) + , ( "--location-name-top", "68%" ) + ] + + Location.Middle -> + [ ( "--location-size", "23px" ) + , ( "--location-name-top", "75%" ) + ] + + Location.Large -> + [ ( "--location-size", "45px" ) + , ( "--location-name-top", "100%" ) + ] + ] ] [] @@ -1375,7 +1548,7 @@ locationsView : Maybe TileCoords -> Html FrontendMsg locationsView maybePlayer = Location.allLocations |> List.map (locationView maybePlayer) - |> H.div [ HA.id "map-locations" ] + |> H.div [ HA.class "absolute inset-0 bg-black-transparent" ] changedCoordsDecoder : Maybe TileCoords -> Decoder TileCoords @@ -1407,12 +1580,14 @@ changedCoordsDecoder mouseCoords = mapMarkerView : TileCoords -> Html FrontendMsg mapMarkerView ( x, y ) = H.img - [ HA.class "map-marker" + [ HA.class "absolute left-0 top-0 z-[2]" + , HA.class "translate-x-[calc(var(--map-cell-size)*(0.5+var(--player-coord-x))-50%)]" + , HA.class "translate-y-[calc(var(--map-cell-size)*(0.5+var(--player-coord-y))-50%)]" , cssVars [ ( "--player-coord-x", String.fromInt x ) , ( "--player-coord-y", String.fromInt y ) ] - , HA.src "/images/map_marker.png" + , HA.src "/images/map_marker.webp" , HA.width 25 , HA.height 13 ] @@ -1430,15 +1605,21 @@ cssVars vars = mapLoggedOutView : List (Html FrontendMsg) mapLoggedOutView = [ pageTitleView "Map" - , H.div - [ HA.id "map" - , cssVars - [ ( "--map-columns", String.fromInt Map.columns ) - , ( "--map-rows", String.fromInt Map.rows ) - , ( "--map-cell-size", String.fromInt Map.tileSize ++ "px" ) + , H.div [ HA.class "flex flex-col items-start gap-4" ] + [ H.div + [ cssVars + [ ( "--map-columns", String.fromInt Map.columns ) + , ( "--map-rows", String.fromInt Map.rows ) + , ( "--map-cell-size", String.fromInt Map.tileSize ++ "px" ) + ] + , HA.class "relative bg-black bg-[url('/public/images/map_whole.webp')] bg-[0_0] bg-no-repeat select-none" + , HA.class "min-w-[calc(var(--map-columns)*var(--map-cell-size))]" + , HA.class "max-w-[calc(var(--map-columns)*var(--map-cell-size))]" + , HA.class "min-h-[calc(var(--map-rows)*var(--map-cell-size))]" + , HA.class "max-h-[calc(var(--map-rows)*var(--map-cell-size))]" ] + [ locationsView Nothing ] ] - [ locationsView Nothing ] ] @@ -1467,28 +1648,24 @@ questProgressbarView { ticksGiven, ticksNeeded, ticksGivenByPlayer } = emptyCount = totalCount - doneCount in - H.div [ HA.class "quest-progressbar" ] - [ H.span [] [ H.text "[" ] - , H.span [] [ H.text <| String.repeat doneCount "=" ++ String.repeat emptyCount "-" ] - , H.span [] [ H.text "]" ] - , H.span [ HA.class "quest-progressbar-text" ] - [ H.span - [ HA.class "quest-number" ] - [ H.text <| String.fromInt (round (percentDone * 100)) ++ "%" ] - , H.span [] [ H.text " done (" ] - , H.span - [ HA.class "quest-number" ] - [ H.text <| String.fromInt ticksGiven ] - , H.span [] [ H.text "/" ] - , H.span - [ HA.class "quest-number" ] - [ H.text <| String.fromInt ticksNeeded ] - , H.span [] [ H.text " ticks, you gave " ] - , H.span - [ HA.class "quest-number" ] - [ H.text <| String.fromInt ticksGivenByPlayer ] - , H.span [] [ H.text ")" ] + H.div [ HA.class "flex flex-row gap-[1ch]" ] + [ H.span [ HA.class "text-green-300" ] + [ H.text <| + "[" + ++ String.repeat doneCount "=" + ++ String.repeat emptyCount "-" + ++ "]" ] + , H.text <| + String.fromInt (round (percentDone * 100)) + ++ "%" + ++ " done (" + ++ String.fromInt ticksGiven + ++ "/" + ++ String.fromInt ticksNeeded + ++ " ticks, you gave " + ++ String.fromInt ticksGivenByPlayer + ++ ")" ] @@ -1504,24 +1681,25 @@ townMainSquareView expandedQuests location { questsProgress } player = not <| List.isEmpty quests in [ pageTitleView <| "Town: " ++ Location.name location - , if Vendor.isInLocation location then - H.div [] - [ H.button - [ HE.onClick GoToTownStore ] - [ H.text "[Visit store]" ] - ] + , H.div [ HA.class "flex flex-col gap-4" ] + [ if Vendor.isInLocation location then + H.div [] + [ UI.button + [ HE.onClick GoToTownStore ] + [ H.text "[Visit store]" ] + ] - else - H.div [] [ H.text "No vendor in this town..." ] - , if hasQuests then - H.h3 [] [ H.text "Quests" ] + else + H.div [] [ H.text "No vendor in this town..." ] + , if hasQuests then + H.h3 [] [ H.text "Quests" ] - else - H.text "No quests in this town..." - , H.viewIf hasQuests <| - H.ul - [ HA.class "quests" ] - (List.map (questView player questsProgress expandedQuests) quests) + else + H.text "No quests in this town..." + , H.viewIf hasQuests <| + H.ul [] + (List.map (questView player questsProgress expandedQuests) quests) + ] ] @@ -1538,17 +1716,8 @@ questView player questsProgress expandedQuests quest = Set_.member quest expandedQuests in H.li - [ HE.onClick - (if isExpanded then - CollapseQuestItem quest - - else - ExpandQuestItem quest - ) - , HA.classList - [ ( "quest", True ) - , ( "expanded", isExpanded ) - ] + [ HA.classList + [ ( "[&:not(:last-child)]:mb-5", isExpanded ) ] ] (if isExpanded then expandedQuestView player progress quest @@ -1560,7 +1729,16 @@ questView player questsProgress expandedQuests quest = collapsedQuestView : Quest.Name -> List (Html FrontendMsg) collapsedQuestView quest = - [ H.text <| Quest.title quest + [ H.span + [ HA.class "cursor-pointer" + , TW.mod "hover" "text-green-100" + , HE.onClick (ExpandQuestItem quest) + ] + [ H.span + [ HA.class "text-green-100 pr-2" ] + [ H.text "[+]" ] + , H.text <| Quest.title quest + ] ] @@ -1591,119 +1769,119 @@ expandedQuestView player progress quest = ticksNeeded = Quest.ticksNeeded quest in - [ H.div [ HA.class "quest-inner" ] + [ H.div [ HA.class "flex flex-col gap-[2ch]" ] [ H.div [] [ H.span - [ HA.class "quest-name" - , HE.onClick <| CollapseQuestItem quest + [ HE.onClick <| CollapseQuestItem quest + , HA.class "cursor-pointer" + , TW.mod "hover" "text-green-100" + ] + [ H.span + [ HA.class "text-green-100 pr-2" ] + [ H.text "[" + , H.span [ HA.class "min-w-[1ch] text-center inline-block" ] [ H.text "-" ] + , H.text "]" + ] + , H.text <| Quest.title quest ] - [ H.text <| Quest.title quest ] , if Set_.member quest player.questsActive then - H.button - [ HA.class "quest-toggle-btn" + UI.button + [ HA.class "ml-[1ch] !text-green-100" + , TW.mod "hover" "text-orange" , HE.onClickStopPropagation <| AskToStopProgressing quest ] [ H.text "[STOP]" ] else - H.button - [ HA.class "quest-toggle-btn" + UI.button + [ HA.class "ml-[1ch] !text-green-100" + , TW.mod "hover" "text-orange" , HE.onClickStopPropagation <| AskToStartProgressing quest ] [ H.text "[START]" ] ] - , questProgressbarView - { ticksGiven = progress.ticksGiven - , ticksNeeded = ticksNeeded - , ticksGivenByPlayer = progress.ticksGivenByPlayer - } - , H.div [ HA.class "quest-players" ] - [ H.span [] [ H.text "Players active: " ] - , H.span - [ HA.class "quest-number" ] - [ H.text <| String.fromInt progress.playersActive ] - , H.span [] [ H.text " (" ] - , H.span - [ HA.class "quest-number" ] - [ H.text <| String.fromInt progress.ticksPerHour ] - , H.span [] [ H.text " ticks/hour)" ] - ] - , H.div [ HA.class "quest-xp-per-tick" ] - [ H.text "XP per tick: " - , H.span - [ HA.class "quest-number" ] - [ H.text <| String.fromInt (Quest.xpPerTickGiven quest) ] - ] - , H.div - [ HA.class "quest-requirements-title" ] - [ H.text "Quest Requirements" ] - , if List.isEmpty questRequirements then - H.div - [ HA.class "quest-requirements-none" ] - [ H.text "NONE" ] + , H.div [ HA.class "bg-green-800 p-[2ch]" ] + [ questProgressbarView + { ticksGiven = progress.ticksGiven + , ticksNeeded = ticksNeeded + , ticksGivenByPlayer = progress.ticksGivenByPlayer + } + , H.div [] + [ H.text <| + "Players active: " + ++ String.fromInt progress.playersActive + ++ " (" + ++ String.fromInt progress.ticksPerHour + ++ " ticks/hour)" + ] + , H.div [] + [ H.text <| + "XP per tick: " + ++ String.fromInt (Quest.xpPerTickGiven quest) + ] + , H.div + [ HA.class "mt-5" ] + [ H.text "Quest Requirements" ] + , if List.isEmpty questRequirements then + H.div + [ HA.class "ml-[4ch]" ] + [ H.text "NONE" ] - else - H.ul - [ HA.class "quest-requirements-list" ] - (List.map (Quest.title >> liText) questRequirements) - , H.div - [ HA.class "quest-requirements-title" ] - [ H.text "Player Requirements" - , H.span - [ HA.class "deemphasized" ] - [ H.text " (affect ticks/hour)" ] - ] - , if List.isEmpty playerRequirements then - H.div - [ HA.class "quest-requirements-none" ] - [ H.text "NONE" ] + else + H.ul + [ HA.class "ps-[4ch]" ] + (List.map (Quest.title >> liText) questRequirements) + , H.div + [ HA.class "mt-5" ] + [ H.text "Player Requirements (affect ticks/hour)" ] + , if List.isEmpty playerRequirements then + H.div + [ HA.class "ml-[4ch]" ] + [ H.text "NONE" ] - else - H.ul - [ HA.class "quest-requirements-list" ] - (List.map (Quest.playerRequirementTitle >> liText) playerRequirements) - , H.div - [ HA.class "quest-requirements-title" ] - [ H.text "Global Rewards" ] - , if List.isEmpty globalRewards then - H.div - [ HA.class "quest-requirements-none" ] - [ H.text "NONE" ] + else + H.ul + [ HA.class "ps-[4ch]" ] + (List.map (Quest.playerRequirementTitle >> liText) playerRequirements) + , H.div + [ HA.class "mt-5" ] + [ H.text "Global Rewards" ] + , if List.isEmpty globalRewards then + H.div + [ HA.class "ml-[4ch]" ] + [ H.text "NONE" ] - else - H.ul - [ HA.class "quest-requirements-list" ] - (List.map (Quest.globalRewardTitle >> liText) globalRewards) - , H.div - [ HA.class "quest-requirements-title" ] - (if List.isEmpty playerRewards then - [ H.text "Player Rewards" ] + else + H.ul + [ HA.class "ps-[4ch]" ] + (List.map (Quest.globalRewardTitle >> liText) globalRewards) + , H.div + [ HA.class "mt-5" ] + (if List.isEmpty playerRewards then + [ H.text "Player Rewards" ] - else - [ H.text "Player Rewards" - , H.span - [ HA.class "deemphasized" ] - [ H.text " (if you give " ] - , H.span - [ HA.class "quest-number" ] - [ H.text <| - String.fromInt (Quest.ticksNeededForPlayerReward quest) - ++ "+" + else + [ H.text "Player Rewards" + , H.text " (if you give " + , H.span + [] + [ H.text <| + String.fromInt (Quest.ticksNeededForPlayerReward quest) + ++ "+" + ] + , H.text " ticks)" ] - , H.span - [ HA.class "deemphasized" ] - [ H.text " ticks)" ] - ] - ) - , if List.isEmpty playerRewards then - H.div - [ HA.class "quest-requirements-none" ] - [ H.text "NONE" ] + ) + , if List.isEmpty playerRewards then + H.div + [ HA.class "ml-[4ch]" ] + [ H.text "NONE" ] - else - H.ul - [ HA.class "quest-requirements-list" ] - (List.map (Quest.playerRewardTitle >> liText) playerRewards) + else + H.ul + [ HA.class "ps-[4ch]" ] + (List.map (Quest.playerRewardTitle >> liText) playerRewards) + ] ] ] @@ -1825,28 +2003,29 @@ townStoreView barter location world player = resetBtn : Html FrontendMsg resetBtn = - H.button - [ HA.id "town-store-reset-btn" + UI.button + [ HA.style "grid-area" "barter-reset-btn" , HE.onClick <| BarterMsg ResetBarter ] [ H.text "[Reset]" ] confirmBtn : Html FrontendMsg confirmBtn = - H.button - [ HA.id "town-store-confirm-btn" + UI.button + [ HA.style "grid-area" "barter-confirm-btn" , HE.onClick <| BarterMsg ConfirmBarter ] [ H.text "[Confirm]" ] capsView : - { class : String + { itemLabelClass : String + , gridArea : String , transfer : Int -> FrontendMsg , transferNPosition : Barter.TransferNPosition } -> Int -> Html FrontendMsg - capsView { class, transfer, transferNPosition } caps = + capsView { itemLabelClass, gridArea, transfer, transferNPosition } caps = let capsString : String capsString = @@ -1867,18 +2046,22 @@ townStoreView barter location world player = transferNView = H.div - [ HA.class "town-store-transfer-n-area" + [ HA.class "flex group" , HE.onMouseEnter <| BarterMsg <| SetTransferNHover transferNPosition , HE.onMouseLeave <| BarterMsg UnsetTransferNHover ] - [ H.button - [ HA.class "town-store-transfer-btn before-hover" + [ UI.button + [ HA.class "py-0.5 px-1 mx-1 bg-green-800 text-green-200 block" + , TW.mod "group-hover" "hidden" + , TW.mod "disabled" "text-green-300 opacity-50 pointer-events-none" + , TW.mod "[&:not(:disabled):hover]" "bg-green-300 text-green-100" , HA.disabled <| caps <= 0 , HA.title "Transfer N items" ] [ H.text "N" ] - , H.input - [ HA.class "town-store-transfer-n-input after-hover" + , UI.input + [ HA.class "w-10 bg-green-800 pl-[6px] hidden" + , TW.mod "group-hover" "block" , HA.value transferNValue , HE.onInput <| BarterMsg << SetTransferNInput transferNPosition , HA.title "Transfer N items" @@ -1886,54 +2069,62 @@ townStoreView barter location world player = [] , case String.toInt transferNValue of Nothing -> - H.button + UI.button [ HA.disabled True - , HA.class "town-store-transfer-btn after-hover" + , HA.class "py-0.5 px-1 mx-1 bg-green-800 text-green-200 hidden" + , TW.mod "disabled" "text-green-300 opacity-50 pointer-events-none" + , TW.mod "[&:not(:disabled):hover]" "bg-green-300 text-green-100" + , TW.mod "group-hover" "block" , HA.title "Transfer N items" ] [ H.text "OK" ] Just n -> - H.button + UI.button [ HE.onClick <| transfer n , HA.disabled <| n <= 0 || n > caps - , HA.class "town-store-transfer-btn after-hover" + , HA.class "py-0.5 px-1 mx-1 bg-green-800 text-green-200 hidden" + , TW.mod "disabled" "text-green-300 opacity-50 pointer-events-none" + , TW.mod "[&:not(:disabled):hover]" "bg-green-300 text-green-100" + , TW.mod "group-hover" "block" , HA.title "Transfer N items" ] [ H.text "OK" ] ] transferOneView = - H.button + UI.button [ HE.onClick <| transfer 1 , HA.disabled <| caps <= 0 - , HA.classList - [ ( "town-store-transfer-btn", True ) - , ( "hidden", isNHovered ) - ] + , HA.class "py-0.5 px-1 mx-1 bg-green-800 text-green-200" + , TW.mod "disabled" "text-green-300 opacity-50 pointer-events-none" + , TW.mod "[&:not(:disabled):hover]" "bg-green-300 text-green-100" + , HA.classList [ ( "hidden", isNHovered ) ] , HA.title "Transfer 1 item" ] [ H.text <| Barter.singleArrow arrowsDirection ] transferAllView = - H.button + UI.button [ HE.onClick <| transfer caps , HA.disabled <| caps <= 0 - , HA.classList - [ ( "town-store-transfer-btn", True ) - , ( "hidden", isNHovered ) - ] + , HA.class "py-0.5 px-1 mx-1 bg-green-800 text-green-200" + , TW.mod "disabled" "text-green-300 opacity-50 pointer-events-none" + , TW.mod "[&:not(:disabled):hover]" "bg-green-300 text-green-100" + , HA.classList [ ( "hidden", isNHovered ) ] , HA.title "Transfer all items" ] [ H.text <| Barter.doubleArrow arrowsDirection ] itemView = H.span - [ HA.class "town-store-item-label" ] + [ HA.class <| "flex-1 " ++ itemLabelClass ] [ H.text <| "Caps: $" ++ capsString ] in H.div - [ HA.class <| "town-store-item town-store-caps " ++ class + [ HA.class <| "flex items-center px-2 pt-1 pb-0.5" + , TW.mod "[&[data-caps='0']]" "text-green-300" + , HA.style "grid-area" gridArea , HA.attribute "data-caps" capsString ] <| @@ -1954,13 +2145,13 @@ townStoreView barter location world player = playerItemView : { items : Dict Item.Id Item - , class : String + , itemLabelClass : String , transfer : Item.Id -> Int -> FrontendMsg , transferNPosition : Item.Id -> Barter.TransferNPosition } -> ( Item.Id, Int ) -> Html FrontendMsg - playerItemView { items, class, transfer, transferNPosition } ( id, count ) = + playerItemView { items, itemLabelClass, transfer, transferNPosition } ( id, count ) = let itemName = case Dict.get id items of @@ -1989,18 +2180,22 @@ townStoreView barter location world player = transferNView = H.div - [ HA.class "town-store-transfer-n-area" + [ HA.class "flex group" , HE.onMouseEnter <| BarterMsg <| SetTransferNHover position , HE.onMouseLeave <| BarterMsg UnsetTransferNHover ] - [ H.button - [ HA.class "town-store-transfer-btn before-hover" + [ UI.button + [ HA.class "py-0.5 px-1 mx-1 bg-green-800 text-green-200 block" + , TW.mod "disabled" "text-green-300 opacity-50 pointer-events-none" + , TW.mod "[&:not(:disabled):hover]" "bg-green-300 text-green-100" + , TW.mod "group-hover" "hidden" , HA.disabled <| count <= 0 , HA.title "Transfer N items" ] [ H.text "N" ] - , H.input - [ HA.class "town-store-transfer-n-input after-hover" + , UI.input + [ HA.class "w-10 bg-green-800 pl-[6px] hidden" + , TW.mod "group-hover" "block" , HA.value transferNValue , HE.onInput <| BarterMsg << SetTransferNInput position , HA.title "Transfer N items" @@ -2008,53 +2203,59 @@ townStoreView barter location world player = [] , case String.toInt transferNValue of Nothing -> - H.button + UI.button [ HA.disabled True - , HA.class "town-store-transfer-btn after-hover" + , HA.class "py-0.5 px-1 mx-1 bg-green-800 text-green-200 hidden" + , TW.mod "disabled" "text-green-300 opacity-50 pointer-events-none" + , TW.mod "[&:not(:disabled):hover]" "bg-green-300 text-green-100" + , TW.mod "group-hover" "block" , HA.title "Transfer N items" ] [ H.text "OK" ] Just n -> - H.button + UI.button [ HE.onClick <| transfer id n , HA.disabled <| n <= 0 || n > count - , HA.class "town-store-transfer-btn after-hover" + , HA.class "py-0.5 px-1 mx-1 bg-green-800 text-green-200 hidden" + , TW.mod "disabled" "text-green-300 opacity-50 pointer-events-none" + , TW.mod "[&:not(:disabled):hover]" "bg-green-300 text-green-100" + , TW.mod "group-hover" "block" , HA.title "Transfer N items" ] [ H.text "OK" ] ] transferOneView = - H.button + UI.button [ HE.onClick <| transfer id 1 , HA.disabled <| count <= 0 - , HA.classList - [ ( "town-store-transfer-btn", True ) - , ( "hidden", isNHovered ) - ] + , HA.class "py-0.5 px-1 mx-1 bg-green-800 text-green-200" + , TW.mod "disabled" "text-green-300 opacity-50 pointer-events-none" + , TW.mod "[&:not(:disabled):hover]" "bg-green-300 text-green-100" + , HA.classList [ ( "hidden", isNHovered ) ] , HA.title "Transfer 1 item" ] [ H.text <| Barter.singleArrow arrowsDirection ] transferAllView = - H.button + UI.button [ HE.onClick <| transfer id count , HA.disabled <| count <= 0 - , HA.classList - [ ( "town-store-transfer-btn", True ) - , ( "hidden", isNHovered ) - ] + , HA.class "py-0.5 px-1 mx-1 bg-green-800 text-green-200" + , TW.mod "disabled" "text-green-300 opacity-50 pointer-events-none" + , TW.mod "[&:not(:disabled):hover]" "bg-green-300 text-green-100" + , HA.classList [ ( "hidden", isNHovered ) ] , HA.title "Transfer all items" ] [ H.text <| Barter.doubleArrow arrowsDirection ] itemView = H.span - [ HA.class "town-store-item-label" ] + [ HA.class <| "flex-1 " ++ itemLabelClass ] [ H.text <| String.fromInt count ++ "x " ++ itemName ] in - H.div [ HA.class <| "town-store-item " ++ class ] <| + H.div [ HA.class "flex items-center px-2 py-0.5" ] <| case arrowsDirection of Barter.ArrowLeft -> [ transferAllView @@ -2073,34 +2274,42 @@ townStoreView barter location world player = playerNameView : Html FrontendMsg playerNameView = H.div - [ HA.id "town-store-player-name" ] + [ HA.class "p-2 border-b-2 border-b-green-800" + , HA.style "grid-area" "player-name" + ] [ H.text <| "Player: " ++ player.name ] vendorNameView : Html FrontendMsg vendorNameView = H.div - [ HA.id "town-store-vendor-name" ] + [ HA.class "p-2 border-b-2 border-b-green-800 text-right" + , HA.style "grid-area" "vendor-name" + ] [ H.text <| "Vendor: " ++ Vendor.nameWithLocation vendor.name ] playerTradedValueView : Html FrontendMsg playerTradedValueView = H.div - [ HA.id "town-store-player-traded-value" ] + [ HA.class "text-green-100 text-center p-2" + , HA.style "grid-area" "player-traded-value" + ] [ H.text <| "Value: $" ++ String.fromInt playerTradedValue ] vendorTradedValueView : Html FrontendMsg vendorTradedValueView = H.div - [ HA.id "town-store-vendor-traded-value" ] + [ HA.class "text-green-100 text-center p-2" + , HA.style "grid-area" "vendor-traded-value" + ] [ H.text <| "Value: $" ++ String.fromInt vendorTradedValue ] playerKeptItemsView : Html FrontendMsg playerKeptItemsView = - H.div [ HA.id "town-store-player-kept-items" ] + H.div [ HA.style "grid-area" "player-kept-items" ] (List.map (playerItemView { items = player.items - , class = "player-kept-item" + , itemLabelClass = "" , transfer = \id count -> BarterMsg <| AddPlayerItem id count , transferNPosition = Barter.PlayerKeptItem } @@ -2110,11 +2319,11 @@ townStoreView barter location world player = playerTradedItemsView : Html FrontendMsg playerTradedItemsView = - H.div [ HA.id "town-store-player-traded-items" ] + H.div [ HA.style "grid-area" "player-traded-items" ] (List.map (playerItemView { items = player.items - , class = "player-traded-item" + , itemLabelClass = "ml-1" , transfer = \id count -> BarterMsg <| RemovePlayerItem id count , transferNPosition = Barter.PlayerTradedItem } @@ -2124,11 +2333,11 @@ townStoreView barter location world player = vendorKeptItemsView : Html FrontendMsg vendorKeptItemsView = - H.div [ HA.id "town-store-vendor-kept-items" ] + H.div [ HA.style "grid-area" "vendor-kept-items" ] (List.map (playerItemView { items = vendor.items - , class = "vendor-kept-item" + , itemLabelClass = "ml-1" , transfer = \id count -> BarterMsg <| AddVendorItem id count , transferNPosition = Barter.VendorKeptItem } @@ -2138,11 +2347,11 @@ townStoreView barter location world player = vendorTradedItemsView : Html FrontendMsg vendorTradedItemsView = - H.div [ HA.id "town-store-vendor-traded-items" ] + H.div [ HA.style "grid-area" "vendor-traded-items" ] (List.map (playerItemView { items = vendor.items - , class = "vendor-traded-item" + , itemLabelClass = "" , transfer = \id count -> BarterMsg <| RemoveVendorItem id count , transferNPosition = Barter.VendorTradedItem } @@ -2153,7 +2362,8 @@ townStoreView barter location world player = playerKeptCapsView : Html FrontendMsg playerKeptCapsView = capsView - { class = "player-kept-caps" + { itemLabelClass = "" + , gridArea = "player-kept-caps" , transfer = BarterMsg << AddPlayerCaps , transferNPosition = Barter.PlayerKeptCaps } @@ -2162,7 +2372,8 @@ townStoreView barter location world player = playerTradedCapsView : Html FrontendMsg playerTradedCapsView = capsView - { class = "player-traded-caps" + { itemLabelClass = "ml-1" + , gridArea = "player-traded-caps" , transfer = BarterMsg << RemovePlayerCaps , transferNPosition = Barter.PlayerTradedCaps } @@ -2171,7 +2382,8 @@ townStoreView barter location world player = vendorKeptCapsView : Html FrontendMsg vendorKeptCapsView = capsView - { class = "vendor-kept-caps" + { itemLabelClass = "ml-1" + , gridArea = "vendor-kept-caps" , transfer = BarterMsg << AddVendorCaps , transferNPosition = Barter.VendorKeptCaps } @@ -2180,7 +2392,8 @@ townStoreView barter location world player = vendorTradedCapsView : Html FrontendMsg vendorTradedCapsView = capsView - { class = "vendor-traded-caps" + { itemLabelClass = "" + , gridArea = "vendor-traded-caps" , transfer = BarterMsg << RemoveVendorCaps , transferNPosition = Barter.VendorTradedCaps } @@ -2188,11 +2401,19 @@ townStoreView barter location world player = playerTradedBg : Html FrontendMsg playerTradedBg = - H.div [ HA.id "town-store-player-traded-bg" ] [] + H.div + [ HA.style "grid-area" "2 / 2 / 5 / 3" + , HA.class "bg-green-800-half-transparent border-r border-r-green-800" + ] + [] vendorTradedBg : Html FrontendMsg vendorTradedBg = - H.div [ HA.id "town-store-vendor-traded-bg" ] [] + H.div + [ HA.style "grid-area" "2 / 3 / 5 / 4" + , HA.class "bg-green-800-half-transparent border-l border-l-green-800" + ] + [] gridContents : List (Html FrontendMsg) gridContents = @@ -2215,14 +2436,18 @@ townStoreView barter location world player = ] in [ pageTitleView <| "Store: " ++ Location.name location - , H.button + , UI.button [ HE.onClick (GoToRoute (PlayerRoute Route.TownMainSquare)) ] [ H.text "[Back]" ] - , H.div [ HA.id "town-store-grid" ] gridContents + , H.div + [ HA.class "mt-10 self-stretch grid grid-cols-[repeat(4,1fr)]" + , HA.class "town-store-grid" + ] + gridContents , H.viewMaybe (\message -> H.div - [ HA.id "town-store-barter-message" ] + [ HA.class "mt-10 text-orange" ] [ H.text <| Barter.messageText message ] ) barter.lastMessage @@ -2233,36 +2458,33 @@ newCharView : Maybe HoveredItem -> NewChar -> List (Html FrontendMsg) newCharView hoveredItem newChar = let createBtnView = - H.div [ HA.id "new-character-create-btn" ] - [ H.button + H.div [ HA.class "mt-10" ] + [ UI.button [ HE.onClick CreateChar ] - [ H.text "[Create]" ] + [ H.text "[ Create ]" ] ] errorView = H.viewMaybe (\error -> - H.div [ HA.id "new-character-error" ] + H.div [ HA.class "text-orange mt-5" ] [ H.text <| NewChar.error error ] ) newChar.error in [ pageTitleView "New Character" , H.div - [ HA.id "new-character-grid" ] - [ H.div - [ HA.class "new-character-column" ] + [ HA.class "grid grid-cols-[42ch_42ch_minmax(0,1fr)] gap-5" ] + [ H.div [ HA.class "flex flex-col gap-8" ] [ newCharSpecialView newChar , newCharTraitsView newChar.traits , createBtnView , errorView ] - , H.div - [ HA.class "new-character-column" ] + , H.div [ HA.class "flex flex-col gap-8" ] [ newCharSkillsView newChar ] - , H.div - [ HA.class "new-character-column" ] + , H.div [ HA.class "flex flex-col gap-8" ] [ newCharDerivedStatsView newChar , newCharHelpView hoveredItem ] @@ -2277,24 +2499,27 @@ newCharHelpView maybeHoveredItem = helpContent = case maybeHoveredItem of Nothing -> - H.p [] [ H.text "Hover over an item to show more information about it here!" ] + H.p + [ HA.class "max-w-[50ch] text-green-300" ] + [ H.text "Hover over an item to show more information about it here!" ] Just hoveredItem -> let { title, description } = HoveredItem.text hoveredItem in - H.div [] + H.div [ HA.class "max-w-[50ch]" ] [ H.h4 - [ HA.class "hovered-item-title" ] + [ HA.class "text-orange" ] [ H.text title ] - , Markdown.toHtml [] description + , -- TODO formatting of lists etc. + Markdown.toHtml [] description ] in H.div - [ HA.id "new-character-help" ] + [ HA.class "flex flex-col gap-4" ] [ H.h3 - [ HA.class "new-character-section-title" ] + [ HA.class "text-green-300" ] [ H.text "Help" ] , helpContent ] @@ -2311,22 +2536,28 @@ newCharDerivedStatsView newChar = , hasSmallFrameTrait = Trait.isSelected Trait.SmallFrame newChar.traits } - itemView : ( String, String, Maybe String ) -> Html FrontendMsg - itemView ( label, value, tooltip ) = + itemView : ( String, String, Maybe HoveredItem ) -> Html FrontendMsg + itemView ( label, value, hoveredItem ) = let - ( liAttrs, valueAttrs ) = - case tooltip of - Just tooltip_ -> - ( [ HA.title tooltip_ ] - , [ HA.class "has-tooltip" ] - ) + liAttrs = + case hoveredItem of + Just hoveredItem_ -> + [ HE.onMouseOver <| HoverItem hoveredItem_ + , HE.onMouseOut StopHoveringItem + ] Nothing -> - ( [], [] ) + [] in - H.li liAttrs - [ H.text <| label ++ ": " - , H.span valueAttrs [ H.text value ] + H.li + (TW.mod "hover" "bg-green-800" + :: liAttrs + ) + [ UI.liBullet + , H.text <| label ++ ": " + , H.span + [ HA.class "text-green-100" ] + [ H.text value ] ] perceptionLevel : PerceptionLevel @@ -2336,12 +2567,11 @@ newCharDerivedStatsView newChar = , hasAwarenessPerk = False } in - H.div - [ HA.id "new-character-derived-stats" ] + H.div [ HA.class "flex flex-col gap-4" ] [ H.h3 - [ HA.class "new-character-section-title" ] + [ HA.class "text-green-300" ] [ H.text "Derived stats" ] - , H.ul [ HA.id "new-character-derived-stats-list" ] <| + , H.ul [] <| List.map itemView [ ( "Hitpoints" , String.fromInt <| @@ -2364,7 +2594,7 @@ newCharDerivedStatsView newChar = ) , ( "Perception Level" , Perception.label perceptionLevel - , Just <| Perception.tooltip perceptionLevel + , Just <| HoveredPerceptionLevel perceptionLevel ) , ( "Action Points" , String.fromInt <| @@ -2395,36 +2625,40 @@ newCharSpecialView newChar = value = Special.get type_ finalSpecial in - H.tr - [ HA.class "character-special-attribute" - , HE.onMouseOver <| HoverItem <| HoveredSpecial type_ + H.div + [ HE.onMouseOver <| HoverItem <| HoveredSpecial type_ , HE.onMouseOut StopHoveringItem + , HA.class "contents group" ] - [ H.td - [ HA.class "character-special-attribute-dec" ] - [ H.button + [ H.div [] + [ UI.button [ HE.onClick <| NewCharDecSpecial type_ , HA.disabled <| not <| Special.canDecrement type_ finalSpecial + , HA.class "!text-green-100" + , TW.mod "disabled" "!text-green-300 cursor-not-allowed" + , TW.mod "[&:not(:disabled):hover]" "!text-orange" + , TW.mod "group-hover" "bg-green-800" ] [ H.text "[-]" ] ] - , H.td - [ HA.class "character-special-attribute-label" ] + , H.div + [ HA.class "px-[1ch]" + , TW.mod "group-hover" "text-green-100 bg-green-800" + ] [ H.text <| Special.label type_ ] - , H.td - [ HA.classList - [ ( "character-special-attribute-value", True ) - , ( "out-of-range", not <| Special.isValueInRange value ) - ] + , H.div + [ HA.class "pr-[1ch] text-right" + , HA.classList [ ( "!text-orange", not <| Special.isValueInRange value ) ] + , TW.mod "group-hover" "text-green-100 bg-green-800" ] [ H.text <| String.fromInt value ] - , H.td - [ HA.class "character-special-attribute-inc" ] - [ H.button + , H.div + [] + [ UI.button [ HE.onClick <| NewCharIncSpecial type_ , HA.disabled <| not <| @@ -2432,25 +2666,30 @@ newCharSpecialView newChar = newChar.availableSpecial type_ finalSpecial + , HA.class "!text-green-100" + , TW.mod "disabled" "!text-green-300 cursor-not-allowed" + , TW.mod "[&:not(:disabled):hover]" "!text-orange" + , TW.mod "group-hover" "bg-green-800" ] [ H.text "[+]" ] ] ] in H.div - [ HA.id "new-character-special" ] + [ HA.class "flex flex-col gap-4" ] [ H.h3 - [ HA.class "new-character-section-title" ] + [ HA.class "text-green-300" ] [ H.text "SPECIAL (" , H.span - [ HA.class "new-character-section-available-number" ] + [ HA.class "text-orange" ] [ H.text <| String.fromInt newChar.availableSpecial ] , H.text " points left)" ] - , H.table - [ HA.id "character-special-table" ] + , H.div [ HA.class "grid grid-cols-[3ch_13ch_3ch_3ch] auto-rows-auto" ] (List.map specialItemView Special.all) - , H.p [] [ H.text "Distribute your SPECIAL points (each attribute can be in range 1..10)." ] + , H.p + [ HA.class "text-green-300" ] + [ H.text "Distribute your SPECIAL points (each attribute can be in range 1..10)." ] ] @@ -2467,46 +2706,41 @@ newCharTraitsView traits = isToggled : Bool isToggled = Set_.member trait traits - - buttonLabel : String - buttonLabel = - if isToggled then - "[*]" - - else - "[ ]" in H.li - [ HA.classList - [ ( "new-character-traits-trait", True ) - , ( "is-toggled", isToggled ) - ] + [ HA.class "flex flex-row gap-[1ch] pr-[2ch] justify-start cursor-pointer group" + , TW.mod "hover" "text-orange bg-green-800" + , HA.classList [ ( "text-orange", isToggled ) ] , HE.onClick <| NewCharToggleTrait trait , HE.onMouseOver <| HoverItem <| HoveredTrait trait , HE.onMouseOut StopHoveringItem ] - [ H.button + [ UI.button [ HE.onClickStopPropagation <| NewCharToggleTrait trait - , HA.class "new-character-trait-tag-btn" + , HA.class "!text-green-100" + , HA.classList [ ( "!text-orange", isToggled ) ] + , TW.mod "group-hover" "!text-orange bg-green-800" ] - [ H.text buttonLabel ] + [ H.text <| UI.checkboxLabel isToggled ] , H.div [] [ H.text <| Trait.name trait ] ] in H.div - [ HA.id "new-character-traits" ] + [ HA.class "flex flex-col gap-4" ] [ H.h3 - [ HA.class "new-character-section-title" ] + [ HA.class "text-green-300" ] [ H.text "Traits (" , H.span - [ HA.class "new-character-section-available-number" ] + [ HA.class "text-orange" ] [ H.text <| String.fromInt availableTraits ] , H.text " available)" ] , H.ul - [ HA.id "new-character-traits-list" ] + [ HA.class "w-max grid grid-cols-2 gap-x-[2ch]" ] (List.map traitView Trait.all) - , H.p [] [ H.text "Select up to two traits." ] + , H.p + [ HA.class "text-green-300" ] + [ H.text "Select up to two traits." ] ] @@ -2533,7 +2767,6 @@ newCharSkillsView newChar = , hasTagPerk = False , availableSkillPoints = 0 , isNewChar = True - , id = "new-character-skills" } @@ -2568,21 +2801,24 @@ choosePerkView maybeHoveredItem applicablePerks = perkView perk = H.li [ HE.onClick <| AskToChoosePerk perk - , HA.class "character-choose-perk-item" + , HA.class "cursor-pointer group" , HE.onMouseOver <| HoverItem <| HoveredPerk perk , HE.onMouseOut StopHoveringItem ] - [ H.text <| Perk.name perk ] + [ UI.liBullet + , H.span + [ TW.mod "group-hover" "text-orange" + ] + [ H.text <| Perk.name perk ] + ] in H.div - [ HA.id "character-choose-perk" ] + [ HA.class "flex-1 flex flex-col self-stretch" ] [ H.div - [ HA.id "character-choose-perk-columns" ] - [ H.div [] + [ HA.class "flex-1 grid grid-cols-[minmax(0,max-content)_minmax(0,60ch)] gap-8" ] + [ H.div [ HA.class "flex flex-col gap-4" ] [ H.h3 [] [ H.text "Choose a perk!" ] - , H.ul - [ HA.id "character-choose-perk-list" ] - (List.map perkView applicablePerks) + , H.ul [] (List.map perkView applicablePerks) ] , H.viewMaybe perkDescriptionView maybeHoveredItem ] @@ -2605,19 +2841,16 @@ perkDescriptionView hoveredItem = normalCharacterView : Maybe HoveredItem -> CPlayer -> Html FrontendMsg normalCharacterView maybeHoveredItem player = H.div - [ HA.id "character-grid" ] - [ H.div - [ HA.class "character-column" ] + [ HA.class "grid grid-cols-[24ch_34ch_minmax(0,1fr)] gap-5" ] + [ H.div [ HA.class "flex flex-col gap-8" ] [ charSpecialView player , charTraitsView player.traits , charPerksView player.perks ] - , H.div - [ HA.class "character-column" ] + , H.div [ HA.class "flex flex-col gap-8" ] [ charSkillsView player ] - , H.div - [ HA.class "character-column" ] + , H.div [ HA.class "flex flex-col gap-8" ] [ charDerivedStatsView player , charHelpView maybeHoveredItem ] @@ -2630,23 +2863,27 @@ charTraitsView traits = itemView : Trait -> Html FrontendMsg itemView trait = H.li - [ HA.class "character-traits-trait" + [ HA.class "pr-[2ch]" + , TW.mod "hover" "text-green-100 bg-green-800" , HE.onMouseOver <| HoverItem <| HoveredTrait trait , HE.onMouseOut StopHoveringItem ] - [ H.text <| Trait.name trait ] + [ UI.liBullet + , H.text <| Trait.name trait + ] in H.div - [ HA.id "character-traits" ] + [ HA.class "flex flex-col" ] [ H.h3 - [ HA.class "character-section-title" ] + [ HA.class "text-green-300" ] [ H.text "Traits" ] , if Set_.isEmpty traits then - H.p [] [ H.text "You have no traits." ] + H.p + [ HA.class "text-green-300" ] + [ H.text "You have no traits." ] else - H.ul - [ HA.id "character-traits-list" ] + H.ul [ HA.class "w-fit" ] (List.map itemView <| Set_.toList traits) ] @@ -2658,24 +2895,26 @@ charHelpView maybeHoveredItem = helpContent = case maybeHoveredItem of Nothing -> - H.p [] [ H.text "Hover over an item to show more information about it here!" ] + H.p + [ HA.class "max-w-[50ch] text-green-300" ] + [ H.text "Hover over an item to show more information about it here!" ] Just hoveredItem -> let { title, description } = HoveredItem.text hoveredItem in - H.div [] + H.div [ HA.class "max-w-[50ch]" ] [ H.h4 - [ HA.class "hovered-item-title" ] + [ HA.class "text-orange" ] [ H.text title ] , Markdown.toHtml [] description ] in H.div - [ HA.id "character-help" ] + [ HA.class "flex flex-col gap-4" ] [ H.h3 - [ HA.class "character-section-title" ] + [ HA.class "text-green-300" ] [ H.text "Help" ] , helpContent ] @@ -2684,22 +2923,28 @@ charHelpView maybeHoveredItem = charDerivedStatsView : CPlayer -> Html FrontendMsg charDerivedStatsView player = let - itemView : ( String, String, Maybe String ) -> Html FrontendMsg - itemView ( label, value, tooltip ) = + itemView : ( String, String, Maybe HoveredItem ) -> Html FrontendMsg + itemView ( label, value, hoveredItem ) = let - ( liAttrs, valueAttrs ) = - case tooltip of - Just tooltip_ -> - ( [ HA.title tooltip_ ] - , [ HA.class "has-tooltip" ] - ) + liAttrs = + case hoveredItem of + Just hoveredItem_ -> + [ HE.onMouseOver <| HoverItem hoveredItem_ + , HE.onMouseOut StopHoveringItem + ] Nothing -> - ( [], [] ) + [] in - H.li liAttrs - [ H.text <| label ++ ": " - , H.span valueAttrs [ H.text value ] + H.li + (TW.mod "hover" "bg-green-800" + :: liAttrs + ) + [ UI.liBullet + , H.text <| label ++ ": " + , H.span + [ HA.class "text-green-100" ] + [ H.text value ] ] perceptionLevel : PerceptionLevel @@ -2709,12 +2954,11 @@ charDerivedStatsView player = , hasAwarenessPerk = Perk.rank Perk.Awareness player.perks > 0 } in - H.div - [ HA.id "character-derived-stats" ] + H.div [ HA.class "flex flex-col gap-4" ] [ H.h3 - [ HA.class "character-section-title" ] + [ HA.class "text-green-300" ] [ H.text "Derived stats" ] - , H.ul [ HA.id "character-derived-stats-list" ] <| + , H.ul [] <| List.map itemView [ ( "Max HP" , String.fromInt <| @@ -2744,7 +2988,7 @@ charDerivedStatsView player = ) , ( "Perception Level" , Perception.label perceptionLevel - , Just <| Perception.tooltip perceptionLevel + , Just <| HoveredPerceptionLevel perceptionLevel ) , ( "Action Points" , String.fromInt <| @@ -2767,29 +3011,30 @@ charSpecialView player = value = Special.get type_ player.special in - H.tr - [ HA.class "character-special-attribute" - , HE.onMouseOver <| HoverItem <| HoveredSpecial type_ + H.div + [ HE.onMouseOver <| HoverItem <| HoveredSpecial type_ , HE.onMouseOut StopHoveringItem + , HA.class "contents group" ] - [ H.td - [ HA.class "character-special-attribute-label" ] + [ H.div + [ HA.class "px-[1ch]" + , TW.mod "group-hover" "text-green-100 bg-green-800" + ] [ H.text <| Special.label type_ ] - , H.td - [ HA.class "character-special-attribute-value" - + , H.div -- TODO highlighted if addiction etc? + [ HA.class "text-right pr-[1ch]" + , TW.mod "group-hover" "text-green-100 bg-green-800" ] [ H.text <| String.fromInt value ] ] in H.div - [ HA.id "character-special" ] + [ HA.class "flex flex-col gap-4" ] [ H.h3 - [ HA.class "character-section-title" ] + [ HA.class "text-green-300" ] [ H.text "SPECIAL" ] - , H.table - [ HA.id "character-special-table" ] + , H.div [ HA.class "grid grid-cols-[13ch_3ch]" ] (List.map specialItemView Special.all) ] @@ -2801,7 +3046,6 @@ skillsView_ : , hasTagPerk : Bool , availableSkillPoints : Int , isNewChar : Bool - , id : String } -> Html FrontendMsg skillsView_ r = @@ -2837,95 +3081,114 @@ skillsView_ r = isTagged = Set_.member skill r.taggedSkills - ( showTagButton, isTaggingDisabled, tagButtonLabel ) = + ( showTagButton, isTaggingDisabled ) = case ( r.isNewChar, isTagged ) of ( True, True ) -> - ( True, False, "[*]" ) + ( True, False ) ( True, False ) -> - ( True, availableTags == 0, "[ ]" ) + ( True, availableTags == 0 ) ( False, True ) -> - ( availableTags > 0, True, "[*]" ) + ( availableTags > 0, True ) ( False, False ) -> - ( availableTags > 0, availableTags == 0, "[ ]" ) + ( availableTags > 0, availableTags == 0 ) isIncButtonDisabled : Bool isIncButtonDisabled = r.availableSkillPoints <= 0 + + isTaggable : Bool + isTaggable = + showTagButton && not isTaggingDisabled + + hoverTextColor : String + hoverTextColor = + if r.isNewChar then + "text-orange" + + else + "text-green-100" in - H.li - [ HA.classList - [ ( "character-skills-skill", True ) - , ( "not-useful", notUseful ) - , ( "is-tagged", isTagged ) - , ( "is-taggable", showTagButton && not isTaggingDisabled ) + H.div + [ HA.class "contents group" + , TW.mod "hover" hoverTextColor + , HA.classList + [ ( "text-green-300", notUseful ) + , ( "text-orange", isTagged ) + , ( "cursor-pointer", isTaggable ) ] , HA.attributeIf (not isTaggingDisabled) <| HE.onClick <| onTag skill , HE.onMouseOver <| HoverItem <| HoveredSkill skill , HE.onMouseOut StopHoveringItem ] - [ H.div - [ HA.class "character-skill-name" ] - [ H.viewIf showTagButton <| - H.button - [ HE.onClickStopPropagation <| onTag skill - , HA.disabled isTaggingDisabled - , HA.class "character-skill-tag-btn" + [ H.viewIf showTagButton <| + UI.button + [ HE.onClickStopPropagation <| onTag skill + , HA.disabled isTaggingDisabled + , HA.class "!text-green-100 px-[1ch]" + , HA.classList + [ ( "!text-orange", isTagged ) + , ( "!text-green-300", notUseful ) ] - [ H.text tagButtonLabel ] - , H.text <| Skill.name skill + , TW.mod "group-hover" "!text-orange bg-green-800" + ] + [ H.text <| UI.checkboxLabel isTagged ] + , H.div + [ HA.class "pr-[1ch]" + , HA.classList [ ( "pl-[1ch]", not showTagButton ) ] + , TW.mod "group-hover" "bg-green-800" ] + [ H.text <| Skill.name skill ] , H.div - [ HA.class "character-skill-value" ] - [ H.div - [ HA.class "character-skill-percent" ] - [ H.text <| String.fromInt percent ++ "%" ] - , H.viewIf (not r.isNewChar) <| - H.button - [ HE.onClickStopPropagation <| AskToUseSkillPoints skill - , HA.class "character-skill-inc-btn" - , HA.disabled isIncButtonDisabled - , HA.attributeIf isIncButtonDisabled <| - HA.title "You have no skill points available." - ] - [ H.text "[+]" ] + [ HA.class "text-right" + , TW.mod "group-hover" "bg-green-800" ] + [ H.text <| String.fromInt percent ++ "%" ] + , H.viewIf (not r.isNewChar) <| + UI.button + [ HE.onClickStopPropagation <| AskToUseSkillPoints skill + , HA.disabled isIncButtonDisabled + , HA.attributeIf isIncButtonDisabled <| + HA.title "You have no skill points available." + , HA.class "pl-[1ch]" + , TW.mod "[&:not(:disabled):hover]" "!text-green-100 cursor-pointer" + , TW.mod "disabled" "cursor-not-allowed opacity-50" + , TW.mod "group-hover" "bg-green-800" + ] + [ H.text "[+]" ] ] in if r.isNewChar then H.div - [ HA.id r.id ] + [ HA.class "flex flex-col gap-4" ] [ H.h3 - [ HA.class "new-character-section-title" ] + [ HA.class "text-green-300" ] [ H.text "Skills (" , H.span - [ HA.class "new-character-section-available-number" ] + [ HA.class "text-orange" ] [ H.text <| String.fromInt availableTags ] , H.text " tags left)" ] - , H.ul - [ HA.id "character-skills-list" ] + , H.div [ HA.class "grid grid-cols-[5ch_16ch_minmax(auto,5ch)]" ] (List.map skillView Skill.all) - , H.p [] [ H.text "Tag three skills. Dimmed skills are not yet useful in the game." ] + , H.p + [ HA.class "text-green-300" ] + [ H.text "Tag three skills. Dimmed skills are not yet useful in the game." ] ] else - H.div - [ HA.id r.id - , HA.classList [ ( "cannot-inc", r.availableSkillPoints <= 0 ) ] - ] + H.div [ HA.class "flex flex-col gap-4" ] [ H.h3 - [ HA.class "character-section-title" ] + [ HA.class "text-green-300" ] [ H.text "Skills (" , H.span - [ HA.class "character-section-available-number" ] + [ HA.class "text-orange" ] [ H.text <| String.fromInt r.availableSkillPoints ] , H.text " points available)" ] - , H.ul - [ HA.id "character-skills-list" ] + , H.div [ HA.class "grid grid-cols-[16ch_minmax(auto,5ch)_4ch]" ] (List.map skillView Skill.all) , H.viewIf (availableTags > 0) <| H.p [] [ H.text <| "Tags available: " ++ String.fromInt availableTags ] @@ -2941,7 +3204,6 @@ charSkillsView player = , hasTagPerk = Perk.rank Perk.Tag player.perks > 0 , availableSkillPoints = player.availableSkillPoints , isNewChar = False - , id = "character-skills" } @@ -2956,11 +3218,13 @@ charPerksView perks = Perk.maxRank perk in H.li - [ HA.class "character-perks-perk" - , HE.onMouseOver <| HoverItem <| HoveredPerk perk + [ HE.onMouseOver <| HoverItem <| HoveredPerk perk , HE.onMouseOut StopHoveringItem + , HA.class "pr-[2ch]" + , TW.mod "hover" "text-green-100 bg-green-800" ] - [ H.text <| + [ UI.liBullet + , H.text <| if maxRank == 1 then Perk.name perk @@ -2968,17 +3232,15 @@ charPerksView perks = Perk.name perk ++ " (" ++ String.fromInt rank ++ "x)" ] in - H.div - [ HA.id "character-perks" ] + H.div [] [ H.h3 - [ HA.class "character-section-title" ] + [ HA.class "text-green-300" ] [ H.text "Perks" ] , if Dict_.isEmpty perks then H.p [] [ H.text "No perks yet!" ] else - H.ul - [ HA.id "character-perks-list" ] + H.ul [] (List.map itemView <| Dict_.toList perks) ] @@ -3024,21 +3286,20 @@ inventoryView _ player = ( True, Just "You're at full HP." ) in H.li - [ HA.class "inventory-item" - , HA.attributeMaybe HA.title tooltip - ] - [ H.button - [ HA.class "inventory-item-use-btn" - , HE.onClick <| AskToUseItem item.id - , HA.disabled isDisabled - ] - [ H.text "[Use]" ] - , H.viewIf (Item.isEquippable item.kind) <| - H.button - [ HA.class "inventory-item-equip-btn" - , HE.onClick <| AskToEquipItem item.id + [ HA.class "flex flex-row gap-[1ch]" ] + [ UI.liBullet + , H.span + [ HA.class "flex flex-row gap-[2ch]" ] + [ UI.button + [ HE.onClick <| AskToUseItem item.id + , HA.disabled isDisabled ] - [ H.text "[Equip]" ] + [ H.text "[Use]" ] + , H.viewIf (Item.isEquippable item.kind) <| + UI.button + [ HE.onClick <| AskToEquipItem item.id ] + [ H.text "[Equip]" ] + ] , H.span [ HA.class "inventory-item-label" ] [ H.text <| String.fromInt item.count ++ "x " ++ Item.name item.kind ] @@ -3098,61 +3359,102 @@ inventoryView _ player = } in [ pageTitleView "Inventory" - , H.p [] [ H.text <| "Total value: $" ++ String.fromInt totalValue ] - , if Dict.isEmpty player.items then - H.p [] [ H.text "You have no items!" ] + , H.div [ HA.class "flex flex-col gap-4" ] + [ H.p [] + [ H.text <| "Total value: " + , H.span [ HA.class "text-green-100" ] [ H.text <| "$" ++ String.fromInt totalValue ] + ] + , H.h3 + [ HA.class "text-green-300" ] + [ H.text "Items" ] + , if Dict.isEmpty player.items then + H.p [] [ H.text "You have no items!" ] - else - H.ul - [ HA.id "inventory-list" ] - (player.items - |> Dict.values - |> List.sortBy - (\{ kind } -> - ( Item.typeName (Item.type_ kind) - , Item.baseValue kind - , Item.name kind + else + H.ul [] + (player.items + |> Dict.values + |> List.sortBy + (\{ kind } -> + ( Item.typeName (Item.type_ kind) + , Item.baseValue kind + , Item.name kind + ) ) - ) - |> List.map itemView - ) - , H.h3 - [ HA.id "inventory-equipment" ] - [ H.text "Equipment" ] - , H.div - [ HA.id "inventory-equipment-armor" ] - [ H.text "Armor: " - , case player.equippedArmor of - Nothing -> - H.text "None" - - Just armor -> - H.span [] - [ H.text <| Item.name armor.kind - , H.button - [ HE.onClick AskToUnequipArmor - , HA.class "inventory-equipment-unequip-btn" + |> List.map itemView + ) + , H.h3 + [ HA.class "text-green-300" ] + [ H.text "Equipment" ] + , H.div [] + [ UI.liBullet + , H.text "Armor: " + , H.span [ HA.class "text-green-100" ] <| + case player.equippedArmor of + Nothing -> + [ H.text "None" ] + + Just armor -> + [ H.text <| Item.name armor.kind + , UI.button + [ HE.onClick AskToUnequipArmor + , HA.class "ml-[1ch]" + ] + [ H.text "[Unequip]" ] ] - [ H.text "[Unequip]" ] - ] - ] - , H.h3 - [ HA.id "inventory-stats" ] - [ H.text "Defence stats" ] - , H.ul - [] - [ H.li [] [ H.text <| "Armor Class: " ++ String.fromInt armorClass ] - , H.li [] [ H.text <| "Damage Threshold: " ++ String.fromInt damageThreshold ] - , H.li [] [ H.text <| "Damage Resistance: " ++ String.fromInt damageResistance ] - ] - , H.h3 - [ HA.id "inventory-stats" ] - [ H.text "Attack stats" ] - , H.ul - [] - [ H.li [] [ H.text <| "Min Damage: " ++ String.fromInt attackStats.minDamage ] - , H.li [] [ H.text <| "Max Damage: " ++ String.fromInt attackStats.maxDamage ] - , H.li [] [ H.text <| "Chance to hit at target armor class 0: " ++ String.fromInt chanceToHitAtArmorClass0 ++ "%" ] + ] + , H.h3 + [ HA.class "text-green-300" ] + [ H.text "Defence stats" ] + , H.ul [] + [ H.li [] + [ UI.liBullet + , H.text "Armor Class: " + , H.span + [ HA.class "text-green-100" ] + [ H.text <| String.fromInt armorClass ] + ] + , H.li [] + [ UI.liBullet + , H.text "Damage Threshold: " + , H.span + [ HA.class "text-green-100" ] + [ H.text <| String.fromInt damageThreshold ] + ] + , H.li [] + [ UI.liBullet + , H.text "Damage Resistance: " + , H.span + [ HA.class "text-green-100" ] + [ H.text <| String.fromInt damageResistance ] + ] + ] + , H.h3 + [ HA.class "text-green-300" ] + [ H.text "Attack stats" ] + , H.ul [] + [ H.li [] + [ UI.liBullet + , H.text "Min Damage: " + , H.span + [ HA.class "text-green-100" ] + [ H.text <| String.fromInt attackStats.minDamage ] + ] + , H.li [] + [ UI.liBullet + , H.text "Max Damage: " + , H.span + [ HA.class "text-green-100" ] + [ H.text <| String.fromInt attackStats.maxDamage ] + ] + , H.li [] + [ UI.liBullet + , H.text "Chance to hit at target armor class 0: " + , H.span + [ HA.class "text-green-100" ] + [ H.text <| String.fromInt chanceToHitAtArmorClass0 ++ "%" ] + ] + ] ] ] @@ -3160,81 +3462,65 @@ inventoryView _ player = messagesView : Posix -> Time.Zone -> PlayerData -> CPlayer -> List (Html FrontendMsg) messagesView currentTime zone _ player = [ pageTitleView "Messages" - , H.table [ HA.id "messages-table" ] - [ H.thead [] - [ H.tr [] - [ H.th - [ HA.class "messages-unread" - , HA.title "Unread" - ] - [ H.text "U" ] - , H.th [ HA.class "messages-summary" ] [ H.text "Summary" ] - , H.th [ HA.class "messages-date" ] [ H.text "Date" ] - , H.th - [ HA.class "messages-remove" - , HA.title "Remove" + , H.div [ HA.class "flex flex-col gap-4" ] + [ H.table [ HA.id "messages-table" ] + [ H.thead [] + [ H.tr [] + [ H.th [ HA.title "Unread" ] [ H.text "U" ] + , H.th [] [ H.text "Summary" ] + , H.th [] [ H.text "Date" ] + , H.th [ HA.title "Remove" ] [ H.text "X" ] ] - [ H.text "✗" ] ] - ] - , H.tbody [] - (player.messages - |> Dict.values - |> List.sortBy (.id >> negate) - |> List.map - (\message -> - let - isUnread : Bool - isUnread = - not message.hasBeenRead - - summary : String - summary = - Message.summary message - - relativeDate : String - relativeDate = - DateFormat.Relative.relativeTime - currentTime - message.date - in - H.tr - [ HA.classList [ ( "is-unread", isUnread ) ] - , HE.onClick <| OpenMessage message.id - ] - [ if isUnread then - H.td - [ HA.class "messages-unread" - , HA.title "Unread" - ] - [ H.text "*" ] - - else - H.td [ HA.class "messages-unread" ] [] - , H.td - [ HA.class "messages-summary" - , HA.title summary - ] - [ H.text summary ] - , H.td - [ HA.class "messages-date" - , HA.title <| Message.fullDate zone message + , H.tbody [] + (player.messages + |> Dict.values + |> List.sortBy (.id >> negate) + |> List.map + (\message -> + let + isUnread : Bool + isUnread = + not message.hasBeenRead + + summary : String + summary = + Message.summary message + + relativeDate : String + relativeDate = + DateFormat.Relative.relativeTime + currentTime + message.date + in + H.tr + [ HA.classList [ ( "text-green-100", isUnread ) ] + , HE.onClick <| OpenMessage message.id ] - [ H.text relativeDate ] - , H.td - [ HA.class "messages-remove" - , HA.title "Remove" - , HE.onClickStopPropagation <| AskToRemoveMessage message.id + [ if isUnread then + H.td [ HA.title "Unread" ] [ H.text "*" ] + + else + H.td [] [] + , H.td + [ HA.title summary ] + [ H.text summary ] + , H.td + [ HA.title <| Message.fullDate zone message ] + [ H.text relativeDate ] + , H.td + [ TW.mod "hover" "text-orange" + , HA.title "Remove" + , HE.onClickStopPropagation <| AskToRemoveMessage message.id + ] + [ H.text "X" ] ] - [ H.text "✗" ] - ] - ) - ) + ) + ) + ] + , H.viewIf (Dict.isEmpty player.messages) <| + H.div [] [ H.text "No messages right now!" ] ] - , H.viewIf (Dict.isEmpty player.messages) <| - H.div - [ HA.id "messages-empty-note" ] - [ H.text "No messages right now!" ] ] @@ -3256,21 +3542,23 @@ messageView zone messageId _ player = } in [ pageTitleView "Message" - , H.h3 - [ HA.id "message-summary" ] - [ H.text <| Message.summary message ] - , H.div - [ HA.id "message-date" ] - [ H.text <| Message.fullDate zone message ] - , Message.content - [ HA.id "message-content" ] - perceptionLevel - message - , H.button - [ HE.onClick <| GoToRoute (PlayerRoute Route.Messages) - , HA.id "message-back-button" + , H.div [ HA.class "flex flex-col gap-4" ] + [ H.div [ HA.class "flex flex-col items-start" ] + [ H.h3 + [ HA.class "m-0 text-green-100 font-bold" ] + [ H.text <| Message.summary message ] + , H.div + [ HA.class "text-green-300" ] + [ H.text <| Message.fullDate zone message ] + , UI.button + [ HE.onClick <| GoToRoute (PlayerRoute Route.Messages) ] + [ H.text "[Back]" ] + ] + , Message.content + [ HA.class "max-w-[70ch]" ] + perceptionLevel + message ] - [ H.text "[Back]" ] ] @@ -3285,7 +3573,7 @@ settingsFightStrategySyntaxHelpView maybeHoveredItem = FightStrategyHelp.Reference reference -> H.span - [ HA.class "fight-strategy-syntax-help-reference" + [ HA.class "text-orange font-mono" , HE.onMouseOver <| HoverItem <| HoveredFightStrategyReference reference , HE.onMouseOut StopHoveringItem ] @@ -3294,7 +3582,7 @@ settingsFightStrategySyntaxHelpView maybeHoveredItem = hoverInfo = case maybeHoveredItem of Nothing -> - { title = "Hover for help" + { title = "Hover a [THING] for help" , description = "" } @@ -3302,20 +3590,29 @@ settingsFightStrategySyntaxHelpView maybeHoveredItem = HoveredItem.text hoveredItem in [ pageTitleView "Fight Strategy syntax help" - , H.button - [ HE.onClick (GoToRoute (PlayerRoute Route.SettingsFightStrategy)) ] - [ H.text "[Back]" ] - , H.div - [ HA.class "fight-strategy-syntax-help-grid" ] - [ H.pre - [ HA.class "fight-strategy-syntax-help-cheatsheet" ] - (List.map viewMarkup FightStrategyHelp.help) + , H.div [ HA.class "flex flex-col gap-4 items-start" ] + [ UI.button + [ HE.onClick (GoToRoute (PlayerRoute Route.SettingsFightStrategy)) ] + [ H.text "[Back]" ] , H.div - [ HA.class "fight-strategy-syntax-help-hover" ] - [ H.h3 [] [ H.text hoverInfo.title ] - , H.pre - [ HA.class "fight-strategy-syntax-help-hover-description" ] - [ H.text hoverInfo.description ] + [ HA.class "flex flex-row gap-[2ch]" ] + [ H.div [ HA.class "w-[80ch]" ] + [ H.div [] + [ H.text "Your strategy needs to be of the shape " + , H.span [ HA.class "text-green-100" ] [ H.text "[STRATEGY]" ] + , H.text ", and its goal is to choose which " + , H.span [ HA.class "text-green-100" ] [ H.text "[COMMAND]" ] + , H.text " to do in your current turn. See below for your options:" + ] + , H.pre [ HA.class "font-mono" ] + (List.map viewMarkup FightStrategyHelp.help) + ] + , H.div [ HA.class "flex-1" ] + [ H.h3 [ HA.classList [ ( "text-orange pb-4", maybeHoveredItem /= Nothing ) ] ] [ H.text hoverInfo.title ] + , H.pre + [ HA.class "font-sans whitespace-pre-wrap max-w-[60ch]" ] + [ H.text hoverInfo.description ] + ] ] ] ] @@ -3348,8 +3645,9 @@ settingsFightStrategyView fightStrategyText _ player = viewWarning : FightStrategy.ValidationWarning -> Html FrontendMsg viewWarning warning = H.li - [ HA.class "fight-strategy-warning" ] - [ H.text <| + [ TW.mod "hover" "text-green-100" ] + [ UI.liBullet + , H.text <| case warning of FightStrategy.ItemDoesntHeal itemKind -> "Item doesn't heal: " ++ Item.name itemKind @@ -3387,9 +3685,12 @@ settingsFightStrategyView fightStrategyText _ player = _ -> "" in + -- TODO when user clicks the dead end, splice it into the program H.li - [ HA.class "fight-strategy-dead-end" ] - [ H.text <| "- " ++ item ] + [ TW.mod "hover" "text-green-100" ] + [ UI.liBullet + , H.text item + ] deadEndCategorization : Parser.DeadEnd -> ( ( Int, Int ), String, String ) deadEndCategorization deadEnd = @@ -3417,8 +3718,8 @@ settingsFightStrategyView fightStrategyText _ player = ) helpBtn = - H.button - [ HA.class "fight-strategy-help-btn" + UI.button + [ HA.class "ml-[1ch]" , HE.onClick (GoToRoute (PlayerRoute Route.SettingsFightStrategySyntaxHelp)) ] [ H.text "[Syntax cheatsheet]" ] @@ -3445,72 +3746,101 @@ settingsFightStrategyView fightStrategyText _ player = in [ pageTitleView "Settings: Fight Strategy" , H.div - [ HA.class "fight-strategy-grid" ] - [ H.div [ HA.class "fight-strategy-examples" ] - (H.text "Examples: " - :: (FightStrategy.all - |> List.map - (\( name, strategy ) -> - H.button - [ HE.onClick <| SetFightStrategyText <| FightStrategy.toString strategy - , HA.class "fight-strategy-example" + [ HA.class "flex flex-row gap-4" ] + [ H.div [ HA.class "flex flex-col" ] + [ H.div [] + (H.text "Examples: " + :: (FightStrategy.all + |> List.map + (\( name, strategy ) -> + UI.button + [ HE.onClick <| SetFightStrategyText <| FightStrategy.toString strategy + , HA.class "normal-case" + , TW.mod "before" "content-['[']" + , TW.mod "after" "content-[']']" + ] + [ H.text name ] + ) + |> List.intersperse (H.text ", ") + ) + ) + , H.div [ HA.class "relative" ] + -- TODO change ch measurements to some kind of pixels. We'll have to hardcode this + [ UI.textarea + [ HE.onInput SetFightStrategyText + , HA.class "!bg-green-800 w-[70ch] h-[25rem] my-4 py-4 px-4 rounded leading-[18px] whitespace-pre font-mono" + , HA.value fightStrategyText + ] + [] + , firstDeadEnd + |> H.viewMaybe + (\{ row, col } -> + H.div + [ HA.class "absolute left-4 top-4 pointer-events-none select-none w-[24px] h-4 -ml-0.5 pl-0.5 border-l border-l-orange leading-[18px]" + , HA.class "bg-[linear-gradient(90deg,var(--orange-transparent)_0%,var(--orange-fully-transparent)_100%)]" + , HA.class "translate-x-[calc((var(--error-col)-1)*8px+1px)]" + , HA.class "translate-y-[calc((var(--error-row)-1)*18px+16px+1px)]" + , cssVars + [ ( "--error-row", String.fromInt row ) + , ( "--error-col", String.fromInt col ) ] - [ H.text name ] + ] + [] + ) + ] + , H.div + [ HA.class "flex flex-row gap-[1ch]" ] + [ UI.button + [ HA.disabled <| not hasTextChanged || Result.isErr parseResult + , parseResult + |> Result.toMaybe + |> HA.attributeMaybe + (\strategy -> + HE.onClick <| + AskToSetFightStrategy ( strategy, fightStrategyText ) ) - |> List.intersperse (H.text ", ") - ) - ) - , H.textarea - [ HE.onInput SetFightStrategyText - , HA.class "fight-strategy-textarea" - , HA.value fightStrategyText + ] + [ H.text "[Save]" ] + , UI.button + [ HA.disabled <| not hasTextChanged + , HE.onClick <| SetFightStrategyText player.fightStrategyText + ] + [ H.text "[Reset to saved]" ] + ] ] - [] - , firstDeadEnd - |> H.viewMaybe - (\{ row, col } -> - H.div - [ HA.class "fight-strategy-hovered-error" - , cssVars - [ ( "--error-row", String.fromInt row ) - , ( "--error-col", String.fromInt col ) - ] - ] - [] - ) - , H.div - [ HA.class "fight-strategy-info" ] - (H.div - [ HA.class "fight-strategy-info-heading" ] + , H.div [ HA.class "flex flex-col gap-4 max-w-[50ch]" ] + (H.div [] [ H.text "Info:" , helpBtn ] :: (if Result.isOk parseResult then - [ H.p - [ HA.class "fight-strategy-info-paragraph" ] - [ H.text "Your strategy is OK" ] + [ H.p [] + [ H.text "Your strategy is " + , H.span [ HA.class "text-green-100" ] [ H.text "OK" ] + ] ] else - [ H.p - [ HA.class "fight-strategy-info-paragraph" ] - [ H.text "Your strategy is not finished yet." ] - , H.p - [ HA.class "fight-strategy-info-paragraph" ] + [ H.p [] + [ H.text "Your strategy is " + , H.span + [ HA.class "text-orange" ] + [ H.text "not finished yet." ] + ] + , H.p [] [ H.text "See the yellow indicator on the left and the notes below to figure out where the problem is." ] - , H.p - [ HA.class "fight-strategy-info-paragraph" ] + , H.p [] [ H.text "If needed, ask on Discord in the " , H.a [ HA.href discordFightStrategiesChannelInviteLink , HA.target "_blank" - , HA.class "fight-strategy-info-link" + , HA.class "text-green-100 whitespace-pre" + , TW.mod "hover" "text-orange" ] [ H.text "#fight-strategies" ] , H.text " channel." ] - , H.p - [ HA.class "fight-strategy-info-paragraph" ] + , H.p [] [ H.text <| if String.isEmpty (String.trim fightStrategyText) then "Start with:" @@ -3528,7 +3858,7 @@ settingsFightStrategyView fightStrategyText _ player = ":" ) ] - , H.ul [ HA.class "fight-strategy-dead-ends" ] + , H.ul [] (deadEnds |> List.sortBy deadEndCategorization |> List.map viewDeadEnd @@ -3539,61 +3869,39 @@ settingsFightStrategyView fightStrategyText _ player = [] else - [ H.p - [ HA.class "fight-strategy-info-paragraph" ] + [ H.p [ HA.class "text-green-300" ] [ H.text "Warnings:" ] - , H.ul - [ HA.class "fight-strategy-warnings" ] + , H.ul [] (List.map viewWarning warnings) ] ) ) ] - , H.div - [ HA.class "fight-strategy-buttons" ] - [ H.button - [ HA.class "fight-strategy-save-btn" - , HA.disabled <| not hasTextChanged || Result.isErr parseResult - , parseResult - |> Result.toMaybe - |> HA.attributeMaybe - (\strategy -> - HE.onClick <| - AskToSetFightStrategy ( strategy, fightStrategyText ) - ) - ] - [ H.text "[Save]" ] - , H.button - [ HA.class "fight-strategy-reset-btn" - , HA.disabled <| not hasTextChanged - , HE.onClick <| SetFightStrategyText player.fightStrategyText - ] - [ H.text "[Reset to saved]" ] - ] ] newsItemView : Time.Zone -> News.Item -> Html FrontendMsg newsItemView zone { date, title, text } = - H.div - [ HA.class "news-item" ] + H.div [] [ H.h3 - [ HA.class "news-item-title" ] + [ HA.class "text-green-100 font-bold" ] [ H.text title ] , H.time - [ HA.class "news-item-date" ] + [ HA.class "text-green-300" ] [ date |> News.formatDate zone |> H.text ] - , News.formatText "news-item-text" text + , News.formatText "max-w-[60ch]" text ] newsView : Time.Zone -> List (Html FrontendMsg) newsView zone = - pageTitleView "News" - :: List.map (newsItemView zone) News.items + [ pageTitleView "News" + , H.div [ HA.class "flex flex-col gap-15" ] + (List.map (newsItemView zone) News.items) + ] fightView : Maybe Fight.Info -> PlayerData -> CPlayer -> List (Html FrontendMsg) @@ -3619,34 +3927,34 @@ fightView maybeFight _ player = } in [ pageTitleView "Fight" - , H.div [] - [ H.text <| - "Attacker: " - ++ Fight.opponentName fight.attacker - ++ (if youAreAttacker then - " (you)" + , H.div [ HA.class "flex flex-col gap-4" ] + [ H.div [] + [ H.text <| + "Attacker: " + ++ Fight.opponentName fight.attacker + ++ (if youAreAttacker then + " (you)" - else - "" - ) - ] - , H.div [] - [ H.text <| - "Target: " - ++ Fight.opponentName fight.target - ++ (if youAreAttacker then - "" + else + "" + ) + ] + , H.div [] + [ H.text <| + "Target: " + ++ Fight.opponentName fight.target + ++ (if youAreAttacker then + "" - else - " (you)" - ) - ] - , Data.Fight.View.view perceptionLevel fight player.name - , H.button - [ HE.onClick <| GoToRoute (PlayerRoute Route.Ladder) - , HA.id "fight-back-button" + else + " (you)" + ) + ] + , Data.Fight.View.view perceptionLevel fight player.name + , UI.button + [ HE.onClick <| GoToRoute (PlayerRoute Route.Ladder) ] + [ H.text "[Back]" ] ] - [ H.text "[Back]" ] ] @@ -3663,23 +3971,36 @@ ladderLoadingView = worldInfoView : WorldInfo -> Html FrontendMsg worldInfoView data = H.ul [] - [ H.li [] [ H.text <| "Name: " ++ data.name ] + [ H.li [] + [ H.text "Name: " + , H.span [ HA.class "text-green-100" ] [ H.text data.name ] + ] , H.li [] - [ H.text <| - "Players: " - ++ String.fromInt data.playersCount + [ H.text "Players: " + , H.span [ HA.class "text-green-100" ] [ H.text (String.fromInt data.playersCount) ] ] , H.li [] - [ H.text <| - "Tick frequency: " - ++ Tick.curveToString data.tickPerIntervalCurve - ++ " ticks every " - ++ Time.intervalToString data.tickFrequency + [ H.text "Tick frequency: " + , H.span [ HA.class "text-green-100" ] + [ case data.tickPerIntervalCurve of + Tick.Linear n -> + H.text <| String.fromInt n ++ " ticks every " ++ Time.intervalToString data.tickFrequency + + Tick.QuarterAndRest { quarter, rest } -> + H.text <| + String.fromInt quarter + ++ " ticks every " + ++ Time.intervalToString data.tickFrequency + ++ " until " + ++ String.fromInt (Tick.limit // 4) + ++ " ticks are reached, then " + ++ String.fromInt rest + ] ] , H.li [] - [ H.text <| - "Vendor restock frequency: every " - ++ Time.intervalToString data.vendorRestockFrequency + [ H.text "Vendor restock frequency: " + , H.span [ HA.class "text-green-100" ] + [ H.text <| "every " ++ Time.intervalToString data.vendorRestockFrequency ] ] ] @@ -3687,15 +4008,17 @@ worldInfoView data = aboutWorldView : PlayerData -> CPlayer -> List (Html FrontendMsg) aboutWorldView data _ = [ pageTitleView <| "About world: " ++ data.worldName - , worldInfoView - { name = data.worldName - , description = data.description - , startedAt = data.startedAt - , tickFrequency = data.tickFrequency - , tickPerIntervalCurve = data.tickPerIntervalCurve - , vendorRestockFrequency = data.vendorRestockFrequency - , playersCount = List.length data.otherPlayers + 1 - } + , H.div [ HA.class "p-[2ch]" ] + [ worldInfoView + { name = data.worldName + , description = data.description + , startedAt = data.startedAt + , tickFrequency = data.tickFrequency + , tickPerIntervalCurve = data.tickPerIntervalCurve + , vendorRestockFrequency = data.vendorRestockFrequency + , playersCount = List.length data.otherPlayers + 1 + } + ] ] @@ -3713,41 +4036,26 @@ ladderView data loggedInPlayer = playerLadderTableView : List COtherPlayer -> CPlayer -> Html FrontendMsg playerLadderTableView players loggedInPlayer = - let - cantFight : String -> Html FrontendMsg - cantFight message = - H.td - [ HA.class "ladder-fight" - , HA.title message - ] - [ H.text "-" ] - in - H.table [ HA.id "ladder-table" ] + H.table + [] [ H.thead [] [ H.tr [] [ H.th - [ HA.class "ladder-rank" + [ HA.class "text-right" , HA.title "Rank" ] [ H.text "#" ] - , H.th [ HA.class "ladder-fight" ] [ H.text "Fight" ] - , H.th [ HA.class "ladder-name" ] [ H.text "Name" ] + , H.th [] [ H.text "Fight" ] + , H.th [] [ H.text "Name" ] + , H.th [ HA.title "Health status" ] [ H.text "Status" ] + , H.th [ HA.class "text-right" ] [ H.text "Lvl" ] , H.th - [ HA.class "ladder-status" - , HA.title "Health status" - ] - [ H.text "Status" ] - , H.th [ HA.class "ladder-lvl" ] [ H.text "Lvl" ] - - --, H.th [HA.class "ladder-city"] [ H.text "City" ] -- city - --, H.th [HA.class "ladder-flag"] [] -- flag - , H.th - [ HA.class "ladder-wins" + [ HA.class "text-right" , HA.title "Wins" ] [ H.text "W" ] , H.th - [ HA.class "ladder-losses" + [ HA.class "text-right" , HA.title "Losses" ] [ H.text "L" ] @@ -3757,12 +4065,25 @@ playerLadderTableView players loggedInPlayer = (players |> List.indexedMap (\i player -> + let + isYou = + loggedInPlayer.name == player.name + + cantFight : String -> Html FrontendMsg + cantFight message = + H.td + [ HA.class "text-green-300 cursor-not-allowed" + , HA.classList [ ( "bg-green-800", isYou ) ] + , HA.title message + ] + [ H.text "-" ] + in H.tr - [ HA.classList - [ ( "is-player", loggedInPlayer.name == player.name ) ] + [ HA.classList [ ( "text-green-100", isYou ) ] ] [ H.td - [ HA.class "ladder-rank" + [ HA.class "text-right" + , HA.classList [ ( "bg-green-800", isYou ) ] , HA.title "Rank" ] [ H.text <| String.fromInt <| i + 1 ] @@ -3780,17 +4101,19 @@ playerLadderTableView players loggedInPlayer = else H.td - [ HA.class "ladder-fight" - , HE.onClick <| AskToFight player.name + [ HE.onClick <| AskToFight player.name + , HA.class "cursor-pointer bg-green-800 text-green-100" + , HA.classList [ ( "bg-green-800", isYou ) ] + , TW.mod "hover" "text-orange" ] [ H.text "Fight" ] , H.td - [ HA.class "ladder-name" + [ HA.classList [ ( "bg-green-800", isYou ) ] , HA.title "Name" ] [ H.text player.name ] , H.td - [ HA.class "ladder-status" + [ HA.classList [ ( "bg-green-800", isYou ) ] , HA.title <| if loggedInPlayer.special.perception <= 1 then "Health status. Your perception is so low you genuinely can't say whether they're even alive or dead." @@ -3800,17 +4123,20 @@ playerLadderTableView players loggedInPlayer = ] [ H.text <| HealthStatus.label player.healthStatus ] , H.td - [ HA.class "ladder-lvl" + [ HA.class "text-right" + , HA.classList [ ( "bg-green-800", isYou ) ] , HA.title "Level" ] [ H.text <| String.fromInt player.level ] , H.td - [ HA.class "ladder-wins" + [ HA.class "text-right" + , HA.classList [ ( "bg-green-800", isYou ) ] , HA.title "Wins" ] [ H.text <| String.fromInt player.wins ] , H.td - [ HA.class "ladder-losses" + [ HA.class "text-right" + , HA.classList [ ( "bg-green-800", isYou ) ] , HA.title "Losses" ] [ H.text <| String.fromInt player.losses ] @@ -3822,7 +4148,7 @@ playerLadderTableView players loggedInPlayer = adminLadderTableView : List SPlayer -> Html FrontendMsg adminLadderTableView players = - H.table [ HA.id "ladder-table" ] + H.table [] [ H.thead [] [ H.tr [] [ H.th @@ -3926,10 +4252,8 @@ contentUnavailableView reason = "Content unavailable (" ++ reason ++ "). This is most likely a bug. We should have redirected you someplace else. Could you report this to the developers please?" - , H.button - [ HE.onClick <| GoToRoute News - , HA.id "message-back-button" - ] + , UI.button + [ HE.onClick <| GoToRoute News ] [ H.text "[Back]" ] ] @@ -3955,51 +4279,23 @@ notInitializedView model = loadingNavView : Html FrontendMsg loadingNavView = - H.div - [ HA.id "loading-nav" ] + H.div [] [ H.text "Loading..." - , H.span [ HA.class "loading-cursor" ] [] + , H.span + [ HA.class "loading-cursor" + , HA.class "inline-block w-[1ch] h-4 -mb-0.5 ml-0.5" + ] + [] ] -view_ : Model -> Html FrontendMsg -view_ model = - let - worldNames : List World.Name - worldNames = - model.worlds - |> Maybe.withDefault [] - |> List.map .name - - leftNav = - case model.worldData of - IsAdmin _ -> - [ alertMessageView model.alertMessage - , adminLinksView model.route - ] - - IsPlayer data -> - [ alertMessageView model.alertMessage - , playerInfoView data.player - , loggedInLinksView data.player model.route - ] - - NotLoggedIn -> - [ loginFormView worldNames model.loginForm - , alertMessageView model.alertMessage - , loggedOutLinksView model.route - ] - in - appView { leftNav = leftNav } model - - alertMessageView : Maybe String -> Html FrontendMsg alertMessageView maybeMessage = maybeMessage |> H.viewMaybe (\message -> H.div - [ HA.id "alert-message" ] + [ HA.class "text-orange" ] [ H.text message ] ) @@ -4007,38 +4303,53 @@ alertMessageView maybeMessage = loginFormView : List World.Name -> Auth Plaintext -> Html FrontendMsg loginFormView worlds auth = let - formId = - "login-form" + input attrs children = + UI.input + (HA.class "text-green-100 w-[18ch] font-extraBold" + :: TW.mod "focus" "bg-green-900" + :: attrs + ) + children in H.form - [ HA.id formId + [ HA.class "w-[20ch]" , HE.onSubmit Login ] - [ H.input - [ HA.id "login-name-input" - , HA.value auth.name + [ input + [ HA.value auth.name , HA.placeholder "Username_______________" , HE.onInput SetAuthName ] [] - , H.input - [ HA.id "login-password-input" - , HA.type_ "password" + , input + [ HA.type_ "password" , HA.value <| Auth.unwrap auth.password , HA.placeholder "Password_______________" , HE.onInput SetAuthPassword ] [] , H.div - [ HA.class "login-world-select-label" ] + [ HA.class "mt-5" ] [ H.text "World: " ] , H.div - [ HA.class "login-world-select-wrapper" ] + [ HA.class "select-wrapper" + , HA.class "grid items-center relative w-[20ch] rounded cursor-pointer bg-green-200 mt-2 text-black" + , TW.mod "after" "justify-self-end -translate-y-0.5 rotate-180 px-2 text-black" + ] [ H.select [ HE.onChange SetAuthWorld - , HA.class "login-world-select" + , HA.class "select" + , HA.class "peer appearance-none bg-transparent border-0 m-0 py-1 pl-2 pr-8 w-full z-[1] outline-none" ] - (("" :: worlds) + (worlds + |> List.sortBy + (\worldName -> + if worldName == Logic.mainWorldName then + 0 + + else + 1 + ) |> List.map (\worldName -> H.option @@ -4048,19 +4359,17 @@ loginFormView worlds auth = [ H.text worldName ] ) ) - , H.span [ HA.class "login-world-select-focus" ] [] + , H.span + [ TW.mod "peer-focus" "absolute inset-[-1px] border-2 border-green-100 rounded-[inherit]" ] + [] ] , H.div - [ HA.id "login-form-buttons" ] - [ H.button - [ HA.id "login-button" - , HE.onClickPreventDefault Login - ] + [ HA.class "mt-4 flex justify-between" ] + [ UI.button + [ HE.onClickPreventDefault Login ] [ H.text "[ Login ]" ] - , H.button - [ HA.id "register-button" - , HE.onClickPreventDefault Register - ] + , UI.button + [ HE.onClickPreventDefault Register ] [ H.text "[ Register ]" ] ] ] @@ -4089,7 +4398,7 @@ linkView currentRoute { label, type_, tooltip, disabled, dimmed } = ) LinkIn { route, isActive } -> - ( H.button + ( UI.button , [ HE.onClick <| GoToRoute route , HA.attributeMaybe HA.title tooltip , HA.attributeIf (isActive currentRoute) <| HA.class "active" @@ -4098,7 +4407,7 @@ linkView currentRoute { label, type_, tooltip, disabled, dimmed } = ) LinkMsg msg -> - ( H.button + ( UI.button , [ HE.onClick msg , HA.attributeMaybe HA.title tooltip , HA.disabled disabled @@ -4107,9 +4416,7 @@ linkView currentRoute { label, type_, tooltip, disabled, dimmed } = in tag (HA.class "link" - :: HA.classList - [ ( "dimmed", dimmed ) - ] + :: HA.classList [ ( "dimmed", dimmed ) ] :: linkAttrs ) [ H.span @@ -4252,10 +4559,7 @@ loggedInLinksView player currentRoute = , linkMsg "Logout" Logout Nothing False ] in - H.div - [ HA.id "logged-in-links" - , HA.class "links" - ] + H.div [] (List.map (linkView currentRoute) links) @@ -4267,23 +4571,16 @@ adminLinksView currentRoute = , linkIn "Worlds" (AdminRoute AdminWorldsList) Nothing False , linkMsg "Import" ImportButtonClicked Nothing False , linkMsg "Export" AskForExport Nothing False - , linkIn "Ladder" (PlayerRoute Route.Ladder) Nothing False , linkMsg "Logout" Logout Nothing False ] in - H.div - [ HA.id "logged-in-links" - , HA.class "links" - ] + H.div [] (List.map (linkView currentRoute) links) loggedOutLinksView : Route -> Html FrontendMsg loggedOutLinksView currentRoute = - H.div - [ HA.id "logged-out-links" - , HA.class "links" - ] + H.div [] ([ linkMsg "Refresh" Refresh Nothing False , linkIn "Map" Map Nothing False , linkIn "Worlds" WorldsList Nothing False @@ -4294,17 +4591,14 @@ loggedOutLinksView currentRoute = commonLinksView : Route -> Html FrontendMsg commonLinksView currentRoute = - H.div - [ HA.id "common-links" - , HA.class "links" - ] + H.div [] ([ linkIn "News" News Nothing False , linkIn "About" About Nothing False , linkOut "Discord" "https://discord.gg/SxymXxvehS" Nothing False , linkOut "Twitter" "https://twitter.com/NuAshworld" Nothing False , linkOut "GitHub" "https://github.com/Janiczek/nu-ashworld" Nothing False , linkOut "Reddit" "https://www.reddit.com/r/NuAshworld/" Nothing False - , linkOut "Donate" "https://patreon.com/janiczek" Nothing False + , linkOut "Donate" "https://github.com/sponsors/Janiczek" Nothing False ] |> List.map (linkView currentRoute) ) @@ -4313,8 +4607,7 @@ commonLinksView currentRoute = adminWorldsListView : String -> Bool -> AdminData -> List (Html FrontendMsg) adminWorldsListView newWorldName newWorldFast data = [ pageTitleView "Admin :: Worlds" - , H.div - [ HA.id "admin-worlds-list" ] + , H.div [] [ H.table [] [ H.thead [] [ H.tr [] @@ -4330,10 +4623,10 @@ adminWorldsListView newWorldName newWorldFast data = H.tr [ HA.class "world" ] [ H.td [] [ H.text worldName ] , H.td [] - [ H.button + [ UI.button [ HE.onClick (GoToRoute (AdminRoute (Route.AdminWorldActivity worldName))) ] [ H.text "[Activity]" ] - , H.button + , UI.button [ HE.onClick (GoToRoute (AdminRoute (Route.AdminWorldHiscores worldName))) ] [ H.text "[Hiscores]" ] ] @@ -4342,26 +4635,19 @@ adminWorldsListView newWorldName newWorldFast data = ) ] ] - , H.div [ HA.id "admin-new-world-form" ] - [ H.input + , H.div [] + [ UI.input [ HE.onInput SetAdminNewWorldName , HA.placeholder "New world name" , HA.value newWorldName ] [] - , H.label - [ HA.for "admin-new-world-fast-checkbox" - , HE.onClick ToggleAdminNewWorldFast - ] - [ H.input - [ HA.type_ "checkbox" - , HA.id "admin-new-world-fast-checkbox" - , HA.checked newWorldFast - ] - [] - , H.text "Fast?" - ] - , H.button + , UI.checkbox + { isOn = newWorldFast + , label = "Fast?" + , toggle = SetAdminNewWorldFast + } + , UI.button [ HE.onClick AskToCreateNewWorld , HA.disabled (Dict.member newWorldName data.worlds) ] @@ -4382,7 +4668,7 @@ adminWorldActivityView lastTenToBackendMsgs worldName data = Just _ -> [ pageTitleView <| "Admin :: World: " ++ worldName ++ " - Activity" , H.h3 [] [ H.text "Last 10 messages" ] - , H.table [ HA.id "admin-last-ten-msgs-table" ] + , H.table [] (H.thead [] [ H.tr [] [ H.th [] [ H.text "World" ] @@ -4452,8 +4738,7 @@ adminWorldHiscoresView worldName data = ] in [ pageTitleView <| "Admin :: World: " ++ worldName ++ " - Hiscores" - , H.div - [ HA.id "admin-hiscores-content" ] + , H.div [] [ H.ul [] (List.map viewMaxBy [ ( "Most money", .caps ) @@ -4503,111 +4788,94 @@ playerInfoView player = createdPlayerInfoView : CPlayer -> Html FrontendMsg createdPlayerInfoView player = H.div - [ HA.id "player-info" ] - [ H.div [ HA.class "player-stat-label" ] [ H.text "Name:" ] + [ HA.class "grid grid-cols-2" ] + [ H.div + [ HA.class "col-start-1 text-right text-green-300 mr-[1ch]" ] + [ H.text "Name:" ] , H.div - [ HA.classList - [ ( "player-stat-value", True ) - , ( "emphasized", True ) - ] - ] + [ HA.class "col-start-2 text-green-100" ] [ H.text player.name ] , H.div - [ HA.class "player-stat-label" + [ HA.class "col-start-1 text-right text-green-300 mr-[1ch]" , HA.title "Hitpoints" ] [ H.text "HP:" ] - , H.div [ HA.class "player-stat-value" ] [ H.text <| String.fromInt player.hp ++ "/" ++ String.fromInt player.maxHp ] , H.div - [ HA.class "player-stat-label" + [ HA.class "col-start-2" ] + [ "{HP}/{MAXHP}" + |> String.replace "{HP}" (String.fromInt player.hp) + |> String.replace "{MAXHP}" (String.fromInt player.maxHp) + |> H.text + ] + , H.div + [ HA.class "col-start-1 text-right text-green-300 mr-[1ch]" , HA.title "Experience points" ] [ H.text "XP:" ] - , H.div [ HA.class "player-stat-value" ] + , H.div [ HA.class "col-start-2" ] [ H.span [] [ H.text <| String.fromInt player.xp ] , H.span - [ HA.class "deemphasized" ] + [ HA.class "text-green-300" ] [ H.text <| "/" ++ String.fromInt (Xp.nextLevelXp player.xp) ] ] - , H.div [ HA.class "player-stat-label" ] [ H.text "Level:" ] - , H.div [ HA.class "player-stat-value" ] [ H.text <| String.fromInt <| Xp.currentLevel player.xp ] , H.div - [ HA.class "player-stat-label" + [ HA.class "col-start-1 text-right text-green-300 mr-[1ch]" ] + [ H.text "Level:" ] + , H.div + [ HA.class "col-start-2" ] + [ H.text <| String.fromInt <| Xp.currentLevel player.xp ] + , H.div + [ HA.class "col-start-1 text-right text-green-300 mr-[1ch]" , HA.title "Wins/Losses" ] [ H.text "W/L:" ] - , H.div [ HA.class "player-stat-value" ] [ H.text <| String.fromInt player.wins ++ "/" ++ String.fromInt player.losses ] - , H.div [ HA.class "player-stat-label" ] [ H.text "Caps:" ] - , H.div [ HA.class "player-stat-value" ] [ H.text <| "$" ++ String.fromInt player.caps ] , H.div - [ HA.class "player-stat-label" + [ HA.class "col-start-2" ] + [ "{WINS}/{LOSSES}" + |> String.replace "{WINS}" (String.fromInt player.wins) + |> String.replace "{LOSSES}" (String.fromInt player.losses) + |> H.text + ] + , H.div + [ HA.class "col-start-1 text-right text-green-300 mr-[1ch]" ] + [ H.text "Caps:" ] + , H.div + [ HA.class "col-start-2" ] + [ "${CAPS}" + |> String.replace "{CAPS}" (String.fromInt player.caps) + |> H.text + ] + , H.div + [ HA.class "col-start-1 text-right text-green-300 mr-[1ch]" , HA.title "Ticks" ] [ H.text "Ticks:" ] - , H.div [ HA.class "player-stat-value" ] [ H.text <| String.fromInt player.ticks ] - ] - - -stylesLinkView : Html msg -stylesLinkView = - H.node "link" - [ HA.rel "stylesheet" - , HA.href <| "/styles/app.css?v=" ++ Version.version - ] - [] - - -favicon16View : Html msg -favicon16View = - H.node "link" - [ HA.rel "icon" - , HA.href "/images/favicon-16.png" - ] - [] - - -favicon32View : Html msg -favicon32View = - H.node "link" - [ HA.rel "icon" - , HA.href "/images/favicon-32.png" - ] - [] - - -genericFaviconView : Html msg -genericFaviconView = - H.node "link" - [ HA.rel "shortcut icon" - , HA.type_ "image/png" - , HA.href "/images/favicon-392.png" + , H.div + [ HA.class "col-start-2" ] + [ H.text <| String.fromInt player.ticks ] ] - [] - -genericFavicon2View : Html msg -genericFavicon2View = - H.node "link" - [ HA.rel "apple-touch-icon" - , HA.href "/images/favicon-392.png" - ] - [] - -logoView : Html msg -logoView = - H.div [ HA.id "logo-wrapper" ] +logoView : Model -> Html msg +logoView model = + H.div [ HA.class "flex flex-col items-end" ] [ H.img [ HA.src "/images/logo-black-small.png" , HA.alt "NuAshworld Logo" , HA.title "NuAshworld - go to homepage" - , HA.id "logo" + , HA.class + (if isPlayer model || isAdmin model then + "filter-logo-active" + + else + "filter-logo-inactive" + ) , HA.width 190 , HA.height 36 ] [] , H.div - [ HA.id "version" + [ HA.class "text-green-300" , HA.title "Game version" ] [ H.text Version.version ] diff --git a/src/Frontend/HoveredItem.elm b/src/Frontend/HoveredItem.elm index 95665c85..89a91097 100644 --- a/src/Frontend/HoveredItem.elm +++ b/src/Frontend/HoveredItem.elm @@ -4,6 +4,7 @@ import Data.FightStrategy.Help as FightStrategyHelp import Data.Perk as Perk exposing (Perk) import Data.Skill as Skill exposing (Skill) import Data.Special as Special +import Data.Special.Perception as Perception exposing (PerceptionLevel) import Data.Trait as Trait exposing (Trait) @@ -13,6 +14,7 @@ type HoveredItem | HoveredSpecial Special.Type | HoveredSkill Skill | HoveredFightStrategyReference FightStrategyHelp.Reference + | HoveredPerceptionLevel PerceptionLevel text : HoveredItem -> { title : String, description : String } @@ -49,3 +51,8 @@ text hoveredItem = { title = FightStrategyHelp.referenceTitle reference , description = FightStrategyHelp.referenceDescription reference } + + HoveredPerceptionLevel perceptionLevel -> + { title = "Perception Level: " ++ Perception.label perceptionLevel + , description = Perception.tooltip perceptionLevel + } diff --git a/src/Frontend/News.elm b/src/Frontend/News.elm index 0bc06a4f..4272e9f6 100644 --- a/src/Frontend/News.elm +++ b/src/Frontend/News.elm @@ -1,10 +1,15 @@ module Frontend.News exposing (Item, formatDate, formatText, items) import DateFormat -import Html exposing (Html) +import Html as H exposing (Html) import Html.Attributes as HA -import Markdown +import Html.Attributes.Extra as HAE +import Markdown.Block +import Markdown.Parser +import Markdown.Renderer exposing (defaultHtmlRenderer) +import Tailwind as TW import Time +import UI type alias Item = @@ -16,568 +21,19 @@ type alias Item = items : List Item items = - [ { date = 0 - , title = "TODO" - , text = """ -Changelog: - -* Quests!! - -* items are now **sorted by type** (food, books, armor, ...) on the inventory page - -* new perk: **Gecko Skinning**: each gecko kill has a guaranteed drop of gecko skin. Given as a reward for a quest. - -* new item: **Meat Jerky** (value $30, heals 40 HP) -* new item: **Beer** (value $200, can't currently be used) -* new item: **BB Gun** (value $3500, small gun, uses BB ammo, can't currently be used) -* new item: **BB Ammo** (value $20, ammo, can't currently be used) - -* new enemy: **Silver Gecko** -* new enemy: **Tough Silver Gecko** -* new enemy: **Golden Gecko** -* new enemy: **Tough Golden Gecko** -* new enemy: **Fire Gecko** -* new enemy: **Tough Fire Gecko** - -TODO: - -* TODO make some vendors sell meat jerky -* TODO new enemy: silver gecko -* TODO make geckos drop the skins if attacker has the perk -* TODO new item: silver gecko skin -* TODO new item: golden gecko skin -* TODO new item: fire gecko skin -* TODO on each tick, progress the quests -* TODO validate startProgressing -* TODO handle quest complete (global rewards) -* TODO handle quest complete (player rewards) -* TODO global rewards - track them in backend model? -* TODO global rewards - use them? -* TODO write more details to the news about the geckos -* TODO check that we're not progressing quests when hard cap is reached -* TODO maybe quest finish XP reward for those who gave enough? - -~janiczek -""" - } - , { date = 1638276029 - , title = "Worlds, fix for a vendor bug" - , text = """ -A big release in preparation for my talk about NuAshworld at NDC Oslo 2021 :) - -You can now play on different worlds with different tick speed settings. - -* For reference, the default speed on the "main" world is 2-4 ticks (depending -on whether you have above or below 50 ticks) per hour. -* The world for NDC Oslo will run at 1-2 ticks per second. -* Depending on how that one goes, I'll create a public "blitz round" world -after the conference. - -A bug was fixed related to being in the middle of a trade while the vendor -restocks. - -Pages in the game now each have their URL. - -(Vendor restock frequency is separate from the tick frequency; 1x per hour on -the main world, 1x per minute for the NDC Oslo world.) - -~janiczek -""" - } - , { date = 1626037313 - , title = "Fight strategy editor now more lenient toward whitespace" - , text = """ -While experimenting with the editor I found I'd like it to allow me to write eg. - -``` -if ((opponent is player - and my AP < 4) - and my HP < 100) -then do whatever -else attack (eyes) -``` - -In other words, newlines all over the place. And that's now possible! - -~janiczek -""" - } - , { date = 1626033582 - , title = "Fight strategy editor" - , text = """ -You can now write your own fight strategies in the **editor** on the Settings page. - -You can learn what's possible from the **examples** above the editor or via the **syntax cheatsheet** page. The info bar on the right of the editor should lead you through writing your strategies. - -There is a [#fight-strategies](https://discord.gg/9NuCZs3YZa) channel on the Discord where you can ask for help or share your own creations. - -~janiczek -""" - } - , { date = 1625920050 - , title = "Fixes for fight strategies" - , text = """ -Running two players with the YOLO strategy has uncovered a few bugs, so here -are the fixes for them: - -* Items in inventory with 0x count can't be used anymore - -* Items used during fight get removed correctly: they don't show up as 0x in -the inventory after the fight - -* Exact HP after healing during fight is only shown to you if it was you -healing yourself, or if you have enough PerceptionLevel to see the opponent's -exact HP. - -* It was possible to craft strategies such that the fight would never end. -We've now enforced a limit of 1000 actions - after that, both players give up -the fight and nobody wins. - -* If falling back to a backup strategy in case action from your strategy cannot -be used, we now correctly let the rest of your turn play back instead of -cutting it after the fallback action. - -* Action 'Heal' isn't needlessly taken if you have full HP. - -~janiczek -""" - } - , { date = 1625880726 - , title = "Fight strategies!" - , text = """ -You can now choose between different **fight strategies** on the **Settings -page** and actually **heal** during fights! - -I'll probably implement an editor to let you write your own strategies before I -dive back into quests. - -~janiczek -""" - } - , { date = 1623181215 - , title = "Your attacks are logged now, fights have a stats section" - , text = """ -A little procrastination patch while I chip away at quests: - -* **each fight has a stats section** with hit rate, damage dealt, critical hit -chance, average damage, max hit for both you and your opponent. - -* **your PvP attacks are now logged** into your messages. You can look at your -fights later if you want. - -This will probably later evolve into some filtering/tab system for the -messages, and/or a checkbox in settings to disable this recording behaviour, -but... we'll get there when we get there. - -Re quests: I have them all listed, the XP rewards roughly distributed, now just -to fill the rest of the data (description, requirements, item rewards, global -and private permanent buff rewards, etc.) and plug it into the code. Please be -patient with me :) - -~janiczek -""" - } - , { date = 1622292832 - , title = "XP and caps nerf in PvP fights" - , text = """ -We're experimenting with balancing the fights. The way things worked until now -is that - -* XP gained from a won fight was **10xp x damage dealt** (HP taken) - -* winner took **all the caps** the loser had on them - -In this update, we're changing that to: - -* XP gained is the above formula **scaled by (loser level / winner level)**. -Thus if a player with a level 20 kills a player with a level 6, they will only -get **6/20** as much of the XP. This works in the other way too! The weaker -player will get **20/6** as much XP if they manage to kill the stronger player. - -* caps gained are **scaled between 50% and 100%** of the full amount based on -the percentage of max HP taken during that fight. Formula: -**loser caps x (50% + 0.5 x damage dealt / max HP)**. -Example: Loser (with 34/80 HP) has 1234 caps on them. Winner kills them and -gets 879 caps. But if the loser was at full HP (80/80), the winner would get -all of the 1234 caps. - -Other changes: - -* the Messages link in menu is now dimmed if you have no unread messages -* the Messages link in menu is now highlighted even if you're in a specific message - -~janiczek -""" - } - , { date = 1621718718 - , title = "About page + Patreons + endgame!" - , text = """ -I've finally filled in the **About page**, because I needed somewhere to thank -my Patreons :) - -Thanks again, **djetelina**! - -To be a bit enigmatic: in my almost-a-week of not working on the game some -thoughts have crystallized on **how I want the endgame to look.** It also -nicely circumvents my fear of writing quests being too time consuming. The -solution is also a mechanic I haven't yet seen in any game I've played, so I'm -very interested in how well will it work. - -Stay tuned! - -~janiczek -""" - } - , { date = 1621370196 - , title = "Map chunks and enemies randomization" - , text = """ -I've separated the map into [five -regions](https://twitter.com/NuAshworld/status/1394754684129267718) of -increasing difficulty: - -1. Arroyo, Klamath, Den -2. Modoc, Vault City, Gecko -3. New Reno, Broken Hills, Redding, Raiders -4. NCR, Vault 13, Vault 15, Military Base -5. San Francisco, Navarro, Enclave - -Rest of the changelog: - -* **The enemies are now generated based on which chunk you're in!** So hopefully no -angry brahmins killing newbies next to the first town :) - -* **Added towns**: Raiders, Navarro, Vault 13, Vault 15 (no vendor in any of -them yet - you can see from them being transparent on the map) - -We'll need to add more enemies so that there is more variety, but maybe I'll -prioritize melee weapons first. Who knows? - -~ janiczek -""" - } - , { date = 1621248342 - , title = "Inventory total value" - , text = """ -A quick little change today - the inventory screen now shows the total value of your items. - -~janiczek -""" - } - , { date = 1621111128 - , title = "One more thing..." - , text = """ -Out of sheer procrastination I've implemented the help descriptions for SPECIAL -attributes, skills and traits. - -~janiczek -""" - } - , { date = 1621102934 - , title = "PvM drops and Brahmins" - , text = """ -Today's update will be short and sweet: **enemies can drop items** and -**Brahmins** were added as new enemies, along with two harder variants of Radscorpions. - -Since right now all enemies spawn everywhere, those radscorpions will probably -give you a bit of trouble. **The next patch** should be about restricting them to -certain areas, so that players can naturally progress from low-level areas to -higher-level areas as they see fit. - -Changelog: - -* Discord invite link was updated to point to the #welcome channel -* Item added: **Fruit** (heals 15 HP, base value $10) -* New enemies: **Brahmins**. Variants are: Brahmin, Angry Brahmin, Weak Brahmin, Wild Brahmin. -* New enemies: two **black** variants of **Radscorpions**. -* Enemies can now drop items: expect fruit, healing powder and an ocassional stimpak for now. - -~janiczek -""" - } - , { date = 1620669882 - , title = "More perks and UI improvements" - , text = """ -I have went through most of the perks in the original game and "ported" the -applicable ones to NuAshworld. Most other perks that are still missing are -waiting for non-unarmed combat, actual weapons etc. to be implemented. - -There is one big bug fixed: the armor class in fights was computed from the -attacker, not from the defending party! This is now fixed, so your hard-earned -metal armor will now finally be useful to you ;) - -And the unused Action Points from your turns in fights get converted to bonus -Armor Class for the next turn - again bringing us closer to what's in Fallout. -See also the **HtH Evade** perk that upgrades this behaviour and makes your -Unarmed skill much more useful. - -Changelog: - -* fixed bug: **Max HP** in Character Screen now shows the proper value instead of one calculated for level 1. -* UI improvement: **Tick heal** in Character Screen now shows the specific HP value healed in addition to the percentage of max HP. -* UI improvement: **Perk selection screen** now shows perk descriptions on hover. -* UI improvement: **Character screen** now shows perk descriptions on hover. - -* new perk: **Action Boy**: gives you +1 Action Point per rank (for use in fights etc). Max rank: 2. Reqs: lvl 12, Agility >= 5 -* new perk: **Adrenaline Rush**: gives you +1 Strength whenever your HP drops below 50%. Max rank: 1. Reqs: lvl 6, Strength < 10 -* new perk: **Bonus HtH Attacks**: all your unarmed attacks consume 1 less AP (so, 2 instead of 3 for normal attacks and 3 instead of 4 for aimed attacks). Max rank: 1. Reqs: lvl 15, Agility >= 6 -* new perk: **Dodger**: gives you +5 to Armor Class. Max rank: 1. Reqs: lvl 9, Agility >= 6 -* new perk: **Fortune Finder**: all caps NPC drops are doubled. Max rank: 1. Reqs: lvl 6, Luck >= 8 -* new perk: **Gambler**: gives you +20% to Gambling. Max rank: 1. Reqs: lvl 6, Gambling >= 50% -* new perk: **HtH Evade**: each Action Point unused in your fight turn gets converted to 2 Armor Class instead of 1. You also gain 1/12 of your Unarmed skill as additional Armor Class. Max rank: 1. Reqs: lvl 12, Unarmed >= 75% -* new perk: **Lifegiver**: gives you +4 HP per level per rank. Max rank: 2. Reqs: lvl 12, Endurance >= 4 -* new perk: **Living Anatomy**: gives you +10% to Doctor and +5 damage to any attack that lands. Max rank: 1. Reqs: lvl 12, Doctor >= 60% -* new perk: **Master Thief**: gives you +15% to Lockpick and Steal. Max rank: 1. Reqs: lvl 12, Lockpick >= 50%, Steal >= 50% -* new perk: **Medic**: gives you +10% to First Aid and Doctor. Max rank: 1. Reqs: lvl 12, First Aid >= 40% or Doctor >= 40% -* new perk: **Mr. Fixit**: gives you +10% to Repair and Science. Max rank: 1. Reqs: lvl 12, Science >= 40% or Repair >= 40% -* new perk: **Negotiator**: gives you +10% to Speech and Barter. Max rank: 1. Reqs: lvl 6, Barter >= 50%, Speech >= 50% -* new perk: **Pathfinder**: your tick cost for map movement is reduced by 25% per rank. Max rank: 2. Reqs: lvl 6, Endurance >= 6, Outdoorsman >= 40% -* new perk: **Ranger**: gives you +15% to Outdoorsman. Max rank: 1. Reqs: lvl 6, Perception >= 6 -* new perk: **Salesman**: gives you +20% to Barter. Max rank: 1. Reqs: lvl 6, Barter >= 50% -* new perk: **Speaker**: gives you +20% to Speech. Max rank: 1. Reqs: lvl 9, Speech >= 50% -* new perk: **Speaker**: gives you +20% to Speech. Max rank: 1. Reqs: lvl 9, Speech >= 50% -* new perk: **Swift Learner**: gives you 5% more XP per rank. Max rank: 3. Reqs: lvl 3, Intelligence >= 4 -* new perk: **Thief**: gives you +10% to Sneak, Lockpick, Steal and Traps. Max rank: 1. Reqs: lvl 3 -* new perk: **Toughness**: gives you +10 to Damage Resistance per rank. Max rank: 3. Reqs: lvl 3, Endurance >= 6, Luck >= 6 - -~ janiczek -""" - } - , { date = 1620348829 - , title = "Critical hits" - , text = """ -The game now properly tracks **critical hits**. You'll find that both you and -your enemies have a chance of hitting each other extra hard (**damage -multiplier** 1.5x to 4x depending on chance and whether you have some of the -critical-enhancing perks). - -As always, it has generated a bunch of TODOs for me to go through - mainly -status effects like crippled legs, knockback / knockout, blindness etc. - well, -one day maybe they'll come! :) - -I've been given feedback by ~djetelina that it would be nice to have -changelogs. So, here goes! - -Changelog: -* fights now correctly name body parts. So, no more ants with arms. -* **critical hits**: ocassionally damage is multiplied. You'll see which hit was -critical in the fight log. -* fixed damage formula: damage resistance is not affected by armor-ignoring -attacks (those don't exist yet anyways!) -* new perk: **Better Criticals**. Upgrades your critical hits' effects -- but not -chance for a critical happening. Reqs: lvl 9, luck 6, perception 6, agility 4 -* new perk: **More Criticals**. Max 3 ranks, each rank gives you 5% extra chance to -score a critical hit. Reqs: lvl 6, luck 6 -* new perk: **Slayer**. All non-miss unarmed/melee hits are upgraded to criticals. -Reqs: lvl 24, agility 8, strength 8, unarmed 80% -* trait **Heavy Handed** now has its critical hit effect debuff implemented. Note -this debuff is larger (-30) than the buff given by Better Criticals (+20). -* new trait: **Finesse**. Critical chance increased by 10%, but all damage is -reduced by 30%. -* map tooltip now correctly pluralizes ticks, so no more "1 ticks". -* fixed bug where damage in a fight could sometimes be negative (healing you) - -~janiczek -""" - } - , { date = 1620065638 - , title = "Armor!" - , text = """ -I have added a few kinds of **armor** to the game and a few new merchants that -can sell it. You can equip it in the Inventory screen - it should make you a -bit more durable in the battle. - -As a reminder, vendors change their stock every tick (so, every hour). May the -odds be ever in your favour :) - -Oh and we now have **Healing Powder** (Hakunin in **Arroyo** sells a bunch of -it) in an attempt to balance the healing in this damn game a bit. - -~janiczek -""" - } - , { date = 1619718120 - , title = "Books, more perks, and a new merchant" - , text = """ -I've been **adding more perks,** prioritizing those unlocked at level 3 (I have -enough time to do those at lvl 6/9/12/... - you guys don't level up that fast -;) ). One of them is related to -[books!](https://fallout.fandom.com/wiki/Fallout_2_skill_books) Which means, I -went and also implemented books. If you go look in the **Klamath** or **Den** -stores (yeah, there's now a vendor in Den!), you might get lucky and find one -of them. - -The books will give you up to 10% to their respective skills, capping somewhere -around 91%. After that, the book for that particular skill is useless to you. - -Note that using a book requires some ticks, related to your Intelligence -attribute. - -Oh and I've also slowed the game again. We now know 60x is too fast! (Duh.) - -~janiczek -""" - } - , { date = 1619693804 - , title = "Perks and a fast testing round" - , text = """ -Perks can now be added from within the **Character** screen (if you have perks -available - usually every 3 levels). Take them for a spin! - -I'm also making the game run a bit faster for a limited time, to let folks test -it and give me some feedback before I make a bigger marketing push :) - -So, enjoy a game tick every minute! - -~janiczek -""" - } - , { date = 1619480881 - , title = "PvM fights" - , text = """ -You can now fight some NPC enemies and get those sweet caps flowing into the -economy! - -When you move out of any town, you'll see that the **[Town]** link in -your menu changes to a **[Wander]** one. Clicking it will find you a NPC to fight -for the price of **one tick,** similarly to the PvP fights. - -Go forth and save up for those stimpaks! And don't forget, if you fight another -player, you get all their caps (or they yours). Should get much more exciting now! - -~janiczek -""" - } - , { date = 1618787348 - , title = "Skills and traits" - , text = """ -I've just revamped the **character creation screen** and added some initial -**traits** and support for **tagged skills** there. On each level-up you'll get -**skill points** to upgrade your skills with. This should all result in more -interesting characters and meta. - -Since I'm resetting the ladder instead of -attempting a complicated migration, you can try the new features out with new -characters! :) - -I also have a basic **perk** support implemented under the hood, but the "pick -a perk" screen is still TODO. - -Next up, the PvM encounters that should pump some caps into the economy, -finally! - -~janiczek -""" - } - , { date = 1618521323 - , title = "Beginnings of economy" - , text = """ -A big change just landed in NuAshworld: - -* you now have an **inventory** (visible on the Character page), and -* there is now a **store** in Klamath where you'll be able to barter with the -one and only [Maida Buckner](https://fallout.fandom.com/wiki/Maida_Buckner). - -The stores will, in general, restock periodically each tick. - -Note that this feature makes use of the **Charisma attribute**, since Charisma -affects your Barter skill, and that affects the prices you'll be getting when -trading with NPCs. - -There is currently only one item available in the game: -the healing item -[Stimpak](https://fallout.fandom.com/wiki/Stimpak_%28Fallout%29). - -A caveat: it doesn't currently do anything yet (this is a huge update as it -is!), but later you'll be able to: - -* use it to **heal yourself manually** (thus saving ticks), and -* **set automatic rules for your fights** ("heal whenever my HP drops below -30%" and so on). - -For trade to be truly useful, I'll have to add **NPC fights** as the next -thing, so that you can farm some caps. - -Stay tuned, good stuff coming soon! - -~janiczek -""" - } - , { date = 1617309687 - , title = "Fight system" - , text = """ -Fights should, now that I've -[implemented](https://twitter.com/janiczek/status/1377043815043846149) the -unarmed version of Fallout 2 combat algorithm and raised the XP rewards, be -interesting and rewarding enough that getting to a level 2 shouldn't be too -much of a problem :) At least, that would be the case if you had an option to -heal instantly. It's planned, read more below! - -What's planned for the immediate future: - -* Fast healing (Pip-boy rest-until-healed that would cost you ticks) -* Skill system (train your Unarmed skill for better damage etc.) -* PvM random encounters to train on -* Inventory system, items, drops -* Non-unarmed combat (melee, guns, ammo) - -And more long-term plans: - -* Perks / traits -* Quests -* Town NPCs (barter vendors, quest givers) - -P.S.: I've created a Twitter account -[@NuAshworld](https://twitter.com/NuAshworld) where I share screenshots from -development. Follow me! - -~janiczek -""" - } - , { date = 1614637525 - , title = "Plans before alpha" - , text = """ -I've just added a tick system (one tick at the start of every hour) which -should heal you and give you ticks to use for movement, fights, etc. Let's hope -it's not too broken :) - -I want to talk about my plans a bit. Some of my immediate plans are: - -* [NEW CHAR] finish the screen -* [FIGHT] dice-rolling instead of 50/50 win chance -* [ECONOMY] source of caps and items: random encounters / quests (simplified) - -More broadly, I'd like the game to have these mechanics: - -* when you lose, the other player gets all the caps you currently have with you -* thus, there is the need for having a stash / vault (hehe) to hide your caps -* I'm thinking that there might be some NPC in every town that will hold on to stuff for you, for a fee (per day?) -* these wouldn't be connected: if you keep 500 caps in Den and go to Redding, you won't be able to pick up the 500 caps there -* thus, there will (probably) be a period of danger where you need to move caps from one town to another -* perhaps even hidden stashes (anywhere on the map, or in locations given by random encounters?) -* these would have a chance to be found out by other players / NPC raiders / whoever - -But I need to somehow trim that down to a small prototype to test the idea out. - -~janiczek -""" - } - , { date = 1614543901 - , title = "Discord" - , text = """ -Development is chugging along; I've also created a [Discord](https://discord.gg/HUmwvnv4xV) server for NuAshworld. Looking forward to seeing you there! - -~janiczek -""" - } - , { date = 1614377234 - , title = "New beginnings!" + [ { date = 1614377234 + , title = "Hello!" , text = """ -Hello everybody! I just want to announce that I'm starting to work on this game again. +This is a test news post. I'll have to **flesh this out.** -You can watch the development plans on NuAshworld's [Trello](https://trello.com/b/WevjfFrt/nuashworld) and the game development itself on [GitHub](https://github.com/Janiczek/nu-ashworld-lamdera). +Check out this [link](https://google.com)! -I want to stay close to finding the fun in the game -- closing in on the mechanics, not getting stuck on unimportant things. We'll see how that goes :) +Some list: + +- one +- second +- 3! ~janiczek """ @@ -587,9 +43,36 @@ I want to stay close to finding the fun in the game -- closing in on the mechani formatText : String -> String -> Html a formatText class markdown = - Markdown.toHtml - [ HA.class class ] - markdown + markdown + |> Markdown.Parser.parse + |> Result.mapError (\_ -> "") + |> Result.andThen (Markdown.Renderer.render renderer) + |> Result.withDefault [ H.text "Failed to parse Markdown" ] + |> H.div [ HA.class ("flex flex-col gap-4 mt-4 " ++ class) ] + + +renderer : Markdown.Renderer.Renderer (Html a) +renderer = + { defaultHtmlRenderer + | link = + \{ title, destination } children -> + H.a + [ HA.class "text-orange relative no-underline" + , TW.mod "after" "absolute content-[''] bg-orange-transparent inset-x-[-3px] bottom-[-2px] h-1 transition-all duration-[250ms]" + , TW.mod "hover:after" "bottom-0 h-full" + , HA.href destination + , HAE.attributeMaybe HA.title title + ] + children + , unorderedList = + \list -> + list + |> List.map + (\(Markdown.Block.ListItem _ children) -> + H.li [] (UI.liBullet :: children) + ) + |> H.ul [ HA.class "flex flex-col" ] + } formatDate : Time.Zone -> Int -> String diff --git a/src/Lamdera/Hash.elm b/src/Lamdera/Hash.elm new file mode 100644 index 00000000..6820c43b --- /dev/null +++ b/src/Lamdera/Hash.elm @@ -0,0 +1,26 @@ +module Lamdera.Hash exposing (hasChanged, hash) + +import Dict exposing (Dict) +import FNV1a +import Hex.Convert +import Lamdera exposing (ClientId) +import Lamdera.Wire3 + + +hash : (a -> Lamdera.Wire3.Encoder) -> a -> Int +hash encode value = + value + |> encode + |> Lamdera.Wire3.bytesEncode + |> Hex.Convert.toString + |> FNV1a.hash + + +hasChanged : Int -> ClientId -> Dict ClientId Int -> Bool +hasChanged newHash clientId cache = + case Dict.get clientId cache of + Nothing -> + True + + Just oldHash -> + oldHash /= newHash diff --git a/src/Tailwind.elm b/src/Tailwind.elm new file mode 100644 index 00000000..74313f87 --- /dev/null +++ b/src/Tailwind.elm @@ -0,0 +1,13 @@ +module Tailwind exposing (mod) + +import Html exposing (Attribute) +import Html.Attributes as HA + + +mod : String -> String -> Attribute msg +mod modifier classes = + classes + |> String.words + |> List.map (\word -> modifier ++ ":" ++ word) + |> String.join " " + |> HA.class diff --git a/src/Types.elm b/src/Types.elm index 1de7365c..06e7e5fc 100644 --- a/src/Types.elm +++ b/src/Types.elm @@ -1,6 +1,7 @@ module Types exposing (..) import AssocSet as Set_ +import BiDict exposing (BiDict) import Browser exposing (UrlRequest) import Browser.Navigation exposing (Key) import Data.Auth exposing (Auth, Hashed, Plaintext) @@ -56,6 +57,7 @@ type alias FrontendModel = , barter : Barter.State , fightStrategyText : String , expandedQuests : Set_.Set Quest.Name + , userWantsToShowAreaDanger : Bool -- admin state , lastTenToBackendMsgs : List ( PlayerName, World.Name, ToBackend ) @@ -68,14 +70,16 @@ type alias BackendModel = { worlds : Dict World.Name World , time : Posix , loggedInPlayers : - Dict - ClientId - { worldName : World.Name - , playerName : PlayerName - } + -- Lets multiple browser windows log into the same (WorldName, PlayerName). + -- BiDict lets us get all the ClientIds for a certain player, meaning we + -- can compute their data just once. + BiDict ClientId ( World.Name, PlayerName ) , adminLoggedIn : Maybe ( ClientId, SessionId ) , lastTenToBackendMsgs : Queue ( PlayerName, World.Name, ToBackend ) , randomSeed : Random.Seed + , -- We don't want to send the same data to players over and over when + -- Tick-ing. This lets us skip that work. + playerDataCache : Dict ClientId Int } @@ -115,6 +119,7 @@ type FrontendMsg | MapMouseAtCoords TileCoords | MapMouseOut | MapMouseClick + | SetShowAreaDanger Bool | OpenMessage Message.Id | AskToRemoveMessage Message.Id | BarterMsg BarterMsg @@ -122,7 +127,7 @@ type FrontendMsg | StopHoveringItem | SetFightStrategyText String | SetAdminNewWorldName String - | ToggleAdminNewWorldFast + | SetAdminNewWorldFast Bool | AskToCreateNewWorld | ExpandQuestItem Quest.Name | CollapseQuestItem Quest.Name @@ -186,6 +191,13 @@ type BackendMsg | LoggedToBackendMsg +{-| Only done for getting the automatic `Types.w3_encode_PlayerData_` encoder +(for hashing a type to Int, for caching purposes) +-} +type alias PlayerData_ = + PlayerData + + type ToFrontend = CurrentPlayer PlayerData | CurrentWorlds (List WorldInfo) diff --git a/src/UI.elm b/src/UI.elm new file mode 100644 index 00000000..4121708c --- /dev/null +++ b/src/UI.elm @@ -0,0 +1,86 @@ +module UI exposing + ( bold + , button + , checkbox + , checkboxLabel + , input + , liBullet + , textarea + ) + +import Html as H exposing (Attribute, Html) +import Html.Attributes as HA +import Html.Events as HE +import Tailwind as TW + + +button : List (Attribute msg) -> List (Html msg) -> Html msg +button attrs content = + H.button + (HA.class "uppercase whitespace-pre cursor-pointer text-green-200 select-none" + :: TW.mod "disabled" "text-green-300" + :: TW.mod "hover" "text-green-100" + :: TW.mod "active" "text-orange" + :: attrs + ) + content + + +input : List (Attribute msg) -> List (Html msg) -> Html msg +input attrs content = + H.input + (HA.class "bg-transparent" + :: TW.mod "focus" "outline-none" + :: attrs + ) + content + + +textarea : List (Attribute msg) -> List (Html msg) -> Html msg +textarea attrs content = + H.textarea + (HA.class "bg-transparent" + :: TW.mod "focus" "outline-none" + :: attrs + ) + content + + +bold : String -> Html msg +bold text = + H.span + [ HA.class "font-bold" ] + [ H.text text ] + + +liBullet : Html msg +liBullet = + H.span + [ HA.class "text-green-300 pl-[1ch]" ] + [ H.text "- " ] + + +checkboxLabel : Bool -> String +checkboxLabel isOn = + if isOn then + "[X]" + + else + -- Space the width of one 'X' (in the font PixelOperator) + "[\u{2007}]" + + +checkbox : + { label : String + , isOn : Bool + , toggle : Bool -> msg + } + -> Html msg +checkbox { label, isOn, toggle } = + H.button + [ HE.onClick (toggle (not isOn)) + , HA.class "cursor-pointer text-green-200 select-none" + , TW.mod "hover" "text-green-100 bg-green-800" + , TW.mod "active" "text-orange" + ] + [ H.text <| checkboxLabel isOn ++ " " ++ label ] diff --git a/tests/Data/FightStrategy/ParserTest.elm b/tests/Data/FightStrategy/ParserTest.elm index c25cec72..d0e18949 100644 --- a/tests/Data/FightStrategy/ParserTest.elm +++ b/tests/Data/FightStrategy/ParserTest.elm @@ -92,6 +92,7 @@ condition = [ ( "op: my HP < 50", "my HP < 50", Just (Operator { value = MyHP, op = LT_, number_ = 50 }) ) , ( "op: my AP >= 3", "my AP >= 3", Just (Operator { value = MyAP, op = GTE, number_ = 3 }) ) , ( "opponent is player", "opponent is player", Just OpponentIsPlayer ) + , ( "opponent is NPC", "opponent is NPC", Just OpponentIsNPC ) , ( "and" , "(my HP < 50 and my AP >= 3)" , Just diff --git a/tests/TestHelpers.elm b/tests/TestHelpers.elm index 67434a2a..1782a880 100644 --- a/tests/TestHelpers.elm +++ b/tests/TestHelpers.elm @@ -164,6 +164,7 @@ conditionFuzzer r = , Fuzz.map2 And conditionFuzzer_ conditionFuzzer_ , Fuzz.map Operator operatorDataFuzzer , Fuzz.constant OpponentIsPlayer + , Fuzz.constant OpponentIsNPC ] diff --git a/yarn.lock b/yarn.lock index f61a62d6..2a8ecde5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,81 @@ # yarn lockfile v1 +"@alloc/quick-lru@^5.2.0": + version "5.2.0" + resolved "https://registry.yarnpkg.com/@alloc/quick-lru/-/quick-lru-5.2.0.tgz#7bf68b20c0a350f936915fcae06f58e32007ce30" + integrity sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw== + +"@isaacs/cliui@^8.0.2": + version "8.0.2" + resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" + integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== + dependencies: + string-width "^5.1.2" + string-width-cjs "npm:string-width@^4.2.0" + strip-ansi "^7.0.1" + strip-ansi-cjs "npm:strip-ansi@^6.0.1" + wrap-ansi "^8.1.0" + wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" + +"@jridgewell/gen-mapping@^0.3.2": + version "0.3.5" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz#dcce6aff74bdf6dad1a95802b69b04a2fcb1fb36" + integrity sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg== + dependencies: + "@jridgewell/set-array" "^1.2.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.24" + +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" + integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== + +"@jridgewell/set-array@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.2.1.tgz#558fb6472ed16a4c850b889530e6b36438c49280" + integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== + +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" + integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== + +"@jridgewell/trace-mapping@^0.3.24": + version "0.3.25" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" + integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@pkgjs/parseargs@^0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" + integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== + "@sindresorhus/is@^2.0.0": version "2.1.1" resolved "https://registry.npmjs.org/@sindresorhus/is/-/is-2.1.1.tgz" @@ -60,6 +135,16 @@ ansi-regex@^5.0.0: resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz" integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-regex@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.1.0.tgz#95ec409c69619d6cb1b8b34f14b660ef28ebd654" + integrity sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA== + ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" @@ -67,6 +152,16 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" +ansi-styles@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + +any-promise@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== + anymatch@~3.1.1: version "3.1.1" resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz" @@ -75,6 +170,19 @@ anymatch@~3.1.1: normalize-path "^3.0.0" picomatch "^2.0.4" +anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +arg@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.2.tgz#c81433cc427c92c4dcf4865142dbca6f15acd59c" + integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg== + at-least-node@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz" @@ -112,6 +220,20 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + +braces@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" + integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== + dependencies: + fill-range "^7.1.1" + braces@~3.0.2: version "3.0.2" resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" @@ -148,6 +270,11 @@ cacheable-request@^7.0.1: normalize-url "^4.1.0" responselike "^2.0.0" +camelcase-css@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5" + integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== + chalk@^4.0.0, chalk@^4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz" @@ -171,6 +298,21 @@ chokidar@^3.4.0: optionalDependencies: fsevents "~2.3.1" +chokidar@^3.5.3: + version "3.6.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" + integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + cli-cursor@^3.1.0: version "3.1.0" resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz" @@ -207,12 +349,17 @@ color-name@~1.1.4: resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +commander@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== + concat-map@0.0.1: version "0.0.1" resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= -cross-spawn@^7.0.3: +cross-spawn@^7.0.0, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -221,6 +368,11 @@ cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + debug@^4.1.1: version "4.3.1" resolved "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz" @@ -247,11 +399,26 @@ defer-to-connect@^2.0.0: resolved "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz" integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== +didyoumean@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037" + integrity sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw== + +dlv@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/dlv/-/dlv-1.1.3.tgz#5c198a8a11453596e751494d49874bc7732f2e79" + integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA== + duplexer3@^0.1.4: version "0.1.4" resolved "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz" integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== + elm-review@^2.5.0: version "2.5.0" resolved "https://registry.npmjs.org/elm-review/-/elm-review-2.5.0.tgz" @@ -286,6 +453,11 @@ emoji-regex@^8.0.0: resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + end-of-stream@^1.1.0: version "1.4.4" resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz" @@ -293,6 +465,17 @@ end-of-stream@^1.1.0: dependencies: once "^1.4.0" +fast-glob@^3.3.0: + version "3.3.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + fast-levenshtein@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-3.0.0.tgz" @@ -305,6 +488,13 @@ fastest-levenshtein@^1.0.7: resolved "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz" integrity sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow== +fastq@^1.6.0: + version "1.17.1" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47" + integrity sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w== + dependencies: + reusify "^1.0.4" + fill-range@^7.0.1: version "7.0.1" resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" @@ -312,6 +502,13 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" +fill-range@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" + integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== + dependencies: + to-regex-range "^5.0.1" + find-up@^4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz" @@ -329,6 +526,14 @@ folder-hash@^3.3.0: graceful-fs "~4.2.0" minimatch "~3.0.4" +foreground-child@^3.1.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.3.0.tgz#0ac8644c06e431439f8561db8ecf29a7b5519c77" + integrity sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg== + dependencies: + cross-spawn "^7.0.0" + signal-exit "^4.0.1" + fs-extra@^9.0.0: version "9.1.0" resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz" @@ -349,6 +554,16 @@ fsevents@~2.3.1: resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== +fsevents@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + get-stream@^5.0.0, get-stream@^5.1.0: version "5.2.0" resolved "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz" @@ -356,13 +571,32 @@ get-stream@^5.0.0, get-stream@^5.1.0: dependencies: pump "^3.0.0" -glob-parent@~5.1.0: +glob-parent@^5.1.2, glob-parent@~5.1.0, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" +glob-parent@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + +glob@^10.3.10: + version "10.4.5" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.5.tgz#f4d9f0b90ffdbab09c9d77f5f29b4262517b0956" + integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg== + dependencies: + foreground-child "^3.1.0" + jackspeak "^3.1.2" + minimatch "^9.0.4" + minipass "^7.1.2" + package-json-from-dist "^1.0.0" + path-scurry "^1.11.1" + glob@^7.1.3, glob@^7.1.4: version "7.1.6" resolved "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz" @@ -406,6 +640,13 @@ has-flag@^4.0.0: resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== +hasown@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" + integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== + dependencies: + function-bind "^1.1.2" + http-cache-semantics@^4.0.0: version "4.1.0" resolved "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz" @@ -436,6 +677,13 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" +is-core-module@^2.13.0: + version "2.15.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.15.1.tgz#a7363a25bee942fefab0de13bf6aa372c82dcc37" + integrity sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ== + dependencies: + hasown "^2.0.2" + is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" @@ -453,6 +701,13 @@ is-glob@^4.0.1, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" +is-glob@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + is-interactive@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz" @@ -473,6 +728,20 @@ isexe@^2.0.0: resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= +jackspeak@^3.1.2: + version "3.4.3" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-3.4.3.tgz#8833a9d89ab4acde6188942bd1c53b6390ed5a8a" + integrity sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + +jiti@^1.21.0: + version "1.21.6" + resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.6.tgz#6c7f7398dd4b3142767f9a168af2f317a428d268" + integrity sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w== + json-buffer@3.0.1: version "3.0.1" resolved "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz" @@ -499,6 +768,21 @@ kleur@^3.0.3: resolved "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== +lilconfig@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52" + integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== + +lilconfig@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-3.1.2.tgz#e4a7c3cb549e3a606c8dcc32e5ae1005e62c05cb" + integrity sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow== + +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + locate-path@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz" @@ -519,6 +803,24 @@ lowercase-keys@^2.0.0: resolved "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz" integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== +lru-cache@^10.2.0: + version "10.4.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" + integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== + +merge2@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +micromatch@^4.0.4, micromatch@^4.0.5: + version "4.0.8" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" + integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== + dependencies: + braces "^3.0.3" + picomatch "^2.3.1" + mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" @@ -541,11 +843,23 @@ minimatch@^3.0.4, minimatch@~3.0.4: dependencies: brace-expansion "^1.1.7" +minimatch@^9.0.4: + version "9.0.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" + integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== + dependencies: + brace-expansion "^2.0.1" + minimist@^1.2.0, minimist@^1.2.5: version "1.2.5" resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707" + integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== + mkdirp@^0.5.1: version "0.5.5" resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz" @@ -558,6 +872,20 @@ ms@2.1.2: resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +mz@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" + integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== + dependencies: + any-promise "^1.0.0" + object-assign "^4.0.1" + thenify-all "^1.0.0" + +nanoid@^3.3.7: + version "3.3.7" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" + integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== + normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" @@ -568,6 +896,16 @@ normalize-url@^4.1.0: resolved "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz" integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ== +object-assign@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + +object-hash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-3.0.0.tgz#73f97f753e7baffc0e2cc9d6e079079744ac82e9" + integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== + once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" @@ -640,6 +978,11 @@ p-try@^2.0.0: resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== +package-json-from-dist@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz#e501cd3094b278495eb4258d4c9f6d5ac3019f00" + integrity sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw== + path-exists@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" @@ -655,11 +998,97 @@ path-key@^3.1.0: resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-scurry@^1.11.1: + version "1.11.1" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.11.1.tgz#7960a668888594a0720b12a911d1a742ab9f11d2" + integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA== + dependencies: + lru-cache "^10.2.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + +picocolors@^1.0.0, picocolors@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.0.tgz#5358b76a78cde483ba5cef6a9dc9671440b27d59" + integrity sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw== + picomatch@^2.0.4, picomatch@^2.2.1: version "2.2.2" resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz" integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== +picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pify@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== + +pirates@^4.0.1: + version "4.0.6" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" + integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== + +postcss-import@^15.1.0: + version "15.1.0" + resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-15.1.0.tgz#41c64ed8cc0e23735a9698b3249ffdbf704adc70" + integrity sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew== + dependencies: + postcss-value-parser "^4.0.0" + read-cache "^1.0.0" + resolve "^1.1.7" + +postcss-js@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-4.0.1.tgz#61598186f3703bab052f1c4f7d805f3991bee9d2" + integrity sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw== + dependencies: + camelcase-css "^2.0.1" + +postcss-load-config@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-4.0.2.tgz#7159dcf626118d33e299f485d6afe4aff7c4a3e3" + integrity sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ== + dependencies: + lilconfig "^3.0.0" + yaml "^2.3.4" + +postcss-nested@^6.0.1: + version "6.2.0" + resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-6.2.0.tgz#4c2d22ab5f20b9cb61e2c5c5915950784d068131" + integrity sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ== + dependencies: + postcss-selector-parser "^6.1.1" + +postcss-selector-parser@^6.0.11, postcss-selector-parser@^6.1.1: + version "6.1.2" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz#27ecb41fb0e3b6ba7a1ec84fff347f734c7929de" + integrity sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-value-parser@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" + integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== + +postcss@^8.4.23: + version "8.4.47" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.47.tgz#5bf6c9a010f3e724c503bf03ef7947dcb0fea365" + integrity sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ== + dependencies: + nanoid "^3.3.7" + picocolors "^1.1.0" + source-map-js "^1.2.1" + prompts@^2.2.1: version "2.4.0" resolved "https://registry.npmjs.org/prompts/-/prompts-2.4.0.tgz" @@ -676,6 +1105,18 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +read-cache@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774" + integrity sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA== + dependencies: + pify "^2.3.0" + readable-stream@^3.4.0: version "3.6.0" resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz" @@ -692,6 +1133,22 @@ readdirp@~3.5.0: dependencies: picomatch "^2.2.1" +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +resolve@^1.1.7, resolve@^1.22.2: + version "1.22.8" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + responselike@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz" @@ -707,6 +1164,11 @@ restore-cursor@^3.1.0: onetime "^5.1.0" signal-exit "^3.0.2" +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + rimraf@~2.6.2: version "2.6.3" resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz" @@ -714,6 +1176,13 @@ rimraf@~2.6.2: dependencies: glob "^7.1.3" +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" @@ -736,11 +1205,30 @@ signal-exit@^3.0.2: resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz" integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== +signal-exit@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== + sisteransi@^1.0.5: version "1.0.5" resolved "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz" integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== +source-map-js@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" + integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== + +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + string-width@^4.1.0: version "4.2.2" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz" @@ -750,6 +1238,15 @@ string-width@^4.1.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.0" +string-width@^5.0.1, string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== + dependencies: + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" + string_decoder@^1.1.1: version "1.3.0" resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" @@ -757,6 +1254,13 @@ string_decoder@^1.1.1: dependencies: safe-buffer "~5.2.0" +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + strip-ansi@^6.0.0: version "6.0.0" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz" @@ -764,6 +1268,33 @@ strip-ansi@^6.0.0: dependencies: ansi-regex "^5.0.0" +strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^7.0.1: + version "7.1.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== + dependencies: + ansi-regex "^6.0.1" + +sucrase@^3.32.0: + version "3.35.0" + resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.35.0.tgz#57f17a3d7e19b36d8995f06679d121be914ae263" + integrity sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA== + dependencies: + "@jridgewell/gen-mapping" "^0.3.2" + commander "^4.0.0" + glob "^10.3.10" + lines-and-columns "^1.1.6" + mz "^2.7.0" + pirates "^4.0.1" + ts-interface-checker "^0.1.9" + supports-color@^7.0.0, supports-color@^7.1.0: version "7.2.0" resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" @@ -779,6 +1310,39 @@ supports-hyperlinks@^2.0.0: has-flag "^4.0.0" supports-color "^7.0.0" +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +tailwindcss@^3.4.12: + version "3.4.12" + resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.4.12.tgz#fd3b67c6d2c04d9d7bfa13e3fc70ccef9fef0455" + integrity sha512-Htf/gHj2+soPb9UayUNci/Ja3d8pTmu9ONTfh4QY8r3MATTZOzmv6UYWF7ZwikEIC8okpfqmGqrmDehua8mF8w== + dependencies: + "@alloc/quick-lru" "^5.2.0" + arg "^5.0.2" + chokidar "^3.5.3" + didyoumean "^1.2.2" + dlv "^1.1.3" + fast-glob "^3.3.0" + glob-parent "^6.0.2" + is-glob "^4.0.3" + jiti "^1.21.0" + lilconfig "^2.1.0" + micromatch "^4.0.5" + normalize-path "^3.0.0" + object-hash "^3.0.0" + picocolors "^1.0.0" + postcss "^8.4.23" + postcss-import "^15.1.0" + postcss-js "^4.0.1" + postcss-load-config "^4.0.1" + postcss-nested "^6.0.1" + postcss-selector-parser "^6.0.11" + resolve "^1.22.2" + sucrase "^3.32.0" + temp@^0.9.1: version "0.9.4" resolved "https://registry.npmjs.org/temp/-/temp-0.9.4.tgz" @@ -795,6 +1359,20 @@ terminal-link@^2.1.1: ansi-escapes "^4.2.1" supports-hyperlinks "^2.0.0" +thenify-all@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" + integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA== + dependencies: + thenify ">= 3.1.0 < 4" + +"thenify@>= 3.1.0 < 4": + version "3.3.1" + resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" + integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== + dependencies: + any-promise "^1.0.0" + to-readable-stream@^2.0.0: version "2.1.0" resolved "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-2.1.0.tgz" @@ -807,6 +1385,11 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" +ts-interface-checker@^0.1.9: + version "0.1.13" + resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699" + integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA== + type-fest@^0.10.0: version "0.10.0" resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.10.0.tgz" @@ -822,7 +1405,7 @@ universalify@^2.0.0: resolved "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz" integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== -util-deprecate@^1.0.1: +util-deprecate@^1.0.1, util-deprecate@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= @@ -841,6 +1424,15 @@ which@^2.0.1, which@^2.0.2: dependencies: isexe "^2.0.0" +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^6.2.0: version "6.2.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz" @@ -850,7 +1442,21 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== + dependencies: + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" + wrappy@1: version "1.0.2" resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +yaml@^2.3.4: + version "2.5.1" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.5.1.tgz#c9772aacf62cb7494a95b0c4f1fb065b563db130" + integrity sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==