-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
400 lines (392 loc) · 30.5 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<title>Game of Life</title>
<meta name='viewport' content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no'>
<meta name='author' content='Paweł Kania'>
<link rel='shortcut icon' type='image/x-icon' href='favicon.ico' />
<link href='https://use.fontawesome.com/releases/v5.15.3/css/all.css' rel='stylesheet' integrity='sha384-SZXxX4whJ79/gErwcOYf+zWLeJdY/qpuqC4cAa9rOGUstPomtqpuNWT9wdPEn2fk' crossorigin='anonymous'>
<link href='https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css' rel='stylesheet' integrity='sha384-eOJMYsd53ii+scO/bJGFsiCZc+5NDVN2yr8+0RDqr0Ql0h+rP48ckxlpbzKgwra6' crossorigin='anonymous'>
<link href='https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css' rel='stylesheet' integrity='sha384-wEmeIV1mKuiNpC+IOBjI7aAzPcEZeedi5yW5f2yOq55WWLwNGmvvx4Um1vskeMj0' crossorigin='anonymous'>
<script src='https://code.jquery.com/jquery-3.6.0.min.js' integrity='sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=' crossorigin='anonymous'></script>
<script src='https://code.jquery.com/ui/1.12.0/jquery-ui.min.js' integrity='sha256-eGE6blurk5sHj+rmkfsGYeKyZx3M4bG+ZlFyA7Kns7E=' crossorigin='anonymous'></script>
<script src='https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js' integrity='sha384-JEW9xMcG8R+pH31jmWH6WWP0WintQrMb4s7ZOdauHnUtxwoG2vI5DkLtS3qm9Ekf' crossorigin='anonymous'></script>
<link href='css/styles.css' rel='stylesheet'>
<link href='css/slider.css' rel='stylesheet'>
<script src='js/app.js' type='application/javascript'></script>
<script src='js/life.js' type='application/javascript'></script>
<script src='js/file.js' type='application/javascript'></script>
<script src='js/point.js' type='application/javascript'></script>
<script src='js/gallery.js' type='application/javascript'></script>
<script src='js/jquery.utility.js' type='application/javascript'></script>
<script src='js/libs/zip-fs.min.js' type='application/javascript'></script>
<script src='js/libs/hashlife.js' type='application/javascript'></script>
<script src='js/libs/hashlife.adapter.js' type='application/javascript'></script>
<script>
$(() => UI.init());
</script>
</head>
<body>
<div id='coords' class='rounded-pill collapse px-2'>
<div id='coord-x'></div>,
<div id='coord-y'></div>
</div>
<canvas id='game-of-life'></canvas>
<div id='toolbar' class='btn-toolbar d-flex flex-wrap-reverse justify-content-end' role='toolbar'>
<div class='btn-group me-1 mb-1' role='group'>
<a id='btn-play' type='button' class='btn btn-secondary' data-bs-toggle='tooltip' data-bs-placement='bottom' title='Play'>
<i class='fas fa-play' aria-hidden='true'></i>
</a>
<a id='btn-next' type='button' class='btn btn-secondary' data-bs-toggle='tooltip' data-bs-placement='bottom' title='Next'>
<i class='fas fa-step-forward' aria-hidden='true'></i>
</a>
<a id='btn-clear' type='button' class='btn btn-secondary' data-bs-toggle='tooltip' data-bs-placement='bottom' title='Clear'>
<i class='fas fa-eraser' aria-hidden='true'></i>
</a>
</div>
<div class='btn-group me-1 mb-1' role='group'>
<a id='btn-slower' type='button' class='btn btn-secondary' data-bs-toggle='tooltip' data-bs-placement='bottom' title='Slower'>
<i class='fas fa-fast-backward' aria-hidden='true'></i>
</a>
<input id='in-speed' type='text' class='form-control form-inline text-center p-1 rounded-0' size='1' placeholder='Speed' aria-label='Speed'>
<a id='btn-faster' type='button' class='btn btn-secondary' data-bs-toggle='tooltip' data-bs-placement='bottom' title='Faster'>
<i class='fas fa-fast-forward' aria-hidden='true'></i>
</a>
</div>
<div class='btn-group me-1 mb-1' role='group'>
<input id='btn-select' type='checkbox' class='btn-check' autocomplete='off'>
<label class='btn btn-secondary' for='btn-select' data-bs-toggle='tooltip' data-bs-placement='bottom' title='Select'>
<i class='fas fa-vector-square' aria-hidden='true'></i>
</label>
<a id='btn-cut' type='button' class='btn btn-secondary' data-bs-toggle='tooltip' data-bs-placement='bottom' title='Cut'>
<i class='fas fa-cut' aria-hidden='true'></i>
</a>
<a id='btn-paste' type='button' class='btn btn-secondary' data-bs-toggle='tooltip' data-bs-placement='bottom' title='Paste'>
<i class='fas fa-paste' aria-hidden='true'></i>
</a>
</div>
<div id='gr-file-info' class='btn-group me-1 mb-1 d-none' role='group'>
<a id='btn-info' type='button' class='btn btn-secondary' data-bs-toggle='dropdown' aria-haspopup='true' aria-expanded='false'>
<i class='fas fa-info-circle' aria-hidden='true'></i>
</a>
<div id='dropdown-info' class='dropdown-menu p-3'>
<div id='gr-info-title'>
<p class='fs-5'>Title</p>
<p id='info-title' class='text-muted'></p>
<hr class='dropdown-divider'>
</div>
<div id='gr-info-author'>
<p class='fs-5'>Author</p>
<p id='info-author' class='text-muted'></p>
<hr class='dropdown-divider'>
</div>
<div id='gr-info-comments'>
<p class='fs-5'>Comments</p>
<p id='info-comments' class='text-muted'></p>
<hr class='dropdown-divider'>
</div>
</div>
<a id='btn-reload' type='button' class='btn btn-secondary' data-bs-toggle='tooltip' data-bs-placement='bottom' title='Reload'>
<i class='fas fa-redo' aria-hidden='true'></i>
</a>
</div>
<div class='btn-group me-1 mb-1' role='group'>
<a id='btn-load' type='button' class='btn btn-secondary' data-bs-toggle='tooltip' data-bs-placement='bottom' title='Load'>
<i class='fas fa-folder-open' aria-hidden='true'></i>
</a>
<a id='btn-save' type='button' class='btn btn-secondary' data-bs-toggle='tooltip' data-bs-placement='bottom' title='Save'>
<i class='fas fa-save' aria-hidden='true'></i>
</a>
<a id='btn-gallery' type='button' class='btn btn-secondary' data-bs-toggle='tooltip' data-bs-placement='bottom' title='Gallery'>
<i class='fas fa-images' aria-hidden='true'></i>
</a>
<a id='btn-random' type='button' class='btn btn-secondary' data-bs-toggle='tooltip' data-bs-placement='bottom' title='Random'>
<i class='fas fa-random' aria-hidden='true'></i>
</a>
<a id='btn-settings' type='button' class='btn btn-secondary' data-bs-toggle='dropdown' aria-haspopup='true' aria-expanded='false'>
<i class='fas fa-sliders-h' aria-hidden='true'></i>
</a>
<form id='dropdown-settings' class='dropdown-menu px-3' autocomplete='off'>
<div class='mt-2'>
<label>Settings</label>
</div>
<div>
<hr class='dropdown-divider'>
</div>
<div class='row g-2 mt-1 mb-3'>
<div class='col'>
<div class='form-floating'>
<input id='in-game-rule' type='text' class='form-control' aria-label='Rulestring'>
<label for='in-game-rule'>Rule</label>
</div>
</div>
<div class='col'>
<div class='form-floating'>
<select id='in-game-rule-name' class='form-select' aria-label='Rule name'>
<option value='B0123478/S01234678' title='The black/white reversal of Conway's Game of Life.'>AntiLife</option>
<option value='B0123478/S34678' title='A rule showing similar oscillators and gliders to Conway's Game of Life. The black/white reversal of B3678/S23.'>InverseLife</option>
<option value='B1/S012345678' title='An exploding rule where H-shaped branches grow from patterns' border.'>H-trees</option>
<option value='B1/S1' title='A simple exploding rule that forms complex patterns from even a single live cell.'>Gnarl</option>
<option value='B1357/S02468' title='A rule in which, like Replicator, every pattern is a replicator. Also known as "Replicator 2".'>Fredkin</option>
<option value='B1357/S1357' title='A rule in which every pattern is a replicator.'>Replicator</option>
<option value='B2/S' title='An exploding rule in which every cell dies in every generation. It has many simple orthogonal spaceships, though it is in general difficult to create patterns that don't explode.'>Seeds</option>
<option value='B2/S0' title='An exploding rule in which only cells with no neighbors survive. It has many spaceships, puffers, and oscillators, some of infinitely extensible size and period.'>Live Free or Die</option>
<option value='B234/S' title='An exploding rule in which every cell dies every generation (like seeds). This rule is of interest because of the fabric-like beauty of the patterns that it produces. Also known as "Persian Rug".'>Serviettes</option>
<option value='B25678/S5678' title='Small masses of solid living cells flicker in and out of existence. Some reach a critical mass and begin to slowly grow. Also known as "Ice nine".'>Iceballs</option>
<option value='B3/S012345678' title='An expanding rule that produces complex flakes, featuring dense wickstretchers named "ladder". Also known as "Flakes" or "Inkspot".'>Life without death</option>
<option value='B3/S023' title='An exploding rule closely related to Conway's Life. The B-heptomino is a common infinite growth pattern in this rule, though it can be stabilized into a spaceship.'>DotLife</option>
<option value='B3/S12' title='Patterns tend to quickly settle into dominos, duoplets and period 2 oscillators. There is a common period 14 shuttle oscillator involving the pre-beehive.'>Flock</option>
<option value='B3/S1234' title='An expanding rule that crystalizes to form maze-like designs that tend to be straighter (ie. have longer "halls") than the standard maze rule.'>Mazectric</option>
<option value='B3/S12345' title='An expanding rule that crystalizes to form maze-like designs.'>Maze</option>
<option value='B3/S1237' title=''>SnowLife</option>
<option value='B3/S124' title='A rule similar to Mazectric but without S3. A slow burn from almost any starting pattern, resulting in a rusting away of the local continuum.'>Corrosion of Conformity</option>
<option value='B3/S13' title=''>LowLife</option>
<option value='B3/S2' title='This rule has 6 small still lives, the tub, the hive, the aircraft carrier, the loaf, and the mango, and the pond. However, there are no still lives with more than 8 and less than 20 cells.'>SmallLife</option>
<option value='B3/S23' title='A chaotic rule that is by far the most well-known and well-studied. It exhibits highly complex behavior.' selected>Conway's Life</option>
<option value='B3/S238' title='Also known as "Pulsar Life".'>EightLife</option>
<option value='B3/S45678' title='An exploding rule in which patterns grow slowly and form coral-like textures.'>Coral</option>
<option value='B34/S34' title='An exploding rule that was initially thought to be a stable alternative to Conway's Life, until computer simulation found that most patterns tend to explode. It has many small oscillators and simple period 3 orthogonal and diagonal spaceships.'>3-4 Life</option>
<option value='B34/S456' title=''>Bacteria</option>
<option value='B345/S2' title=''>Blinkers</option>
<option value='B345/S4567' title='A very stable rule that forms permanent diamond-shaped patterns with partially filled interiors. Like in 2×2, patterns made of blocks will permanently remain made of blocks.'>Assimilation</option>
<option value='B345/S5' title='A stable rule that gets its name from the fact that it has many simple extremely high period oscillators.'>Long Life</option>
<option value='B3457/S4568' title='An exploding rule with many smaller high-period oscillators and a c/5648 spaceship.'>Gems</option>
<option value='B34578/S456' title='An exploding rule with many smaller high-period oscillators and a c/2068 spaceship.'>Gems Minor</option>
<option value='B35/S234578' title=''>Land Rush</option>
<option value='B3567/S15678' title=''>Bugs</option>
<option value='B35678/S4678' title=''>Holstein</option>
<option value='B35678/S5678' title='A chaotic pattern that forms large diamonds with chaotically oscillating boundaries. Known to have quadratically-growing patterns. Like in 2×2, patterns made of blocks will permanently remain made of blocks.'>Diamoeba</option>
<option value='B357/S1358' title='A chaotic rule that is well balanced between life and death; it forms patterns with chaotic interiors and wildly moving boundaries.'>Amoeba</option>
<option value='B357/S238' title='A chaotic rule with evolution that resembles Conway's Life, but few patterns from Life work in this rule because the glider is unstable.'>Pseudo Life</option>
<option value='B36/S125' title='A chaotic rule with many simple still lifes, oscillators and spaceships. Its name comes from the fact that it sends patterns made up of 2×2 blocks to patterns made up of 2×2 blocks.'>2×2</option>
<option value='B36/S235' title='An exploding rule where the T-tetromino is a blinker puffer, appropriate because it evolves into traffic light in Life, also made of blinkers.'>Blinker Life</option>
<option value='B36/S23' title='A chaotic rule very similar to Conway's Life that is of interest because it has a simple replicator.'>HighLife</option>
<option value='B367/S125678' title=''>Slow Blob</option>
<option value='B3678/S235678' title='A stable rule in which most patterns tend to "fill in" bounded regions. Most nearby rules (such as coagulations) tend to explode.'>Stains</option>
<option value='B3678/S34678' title='A stable rule that is symmetric under on-off reversal. Many patterns exhibiting highly complex behavior have been found for it.'>Day & Night</option>
<option value='B368/S238' title='HighLife's replicator works in this rule, albeit with a different evolution sequence due to the result of B38/S23's pedestrian effect.'>LowDeath</option>
<option value='B368/S245' title='A rule in which random patterns tend to stabilize extremely quickly. Has a very common slow-moving spaceship and slow-moving puffer. Also known as "Morley".'>Move</option>
<option value='B37/S1234' title='Some "mice" run back and forth in the halls of maze.'>Mazectric with Mice</option>
<option value='B37/S12345' title=''>Maze with Mice</option>
<option value='B37/S23' title='An exploding rule closely related to Conway's Life, named after the fact that the standard spaceships bigger than the glider do not function in the rule. Has a small puffer based on the R-pentomino, which resembles the switch engine in the possibility of combining several to form a spaceship.'>DryLife</option>
<option value='B378/S012345678' title=''>Plow World</option>
<option value='B378/S235678' title='An exploding rule in which patterns tend to expand forever, producing a thick "goo" as it does so. Suprisingly, Coagulations actually has one less birth condition than Stains.'>Coagulations</option>
<option value='B38/S23' title='A close Life variant with a number of distinctive natural growth patterns and (5,2)c/190 oblique spaceships.'>Pedestrian Life</option>
<option value='B38/S238' title=''>HoneyLife</option>
<option value='B45/S12345' title=''>Electrified Maze</option>
<option value='B45678/S2345' title='A stable rule that forms centers of pseudo-random activity separated by walls.'>Walled cities</option>
<option value='B4678/S35678' title='A modification of the standard Gérard Vichniac voting rule, also known as "Anneal", used as a model for majority voting.'>Vote 4/5</option>
<option value='B5678/S45678' title='Standard Gérard Vichniac voting rule, also known as "Majority", used as a model for majority voting.'>Vote</option>
<option class='d-none' disabled>Custom</option>
</select>
<label for='in-game-rule-name'>Name</label>
</div>
</div>
</div>
<div class='mb-3 form-floating'>
<select id='in-board-type' class='form-select' aria-label='Choose board type'>
<option value='infinite' selected>Infinite</option>
<option value='finite'>Finite</option>
<option value='wrapped'>Wrapped</option>
</select>
<label for='in-board-type'>Board type</label>
</div>
<div id='gr-board-size' class='mb-3 collapse'>
<label for='in-board-size' class='form-label'>Board size</label>
<div id='in-board-size' class='input-group'>
<input id='in-board-width' type='text' class='form-control text-center' size='9' aria-label='Width'>
<span class='input-group-text'>x</span>
<input id='in-board-height' type='text' class='form-control text-center' size='9' aria-label='Height'>
</div>
</div>
<div id='gr-game-step' class='mb-3'>
<label for='in-game-step' class='form-label'>Generation step</label>
<div class='range-slider'>
<input id='in-game-step' class='range-slider__range' type='range' value='0' min='0' max='16' step='1'>
<span class='range-slider__value'></span>
</div>
</div>
<div class='mb-3 form-floating'>
<select id='in-coord-display' class='form-select' aria-label='Choose how coords label should be displayed'>
<option value='follow' selected>Follow cursor</option>
<option value='corner'>In the corner</option>
<option value='off'>Don't show</option>
</select>
<label for='in-coord-display'>Coordinates</label>
</div>
<div>
<hr class='dropdown-divider'>
</div>
<div class='mb-1 form-check form-switch'>
<input id='sw-inverse' type='checkbox' class='form-check-input'>
<label for='sw-inverse' class='form-check-label text-end'>Allow inverse rules</label>
</div>
<div class='mb-1 form-check form-switch'>
<input id='sw-dead' type='checkbox' class='form-check-input' checked>
<label for='sw-dead' class='form-check-label text-end'>Stop at still life</label>
</div>
<div class='mb-1 form-check form-switch'>
<input id='sw-colors' type='checkbox' class='form-check-input' checked>
<label for='sw-colors' class='form-check-label text-end'>Show cell age</label>
</div>
<div class='mb-1 form-check form-switch'>
<input id='sw-stats' type='checkbox' class='form-check-input' checked>
<label for='sw-stats' class='form-check-label text-end'>Show statistics</label>
</div>
<div class='mb-1 form-check form-switch'>
<input id='sw-fps' type='checkbox' class='form-check-input'>
<label for='sw-fps' class='form-check-label text-end'>Show generation speed</label>
</div>
<div>
<hr class='dropdown-divider'>
</div>
<div class='mb-1 mt-1 form-floating'>
<select id='in-engine' class='form-select' aria-label='Choose engine'>
<option value='hashlife' selected>HashLife</option>
<option value='worker'>Web Worker</option>
<option value='naive'>Naive</option>
</select>
<label for='in-engine'>Engine</label>
</div>
</form>
<a id='btn-lock' type='button' class='btn btn-secondary' data-bs-toggle='tooltip' data-bs-placement='bottom' title='Lock'>
<i class='fas fa-unlock' aria-hidden='true'></i>
</a>
<a id='btn-night' type='button' class='btn btn-secondary' data-bs-toggle='tooltip' data-bs-placement='bottom' title='Dark mode'>
<i class='fas fa-lightbulb' aria-hidden='true'></i>
</a>
</div>
<div class='btn-group mb-1' role='group'>
<a id='btn-hide' type='button' class='btn btn-secondary' data-bs-toggle='tooltip' data-bs-placement='bottom' title='Hide'>
<i class='fas fa-arrow-right' aria-hidden='true'></i>
</a>
</div>
</div>
<div id='info' class='btn-toolbar d-flex flex-wrap-reverse justify-content-end' role='toolbar'>
<div class='input-group collapse'>
<span class='input-group-text bg-secondary text-white border-0'>GPS</span>
<span id='out-fps' type='text' class='form-control'>0 | 0 | 0</span>
</div>
<div class='input-group'>
<span class='input-group-text bg-secondary text-white border-0'>Generation</span>
<span id='out-gens' type='text' class='form-control'>0</span>
</div>
<div class='input-group'>
<span class='input-group-text bg-secondary text-white border-0'>Population</span>
<span id='out-populus' type='text' class='form-control'>0</span>
</div>
</div>
<div id='modal-save' class='modal fade' tabindex='-1' aria-hidden='true'>
<div class='modal-dialog modal-dialog-centered'>
<div class='modal-content'>
<div class='modal-header'>
<h5 class='modal-title' id='modal-save-label'>Save pattern</h5>
<button type='button' class='btn-close' data-bs-dismiss='modal' aria-label='Close'></button>
</div>
<form class='modal-body' autocomplete='off'>
<div class='form-floating mt-1 mb-3'>
<input id='in-file-title' type='text' class='form-control'>
<label for='in-file-title'>Title</label>
</div>
<div class='form-floating mb-3'>
<input id='in-file-author' type='text' class='form-control'>
<label for='in-file-author'>Author</label>
</div>
<div class='form-floating mb-3'>
<textarea id='in-file-comments' class='form-control' aria-label='Comments' rows='5'></textarea>
<label for='in-file-comments'>Comments</label>
</div>
<div class='input-group mb-1'>
<div class='form-floating'>
<input id='in-file-name' type='text' class='form-control' aria-label='Filename'>
<label for='in-file-name'>File name</label>
</div>
<select id='in-file-format' class='input-group-text' aria-label='File format' disabled>
<option value='rle' selected>.rle</option>
<option value='life'>.lif</option>
</select>
</div>
</form>
<div class='modal-footer'>
<button type='button' class='btn btn-secondary' data-bs-dismiss='modal'>Close</button>
<button id='btn-download' type='button' class='btn btn-primary'>Download</button>
</div>
</div>
</div>
</div>
<div id='modal-gallery' class='modal fade' tabindex='-1' aria-hidden='true'>
<div class='modal-dialog modal-xl modal-dialog-scrollable modal-dialog-centered'>
<div class='modal-content'>
<div class='modal-header'>
<h5 class='modal-title' id='modal-save-label'>Pattern gallery</h5>
<button type='button' class='btn-close' data-bs-dismiss='modal' aria-label='Close'></button>
</div>
<div class='modal-body'>
<div class='container'>
<div class='row'>
<div class='col-lg-8 col-md-5 col-sm-4 col-3 border-end pe-3'>
<canvas id='gallery-preview' class='sticky-top collapse'></canvas>
</div>
<div class='col-lg-4 col-md-7 col-sm-8 col-9 border-start pe-0'>
<div class='ms-2'>
<div class='input-group'>
<span id='in-gallery-type' class='input-group-text' data-bs-toggle='tooltip' data-bs-placement='left' title='Search'>
<i class='fas fa-list'></i>
</span>
<select id='gallery-set' class='form-select' aria-label='Choose set of files'>
</select>
<input id='in-gallery-file-name' type='text' class='form-control collapse' placeholder='Search'>
</div>
</div>
<hr class='my-2 ms-2'/>
<div class='ms-2 mb-3'>
<div id='gallery-file-list' class='list-group'>
</div>
</div>
</div>
</div>
</div>
</div>
<div class='modal-footer'>
<button type='button' class='btn btn-secondary' data-bs-dismiss='modal'>Close</button>
<button id='btn-gallery-load' type='button' class='btn btn-primary'>Load pattern</button>
</div>
</div>
</div>
</div>
<div id='info-toast' class='toast align-items-center position-relative bg-secondary bg-gradient text-white border-0' role='alert' aria-live='assertive' aria-atomic='true'>
<div class='d-flex'>
<button type='button' class='btn-close btn-close-white my-auto ms-2' data-bs-dismiss='toast' aria-label='Close'></button>
<div class='toast-body'> </div>
</div>
</div>
<div id='modal-soup' class='modal fade' tabindex='-1' aria-hidden='true'>
<div class='modal-dialog modal-sm modal-dialog-scrollable modal-dialog-centered'>
<div class='modal-content'>
<div class='modal-header'>
<h5 class='modal-title' id='modal-save-label'>Soup Generator</h5>
<button type='button' class='btn-close' data-bs-dismiss='modal' aria-label='Close'></button>
</div>
<form class='modal-body' autocomplete='off'>
<div class='form-floating mt-1 mb-3'>
<input id='in-soup-width' type='text' class='form-control' value='20'>
<label for='in-soup-width'>Width</label>
</div>
<div class='form-floating mb-3'>
<input id='in-soup-height' type='text' class='form-control' value='20'>
<label for='in-soup-height'>Height</label>
</div>
<div class='form-floating mb-1'>
<input id='in-soup-density' type='number' class='form-control' min='0.0' max='1.0' step='0.01' value='0.5'>
<label for='in-soup-density'>Density</label>
</div>
</form>
<div class='modal-footer'>
<button id='btn-soup-gen' type='button' class='btn btn-primary'>Generate</button>
</div>
</div>
</div>
</div>
</body>
</html>