SadP0i commited on
Commit
bb71914
β€’
1 Parent(s): aedd20b

Upload 3 files

Browse files
Files changed (3) hide show
  1. README.md +4 -3
  2. index.html +517 -18
  3. styles.css +928 -0
README.md CHANGED
@@ -1,11 +1,12 @@
1
  ---
2
  title: GGUF Model VRAM Calculator
3
- emoji: 🐒
4
- colorFrom: blue
5
- colorTo: indigo
6
  sdk: static
7
  pinned: false
8
  license: mit
9
  ---
10
 
11
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
1
  ---
2
  title: GGUF Model VRAM Calculator
3
+ emoji: πŸ“ˆ
4
+ colorFrom: gray
5
+ colorTo: purple
6
  sdk: static
7
  pinned: false
8
  license: mit
9
  ---
10
 
11
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
12
+ Check out the original calculator at https://huggingface.co/spaces/NyxKrage/LLM-Model-VRAM-Calculator
index.html CHANGED
@@ -1,19 +1,518 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  </html>
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <script>
7
+ function strToHtml(str) {
8
+ let parser = new DOMParser();
9
+ return parser.parseFromString(str, "text/html");
10
+ }
11
+
12
+ //Short, jQuery-independent function to read html table and write them into an Array.
13
+ //Kudos to RobG at StackOverflow
14
+ function tableToObj(table) {
15
+ var rows = table.rows;
16
+ var propCells = rows[0].cells;
17
+ var propNames = [];
18
+ var results = [];
19
+ var obj, row, cells;
20
+
21
+ // Use the first row for the property names
22
+ // Could use a header section but result is the same if
23
+ // there is only one header row
24
+ for (var i = 0, iLen = propCells.length; i < iLen; i++) {
25
+ propNames.push(
26
+ (propCells[i].textContent || propCells[i].innerText).trim()
27
+ );
28
+ }
29
+
30
+ // Use the rows for data
31
+ // Could use tbody rows here to exclude header & footer
32
+ // but starting from 1 gives required result
33
+ for (var j = 1, jLen = rows.length; j < jLen; j++) {
34
+ cells = rows[j].cells;
35
+ obj = {};
36
+
37
+ for (var k = 0; k < iLen; k++) {
38
+ obj[propNames[k]] = (
39
+ cells[k].textContent || cells[k].innerText
40
+ ).trim();
41
+ }
42
+ results.push(obj);
43
+ }
44
+ return results;
45
+ }
46
+
47
+ function formatGpu(gpus) {
48
+ return gpus.map(
49
+ (g) => `${g["Product Name"]} - ${g["Memory"].split(",")[0]}`
50
+ );
51
+ }
52
+
53
+ const gguf_quants = {
54
+ "Q2_K": 3.35,
55
+ "Q3_K_S": 3.5,
56
+ "Q3_K_M": 3.91,
57
+ "Q3_K_L": 4.27,
58
+ "Q4_0": 4.55,
59
+ "Q4_K_S": 4.58,
60
+ "Q4_K_M": 4.85,
61
+ "Q5_0": 5.54,
62
+ "Q5_K_S": 5.54,
63
+ "Q5_K_M": 5.69,
64
+ "Q6_K": 6.59,
65
+ "Q8_0": 8.5,
66
+ }
67
+
68
+ async function modelConfig(hf_model) {
69
+ let config = await fetch(
70
+ `https://huggingface.co/${hf_model}/raw/main/config.json`
71
+ ).then(r => r.json())
72
+ let model_size = 0
73
+ try {
74
+ model_size = (await fetch(`https://huggingface.co/${hf_model}/resolve/main/model.safetensors.index.json`).then(r => r.json()))["metadata"]["total_size"] / 2
75
+ if (isNaN(model_size)) {
76
+ throw new Erorr("no size in safetensors metadata")
77
+ }
78
+ } catch (e) {
79
+ try {
80
+ model_size = (await fetch(`https://huggingface.co/${hf_model}/resolve/main/pytorch_model.bin.index.json`).then(r => r.json()))["metadata"]["total_size"] / 2
81
+ if (isNaN(model_size)) {
82
+ throw new Erorr("no size in pytorch metadata")
83
+ }
84
+ } catch {
85
+ let model_page = await fetch(
86
+ "https://corsproxy.io/?" + encodeURIComponent(`https://huggingface.co/${hf_model}`)
87
+ ).then(r => r.text())
88
+ let el = document.createElement( 'html' );
89
+ el.innerHTML = model_page
90
+ let params_el = el.querySelector('div[data-target="ModelSafetensorsParams"]')
91
+ if (params_el !== null) {
92
+ model_size = JSON.parse(params_el.attributes.getNamedItem("data-props").value)["safetensors"]["total"]
93
+ } else {
94
+ params_el = el.querySelector('div[data-target="ModelHeader"]')
95
+ model_size = JSON.parse(params_el.attributes.getNamedItem("data-props").value)["model"]["safetensors"]["total"]
96
+ }
97
+ }
98
+ }
99
+ config.parameters = model_size
100
+ return config
101
+ }
102
+
103
+ function inputBuffer(context=8192, model_config, bsz=512) {
104
+ /* Calculation taken from github:ggerganov/llama.cpp/llama.cpp:11248
105
+ ctx->inp_tokens = ggml_new_tensor_1d(ctx->ctx_input, GGML_TYPE_I32, cparams.n_batch);
106
+ ctx->inp_embd = ggml_new_tensor_2d(ctx->ctx_input, GGML_TYPE_F32, hparams.n_embd, cparams.n_batch);
107
+ ctx->inp_pos = ggml_new_tensor_1d(ctx->ctx_input, GGML_TYPE_I32, cparams.n_batch);
108
+ ctx->inp_KQ_mask = ggml_new_tensor_2d(ctx->ctx_input, GGML_TYPE_F32, cparams.n_ctx, cparams.n_batch);
109
+ ctx->inp_K_shift = ggml_new_tensor_1d(ctx->ctx_input, GGML_TYPE_I32, cparams.n_ctx);
110
+ ctx->inp_sum = ggml_new_tensor_2d(ctx->ctx_input, GGML_TYPE_F32, 1, cparams.n_batch);
111
+
112
+ n_embd is hidden size (github:ggeranov/llama.cpp/convert.py:248)
113
+ */
114
+ const inp_tokens = bsz
115
+ const inp_embd = model_config["hidden_size"] * bsz
116
+ const inp_pos = bsz
117
+ const inp_KQ_mask = context * bsz
118
+ const inp_K_shift = context
119
+ const inp_sum = bsz
120
+
121
+ return inp_tokens + inp_embd + inp_pos + inp_KQ_mask + inp_K_shift + inp_sum
122
+ }
123
+
124
+ function computeBuffer(context=8192, model_config, bsz=512) {
125
+ if (bsz != 512) {
126
+ alert("batch size other than 512 is currently not supported for the compute buffer, using batchsize 512 for compute buffer calculation, end result result will be an overestimatition")
127
+ }
128
+ return (context / 1024 * 2 + 0.75) * model_config["num_attention_heads"] * 1024 * 1024
129
+ }
130
+
131
+ function kvCache(context=8192, model_config, cache_bit=16) {
132
+ const n_gqa = model_config["num_attention_heads"] / model_config["num_key_value_heads"]
133
+ const n_embd_gqa = model_config["hidden_size"] / n_gqa
134
+ const n_elements = n_embd_gqa * (model_config["num_hidden_layers"] * context)
135
+ const size = 2 * n_elements
136
+ return size * (cache_bit / 8)
137
+ }
138
+
139
+ function contextSize(context=8192, model_config, bsz=512, cache_bit=16) {
140
+ return Number.parseFloat((inputBuffer(context, model_config, bsz) + kvCache(context, model_config, cache_bit) + computeBuffer(context, model_config, bsz)).toFixed(2))
141
+ }
142
+
143
+ function modelSize(model_config, bpw=4.5) {
144
+ return Number.parseFloat((model_config["parameters"] * bpw / 8).toFixed(2))
145
+ }
146
+
147
+ async function calculateSizes(format) {
148
+
149
+ format = "gguf"
150
+
151
+ try {
152
+ const model_config = await modelConfig(document.getElementById("modelsearch").value)
153
+ const context = parseInt(document.getElementById("contextsize").value)
154
+ let bsz = 512
155
+ let cache_bit = 16
156
+ let bpw = 0
157
+ if (format === "gguf") {
158
+ bsz = parseInt(document.getElementById("batchsize").value)
159
+ bpw = gguf_quants[document.getElementById("quantsize").innerText]
160
+
161
+ } else if (format == "exl2") {
162
+ cache_bit = Number.parseInt(document.getElementById("kvCache").value)
163
+ bpw = Number.parseFloat(document.getElementById("bpw").value)
164
+ }
165
+
166
+ const model_size = modelSize(model_config, bpw)
167
+ const context_size = contextSize(context, model_config, bsz, cache_bit)
168
+ const total_size = ((model_size + context_size) / 2**30)
169
+ document.getElementById("resultmodel").innerText = (model_size / 2**30).toFixed(2)
170
+ document.getElementById("resultcontext").innerText = (context_size / 2**30).toFixed(2)
171
+ const result_total_el = document.getElementById("resulttotal");
172
+ result_total_el.innerText = total_size.toFixed(2)
173
+
174
+ //const gpu = document.getElementById("gpusearch").value
175
+ // if (gpu !== "") {
176
+ // const vram = parseFloat(gpu.split("-")[1].replace("GB", "").trim())
177
+ // if (vram - total_size > 0.5) {
178
+ // result_total_el.style.backgroundColor = "#bef264"
179
+ // } else if (vram - total_size > 0) {
180
+ // result_total_el.style.backgroundColor = "#facc15"
181
+ // } else {
182
+ // result_total_el.style.backgroundColor = "#ef4444"
183
+ // }
184
+ // }
185
+
186
+ const allocated_vram = Number.parseInt(document.getElementById("maxvram").value);
187
+ const vram = allocated_vram
188
+ if (vram - total_size > 0.5) {
189
+ result_total_el.style.backgroundColor = "#bef264"
190
+ } else if (vram - total_size > 0) {
191
+ result_total_el.style.backgroundColor = "#facc15"
192
+ } else {
193
+ result_total_el.style.backgroundColor = "#ef4444"
194
+ }
195
+
196
+ const layer_size = ((model_size / 2**30) / model_config["num_hidden_layers"])
197
+ const layer_size_el = document.getElementById("layersize");
198
+ layer_size_el.innerText = layer_size.toFixed(2)
199
+
200
+ const layers_offload = Math.floor((allocated_vram - (context_size / 2**30)) / layer_size)
201
+
202
+ const layers_offload_el = document.getElementById("layersoffload");
203
+ layers_offload_el.innerText = layers_offload > model_config["num_hidden_layers"] ? model_config["num_hidden_layers"] : Math.max(0, layers_offload)
204
+
205
+ } catch(e) {
206
+ alert(e);
207
+ }
208
+ }
209
+ </script>
210
+ <link href="./styles.css" rel="stylesheet">
211
+ <title>Can I split it? - GGUF VRAM Calculator</title>
212
+ </head>
213
+ <body class="p-8">
214
+ <div x-data="{ format: 'gguf' }" class="flex flex-col max-h-screen items-center mt-16 gap-10">
215
+ <div style="text-align: center;">
216
+ <h1 class="text-xl font-semibold leading-6 text-gray-900">
217
+ GGUF Model, Can I split it?
218
+ </h1>
219
+ <h3 class="font-semibold leading-6 text-gray-900">
220
+ Based on NyxKrage's LLM VRAM calculator
221
+ </h3>
222
+ </div>
223
+ <div class="flex flex-col gap-10">
224
+ <div class="w-auto flex flex-col gap-4">
225
+ <div class="relative">
226
+ <label
227
+ for="maxvram"
228
+ class="absolute -top-2 left-2 inline-block bg-white px-1 text-xs font-medium text-gray-900"
229
+ >
230
+ Max Allocated VRAM
231
+ </label>
232
+ <input
233
+ value="24"
234
+ type="number"
235
+ name="maxvram"
236
+ id="maxvram"
237
+ step="1"
238
+ class="block w-full rounded-md border-0 p-3 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
239
+ />
240
+ </div>
241
+
242
+ <!-- Model Selector -->
243
+
244
+
245
+ <div class="flex flex-row gap-4 relative">
246
+ <label
247
+ for="contextsize"
248
+ class="absolute -top-2 left-2 inline-block bg-white px-1 text-xs font-medium text-gray-900"
249
+ >
250
+ Model (unquantized)
251
+ </label>
252
+ <div
253
+ class="block w-full rounded-md border-0 p-3 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
254
+ x-data="{
255
+ open: false,
256
+ value: 'Nexusflow/Starling-LM-7B-beta',
257
+ results: null,
258
+ toggle() {
259
+ if (this.open) {
260
+ return this.close()
261
+ }
262
+
263
+ this.$refs.input.focus()
264
+
265
+ this.open = true
266
+ },
267
+ close(focusAfter) {
268
+ if (! this.open) return
269
+
270
+ this.open = false
271
+
272
+ focusAfter && focusAfter.focus()
273
+ }
274
+ }"
275
+ x-on:keydown.escape.prevent.stop="close($refs.input)"
276
+ x-id="['model-typeahead']"
277
+ class="relative"
278
+ >
279
+ <!-- Input -->
280
+ <input
281
+ id="modelsearch"
282
+ x-ref="input"
283
+ x-on:click="toggle()"
284
+ @keypress.debounce.150ms="results = (await
285
+ fetch('https://huggingface.co/api/quicksearch?type=model&q=' +
286
+ encodeURIComponent(value)).then(r => r.json())).models.filter(m => !m.id.includes('GGUF') && !m.id.includes('AWQ') && !m.id.includes('GPTQ') && !m.id.includes('exl2'));"
287
+ :aria-expanded="open"
288
+ :aria-controls="$id('model-typeahead')"
289
+ x-model="value"
290
+ class="flex justify-between items-center gap-2 w-full"
291
+ />
292
+
293
+ <!-- Panel -->
294
+ <div
295
+ x-ref="panel"
296
+ x-show="open"
297
+ x-transition.origin.top.left
298
+ x-on:click.outside="close($refs.input)"
299
+ :id="$id('model-typeahead')"
300
+ style="display: none"
301
+ class="absolute left-0 mt-4 w-full rounded-md bg-white shadow-sm ring-1 ring-inset ring-gray-300 z-10"
302
+ >
303
+ <template x-for="result in results">
304
+ <a
305
+ @click="value = result.id; close($refs.input)"
306
+ x-text="result.id"
307
+ class="flex cursor-pointer items-center gap-2 w-full first-of-type:rounded-t-md last-of-type:rounded-b-md px-4 py-2.5 text-left text-sm hover:bg-gray-500/5 disabled:text-gray-500"
308
+ ></a>
309
+ </template>
310
+ </div>
311
+ </div>
312
+ </div>
313
+
314
+
315
+ <!-- Context Size Selector -->
316
+ <div class="relative">
317
+ <label
318
+ for="contextsize"
319
+ class="absolute -top-2 left-2 inline-block bg-white px-1 text-xs font-medium text-gray-900"
320
+ >
321
+ Context Size
322
+ </label>
323
+ <input
324
+ value="8192"
325
+ type="number"
326
+ name="contextsize"
327
+ id="contextsize"
328
+ step="1024"
329
+ class="block w-full rounded-md border-0 p-3 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
330
+ />
331
+ </div>
332
+ <!-- GGUF Options -->
333
+ <div x-show="format === 'gguf'" class="relative">
334
+ <div class="flex flex-row gap-4">
335
+ <label
336
+ for="contextsize"
337
+ class="absolute -top-2 left-2 inline-block bg-white px-1 text-xs font-medium text-gray-900"
338
+ >
339
+ Quantization Size
340
+ </label>
341
+ <div
342
+ class="block w-full rounded-md border-0 p-3 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
343
+ x-data="{
344
+ open: false,
345
+ value: '',
346
+ toggle() {
347
+ if (this.open) {
348
+ return this.close()
349
+ }
350
+
351
+ this.$refs.button.focus()
352
+
353
+ this.open = true
354
+ },
355
+ close(focusAfter) {
356
+ if (! this.open) return
357
+
358
+ this.open = false
359
+
360
+ focusAfter && focusAfter.focus()
361
+ }
362
+ }"
363
+ x-on:keydown.escape.prevent.stop="close($refs.button)"
364
+ x-id="['dropdown-button']"
365
+ class="relative"
366
+ >
367
+ <!-- Button -->
368
+ <button
369
+ x-ref="button"
370
+ x-on:click="toggle()"
371
+ :aria-expanded="open"
372
+ :aria-controls="$id('dropdown-button')"
373
+ type="button"
374
+ id="quantsize"
375
+ x-text="value.length === 0 ? 'Q4_K_S' : value"
376
+ class="flex justify-between items-center gap-2 w-full"
377
+ >
378
+ Q4_K_S
379
+
380
+ <!-- Heroicon: chevron-down -->
381
+ <svg
382
+ xmlns="http://www.w3.org/2000/svg"
383
+ class="h-5 w-5 text-gray-400"
384
+ viewBox="0 0 20 20"
385
+ fill="currentColor"
386
+ >
387
+ <path
388
+ fill-rule="evenodd"
389
+ d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
390
+ clip-rule="evenodd"
391
+ />
392
+ </svg>
393
+ </button>
394
+
395
+ <!-- Panel -->
396
+ <div
397
+ x-data="{ quants: [
398
+ 'Q3_K_S',
399
+ 'Q3_K_M',
400
+ 'Q3_K_L',
401
+ 'Q4_0',
402
+ 'Q4_K_S',
403
+ 'Q4_K_M',
404
+ 'Q5_0',
405
+ 'Q5_K_S',
406
+ 'Q5_K_M',
407
+ 'Q6_K',
408
+ 'Q8_0'
409
+ ]}"
410
+ x-ref="panel"
411
+ x-show="open"
412
+ x-transition.origin.top.left
413
+ x-on:click.outside="close($refs.button)"
414
+ :id="$id('dropdown-button')"
415
+ style="display: none"
416
+ class="absolute left-0 mt-4 w-full rounded-md bg-white shadow-sm ring-1 ring-inset ring-gray-300 z-10"
417
+ >
418
+ <template x-for="quant in quants">
419
+ <a
420
+ @click="value = quant; close($refs.button)"
421
+ x-text="quant"
422
+ class="flex cursor-pointer items-center gap-2 w-full first-of-type:rounded-t-md last-of-type:rounded-b-md px-4 py-2.5 text-left text-sm hover:bg-gray-500/5 disabled:text-gray-500"
423
+ ></a>
424
+ </template>
425
+ </div>
426
+ </div>
427
+ <div class="relative">
428
+ <label
429
+ for="batchsize"
430
+ class="absolute -top-2 left-2 inline-block bg-white px-1 text-xs font-medium text-gray-900"
431
+ >
432
+ Batch Size
433
+ </label>
434
+ <input
435
+ value="512"
436
+ type="number"
437
+ step="128"
438
+ id="batchsize"
439
+ class="block w-full rounded-md border-0 p-3 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
440
+ />
441
+ </div>
442
+ </div>
443
+ </div>
444
+ <button
445
+ type="button"
446
+ class="rounded-md bg-slate-800 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-slate-700 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
447
+ @click="calculateSizes(format)"
448
+ >
449
+ Submit
450
+ </button>
451
+ </div>
452
+ <div class="w-auto flex flex-col gap-4">
453
+ <div class="relative">
454
+ <label
455
+ class="absolute -top-2 left-2 inline-block bg-white px-1 text-xs font-medium text-gray-900"
456
+ >
457
+ Model Size (GB)
458
+ </label>
459
+ <div
460
+ id="resultmodel"
461
+ class="block w-full rounded-md border-0 p-3 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
462
+ >4.20</div>
463
+ </div>
464
+ <div class="relative">
465
+ <label
466
+ class="absolute -top-2 left-2 inline-block bg-white px-1 text-xs font-medium text-gray-900"
467
+ >
468
+ Context Size (GB)
469
+ </label>
470
+ <div
471
+ id="resultcontext"
472
+ class="block w-full rounded-md border-0 p-3 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
473
+ >6.90</div>
474
+ </div>
475
+ <div class="relative">
476
+ <label
477
+ class="absolute -top-2 left-2 inline-block bg-white px-1 text-xs font-medium text-gray-900"
478
+ >
479
+ Total Size (GB)
480
+ </label>
481
+ <div
482
+ id="resulttotal"
483
+ class="block w-full rounded-md border-0 p-3 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
484
+ >420.69</div>
485
+ </div>
486
+ <div class="relative">
487
+ <label
488
+ class="absolute -top-2 left-2 inline-block bg-white px-1 text-xs font-medium text-gray-900"
489
+ >
490
+ Layer size (GB)
491
+ </label>
492
+ <div
493
+ id="layersize"
494
+ class="block w-full rounded-md border-0 p-3 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
495
+ >42.69</div>
496
+ </div>
497
+ <div class="relative">
498
+ <label
499
+ class="absolute -top-2 left-2 inline-block bg-white px-1 text-xs font-medium text-gray-900"
500
+ >
501
+ Layers offloaded to GPU
502
+ </label>
503
+ <div
504
+ id="layersoffload"
505
+ class="block w-full rounded-md border-0 p-3 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
506
+ >42</div>
507
+ </div>
508
+ </div>
509
+ </div>
510
+ </div>
511
+ <script
512
+ src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"
513
+ ></script>
514
+ <script defer>
515
+ calculateSizes("gguf")
516
+ </script>
517
+ </body>
518
  </html>
styles.css ADDED
@@ -0,0 +1,928 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ ! tailwindcss v3.4.1 | MIT License | https://tailwindcss.com
3
+ */
4
+
5
+ /*
6
+ 1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
7
+ 2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
8
+ */
9
+
10
+ *,
11
+ ::before,
12
+ ::after {
13
+ box-sizing: border-box;
14
+ /* 1 */
15
+ border-width: 0;
16
+ /* 2 */
17
+ border-style: solid;
18
+ /* 2 */
19
+ border-color: #e5e7eb;
20
+ /* 2 */
21
+ }
22
+
23
+ ::before,
24
+ ::after {
25
+ --tw-content: '';
26
+ }
27
+
28
+ /*
29
+ 1. Use a consistent sensible line-height in all browsers.
30
+ 2. Prevent adjustments of font size after orientation changes in iOS.
31
+ 3. Use a more readable tab size.
32
+ 4. Use the user's configured `sans` font-family by default.
33
+ 5. Use the user's configured `sans` font-feature-settings by default.
34
+ 6. Use the user's configured `sans` font-variation-settings by default.
35
+ 7. Disable tap highlights on iOS
36
+ */
37
+
38
+ html,
39
+ :host {
40
+ line-height: 1.5;
41
+ /* 1 */
42
+ -webkit-text-size-adjust: 100%;
43
+ /* 2 */
44
+ -moz-tab-size: 4;
45
+ /* 3 */
46
+ -o-tab-size: 4;
47
+ tab-size: 4;
48
+ /* 3 */
49
+ font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
50
+ /* 4 */
51
+ font-feature-settings: normal;
52
+ /* 5 */
53
+ font-variation-settings: normal;
54
+ /* 6 */
55
+ -webkit-tap-highlight-color: transparent;
56
+ /* 7 */
57
+ }
58
+
59
+ /*
60
+ 1. Remove the margin in all browsers.
61
+ 2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.
62
+ */
63
+
64
+ body {
65
+ margin: 0;
66
+ /* 1 */
67
+ line-height: inherit;
68
+ /* 2 */
69
+ }
70
+
71
+ /*
72
+ 1. Add the correct height in Firefox.
73
+ 2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
74
+ 3. Ensure horizontal rules are visible by default.
75
+ */
76
+
77
+ hr {
78
+ height: 0;
79
+ /* 1 */
80
+ color: inherit;
81
+ /* 2 */
82
+ border-top-width: 1px;
83
+ /* 3 */
84
+ }
85
+
86
+ /*
87
+ Add the correct text decoration in Chrome, Edge, and Safari.
88
+ */
89
+
90
+ abbr:where([title]) {
91
+ -webkit-text-decoration: underline dotted;
92
+ text-decoration: underline dotted;
93
+ }
94
+
95
+ /*
96
+ Remove the default font size and weight for headings.
97
+ */
98
+
99
+ h1,
100
+ h2,
101
+ h3,
102
+ h4,
103
+ h5,
104
+ h6 {
105
+ font-size: inherit;
106
+ font-weight: inherit;
107
+ }
108
+
109
+ /*
110
+ Reset links to optimize for opt-in styling instead of opt-out.
111
+ */
112
+
113
+ a {
114
+ color: inherit;
115
+ text-decoration: inherit;
116
+ }
117
+
118
+ /*
119
+ Add the correct font weight in Edge and Safari.
120
+ */
121
+
122
+ b,
123
+ strong {
124
+ font-weight: bolder;
125
+ }
126
+
127
+ /*
128
+ 1. Use the user's configured `mono` font-family by default.
129
+ 2. Use the user's configured `mono` font-feature-settings by default.
130
+ 3. Use the user's configured `mono` font-variation-settings by default.
131
+ 4. Correct the odd `em` font sizing in all browsers.
132
+ */
133
+
134
+ code,
135
+ kbd,
136
+ samp,
137
+ pre {
138
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
139
+ /* 1 */
140
+ font-feature-settings: normal;
141
+ /* 2 */
142
+ font-variation-settings: normal;
143
+ /* 3 */
144
+ font-size: 1em;
145
+ /* 4 */
146
+ }
147
+
148
+ /*
149
+ Add the correct font size in all browsers.
150
+ */
151
+
152
+ small {
153
+ font-size: 80%;
154
+ }
155
+
156
+ /*
157
+ Prevent `sub` and `sup` elements from affecting the line height in all browsers.
158
+ */
159
+
160
+ sub,
161
+ sup {
162
+ font-size: 75%;
163
+ line-height: 0;
164
+ position: relative;
165
+ vertical-align: baseline;
166
+ }
167
+
168
+ sub {
169
+ bottom: -0.25em;
170
+ }
171
+
172
+ sup {
173
+ top: -0.5em;
174
+ }
175
+
176
+ /*
177
+ 1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
178
+ 2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
179
+ 3. Remove gaps between table borders by default.
180
+ */
181
+
182
+ table {
183
+ text-indent: 0;
184
+ /* 1 */
185
+ border-color: inherit;
186
+ /* 2 */
187
+ border-collapse: collapse;
188
+ /* 3 */
189
+ }
190
+
191
+ /*
192
+ 1. Change the font styles in all browsers.
193
+ 2. Remove the margin in Firefox and Safari.
194
+ 3. Remove default padding in all browsers.
195
+ */
196
+
197
+ button,
198
+ input,
199
+ optgroup,
200
+ select,
201
+ textarea {
202
+ font-family: inherit;
203
+ /* 1 */
204
+ font-feature-settings: inherit;
205
+ /* 1 */
206
+ font-variation-settings: inherit;
207
+ /* 1 */
208
+ font-size: 100%;
209
+ /* 1 */
210
+ font-weight: inherit;
211
+ /* 1 */
212
+ line-height: inherit;
213
+ /* 1 */
214
+ color: inherit;
215
+ /* 1 */
216
+ margin: 0;
217
+ /* 2 */
218
+ padding: 0;
219
+ /* 3 */
220
+ }
221
+
222
+ /*
223
+ Remove the inheritance of text transform in Edge and Firefox.
224
+ */
225
+
226
+ button,
227
+ select {
228
+ text-transform: none;
229
+ }
230
+
231
+ /*
232
+ 1. Correct the inability to style clickable types in iOS and Safari.
233
+ 2. Remove default button styles.
234
+ */
235
+
236
+ button,
237
+ [type='button'],
238
+ [type='reset'],
239
+ [type='submit'] {
240
+ -webkit-appearance: button;
241
+ /* 1 */
242
+ background-color: transparent;
243
+ /* 2 */
244
+ background-image: none;
245
+ /* 2 */
246
+ }
247
+
248
+ /*
249
+ Use the modern Firefox focus style for all focusable elements.
250
+ */
251
+
252
+ :-moz-focusring {
253
+ outline: auto;
254
+ }
255
+
256
+ /*
257
+ Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
258
+ */
259
+
260
+ :-moz-ui-invalid {
261
+ box-shadow: none;
262
+ }
263
+
264
+ /*
265
+ Add the correct vertical alignment in Chrome and Firefox.
266
+ */
267
+
268
+ progress {
269
+ vertical-align: baseline;
270
+ }
271
+
272
+ /*
273
+ Correct the cursor style of increment and decrement buttons in Safari.
274
+ */
275
+
276
+ ::-webkit-inner-spin-button,
277
+ ::-webkit-outer-spin-button {
278
+ height: auto;
279
+ }
280
+
281
+ /*
282
+ 1. Correct the odd appearance in Chrome and Safari.
283
+ 2. Correct the outline style in Safari.
284
+ */
285
+
286
+ [type='search'] {
287
+ -webkit-appearance: textfield;
288
+ /* 1 */
289
+ outline-offset: -2px;
290
+ /* 2 */
291
+ }
292
+
293
+ /*
294
+ Remove the inner padding in Chrome and Safari on macOS.
295
+ */
296
+
297
+ ::-webkit-search-decoration {
298
+ -webkit-appearance: none;
299
+ }
300
+
301
+ /*
302
+ 1. Correct the inability to style clickable types in iOS and Safari.
303
+ 2. Change font properties to `inherit` in Safari.
304
+ */
305
+
306
+ ::-webkit-file-upload-button {
307
+ -webkit-appearance: button;
308
+ /* 1 */
309
+ font: inherit;
310
+ /* 2 */
311
+ }
312
+
313
+ /*
314
+ Add the correct display in Chrome and Safari.
315
+ */
316
+
317
+ summary {
318
+ display: list-item;
319
+ }
320
+
321
+ /*
322
+ Removes the default spacing and border for appropriate elements.
323
+ */
324
+
325
+ blockquote,
326
+ dl,
327
+ dd,
328
+ h1,
329
+ h2,
330
+ h3,
331
+ h4,
332
+ h5,
333
+ h6,
334
+ hr,
335
+ figure,
336
+ p,
337
+ pre {
338
+ margin: 0;
339
+ }
340
+
341
+ fieldset {
342
+ margin: 0;
343
+ padding: 0;
344
+ }
345
+
346
+ legend {
347
+ padding: 0;
348
+ }
349
+
350
+ ol,
351
+ ul,
352
+ menu {
353
+ list-style: none;
354
+ margin: 0;
355
+ padding: 0;
356
+ }
357
+
358
+ /*
359
+ Reset default styling for dialogs.
360
+ */
361
+
362
+ dialog {
363
+ padding: 0;
364
+ }
365
+
366
+ /*
367
+ Prevent resizing textareas horizontally by default.
368
+ */
369
+
370
+ textarea {
371
+ resize: vertical;
372
+ }
373
+
374
+ /*
375
+ 1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
376
+ 2. Set the default placeholder color to the user's configured gray 400 color.
377
+ */
378
+
379
+ input::-moz-placeholder, textarea::-moz-placeholder {
380
+ opacity: 1;
381
+ /* 1 */
382
+ color: #9ca3af;
383
+ /* 2 */
384
+ }
385
+
386
+ input::placeholder,
387
+ textarea::placeholder {
388
+ opacity: 1;
389
+ /* 1 */
390
+ color: #9ca3af;
391
+ /* 2 */
392
+ }
393
+
394
+ /*
395
+ Set the default cursor for buttons.
396
+ */
397
+
398
+ button,
399
+ [role="button"] {
400
+ cursor: pointer;
401
+ }
402
+
403
+ /*
404
+ Make sure disabled buttons don't get the pointer cursor.
405
+ */
406
+
407
+ :disabled {
408
+ cursor: default;
409
+ }
410
+
411
+ /*
412
+ 1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)
413
+ 2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)
414
+ This can trigger a poorly considered lint error in some tools but is included by design.
415
+ */
416
+
417
+ img,
418
+ svg,
419
+ video,
420
+ canvas,
421
+ audio,
422
+ iframe,
423
+ embed,
424
+ object {
425
+ display: block;
426
+ /* 1 */
427
+ vertical-align: middle;
428
+ /* 2 */
429
+ }
430
+
431
+ /*
432
+ Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
433
+ */
434
+
435
+ img,
436
+ video {
437
+ max-width: 100%;
438
+ height: auto;
439
+ }
440
+
441
+ /* Make elements with the HTML hidden attribute stay hidden by default */
442
+
443
+ [hidden] {
444
+ display: none;
445
+ }
446
+
447
+ *, ::before, ::after {
448
+ --tw-border-spacing-x: 0;
449
+ --tw-border-spacing-y: 0;
450
+ --tw-translate-x: 0;
451
+ --tw-translate-y: 0;
452
+ --tw-rotate: 0;
453
+ --tw-skew-x: 0;
454
+ --tw-skew-y: 0;
455
+ --tw-scale-x: 1;
456
+ --tw-scale-y: 1;
457
+ --tw-pan-x: ;
458
+ --tw-pan-y: ;
459
+ --tw-pinch-zoom: ;
460
+ --tw-scroll-snap-strictness: proximity;
461
+ --tw-gradient-from-position: ;
462
+ --tw-gradient-via-position: ;
463
+ --tw-gradient-to-position: ;
464
+ --tw-ordinal: ;
465
+ --tw-slashed-zero: ;
466
+ --tw-numeric-figure: ;
467
+ --tw-numeric-spacing: ;
468
+ --tw-numeric-fraction: ;
469
+ --tw-ring-inset: ;
470
+ --tw-ring-offset-width: 0px;
471
+ --tw-ring-offset-color: #fff;
472
+ --tw-ring-color: rgb(59 130 246 / 0.5);
473
+ --tw-ring-offset-shadow: 0 0 #0000;
474
+ --tw-ring-shadow: 0 0 #0000;
475
+ --tw-shadow: 0 0 #0000;
476
+ --tw-shadow-colored: 0 0 #0000;
477
+ --tw-blur: ;
478
+ --tw-brightness: ;
479
+ --tw-contrast: ;
480
+ --tw-grayscale: ;
481
+ --tw-hue-rotate: ;
482
+ --tw-invert: ;
483
+ --tw-saturate: ;
484
+ --tw-sepia: ;
485
+ --tw-drop-shadow: ;
486
+ --tw-backdrop-blur: ;
487
+ --tw-backdrop-brightness: ;
488
+ --tw-backdrop-contrast: ;
489
+ --tw-backdrop-grayscale: ;
490
+ --tw-backdrop-hue-rotate: ;
491
+ --tw-backdrop-invert: ;
492
+ --tw-backdrop-opacity: ;
493
+ --tw-backdrop-saturate: ;
494
+ --tw-backdrop-sepia: ;
495
+ }
496
+
497
+ ::backdrop {
498
+ --tw-border-spacing-x: 0;
499
+ --tw-border-spacing-y: 0;
500
+ --tw-translate-x: 0;
501
+ --tw-translate-y: 0;
502
+ --tw-rotate: 0;
503
+ --tw-skew-x: 0;
504
+ --tw-skew-y: 0;
505
+ --tw-scale-x: 1;
506
+ --tw-scale-y: 1;
507
+ --tw-pan-x: ;
508
+ --tw-pan-y: ;
509
+ --tw-pinch-zoom: ;
510
+ --tw-scroll-snap-strictness: proximity;
511
+ --tw-gradient-from-position: ;
512
+ --tw-gradient-via-position: ;
513
+ --tw-gradient-to-position: ;
514
+ --tw-ordinal: ;
515
+ --tw-slashed-zero: ;
516
+ --tw-numeric-figure: ;
517
+ --tw-numeric-spacing: ;
518
+ --tw-numeric-fraction: ;
519
+ --tw-ring-inset: ;
520
+ --tw-ring-offset-width: 0px;
521
+ --tw-ring-offset-color: #fff;
522
+ --tw-ring-color: rgb(59 130 246 / 0.5);
523
+ --tw-ring-offset-shadow: 0 0 #0000;
524
+ --tw-ring-shadow: 0 0 #0000;
525
+ --tw-shadow: 0 0 #0000;
526
+ --tw-shadow-colored: 0 0 #0000;
527
+ --tw-blur: ;
528
+ --tw-brightness: ;
529
+ --tw-contrast: ;
530
+ --tw-grayscale: ;
531
+ --tw-hue-rotate: ;
532
+ --tw-invert: ;
533
+ --tw-saturate: ;
534
+ --tw-sepia: ;
535
+ --tw-drop-shadow: ;
536
+ --tw-backdrop-blur: ;
537
+ --tw-backdrop-brightness: ;
538
+ --tw-backdrop-contrast: ;
539
+ --tw-backdrop-grayscale: ;
540
+ --tw-backdrop-hue-rotate: ;
541
+ --tw-backdrop-invert: ;
542
+ --tw-backdrop-opacity: ;
543
+ --tw-backdrop-saturate: ;
544
+ --tw-backdrop-sepia: ;
545
+ }
546
+
547
+ .sr-only {
548
+ position: absolute;
549
+ width: 1px;
550
+ height: 1px;
551
+ padding: 0;
552
+ margin: -1px;
553
+ overflow: hidden;
554
+ clip: rect(0, 0, 0, 0);
555
+ white-space: nowrap;
556
+ border-width: 0;
557
+ }
558
+
559
+ .absolute {
560
+ position: absolute;
561
+ }
562
+
563
+ .relative {
564
+ position: relative;
565
+ }
566
+
567
+ .-top-2 {
568
+ top: -0.5rem;
569
+ }
570
+
571
+ .left-0 {
572
+ left: 0px;
573
+ }
574
+
575
+ .left-2 {
576
+ left: 0.5rem;
577
+ }
578
+
579
+ .z-10 {
580
+ z-index: 10;
581
+ }
582
+
583
+ .ml-3 {
584
+ margin-left: 0.75rem;
585
+ }
586
+
587
+ .mt-16 {
588
+ margin-top: 4rem;
589
+ }
590
+
591
+ .mt-4 {
592
+ margin-top: 1rem;
593
+ }
594
+
595
+ .block {
596
+ display: block;
597
+ }
598
+
599
+ .inline-block {
600
+ display: inline-block;
601
+ }
602
+
603
+ .flex {
604
+ display: flex;
605
+ }
606
+
607
+ .table {
608
+ display: table;
609
+ }
610
+
611
+ .hidden {
612
+ display: none;
613
+ }
614
+
615
+ .h-4 {
616
+ height: 1rem;
617
+ }
618
+
619
+ .h-5 {
620
+ height: 1.25rem;
621
+ }
622
+
623
+ .h-full {
624
+ height: 100%;
625
+ }
626
+
627
+ .max-h-screen {
628
+ max-height: 100vh;
629
+ }
630
+
631
+ .w-4 {
632
+ width: 1rem;
633
+ }
634
+
635
+ .w-5 {
636
+ width: 1.25rem;
637
+ }
638
+
639
+ .w-auto {
640
+ width: auto;
641
+ }
642
+
643
+ .w-fit {
644
+ width: -moz-fit-content;
645
+ width: fit-content;
646
+ }
647
+
648
+ .w-full {
649
+ width: 100%;
650
+ }
651
+
652
+ .flex-shrink {
653
+ flex-shrink: 1;
654
+ }
655
+
656
+ .flex-grow {
657
+ flex-grow: 1;
658
+ }
659
+
660
+ .cursor-pointer {
661
+ cursor: pointer;
662
+ }
663
+
664
+ .flex-row {
665
+ flex-direction: row;
666
+ }
667
+
668
+ .flex-col {
669
+ flex-direction: column;
670
+ }
671
+
672
+ .items-center {
673
+ align-items: center;
674
+ }
675
+
676
+ .justify-center {
677
+ justify-content: center;
678
+ }
679
+
680
+ .justify-between {
681
+ justify-content: space-between;
682
+ }
683
+
684
+ .gap-10 {
685
+ gap: 2.5rem;
686
+ }
687
+
688
+ .gap-2 {
689
+ gap: 0.5rem;
690
+ }
691
+
692
+ .gap-4 {
693
+ gap: 1rem;
694
+ }
695
+
696
+ .space-y-4 > :not([hidden]) ~ :not([hidden]) {
697
+ --tw-space-y-reverse: 0;
698
+ margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse)));
699
+ margin-bottom: calc(1rem * var(--tw-space-y-reverse));
700
+ }
701
+
702
+ .rounded-md {
703
+ border-radius: 0.375rem;
704
+ }
705
+
706
+ .border-0 {
707
+ border-width: 0px;
708
+ }
709
+
710
+ .border-gray-300 {
711
+ --tw-border-opacity: 1;
712
+ border-color: rgb(209 213 219 / var(--tw-border-opacity));
713
+ }
714
+
715
+ .bg-slate-800 {
716
+ --tw-bg-opacity: 1;
717
+ background-color: rgb(30 41 59 / var(--tw-bg-opacity));
718
+ }
719
+
720
+ .bg-white {
721
+ --tw-bg-opacity: 1;
722
+ background-color: rgb(255 255 255 / var(--tw-bg-opacity));
723
+ }
724
+
725
+ .p-3 {
726
+ padding: 0.75rem;
727
+ }
728
+
729
+ .p-8 {
730
+ padding: 2rem;
731
+ }
732
+
733
+ .px-1 {
734
+ padding-left: 0.25rem;
735
+ padding-right: 0.25rem;
736
+ }
737
+
738
+ .px-3 {
739
+ padding-left: 0.75rem;
740
+ padding-right: 0.75rem;
741
+ }
742
+
743
+ .px-4 {
744
+ padding-left: 1rem;
745
+ padding-right: 1rem;
746
+ }
747
+
748
+ .py-2 {
749
+ padding-top: 0.5rem;
750
+ padding-bottom: 0.5rem;
751
+ }
752
+
753
+ .py-2\.5 {
754
+ padding-top: 0.625rem;
755
+ padding-bottom: 0.625rem;
756
+ }
757
+
758
+ .text-left {
759
+ text-align: left;
760
+ }
761
+
762
+ .text-sm {
763
+ font-size: 0.875rem;
764
+ line-height: 1.25rem;
765
+ }
766
+
767
+ .text-xl {
768
+ font-size: 1.25rem;
769
+ line-height: 1.75rem;
770
+ }
771
+
772
+ .text-xs {
773
+ font-size: 0.75rem;
774
+ line-height: 1rem;
775
+ }
776
+
777
+ .font-medium {
778
+ font-weight: 500;
779
+ }
780
+
781
+ .font-semibold {
782
+ font-weight: 600;
783
+ }
784
+
785
+ .leading-6 {
786
+ line-height: 1.5rem;
787
+ }
788
+
789
+ .text-gray-400 {
790
+ --tw-text-opacity: 1;
791
+ color: rgb(156 163 175 / var(--tw-text-opacity));
792
+ }
793
+
794
+ .text-gray-900 {
795
+ --tw-text-opacity: 1;
796
+ color: rgb(17 24 39 / var(--tw-text-opacity));
797
+ }
798
+
799
+ .text-indigo-600 {
800
+ --tw-text-opacity: 1;
801
+ color: rgb(79 70 229 / var(--tw-text-opacity));
802
+ }
803
+
804
+ .text-white {
805
+ --tw-text-opacity: 1;
806
+ color: rgb(255 255 255 / var(--tw-text-opacity));
807
+ }
808
+
809
+ .shadow-sm {
810
+ --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
811
+ --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
812
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
813
+ }
814
+
815
+ .ring-1 {
816
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
817
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
818
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
819
+ }
820
+
821
+ .ring-inset {
822
+ --tw-ring-inset: inset;
823
+ }
824
+
825
+ .ring-gray-300 {
826
+ --tw-ring-opacity: 1;
827
+ --tw-ring-color: rgb(209 213 219 / var(--tw-ring-opacity));
828
+ }
829
+
830
+ .filter {
831
+ filter: 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);
832
+ }
833
+
834
+ .placeholder\:text-gray-400::-moz-placeholder {
835
+ --tw-text-opacity: 1;
836
+ color: rgb(156 163 175 / var(--tw-text-opacity));
837
+ }
838
+
839
+ .placeholder\:text-gray-400::placeholder {
840
+ --tw-text-opacity: 1;
841
+ color: rgb(156 163 175 / var(--tw-text-opacity));
842
+ }
843
+
844
+ .first-of-type\:rounded-t-md:first-of-type {
845
+ border-top-left-radius: 0.375rem;
846
+ border-top-right-radius: 0.375rem;
847
+ }
848
+
849
+ .last-of-type\:rounded-b-md:last-of-type {
850
+ border-bottom-right-radius: 0.375rem;
851
+ border-bottom-left-radius: 0.375rem;
852
+ }
853
+
854
+ .hover\:bg-gray-500\/5:hover {
855
+ background-color: rgb(107 114 128 / 0.05);
856
+ }
857
+
858
+ .hover\:bg-slate-700:hover {
859
+ --tw-bg-opacity: 1;
860
+ background-color: rgb(51 65 85 / var(--tw-bg-opacity));
861
+ }
862
+
863
+ .focus\:ring-2:focus {
864
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
865
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
866
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
867
+ }
868
+
869
+ .focus\:ring-inset:focus {
870
+ --tw-ring-inset: inset;
871
+ }
872
+
873
+ .focus\:ring-indigo-600:focus {
874
+ --tw-ring-opacity: 1;
875
+ --tw-ring-color: rgb(79 70 229 / var(--tw-ring-opacity));
876
+ }
877
+
878
+ .focus-visible\:outline:focus-visible {
879
+ outline-style: solid;
880
+ }
881
+
882
+ .focus-visible\:outline-2:focus-visible {
883
+ outline-width: 2px;
884
+ }
885
+
886
+ .focus-visible\:outline-offset-2:focus-visible {
887
+ outline-offset: 2px;
888
+ }
889
+
890
+ .focus-visible\:outline-indigo-600:focus-visible {
891
+ outline-color: #4f46e5;
892
+ }
893
+
894
+ .disabled\:text-gray-500:disabled {
895
+ --tw-text-opacity: 1;
896
+ color: rgb(107 114 128 / var(--tw-text-opacity));
897
+ }
898
+
899
+ @media (min-width: 640px) {
900
+ .sm\:flex {
901
+ display: flex;
902
+ }
903
+
904
+ .sm\:items-center {
905
+ align-items: center;
906
+ }
907
+
908
+ .sm\:space-x-10 > :not([hidden]) ~ :not([hidden]) {
909
+ --tw-space-x-reverse: 0;
910
+ margin-right: calc(2.5rem * var(--tw-space-x-reverse));
911
+ margin-left: calc(2.5rem * calc(1 - var(--tw-space-x-reverse)));
912
+ }
913
+
914
+ .sm\:space-y-0 > :not([hidden]) ~ :not([hidden]) {
915
+ --tw-space-y-reverse: 0;
916
+ margin-top: calc(0px * calc(1 - var(--tw-space-y-reverse)));
917
+ margin-bottom: calc(0px * var(--tw-space-y-reverse));
918
+ }
919
+
920
+ .sm\:text-sm {
921
+ font-size: 0.875rem;
922
+ line-height: 1.25rem;
923
+ }
924
+
925
+ .sm\:leading-6 {
926
+ line-height: 1.5rem;
927
+ }
928
+ }