Compare commits
No commits in common. "a56e33b9f2449970257db80c3602cbe28eb26126" and "775aa83134d6b261a31c5b87644a621aa60e2160" have entirely different histories.
a56e33b9f2
...
775aa83134
|
@ -2,5 +2,5 @@
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="https://jenkins.blek.codes/job/bWordle/badge/icon?style=plastic"></img>
|
<img src="https://jenkins.blek.codes/job/bWordle/badge/icon?style=plastic"></img>
|
||||||
</p>
|
</p>
|
||||||
OpenWordle is a completely open source and lightweight wordle game with very minimal set of runtime dependencies
|
OpenWordle is a completely open source and lightweight wordle game with no runtime dependencies
|
||||||
|
|
||||||
|
|
|
@ -19,9 +19,5 @@
|
||||||
"typescript": "^5.0.2",
|
"typescript": "^5.0.2",
|
||||||
"vite": "^4.4.5",
|
"vite": "^4.4.5",
|
||||||
"vite-plugin-compression": "^0.5.1"
|
"vite-plugin-compression": "^0.5.1"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"copy-to-clipboard": "^3.3.3",
|
|
||||||
"qr-creator": "^1.0.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,6 @@
|
||||||
import { isIn, loadDict } from "./dictionary";
|
import { isIn, loadDict } from "./dictionary";
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
import Keyboard from "./Keyboard.svelte";
|
import Keyboard from "./Keyboard.svelte";
|
||||||
import GameCreator from "./GameCreator.svelte";
|
|
||||||
import { decode } from "./lib/cipher";
|
|
||||||
|
|
||||||
let targets = getForNWord(5);
|
let targets = getForNWord(5);
|
||||||
|
|
||||||
|
@ -25,22 +23,12 @@
|
||||||
|
|
||||||
let loading = true;
|
let loading = true;
|
||||||
let not_a_word = false;
|
let not_a_word = false;
|
||||||
let game_creator = false;
|
|
||||||
|
|
||||||
let green_letters: string[] = [];
|
let green_letters: string[] = [];
|
||||||
let yellow_letters: string[] = [];
|
let yellow_letters: string[] = [];
|
||||||
let unfit_letters: string[] = [];
|
let unfit_letters: string[] = [];
|
||||||
|
|
||||||
(
|
console.log(word);
|
||||||
function() {
|
|
||||||
const urlprops = new URLSearchParams(window.location.search);
|
|
||||||
const challenge = urlprops.get('challenge');
|
|
||||||
if (challenge !== null) {
|
|
||||||
word = decode(atob(decodeURIComponent(challenge)));
|
|
||||||
console.log(word)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)()
|
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
await loadDict();
|
await loadDict();
|
||||||
|
@ -142,8 +130,6 @@
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<GameCreator bind:show={game_creator} />
|
|
||||||
|
|
||||||
{#if not_a_word}
|
{#if not_a_word}
|
||||||
<Modal show animate={false}>
|
<Modal show animate={false}>
|
||||||
<ModalTitle>
|
<ModalTitle>
|
||||||
|
@ -188,10 +174,6 @@
|
||||||
Give up
|
Give up
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button on:click={() => {game_creator = true}}>
|
|
||||||
Create a game
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<p style='line-height:0;margin-top:48px'>
|
<p style='line-height:0;margin-top:48px'>
|
||||||
{#each guessed as g1, i}
|
{#each guessed as g1, i}
|
||||||
{#each g1 as letter, ii}
|
{#each g1 as letter, ii}
|
||||||
|
|
|
@ -1,69 +0,0 @@
|
||||||
<script lang='ts'>
|
|
||||||
import { onMount } from "svelte";
|
|
||||||
import Modal from "./modal/Modal.svelte";
|
|
||||||
import ModalButton from "./modal/ModalButton.svelte";
|
|
||||||
import ModalContent from "./modal/ModalContent.svelte";
|
|
||||||
import ModalFooter from "./modal/ModalFooter.svelte";
|
|
||||||
import ModalTitle from "./modal/ModalTitle.svelte";
|
|
||||||
import { encode } from "./lib/cipher";
|
|
||||||
import { getRandom } from "./targets";
|
|
||||||
|
|
||||||
export let show = false;
|
|
||||||
|
|
||||||
let word = getRandom(5);
|
|
||||||
let qrurl: string | false = false;
|
|
||||||
let wordurl = '';
|
|
||||||
let qrcanvas: HTMLCanvasElement;
|
|
||||||
|
|
||||||
async function upd_qr() {
|
|
||||||
if (word == '') return;
|
|
||||||
if (!qrcanvas) return;
|
|
||||||
wordurl = `${window.location.protocol}//${window.location.host}?challenge=${encodeURIComponent(btoa(encode(word)))}`;
|
|
||||||
const QrCreator = (await import('qr-creator')).default;
|
|
||||||
|
|
||||||
QrCreator.render({
|
|
||||||
text: wordurl,
|
|
||||||
radius: 0.5,
|
|
||||||
ecLevel: 'L',
|
|
||||||
fill: '#000000',
|
|
||||||
background: '#ffffff',
|
|
||||||
size: 120
|
|
||||||
}, qrcanvas);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function copylink() {
|
|
||||||
const copy = (await import('copy-to-clipboard')).default;
|
|
||||||
copy(wordurl);
|
|
||||||
}
|
|
||||||
|
|
||||||
onMount(async () => {
|
|
||||||
await upd_qr();
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
{#if show}
|
|
||||||
<Modal show>
|
|
||||||
<ModalTitle>
|
|
||||||
Create a game
|
|
||||||
</ModalTitle>
|
|
||||||
<ModalContent>
|
|
||||||
<p>
|
|
||||||
Word:
|
|
||||||
<input type='text' bind:value={word} on:input={upd_qr}>
|
|
||||||
</p>
|
|
||||||
<p style='min-height:160px'>
|
|
||||||
<span style='border-radius:12px;padding:20px;background:white;display:inline-block'>
|
|
||||||
<canvas bind:this={qrcanvas} width="120px" height="122px" style='border-radius:4px' />
|
|
||||||
</span>
|
|
||||||
</p>
|
|
||||||
</ModalContent>
|
|
||||||
<ModalFooter>
|
|
||||||
<ModalButton style='width:50%;border-right:0;border-radius:0 0 0 16px' onclick={() => {show = false; word = getRandom(5); upd_qr()}}>
|
|
||||||
Close
|
|
||||||
</ModalButton>
|
|
||||||
<ModalButton style='width:50%;border-radius:0 0 16px 0' onclick={copylink}>
|
|
||||||
Copy link
|
|
||||||
</ModalButton>
|
|
||||||
</ModalFooter>
|
|
||||||
</Modal>
|
|
||||||
{/if}
|
|
12
src/app.css
12
src/app.css
|
@ -43,18 +43,6 @@ button:active {
|
||||||
background: #161616;
|
background: #161616;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type=text] {
|
|
||||||
background: #181818;
|
|
||||||
border: 1px solid #343434;
|
|
||||||
border-radius: 6px;
|
|
||||||
margin: 0 4px;
|
|
||||||
padding: 4px 6px;
|
|
||||||
outline: none;
|
|
||||||
min-width: 80px;
|
|
||||||
width: 80px;
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-color-scheme: light) {
|
@media (prefers-color-scheme: light) {
|
||||||
:root {
|
:root {
|
||||||
color: #213547;
|
color: #213547;
|
||||||
|
|
|
@ -1,12 +1,7 @@
|
||||||
import targets from "./targets";
|
|
||||||
|
|
||||||
let dict: string[] = [];
|
let dict: string[] = [];
|
||||||
let dict_loaded = false;
|
let dict_loaded = false;
|
||||||
|
|
||||||
export async function loadDict(onprogress?: {(data: { loaded: number, total: number }): void}) {
|
export async function loadDict(onprogress?: {(data: { loaded: number, total: number }): void}) {
|
||||||
|
|
||||||
if (dict_loaded) return dict;
|
|
||||||
|
|
||||||
const req = await fetch('/dictionary.csv', {
|
const req = await fetch('/dictionary.csv', {
|
||||||
cache: 'force-cache'
|
cache: 'force-cache'
|
||||||
});
|
});
|
||||||
|
@ -29,7 +24,6 @@ export async function loadDict(onprogress?: {(data: { loaded: number, total: num
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
dict = data.split(',');
|
dict = data.split(',');
|
||||||
dict = [ ...targets, ...dict ];
|
|
||||||
dict_loaded = true;
|
dict_loaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
import { random } from "./random";
|
|
||||||
|
|
||||||
export function encode(word: string) {
|
|
||||||
let out = '';
|
|
||||||
for (const letter of word) {
|
|
||||||
out += String.fromCharCode(random(32, 128)) + letter;
|
|
||||||
}
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
export function decode(ciphertext: string) {
|
|
||||||
let out = '';
|
|
||||||
for (let i = 0; i != ciphertext.length; i++) {
|
|
||||||
if (i % 2 == 1) {
|
|
||||||
out += ciphertext[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
globalThis.encode = encode;
|
|
||||||
globalThis.decode = decode;
|
|
|
@ -11,14 +11,4 @@ export function getForNWord(len: number) {
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getRandom(len: number | null = null) {
|
|
||||||
const dataset = len ? getForNWord(len) : targets;
|
|
||||||
for (const target of dataset) {
|
|
||||||
if (random(0, Math.floor(dataset.length * 0.5)) == 0) {
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dataset[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
export default targets
|
export default targets
|
|
@ -1,4 +1,3 @@
|
||||||
/// <reference types="svelte" />
|
/// <reference types="svelte" />
|
||||||
/// <reference types="vite/client" />
|
/// <reference types="vite/client" />
|
||||||
const TARGETS: string;
|
const TARGETS: string
|
||||||
declare module 'qr-creator';
|
|
17
yarn.lock
17
yarn.lock
|
@ -333,13 +333,6 @@ concat-map@0.0.1:
|
||||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||||
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
|
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
|
||||||
|
|
||||||
copy-to-clipboard@^3.3.3:
|
|
||||||
version "3.3.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz#55ac43a1db8ae639a4bd99511c148cdd1b83a1b0"
|
|
||||||
integrity sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==
|
|
||||||
dependencies:
|
|
||||||
toggle-selection "^1.0.6"
|
|
||||||
|
|
||||||
css-tree@^2.3.1:
|
css-tree@^2.3.1:
|
||||||
version "2.3.1"
|
version "2.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.3.1.tgz#10264ce1e5442e8572fc82fbe490644ff54b5c20"
|
resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.3.1.tgz#10264ce1e5442e8572fc82fbe490644ff54b5c20"
|
||||||
|
@ -677,11 +670,6 @@ postcss@^8.4.27:
|
||||||
picocolors "^1.0.0"
|
picocolors "^1.0.0"
|
||||||
source-map-js "^1.0.2"
|
source-map-js "^1.0.2"
|
||||||
|
|
||||||
qr-creator@^1.0.0:
|
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/qr-creator/-/qr-creator-1.0.0.tgz#f350a8f0b5be02bd1fc1ef133a038a06ef8bc5ef"
|
|
||||||
integrity sha512-C0cqfbS1P5hfqN4NhsYsUXePlk9BO+a45bAQ3xLYjBL3bOIFzoVEjs79Fado9u9BPBD3buHi3+vY+C8tHh4qMQ==
|
|
||||||
|
|
||||||
queue-microtask@^1.2.2:
|
queue-microtask@^1.2.2:
|
||||||
version "1.2.3"
|
version "1.2.3"
|
||||||
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
|
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
|
||||||
|
@ -827,11 +815,6 @@ to-regex-range@^5.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
is-number "^7.0.0"
|
is-number "^7.0.0"
|
||||||
|
|
||||||
toggle-selection@^1.0.6:
|
|
||||||
version "1.0.6"
|
|
||||||
resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32"
|
|
||||||
integrity sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==
|
|
||||||
|
|
||||||
tslib@^2.6.0:
|
tslib@^2.6.0:
|
||||||
version "2.6.2"
|
version "2.6.2"
|
||||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"
|
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"
|
||||||
|
|
Loading…
Reference in New Issue