|
|
|
@ -9,18 +9,28 @@ |
|
|
|
|
// according to those terms. |
|
|
|
|
--> |
|
|
|
|
|
|
|
|
|
<!-- |
|
|
|
|
The Login Procedure. |
|
|
|
|
Has multiple states (steps) through the user flow. |
|
|
|
|
--> |
|
|
|
|
|
|
|
|
|
<script lang="ts"> |
|
|
|
|
import { Alert, Toggle } from "flowbite-svelte"; |
|
|
|
|
import { onMount, createEventDispatcher, tick } from "svelte"; |
|
|
|
|
import ng from "../api"; |
|
|
|
|
import { emoji_cat, emojis, load_svg } from "../wallet_emojis"; |
|
|
|
|
import { PuzzlePiece } from "svelte-heros-v2"; |
|
|
|
|
import { |
|
|
|
|
PuzzlePiece, |
|
|
|
|
XCircle, |
|
|
|
|
Backspace, |
|
|
|
|
ArrowPath, |
|
|
|
|
LockOpen, |
|
|
|
|
} from "svelte-heros-v2"; |
|
|
|
|
//import Worker from "../worker.js?worker&inline"; |
|
|
|
|
export let wallet; |
|
|
|
|
export let for_import = false; |
|
|
|
|
|
|
|
|
|
let tauri_platform = import.meta.env.TAURI_PLATFORM; |
|
|
|
|
let mobile = tauri_platform == "android" || tauri_platform == "ios"; |
|
|
|
|
|
|
|
|
|
const dispatch = createEventDispatcher(); |
|
|
|
|
|
|
|
|
@ -46,7 +56,7 @@ |
|
|
|
|
} |
|
|
|
|
emojis2 = emojis2; |
|
|
|
|
|
|
|
|
|
display = 0; |
|
|
|
|
pazzlePage = 0; |
|
|
|
|
selection = []; |
|
|
|
|
error = undefined; |
|
|
|
|
|
|
|
|
@ -68,16 +78,14 @@ |
|
|
|
|
|
|
|
|
|
let pazzle_length = 9; |
|
|
|
|
|
|
|
|
|
let display = 0; |
|
|
|
|
let pazzlePage = 0; |
|
|
|
|
|
|
|
|
|
let selection = []; |
|
|
|
|
let selection = [].fill(null, 0, pazzle_length); |
|
|
|
|
|
|
|
|
|
let pin_code = []; |
|
|
|
|
|
|
|
|
|
let ordered = []; |
|
|
|
|
|
|
|
|
|
let last_one = {}; |
|
|
|
|
|
|
|
|
|
let shuffle_pin; |
|
|
|
|
|
|
|
|
|
let error; |
|
|
|
@ -87,10 +95,9 @@ |
|
|
|
|
function order() { |
|
|
|
|
step = "order"; |
|
|
|
|
ordered = []; |
|
|
|
|
last_one = {}; |
|
|
|
|
for (let i = 0; i < pazzle_length; i++) { |
|
|
|
|
last_one[i] = true; |
|
|
|
|
} |
|
|
|
|
// In case, this is called by the cancel button, we need to reset the selection. |
|
|
|
|
selection.forEach((emoji) => (emoji.sel = undefined)); |
|
|
|
|
selection = selection; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
async function start_pin() { |
|
|
|
@ -101,20 +108,21 @@ |
|
|
|
|
//console.log(shuffle_pin); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** Called on selecting emoji in a category. */ |
|
|
|
|
function select(val) { |
|
|
|
|
//console.log(emojis2[display][val]); |
|
|
|
|
let cat_idx = shuffle.category_indices[display]; |
|
|
|
|
let cat_idx = shuffle.category_indices[pazzlePage]; |
|
|
|
|
let cat = emojis[emoji_cat[cat_idx]]; |
|
|
|
|
let idx = shuffle.emoji_indices[display][val]; |
|
|
|
|
let idx = shuffle.emoji_indices[pazzlePage][val]; |
|
|
|
|
//console.log(cat_idx, emoji_cat[cat_idx], idx, cat[idx].code); |
|
|
|
|
|
|
|
|
|
selection.push({ cat: cat_idx, index: idx }); |
|
|
|
|
//console.log(selection); |
|
|
|
|
selection[pazzlePage] = { cat: cat_idx, index: idx }; |
|
|
|
|
console.debug(selection, cat, cat_idx, idx, val); |
|
|
|
|
|
|
|
|
|
if (display == pazzle_length - 1) { |
|
|
|
|
if (pazzlePage == pazzle_length - 1) { |
|
|
|
|
order(); |
|
|
|
|
} else { |
|
|
|
|
display = display + 1; |
|
|
|
|
pazzlePage = pazzlePage + 1; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -214,23 +222,16 @@ |
|
|
|
|
dispatch("cancel"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
async function pin(val) { |
|
|
|
|
//console.log(val); |
|
|
|
|
pin_code.push(val); |
|
|
|
|
if (pin_code.length == 4) { |
|
|
|
|
await finish(); |
|
|
|
|
} |
|
|
|
|
async function on_pin_key(val) { |
|
|
|
|
pin_code = [...pin_code, val]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
async function select_order(val, pos) { |
|
|
|
|
delete last_one[pos]; |
|
|
|
|
//console.log(last_one); |
|
|
|
|
//console.log(val); |
|
|
|
|
async function select_order(val) { |
|
|
|
|
ordered.push(val); |
|
|
|
|
val.sel = ordered.length; |
|
|
|
|
selection = selection; |
|
|
|
|
if (ordered.length == pazzle_length - 1) { |
|
|
|
|
let last = selection[Object.keys(last_one)[0]]; |
|
|
|
|
let last = selection.find((emoji) => !emoji.sel); |
|
|
|
|
ordered.push(last); |
|
|
|
|
last.sel = ordered.length; |
|
|
|
|
selection = selection; |
|
|
|
@ -238,8 +239,60 @@ |
|
|
|
|
await start_pin(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function go_back() { |
|
|
|
|
if (step === "pazzle") { |
|
|
|
|
// Go to previous pazzle or init page, if on first pazzle. |
|
|
|
|
if (pazzlePage === 0) { |
|
|
|
|
init(); |
|
|
|
|
} else { |
|
|
|
|
pazzlePage -= 1; |
|
|
|
|
} |
|
|
|
|
} else if (step === "order") { |
|
|
|
|
if (ordered.length === 0) { |
|
|
|
|
step = "pazzle"; |
|
|
|
|
} else { |
|
|
|
|
const last_selected = ordered.pop(); |
|
|
|
|
last_selected.sel = null; |
|
|
|
|
ordered = ordered; |
|
|
|
|
selection = selection; |
|
|
|
|
} |
|
|
|
|
} else if (step === "pin") { |
|
|
|
|
if (pin_code.length === 0) { |
|
|
|
|
// Unselect the last two elements. |
|
|
|
|
const to_unselect = ordered.slice(-2); |
|
|
|
|
to_unselect.forEach((val) => { |
|
|
|
|
val.sel = null; |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
ordered = ordered.slice(0, -2); |
|
|
|
|
selection = selection; |
|
|
|
|
step = "order"; |
|
|
|
|
} else { |
|
|
|
|
pin_code = pin_code.slice(0, pin_code.length - 1); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
let width: number; |
|
|
|
|
let height: number; |
|
|
|
|
const breakPointWidth: number = 530; |
|
|
|
|
const breakPointHeight: number = 900; |
|
|
|
|
let mobile = false; |
|
|
|
|
$: if (width >= breakPointWidth && height >= breakPointHeight) { |
|
|
|
|
mobile = false; |
|
|
|
|
} else { |
|
|
|
|
mobile = true; |
|
|
|
|
} |
|
|
|
|
</script> |
|
|
|
|
|
|
|
|
|
<div |
|
|
|
|
class="flex flex-col justify-center h-screen p-4" |
|
|
|
|
class:min-w-[310px]={mobile} |
|
|
|
|
class:min-w-[500px]={!mobile} |
|
|
|
|
class:max-w-[360px]={mobile} |
|
|
|
|
class:max-w-[600px]={!mobile} |
|
|
|
|
> |
|
|
|
|
{#if step == "load"} |
|
|
|
|
<div class=" max-w-xl lg:px-8 mx-auto px-4 mt-10"> |
|
|
|
|
<h2 class="pb-5 text-xl">How to open your wallet, step by step:</h2> |
|
|
|
@ -251,31 +304,31 @@ |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
At each category, only one of the 15 displayed choices is the correct |
|
|
|
|
image that belongs to your pazzle. Find it and tap or click on that one. |
|
|
|
|
The 15 images are shuffled too, they will not appear at the same |
|
|
|
|
image that belongs to your pazzle. Find it and tap or click on that |
|
|
|
|
one. The 15 images are shuffled too, they will not appear at the same |
|
|
|
|
position at each login. On a computer, you can also use the tab key on |
|
|
|
|
your keyboard to move to the desired item on the screen, then press the |
|
|
|
|
space bar to select each one. |
|
|
|
|
your keyboard to move to the desired item on the screen, then press |
|
|
|
|
the space bar to select each one. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Once you completed the last category, you will be presented with all the |
|
|
|
|
images you have previously selected. Their order is displayed as it was |
|
|
|
|
when you picked them. But this is not the correct order of the images in |
|
|
|
|
your pazzle. You now have to order them correctly. |
|
|
|
|
Once you completed the last category, you will be presented with all |
|
|
|
|
the images you have previously selected. Their order is displayed as |
|
|
|
|
it was when you picked them. But this is not the correct order of the |
|
|
|
|
images in your pazzle. You now have to order them correctly. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
You must remember which image should be the first one in your pazzle. |
|
|
|
|
Find it on the screen and click or tap on it. It will be greyed out and |
|
|
|
|
the number 1 will appear on top of it. |
|
|
|
|
Find it on the screen and click or tap on it. It will be greyed out |
|
|
|
|
and the number 1 will appear on top of it. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Move on to the second image of your pazzle (that you memorized). Find it |
|
|
|
|
on the screen and tap on it. Repeat this step until you reached the last |
|
|
|
|
image. |
|
|
|
|
Move on to the second image of your pazzle (that you memorized). Find |
|
|
|
|
it on the screen and tap on it. Repeat this step until you reached the |
|
|
|
|
last image. |
|
|
|
|
</li> |
|
|
|
|
<li> |
|
|
|
|
Finally, your PIN code will be asked. enter it by clicking or tapping on |
|
|
|
|
the digits. |
|
|
|
|
Finally, your PIN code will be asked. enter it by clicking or tapping |
|
|
|
|
on the digits. |
|
|
|
|
</li> |
|
|
|
|
</ul> |
|
|
|
|
</div> |
|
|
|
@ -304,9 +357,18 @@ |
|
|
|
|
/> |
|
|
|
|
</svg> |
|
|
|
|
{:else} |
|
|
|
|
<div class="flex justify-center space-x-12 mt-4 mb-4"> |
|
|
|
|
<button |
|
|
|
|
on:click={cancel} |
|
|
|
|
class="mt-1 mb-2 bg-red-100 hover:bg-red-100/90 focus:ring-4 focus:ring-primary-100/50 rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55" |
|
|
|
|
><XCircle |
|
|
|
|
tabindex="-1" |
|
|
|
|
class="w-8 h-8 mr-2 -ml-1 transition duration-75 group-hover:text-gray-900 dark:group-hover:text-white" |
|
|
|
|
/>Cancel</button |
|
|
|
|
> |
|
|
|
|
<button |
|
|
|
|
on:click={letsgo} |
|
|
|
|
class="mt-1 text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-100/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55 mb-2" |
|
|
|
|
class="mt-1 text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-100/50 rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55 mb-2" |
|
|
|
|
> |
|
|
|
|
<PuzzlePiece |
|
|
|
|
tabindex="-1" |
|
|
|
@ -314,6 +376,7 @@ |
|
|
|
|
/> |
|
|
|
|
Open my wallet now! |
|
|
|
|
</button> |
|
|
|
|
</div> |
|
|
|
|
{/if} |
|
|
|
|
</div> |
|
|
|
|
{#if for_import} |
|
|
|
@ -325,26 +388,38 @@ |
|
|
|
|
> |
|
|
|
|
</div> |
|
|
|
|
<p class="text-sm"> |
|
|
|
|
If you do, if this device is yours or is used by few trusted persons of |
|
|
|
|
your family or workplace, and you would like to login again from this |
|
|
|
|
device in the future, then you can save your wallet on this device. To |
|
|
|
|
the contrary, if this device is public and shared by strangers, do not |
|
|
|
|
save your wallet here. {#if !tauri_platform}By selecting this option, |
|
|
|
|
you agree to save some cookies on your browser.{/if}<br /> |
|
|
|
|
If you do, if this device is yours or is used by few trusted persons |
|
|
|
|
of your family or workplace, and you would like to login again from |
|
|
|
|
this device in the future, then you can save your wallet on this |
|
|
|
|
device. To the contrary, if this device is public and shared by |
|
|
|
|
strangers, do not save your wallet here. {#if !tauri_platform}By |
|
|
|
|
selecting this option, you agree to save some cookies on your |
|
|
|
|
browser.{/if}<br /> |
|
|
|
|
</p> |
|
|
|
|
</div> |
|
|
|
|
{/if} |
|
|
|
|
{:else if step == "pazzle"} |
|
|
|
|
<!-- The following have navigation buttons and fixed layout --> |
|
|
|
|
{:else if step == "pazzle" || step == "order" || step == "pin" || step == "mnemonic"} |
|
|
|
|
<div |
|
|
|
|
class="h-screen aspect-[3/5] pazzleline" |
|
|
|
|
class="flex flex-col justify-center h-screen p-4" |
|
|
|
|
class:min-w-[310px]={mobile} |
|
|
|
|
class:min-w-[500px]={!mobile} |
|
|
|
|
class:max-w-[360px]={mobile} |
|
|
|
|
class:max-w-[600px]={!mobile} |
|
|
|
|
> |
|
|
|
|
<div class="mt-auto flex flex-col justify-center"> |
|
|
|
|
{#if step == "pazzle"} |
|
|
|
|
<p class="max-w-xl md:mx-auto lg:max-w-2xl"> |
|
|
|
|
<span class="text-xl"> |
|
|
|
|
<!-- TODO: Internationalization--> |
|
|
|
|
Select your emoji of category: {emoji_cat[ |
|
|
|
|
shuffle.category_indices[pazzlePage] |
|
|
|
|
]}</span |
|
|
|
|
> |
|
|
|
|
</p> |
|
|
|
|
{#each [0, 1, 2, 3, 4] as row} |
|
|
|
|
<div class="columns-3 gap-0"> |
|
|
|
|
{#each emojis2[display]?.slice(0 + row * 3, 3 + row * 3) || [] as emoji, i} |
|
|
|
|
{#each emojis2[pazzlePage]?.slice(0 + row * 3, 3 + row * 3) || [] as emoji, i (pazzlePage + "-" + row + "-" + i)} |
|
|
|
|
<div |
|
|
|
|
role="button" |
|
|
|
|
tabindex="0" |
|
|
|
@ -357,16 +432,10 @@ |
|
|
|
|
{/each} |
|
|
|
|
</div> |
|
|
|
|
{/each} |
|
|
|
|
</div> |
|
|
|
|
{:else if step == "order"} |
|
|
|
|
<!-- console.log(cat_idx, emoji_cat[cat_idx], idx, cat[idx].code); --> |
|
|
|
|
<div |
|
|
|
|
class="h-screen aspect-[3/3] pazzleline" |
|
|
|
|
class:min-w-[320px]={mobile} |
|
|
|
|
class:min-w-[500px]={!mobile} |
|
|
|
|
class:max-w-[360px]={mobile} |
|
|
|
|
class:max-w-[600px]={!mobile} |
|
|
|
|
> |
|
|
|
|
<p class="max-w-xl md:mx-auto lg:max-w-2xl mb-2"> |
|
|
|
|
<span class="text-xl">Click your emojis in the correct order</span> |
|
|
|
|
</p> |
|
|
|
|
{#each [0, 1, 2] as row} |
|
|
|
|
<div class="columns-3 gap-0"> |
|
|
|
|
{#each selection.slice(0 + row * 3, 3 + row * 3) || [] as emoji, i} |
|
|
|
@ -375,19 +444,24 @@ |
|
|
|
|
role="button" |
|
|
|
|
tabindex="0" |
|
|
|
|
class="w-full aspect-square emoji focus:outline-none focus:bg-gray-300" |
|
|
|
|
on:click={() => select_order(emoji, row * 3 + i)} |
|
|
|
|
on:keypress={() => select_order(emoji, row * 3 + i)} |
|
|
|
|
on:click={() => select_order(emoji)} |
|
|
|
|
on:keypress={() => select_order(emoji)} |
|
|
|
|
> |
|
|
|
|
<svelte:component |
|
|
|
|
this={emojis[emoji_cat[emoji.cat]][emoji.index].svg?.default} |
|
|
|
|
this={emojis[emoji_cat[emoji.cat]][emoji.index].svg |
|
|
|
|
?.default} |
|
|
|
|
/> |
|
|
|
|
</div> |
|
|
|
|
{:else} |
|
|
|
|
<div class="w-full aspect-square opacity-25 select-none sel-emoji"> |
|
|
|
|
<div |
|
|
|
|
class="w-full aspect-square opacity-25 select-none sel-emoji" |
|
|
|
|
> |
|
|
|
|
<svelte:component |
|
|
|
|
this={emojis[emoji_cat[emoji.cat]][emoji.index].svg?.default} |
|
|
|
|
this={emojis[emoji_cat[emoji.cat]][emoji.index].svg |
|
|
|
|
?.default} |
|
|
|
|
/> |
|
|
|
|
<span class="sel drop-shadow-[2px_2px_2px_rgba(255,255,255,1)]" |
|
|
|
|
<span |
|
|
|
|
class="sel drop-shadow-[2px_2px_2px_rgba(255,255,255,1)]" |
|
|
|
|
>{emoji.sel}</span |
|
|
|
|
> |
|
|
|
|
</div> |
|
|
|
@ -395,33 +469,69 @@ |
|
|
|
|
{/each} |
|
|
|
|
</div> |
|
|
|
|
{/each} |
|
|
|
|
</div> |
|
|
|
|
{:else if step == "pin"} |
|
|
|
|
<div class=" max-w-6xl lg:px-8 mx-auto px-3"> |
|
|
|
|
<p class="max-w-xl md:mx-auto lg:max-w-2xl"> |
|
|
|
|
<span class="text-xl">Enter your PIN code</span> |
|
|
|
|
<p class="flex items-center md:mx-auto lg:max-w-2xl"> |
|
|
|
|
<span class="text-xl">Enter your PIN code:</span> |
|
|
|
|
<span class="text-xl min-w-[2em] ml-1 text-left" |
|
|
|
|
>{#each pin_code as pin_key}*{/each}</span |
|
|
|
|
> |
|
|
|
|
</p> |
|
|
|
|
<div class="w-[295px] mx-auto"> |
|
|
|
|
{#each [0, 1, 2] as row} |
|
|
|
|
<div class=""> |
|
|
|
|
<div class="columns-3 gap-2"> |
|
|
|
|
{#each shuffle_pin.slice(0 + row * 3, 3 + row * 3) as num} |
|
|
|
|
<button |
|
|
|
|
tabindex="0" |
|
|
|
|
class="m-1 select-none align-bottom text-7xl w-[90px] h-[90px] p-0" |
|
|
|
|
on:click={async () => await pin(num)} |
|
|
|
|
class="m-1 disabled:opacity-15 select-none align-bottom text-7xl p-0 w-full aspect-square border-0" |
|
|
|
|
on:click={async () => await on_pin_key(num)} |
|
|
|
|
disabled={pin_code.length >= 4} |
|
|
|
|
> |
|
|
|
|
<span>{num}</span> |
|
|
|
|
</button> |
|
|
|
|
{/each} |
|
|
|
|
</div> |
|
|
|
|
{/each} |
|
|
|
|
<div class="columns-3 gap-2"> |
|
|
|
|
<div class="m-1 w-full aspect-square" /> |
|
|
|
|
<button |
|
|
|
|
tabindex="0" |
|
|
|
|
class="m-1 select-none mx-auto align-bottom text-7xl w-[90px] h-[90px] p-0" |
|
|
|
|
on:click={async () => await pin(shuffle_pin[9])} |
|
|
|
|
class="disabled:opacity-15 m-1 select-none align-bottom text-7xl p-0 w-full aspect-square border-0" |
|
|
|
|
on:click={async () => await on_pin_key(shuffle_pin[9])} |
|
|
|
|
disabled={pin_code.length >= 4} |
|
|
|
|
> |
|
|
|
|
<span>{shuffle_pin[9]}</span> |
|
|
|
|
</button> |
|
|
|
|
<button |
|
|
|
|
tabindex="0" |
|
|
|
|
class="w-full bg-green-300 hover:bg-green-300/90 disabled:opacity-15 m-1 select-none align-bottom text-7xl p-0 w-full aspect-square border-0" |
|
|
|
|
on:click={async () => await finish()} |
|
|
|
|
disabled={pin_code.length < 4} |
|
|
|
|
> |
|
|
|
|
<LockOpen |
|
|
|
|
tabindex="-1" |
|
|
|
|
class="w-full h-[50%] transition duration-75 group-hover:text-gray-900 dark:group-hover:text-white" |
|
|
|
|
/> |
|
|
|
|
</button> |
|
|
|
|
</div> |
|
|
|
|
{/if} |
|
|
|
|
</div> |
|
|
|
|
<!-- Navigation Buttons for pazzle, order pin, mnemonic --> |
|
|
|
|
<div class="flex justify-between mt-auto"> |
|
|
|
|
<button |
|
|
|
|
on:click={cancel} |
|
|
|
|
class="mt-1 bg-red-100 hover:bg-red-100/90 focus:ring-4 focus:ring-primary-100/50 rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55" |
|
|
|
|
><XCircle |
|
|
|
|
tabindex="-1" |
|
|
|
|
class="w-8 h-8 mr-2 -ml-1 transition duration-75 group-hover:text-gray-900 dark:group-hover:text-white" |
|
|
|
|
/>Cancel</button |
|
|
|
|
> |
|
|
|
|
<button |
|
|
|
|
class="mt-1 focus:ring-4 focus:ring-primary-100/50 rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55" |
|
|
|
|
on:click={go_back} |
|
|
|
|
><Backspace |
|
|
|
|
tabindex="-1" |
|
|
|
|
class="w-8 h-8 mr-2 -ml-1 transition duration-75 group-hover:text-gray-900 dark:group-hover:text-white" |
|
|
|
|
/>Go Back</button |
|
|
|
|
> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
{:else if step == "opening"} |
|
|
|
@ -453,6 +563,7 @@ |
|
|
|
|
{:else if step == "end"} |
|
|
|
|
{#if error} |
|
|
|
|
<div class=" max-w-6xl lg:px-8 mx-auto px-4 text-red-800"> |
|
|
|
|
<div class="mt-auto max-w-6xl lg:px-8"> |
|
|
|
|
An error occurred ! |
|
|
|
|
<svg |
|
|
|
|
fill="none" |
|
|
|
@ -472,8 +583,27 @@ |
|
|
|
|
<Alert color="red" class="mt-5"> |
|
|
|
|
{error} |
|
|
|
|
</Alert> |
|
|
|
|
<button class="mt-10 select-none" on:click={init}> Try again </button> |
|
|
|
|
<button class="mt-10 ml-5 select-none" on:click={cancel}> Cancel </button> |
|
|
|
|
</div> |
|
|
|
|
<div class="flex justify-between mt-auto gap-4"> |
|
|
|
|
<button |
|
|
|
|
class="mt-10 select-none text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-100/50 rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55" |
|
|
|
|
on:click={init} |
|
|
|
|
> |
|
|
|
|
<ArrowPath |
|
|
|
|
tabindex="-1" |
|
|
|
|
class="w-8 h-8 mr-2 -ml-1 transition duration-75 group-hover:text-gray-900 dark:group-hover:text-white" |
|
|
|
|
/> |
|
|
|
|
Try again |
|
|
|
|
</button> |
|
|
|
|
<button |
|
|
|
|
on:click={cancel} |
|
|
|
|
class="mt-10 bg-red-100 hover:bg-red-100/90 focus:ring-4 focus:ring-primary-100/50 rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55" |
|
|
|
|
><XCircle |
|
|
|
|
tabindex="-1" |
|
|
|
|
class="w-8 h-8 mr-2 -ml-1 transition duration-75 group-hover:text-gray-900 dark:group-hover:text-white" |
|
|
|
|
/>Cancel</button |
|
|
|
|
> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
{:else} |
|
|
|
|
<div class=" max-w-6xl lg:px-8 mx-auto px-4 text-green-800"> |
|
|
|
@ -496,6 +626,9 @@ |
|
|
|
|
</div> |
|
|
|
|
{/if} |
|
|
|
|
{/if} |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<svelte:window bind:innerWidth={width} bind:innerHeight={height} /> |
|
|
|
|
|
|
|
|
|
<style> |
|
|
|
|
.pazzleline { |
|
|
|
|