This commit is contained in:
Philippe Torrel
2026-08-19 11:41:58 +02:00
parent c6d9611e81
commit ae9b04f27f
111 changed files with 3878 additions and 24 deletions

View File

@@ -0,0 +1,8 @@
function calculateAverage(numbers) {
const total = numbers.reduce((sum, num) => sum + num, 0);
const average = total / numbers.length;
return average;
}
console.log(calculateAverage([10, 20, 30])); // => 20
console.log(calculateAverage([5, 15, 25, 35])); // => 20

View File

@@ -0,0 +1,40 @@
// logical error
function findMaximum(a, b, c) {
if (a >= b && a >= c) {
return a;
} else if (b >= a && b >= c) {
return b;
} else {
return c;
}
}
const findMaximum2 = (...numbers) => {
return numbers.reduce((max, current) => {
if (current > max) return current;
else return max;
});
};
const findMaximum3 = (...numbers) => {
return Math.max(...numbers);
};
console.time('if else');
console.log(findMaximum(1, 2, 3)); // => 3
console.log(findMaximum(102, 59, 18)); // => 102
console.log(findMaximum(532, 532, 345)); // => 532
console.timeEnd('if else');
console.time('reduce');
console.log(findMaximum2(1, 2, 3)); // => 3
console.log(findMaximum2(102, 59, 18)); // => 102
console.log(findMaximum2(532, 532, 345)); // => 532
console.timeEnd('reduce');
console.time('Math.max');
console.log(findMaximum3(1, 2, 3)); // => 3
console.log(findMaximum3(102, 59, 18)); // => 102
console.log(findMaximum3(532, 532, 345)); // => 532
console.timeEnd('Math.max');

View File

@@ -1,17 +1,47 @@
'use strict'; 'use strict';
(() => { (() => {
// === DOM & VARS ======= // ===== DOM =====
const DOM = {}; const DOM = {
temperatureForm: document.querySelector('#temperatureForm'),
celsiusInput: document.querySelector('#celsius'),
result: document.querySelector('#result'),
};
// === INIT ============= // ===== INIT =====
const init = () => {}; const init = () => {
DOM.temperatureForm.addEventListener('submit', handleFormSubmit);
};
// === EVENTHANDLER ===== // ===== EVENT HANDLERS =====
function handleFormSubmit(e) {
e.preventDefault(); // Standardverhalten unterbinden
const celsius = Number(DOM.celsiusInput.value);
// === XHR/FETCH ======== // falsche Verneinung
if (isNaN(celsius)) {
alert('Please enter a valid number');
return;
}
// === FUNCTIONS ======== const fahrenheit = convertToFahrenheit(celsius);
displayResult(fahrenheit);
DOM.temperatureForm.reset();
}
// ===== FUNCTIONS =====
function convertToFahrenheit(celsius) {
if (typeof celsius !== 'number') return NaN;
return (celsius * 9) / 5 + 32;
}
function displayResult(result) {
DOM.result.textContent = result.toFixed(2);
}
// ===== CALL INIT =====
init(); init();
})(); })();

View File

@@ -8,18 +8,20 @@
</head> </head>
<body> <body>
<div class="container py-5"> <div class="container py-5">
<div class="counter">
<h1>Counter</h1> <h1>Counter</h1>
<div class="row mt-4"> <div class="row mt-4">
<div class="col col-12 col-sm-10 col-lg-6"> <div class="col col-12 col-sm-10 col-lg-6">
<div class="input-group mb-3"> <div class="input-group mb-3">
<span class="input-group-text" id="basic-addon1">Count:</span> <span class="input-group-text" id="basic-addon1">Count:</span>
<input type="text" id="count" class="form-control" value="0" readonly /> <input type="text" id="count" class="form-control input-count" value="0" readonly aria-label="Counter" />
</div> </div>
<button id="incrementButton" class="btn btn-primary w-100">Increment</button> <button id="incrementButton" class="btn btn-primary w-100">Increment</button>
</div> </div>
</div> </div>
</div> </div>
</div>
<script> <script>
'use strict'; 'use strict';
@@ -38,8 +40,8 @@
// ===== EVENT HANDLER ===== // ===== EVENT HANDLER =====
function onClickIncrement() { function onClickIncrement() {
let count = counter.count; let count = ++counter.count;
count++; // count++;
countEl.value = counter.count; countEl.value = counter.count;
} }

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
@@ -25,18 +25,33 @@
'use strict'; 'use strict';
(() => { (() => {
// === DOM & VARS ======= // ===== DOM & VARS =====
const DOM = {}; const countEl = document.querySelector('#count');
const btnEl = document.querySelector('#incrementButton');
// === INIT ============= let counter = { count: 0 };
const init = () => {};
// === EVENTHANDLER ===== // ===== INIT =====
const init = () => {
btnEl.addEventListener('click', onClickIncrement);
};
// === XHR/FETCH ======== // ===== EVENT HANDLER =====
function onClickIncrement() {
// variante 1
// let count = counter.count;
// count++;
// counter = { count: count };
// === FUNCTIONS ======== // Variante 2
// counter = { count: ++counter.count }; // hier ist der präfix-inkrement wichtig - der post-inkrement würde ins "leere" gehen, da er erst zugewiesen wird und dann erhöht und diese somit verloren ginge
// Variante 3 - direkt counter.count erhöhren
counter.count++;
countEl.value = counter.count;
}
// ===== CALL INIT =====
init(); init();
})(); })();
</script> </script>

View File

@@ -0,0 +1,44 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="A lightweight local AI assistant chat interface." />
<title>AI Assistant (Test)</title>
<link rel="stylesheet" href="style.css" />
<script src="script.js" defer></script>
</head>
<body>
<main class="chat-window" aria-label="AI Assistant chat">
<header class="chat-header">
<div class="header-icon" aria-hidden="true">AI</div>
<div class="header-copy">
<h1>AI Assistant (Test)</h1>
<p class="status"><span class="status-dot" aria-hidden="true"></span>Online · Test environment</p>
</div>
</header>
<section id="messageLog" class="message-log" aria-live="polite" aria-label="Chat messages">
<div class="message-row assistant">
<div class="avatar" aria-hidden="true">AI</div>
<div class="bubble">Hello! The test assistant is online and ready.</div>
</div>
<div class="message-row user">
<div class="bubble">Run a quick systems check.</div>
</div>
<div class="message-row assistant">
<div class="avatar" aria-hidden="true">AI</div>
<div class="bubble">All interface systems are operational. Send a message to continue.</div>
</div>
</section>
<form id="chatForm" class="input-bar">
<label class="sr-only" for="messageInput">Message</label>
<input id="messageInput" type="text" placeholder="Type a message..." autocomplete="off" />
<button type="submit">Send</button>
</form>
</main>
</body>
</html>

View File

@@ -0,0 +1,60 @@
"use strict";
const chatForm = document.getElementById("chatForm");
const messageInput = document.getElementById("messageInput");
const messageLog = document.getElementById("messageLog");
const mockResponses = [
"Mock response received. Systems operational.",
"Test message acknowledged.",
"Processing complete. Everything looks good.",
"Your message has been logged successfully.",
"Simulation active. Ready for the next command."
];
function scrollToBottom() {
messageLog.scrollTop = messageLog.scrollHeight;
}
function appendMessage(text, sender) {
const row = document.createElement("div");
row.className = `message-row ${sender}`;
if (sender === "assistant") {
const avatar = document.createElement("div");
avatar.className = "avatar";
avatar.setAttribute("aria-hidden", "true");
avatar.textContent = "AI";
row.appendChild(avatar);
}
const bubble = document.createElement("div");
bubble.className = "bubble";
bubble.textContent = text;
row.appendChild(bubble);
messageLog.appendChild(row);
scrollToBottom();
}
chatForm.addEventListener("submit", (event) => {
event.preventDefault();
const message = messageInput.value.trim();
if (!message) {
messageInput.focus();
return;
}
appendMessage(message, "user");
messageInput.value = "";
messageInput.focus();
window.setTimeout(() => {
const randomIndex = Math.floor(Math.random() * mockResponses.length);
appendMessage(mockResponses[randomIndex], "assistant");
}, 1000);
});
scrollToBottom();
messageInput.focus();

View File

@@ -0,0 +1,285 @@
:root {
color-scheme: dark;
--background: #070b14;
--panel: #111827;
--panel-soft: #182235;
--border: rgba(148, 163, 184, 0.16);
--text: #f8fafc;
--muted: #94a3b8;
--cyan: #22d3ee;
--blue: #2563eb;
}
* {
box-sizing: border-box;
}
body {
min-height: 100vh;
margin: 0;
display: grid;
place-items: center;
padding: 20px;
overflow: hidden;
color: var(--text);
font-family:
Inter,
ui-sans-serif,
system-ui,
-apple-system,
BlinkMacSystemFont,
'Segoe UI',
sans-serif;
background:
radial-gradient(circle at 20% 15%, rgba(37, 99, 235, 0.15), transparent 32%),
radial-gradient(circle at 80% 85%, rgba(34, 211, 238, 0.11), transparent 30%), var(--background);
}
.chat-window {
width: min(100%, 460px);
height: min(600px, calc(100vh - 40px));
display: flex;
flex-direction: column;
overflow: hidden;
border: 1px solid var(--border);
border-radius: 24px;
background: rgba(17, 24, 39, 0.94);
box-shadow:
0 30px 80px rgba(0, 0, 0, 0.55),
0 0 40px rgba(34, 211, 238, 0.06);
backdrop-filter: blur(18px);
}
.chat-header {
flex: 0 0 auto;
display: flex;
align-items: center;
gap: 12px;
min-height: 76px;
padding: 16px 20px;
border-bottom: 1px solid var(--border);
background: rgba(15, 23, 42, 0.82);
}
.header-icon,
.avatar {
display: grid;
place-items: center;
flex: 0 0 auto;
color: #06101b;
font-weight: 800;
background: linear-gradient(135deg, var(--cyan), #60a5fa);
box-shadow: 0 0 20px rgba(34, 211, 238, 0.28);
}
.header-icon {
width: 42px;
height: 42px;
border-radius: 14px;
font-size: 20px;
}
.header-copy {
min-width: 0;
}
.header-copy h1 {
margin: 0;
overflow: hidden;
font-size: 16px;
letter-spacing: 0.01em;
text-overflow: ellipsis;
white-space: nowrap;
}
.status {
display: flex;
align-items: center;
gap: 7px;
margin: 4px 0 0;
color: var(--muted);
font-size: 12px;
}
.status-dot {
width: 7px;
height: 7px;
border-radius: 50%;
background: #34d399;
box-shadow: 0 0 10px #34d399;
}
.message-log {
flex: 1 1 auto;
min-height: 0;
overflow-y: auto;
padding: 22px 18px;
scroll-behavior: smooth;
scrollbar-color: #334155 transparent;
scrollbar-width: thin;
}
.message-log::-webkit-scrollbar {
width: 6px;
}
.message-log::-webkit-scrollbar-thumb {
border-radius: 999px;
background: #334155;
}
.message-row {
display: flex;
align-items: flex-end;
gap: 9px;
margin-bottom: 16px;
animation: appear 180ms ease-out;
}
.message-row.user {
justify-content: flex-end;
}
.avatar {
width: 30px;
height: 30px;
border-radius: 10px;
font-size: 13px;
}
.bubble {
max-width: 78%;
padding: 11px 14px;
overflow-wrap: anywhere;
border: 1px solid var(--border);
border-radius: 17px 17px 17px 5px;
color: #e2e8f0;
font-size: 14px;
line-height: 1.48;
background: var(--panel-soft);
box-shadow: 0 8px 18px rgba(0, 0, 0, 0.15);
}
.user .bubble {
border: 0;
border-radius: 17px 17px 5px 17px;
color: white;
background: linear-gradient(135deg, #0891b2, var(--blue));
box-shadow: 0 8px 22px rgba(37, 99, 235, 0.24);
}
.input-bar {
flex: 0 0 auto;
display: flex;
gap: 10px;
padding: 15px;
border-top: 1px solid var(--border);
background: rgba(15, 23, 42, 0.92);
}
.input-bar input {
min-width: 0;
flex: 1;
height: 46px;
padding: 0 15px;
border: 1px solid #334155;
border-radius: 14px;
outline: none;
color: var(--text);
font: inherit;
background: #0b1220;
transition:
border-color 160ms ease,
box-shadow 160ms ease;
}
.input-bar input::placeholder {
color: #64748b;
}
.input-bar input:focus {
border-color: var(--cyan);
box-shadow: 0 0 0 3px rgba(34, 211, 238, 0.12);
}
.input-bar button {
height: 46px;
padding: 0 19px;
border: 0;
border-radius: 14px;
cursor: pointer;
color: #03131d;
font: inherit;
font-weight: 800;
background: linear-gradient(135deg, #67e8f9, #38bdf8);
box-shadow: 0 8px 22px rgba(34, 211, 238, 0.2);
transition:
transform 140ms ease,
filter 140ms ease;
}
.input-bar button:hover {
filter: brightness(1.08);
transform: translateY(-1px);
}
.input-bar button:active {
transform: translateY(1px);
}
.input-bar button:focus-visible,
.input-bar input:focus-visible {
outline: 2px solid var(--cyan);
outline-offset: 2px;
}
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
@keyframes appear {
from {
opacity: 0;
transform: translateY(6px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@media (max-width: 480px) {
body {
padding: 0;
}
.chat-window {
width: 100%;
height: 100vh;
height: 100dvh;
border: 0;
border-radius: 0;
}
.bubble {
max-width: 84%;
}
}
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
scroll-behavior: auto !important;
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
}
}

View File

@@ -0,0 +1,136 @@
/* style.css */
body {
margin: 0;
padding: 0;
background-color: #1e1e1e;
color: white;
font-family: 'Segoe UI', sans-serif;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.chat-container {
width: 480px;
height: 600px;
background-color: #2c2c2c;
border-radius: 16px;
box-shadow: 0 0 20px rgba(0, 123, 255, 0.3);
display: flex;
flex-direction: column;
overflow: hidden;
}
.chat-container .chat-header {
padding: 16px;
background-color: #3c3c3c;
color: #00bfff;
font-size: 18px;
font-weight: bold;
text-align: center;
border-bottom: 1px solid #4c4c4c;
}
.chat-container .chat-body {
flex: 1;
padding: 16px;
overflow-y: auto;
display: flex;
flex-direction: column;
gap: 12px;
}
.chat-container .message {
display: flex;
align-items: start;
gap: 10px;
}
.chat-container .message.user {
justify-content: flex-end;
}
.chat-container .message.user .text {
background-color: #00bfff;
color: white;
padding: 12px 16px;
border-radius: 18px;
max-width: 70%;
margin-left: auto;
position: relative;
animation: fadeIn 0.3s ease;
}
.chat-container .message.assistant {
justify-content: flex-start;
}
.chat-container .message.assistant .avatar {
background-color: #3c3c3c;
color: #00bfff;
border-radius: 50%;
width: 36px;
height: 36px;
display: flex;
align-items: center;
justify-content: center;
font-size: 20px;
flex-shrink: 0;
}
.chat-container .message.assistant .text {
background-color: #2c2c2c;
color: #ccc;
padding: 12px 16px;
border-radius: 18px;
max-width: 70%;
margin-right: auto;
position: relative;
animation: fadeIn 0.3s ease;
}
.chat-container .chat-input {
display: flex;
gap: 8px;
padding: 12px;
background-color: #3c3c3c;
border-top: 1px solid #4c4c4c;
}
.chat-container .chat-input input {
flex: 1;
padding: 10px 12px;
border: none;
border-radius: 20px;
background-color: #3c3c3c;
color: white;
outline: none;
font-size: 14px;
}
.chat-container .chat-input button {
padding: 10px 20px;
border: none;
border-radius: 20px;
background-color: #00bfff;
color: white;
font-weight: bold;
cursor: pointer;
transition: background-color 0.2s ease;
}
.chat-container .chat-input button:hover {
background-color: #009ddc;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}

View File

@@ -0,0 +1,59 @@
// script.js
document.addEventListener('DOMContentLoaded', () => {
const chatBody = document.getElementById('chatBody');
const chatForm = document.getElementById('chatForm');
const userInput = document.getElementById('userInput');
const mockResponses = [
'Mock response received. Systems operational.',
'Test message acknowledged.',
"I'm here to help with any questions you may have.",
'Let me look that up for you...',
'Would you like me to provide more details?',
];
function addMessage(text, isUser = false) {
const messageDiv = document.createElement('div');
messageDiv.classList.add('message', isUser ? 'user' : 'assistant');
if (!isUser) {
const avatar = document.createElement('div');
avatar.classList.add('avatar');
avatar.textContent = '🤖';
messageDiv.appendChild(avatar);
}
const textDiv = document.createElement('div');
textDiv.classList.add('text');
textDiv.textContent = text;
messageDiv.appendChild(textDiv);
chatBody.appendChild(messageDiv);
chatBody.scrollTop = chatBody.scrollHeight;
userInput.focus();
}
function handleSubmit(e) {
e.preventDefault();
const inputText = userInput.value.trim();
if (inputText) {
addMessage(inputText, true);
userInput.value = '';
setTimeout(() => {
const randomIndex = Math.floor(Math.random() * mockResponses.length);
addMessage(mockResponses[randomIndex]);
}, 1000);
}
}
chatForm.addEventListener('submit', handleSubmit);
// Handle Enter key
userInput.addEventListener('keydown', (e) => {
if (e.key === 'Enter') {
handleSubmit(e);
}
});
});

View File

@@ -0,0 +1,33 @@
<!-- index.html -->
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>AI Chat</title>
<link rel="stylesheet" href="assets/css/style.css" />
<script src="assets/js/script.js" defer></script>
</head>
<body>
<div class="chat-container">
<div class="chat-header">AI Assistant (Test)</div>
<div class="chat-body" id="chatBody">
<div class="message assistant">
<div class="avatar">🤖</div>
<div class="text">Hello! How can I assist you today?</div>
</div>
<div class="message user">
<div class="text">Hi, can you help me with something?</div>
</div>
<div class="message assistant">
<div class="avatar">🤖</div>
<div class="text">Of course! What would you like help with?</div>
</div>
</div>
<form class="chat-input" id="chatForm">
<input type="text" id="userInput" placeholder="Type a message..." required />
<button type="submit">Send</button>
</form>
</div>
</body>
</html>

View File

@@ -0,0 +1,15 @@
export { default as MAX } from './max.js';
export { default as NIL } from './nil.js';
export { default as parse } from './parse.js';
export { default as stringify } from './stringify.js';
export type * from './types.js';
export { default as v1 } from './v1.js';
export { default as v1ToV6 } from './v1ToV6.js';
export { default as v3 } from './v3.js';
export { default as v4 } from './v4.js';
export { default as v5 } from './v5.js';
export { default as v6 } from './v6.js';
export { default as v6ToV1 } from './v6ToV1.js';
export { default as v7 } from './v7.js';
export { default as validate } from './validate.js';
export { default as version } from './version.js';

View File

@@ -0,0 +1,14 @@
export { default as MAX } from './max.js';
export { default as NIL } from './nil.js';
export { default as parse } from './parse.js';
export { default as stringify } from './stringify.js';
export { default as v1 } from './v1.js';
export { default as v1ToV6 } from './v1ToV6.js';
export { default as v3 } from './v3.js';
export { default as v4 } from './v4.js';
export { default as v5 } from './v5.js';
export { default as v6 } from './v6.js';
export { default as v6ToV1 } from './v6ToV1.js';
export { default as v7 } from './v7.js';
export { default as validate } from './validate.js';
export { default as version } from './version.js';

View File

@@ -0,0 +1,2 @@
declare const _default: "ffffffff-ffff-ffff-ffff-ffffffffffff";
export default _default;

View File

@@ -0,0 +1 @@
export default 'ffffffff-ffff-ffff-ffff-ffffffffffff';

View File

@@ -0,0 +1,2 @@
declare function md5(bytes: Uint8Array): Uint8Array;
export default md5;

View File

@@ -0,0 +1,135 @@
function md5(bytes) {
const words = uint8ToUint32(bytes);
const md5Bytes = wordsToMd5(words, bytes.length * 8);
return uint32ToUint8(md5Bytes);
}
function uint32ToUint8(input) {
const bytes = new Uint8Array(input.length * 4);
for (let i = 0; i < input.length * 4; i++) {
bytes[i] = (input[i >> 2] >>> ((i % 4) * 8)) & 0xff;
}
return bytes;
}
function getOutputLength(inputLength8) {
return (((inputLength8 + 64) >>> 9) << 4) + 14 + 1;
}
function wordsToMd5(x, len) {
const xpad = new Uint32Array(getOutputLength(len)).fill(0);
xpad.set(x);
xpad[len >> 5] |= 0x80 << (len % 32);
xpad[xpad.length - 1] = len;
x = xpad;
let a = 1732584193;
let b = -271733879;
let c = -1732584194;
let d = 271733878;
for (let i = 0; i < x.length; i += 16) {
const olda = a;
const oldb = b;
const oldc = c;
const oldd = d;
a = md5ff(a, b, c, d, x[i], 7, -680876936);
d = md5ff(d, a, b, c, x[i + 1], 12, -389564586);
c = md5ff(c, d, a, b, x[i + 2], 17, 606105819);
b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330);
a = md5ff(a, b, c, d, x[i + 4], 7, -176418897);
d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426);
c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341);
b = md5ff(b, c, d, a, x[i + 7], 22, -45705983);
a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416);
d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417);
c = md5ff(c, d, a, b, x[i + 10], 17, -42063);
b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162);
a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682);
d = md5ff(d, a, b, c, x[i + 13], 12, -40341101);
c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290);
b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329);
a = md5gg(a, b, c, d, x[i + 1], 5, -165796510);
d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632);
c = md5gg(c, d, a, b, x[i + 11], 14, 643717713);
b = md5gg(b, c, d, a, x[i], 20, -373897302);
a = md5gg(a, b, c, d, x[i + 5], 5, -701558691);
d = md5gg(d, a, b, c, x[i + 10], 9, 38016083);
c = md5gg(c, d, a, b, x[i + 15], 14, -660478335);
b = md5gg(b, c, d, a, x[i + 4], 20, -405537848);
a = md5gg(a, b, c, d, x[i + 9], 5, 568446438);
d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690);
c = md5gg(c, d, a, b, x[i + 3], 14, -187363961);
b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501);
a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467);
d = md5gg(d, a, b, c, x[i + 2], 9, -51403784);
c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473);
b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734);
a = md5hh(a, b, c, d, x[i + 5], 4, -378558);
d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463);
c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562);
b = md5hh(b, c, d, a, x[i + 14], 23, -35309556);
a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060);
d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353);
c = md5hh(c, d, a, b, x[i + 7], 16, -155497632);
b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640);
a = md5hh(a, b, c, d, x[i + 13], 4, 681279174);
d = md5hh(d, a, b, c, x[i], 11, -358537222);
c = md5hh(c, d, a, b, x[i + 3], 16, -722521979);
b = md5hh(b, c, d, a, x[i + 6], 23, 76029189);
a = md5hh(a, b, c, d, x[i + 9], 4, -640364487);
d = md5hh(d, a, b, c, x[i + 12], 11, -421815835);
c = md5hh(c, d, a, b, x[i + 15], 16, 530742520);
b = md5hh(b, c, d, a, x[i + 2], 23, -995338651);
a = md5ii(a, b, c, d, x[i], 6, -198630844);
d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415);
c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905);
b = md5ii(b, c, d, a, x[i + 5], 21, -57434055);
a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571);
d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606);
c = md5ii(c, d, a, b, x[i + 10], 15, -1051523);
b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799);
a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359);
d = md5ii(d, a, b, c, x[i + 15], 10, -30611744);
c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380);
b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649);
a = md5ii(a, b, c, d, x[i + 4], 6, -145523070);
d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379);
c = md5ii(c, d, a, b, x[i + 2], 15, 718787259);
b = md5ii(b, c, d, a, x[i + 9], 21, -343485551);
a = safeAdd(a, olda);
b = safeAdd(b, oldb);
c = safeAdd(c, oldc);
d = safeAdd(d, oldd);
}
return Uint32Array.of(a, b, c, d);
}
function uint8ToUint32(input) {
if (input.length === 0) {
return new Uint32Array();
}
const output = new Uint32Array(getOutputLength(input.length * 8)).fill(0);
for (let i = 0; i < input.length; i++) {
output[i >> 2] |= (input[i] & 0xff) << ((i % 4) * 8);
}
return output;
}
function safeAdd(x, y) {
const lsw = (x & 0xffff) + (y & 0xffff);
const msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xffff);
}
function bitRotateLeft(num, cnt) {
return (num << cnt) | (num >>> (32 - cnt));
}
function md5cmn(q, a, b, x, s, t) {
return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b);
}
function md5ff(a, b, c, d, x, s, t) {
return md5cmn((b & c) | (~b & d), a, b, x, s, t);
}
function md5gg(a, b, c, d, x, s, t) {
return md5cmn((b & d) | (c & ~d), a, b, x, s, t);
}
function md5hh(a, b, c, d, x, s, t) {
return md5cmn(b ^ c ^ d, a, b, x, s, t);
}
function md5ii(a, b, c, d, x, s, t) {
return md5cmn(c ^ (b | ~d), a, b, x, s, t);
}
export default md5;

View File

@@ -0,0 +1,2 @@
declare const _default: "00000000-0000-0000-0000-000000000000";
export default _default;

View File

@@ -0,0 +1 @@
export default '00000000-0000-0000-0000-000000000000';

View File

@@ -0,0 +1,3 @@
import type { NonSharedArrayBuffer } from './types.js';
declare function parse(uuid: string): NonSharedArrayBuffer;
export default parse;

View File

@@ -0,0 +1,9 @@
import validate from './validate.js';
function parse(uuid) {
if (!validate(uuid)) {
throw TypeError('Invalid UUID');
}
let v;
return Uint8Array.of((v = parseInt(uuid.slice(0, 8), 16)) >>> 24, (v >>> 16) & 0xff, (v >>> 8) & 0xff, v & 0xff, (v = parseInt(uuid.slice(9, 13), 16)) >>> 8, v & 0xff, (v = parseInt(uuid.slice(14, 18), 16)) >>> 8, v & 0xff, (v = parseInt(uuid.slice(19, 23), 16)) >>> 8, v & 0xff, ((v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000) & 0xff, (v / 0x100000000) & 0xff, (v >>> 24) & 0xff, (v >>> 16) & 0xff, (v >>> 8) & 0xff, v & 0xff);
}
export default parse;

View File

@@ -0,0 +1,2 @@
declare const _default: RegExp;
export default _default;

View File

@@ -0,0 +1 @@
export default /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/i;

View File

@@ -0,0 +1 @@
export default function rng(): Uint8Array;

View File

@@ -0,0 +1,4 @@
const rnds8 = new Uint8Array(16);
export default function rng() {
return crypto.getRandomValues(rnds8);
}

View File

@@ -0,0 +1,2 @@
declare function sha1(bytes: Uint8Array): Uint8Array;
export default sha1;

View File

@@ -0,0 +1,70 @@
function f(s, x, y, z) {
switch (s) {
case 0:
return (x & y) ^ (~x & z);
case 1:
return x ^ y ^ z;
case 2:
return (x & y) ^ (x & z) ^ (y & z);
case 3:
return x ^ y ^ z;
}
}
function ROTL(x, n) {
return (x << n) | (x >>> (32 - n));
}
function sha1(bytes) {
const K = [0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6];
const H = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0];
const newBytes = new Uint8Array(bytes.length + 1);
newBytes.set(bytes);
newBytes[bytes.length] = 0x80;
bytes = newBytes;
const l = bytes.length / 4 + 2;
const N = Math.ceil(l / 16);
const M = new Array(N);
for (let i = 0; i < N; ++i) {
const arr = new Uint32Array(16);
for (let j = 0; j < 16; ++j) {
arr[j] =
(bytes[i * 64 + j * 4] << 24) |
(bytes[i * 64 + j * 4 + 1] << 16) |
(bytes[i * 64 + j * 4 + 2] << 8) |
bytes[i * 64 + j * 4 + 3];
}
M[i] = arr;
}
M[N - 1][14] = ((bytes.length - 1) * 8) / 2 ** 32;
M[N - 1][14] = Math.floor(M[N - 1][14]);
M[N - 1][15] = ((bytes.length - 1) * 8) & 0xffffffff;
for (let i = 0; i < N; ++i) {
const W = new Uint32Array(80);
for (let t = 0; t < 16; ++t) {
W[t] = M[i][t];
}
for (let t = 16; t < 80; ++t) {
W[t] = ROTL(W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16], 1);
}
let a = H[0];
let b = H[1];
let c = H[2];
let d = H[3];
let e = H[4];
for (let t = 0; t < 80; ++t) {
const s = Math.floor(t / 20);
const T = (ROTL(a, 5) + f(s, b, c, d) + e + K[s] + W[t]) >>> 0;
e = d;
d = c;
c = ROTL(b, 30) >>> 0;
b = a;
a = T;
}
H[0] = (H[0] + a) >>> 0;
H[1] = (H[1] + b) >>> 0;
H[2] = (H[2] + c) >>> 0;
H[3] = (H[3] + d) >>> 0;
H[4] = (H[4] + e) >>> 0;
}
return Uint8Array.of(H[0] >> 24, H[0] >> 16, H[0] >> 8, H[0], H[1] >> 24, H[1] >> 16, H[1] >> 8, H[1], H[2] >> 24, H[2] >> 16, H[2] >> 8, H[2], H[3] >> 24, H[3] >> 16, H[3] >> 8, H[3], H[4] >> 24, H[4] >> 16, H[4] >> 8, H[4]);
}
export default sha1;

View File

@@ -0,0 +1,3 @@
export declare function unsafeStringify(arr: Uint8Array, offset?: number): string;
declare function stringify(arr: Uint8Array, offset?: number): string;
export default stringify;

View File

@@ -0,0 +1,35 @@
import validate from './validate.js';
const byteToHex = [];
for (let i = 0; i < 256; ++i) {
byteToHex.push((i + 0x100).toString(16).slice(1));
}
export function unsafeStringify(arr, offset = 0) {
return (byteToHex[arr[offset + 0]] +
byteToHex[arr[offset + 1]] +
byteToHex[arr[offset + 2]] +
byteToHex[arr[offset + 3]] +
'-' +
byteToHex[arr[offset + 4]] +
byteToHex[arr[offset + 5]] +
'-' +
byteToHex[arr[offset + 6]] +
byteToHex[arr[offset + 7]] +
'-' +
byteToHex[arr[offset + 8]] +
byteToHex[arr[offset + 9]] +
'-' +
byteToHex[arr[offset + 10]] +
byteToHex[arr[offset + 11]] +
byteToHex[arr[offset + 12]] +
byteToHex[arr[offset + 13]] +
byteToHex[arr[offset + 14]] +
byteToHex[arr[offset + 15]]).toLowerCase();
}
function stringify(arr, offset = 0) {
const uuid = unsafeStringify(arr, offset);
if (!validate(uuid)) {
throw TypeError('Stringified UUID is invalid');
}
return uuid;
}
export default stringify;

View File

@@ -0,0 +1,22 @@
export type UUIDTypes<TBuf extends Uint8Array = Uint8Array> = string | TBuf;
export type Version1Options = {
node?: Uint8Array;
clockseq?: number;
random?: Uint8Array;
rng?: () => Uint8Array;
msecs?: number;
nsecs?: number;
_v6?: boolean;
};
export type Version4Options = {
random?: Uint8Array;
rng?: () => Uint8Array;
};
export type Version6Options = Version1Options;
export type Version7Options = {
random?: Uint8Array;
msecs?: number;
seq?: number;
rng?: () => Uint8Array;
};
export type NonSharedArrayBuffer = ReturnType<typeof Uint8Array.of>;

View File

@@ -0,0 +1,70 @@
import * as assert from 'node:assert/strict';
import v1 from './v1.js';
import v3 from './v3.js';
import v4 from './v4.js';
import v5 from './v5.js';
import v6 from './v6.js';
import v7 from './v7.js';
function usage() {
console.log('Usage:');
console.log(' uuid');
console.log(' uuid v1');
console.log(' uuid v3 <name> <namespace uuid>');
console.log(' uuid v4');
console.log(' uuid v5 <name> <namespace uuid>');
console.log(' uuid v6');
console.log(' uuid v7');
console.log(' uuid --help');
console.log('\nNote: <namespace uuid> may be "URL" or "DNS" to use the corresponding UUIDs defined by RFC9562');
}
const args = process.argv.slice(2);
if (args.indexOf('--help') >= 0) {
usage();
process.exit(0);
}
const version = args.shift() || 'v4';
switch (version) {
case 'v1':
console.log(v1());
break;
case 'v3': {
const name = args.shift();
let namespace = args.shift();
assert.ok(name != null, 'v3 name not specified');
assert.ok(namespace != null, 'v3 namespace not specified');
if (namespace === 'URL') {
namespace = v3.URL;
}
if (namespace === 'DNS') {
namespace = v3.DNS;
}
console.log(v3(name, namespace));
break;
}
case 'v4':
console.log(v4());
break;
case 'v5': {
const name = args.shift();
let namespace = args.shift();
assert.ok(name != null, 'v5 name not specified');
assert.ok(namespace != null, 'v5 namespace not specified');
if (namespace === 'URL') {
namespace = v5.URL;
}
if (namespace === 'DNS') {
namespace = v5.DNS;
}
console.log(v5(name, namespace));
break;
}
case 'v6':
console.log(v6());
break;
case 'v7':
console.log(v7());
break;
default:
usage();
process.exit(1);
}

View File

@@ -0,0 +1,11 @@
import type { Version1Options } from './types.js';
type V1State = {
node?: Uint8Array;
clockseq?: number;
msecs?: number;
nsecs?: number;
};
declare function v1(options?: Version1Options, buf?: undefined, offset?: number): string;
declare function v1<Buf extends Uint8Array = Uint8Array>(options: Version1Options | undefined, buf: Buf, offset?: number): Buf;
export declare function updateV1State(state: V1State, now: number, rnds: Uint8Array): V1State;
export default v1;

View File

@@ -0,0 +1,87 @@
import rng from './rng.js';
import { unsafeStringify } from './stringify.js';
const _state = {};
function v1(options, buf, offset) {
let bytes;
const isV6 = options?._v6 ?? false;
if (options) {
const optionsKeys = Object.keys(options);
if (optionsKeys.length === 1 && optionsKeys[0] === '_v6') {
options = undefined;
}
}
if (options) {
bytes = v1Bytes(options.random ?? options.rng?.() ?? rng(), options.msecs, options.nsecs, options.clockseq, options.node, buf, offset);
}
else {
const now = Date.now();
const rnds = rng();
updateV1State(_state, now, rnds);
bytes = v1Bytes(rnds, _state.msecs, _state.nsecs, isV6 ? undefined : _state.clockseq, isV6 ? undefined : _state.node, buf, offset);
}
return buf ?? unsafeStringify(bytes);
}
export function updateV1State(state, now, rnds) {
state.msecs ??= -Infinity;
state.nsecs ??= 0;
if (now === state.msecs) {
state.nsecs++;
if (state.nsecs >= 10000) {
state.node = undefined;
state.nsecs = 0;
}
}
else if (now > state.msecs) {
state.nsecs = 0;
}
else if (now < state.msecs) {
state.node = undefined;
}
if (!state.node) {
state.node = rnds.slice(10, 16);
state.node[0] |= 0x01;
state.clockseq = ((rnds[8] << 8) | rnds[9]) & 0x3fff;
}
state.msecs = now;
return state;
}
function v1Bytes(rnds, msecs, nsecs, clockseq, node, buf, offset = 0) {
if (rnds.length < 16) {
throw new Error('Random bytes length must be >= 16');
}
if (!buf) {
buf = new Uint8Array(16);
offset = 0;
}
else {
if (offset < 0 || offset + 16 > buf.length) {
throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);
}
}
msecs ??= Date.now();
nsecs ??= 0;
clockseq ??= ((rnds[8] << 8) | rnds[9]) & 0x3fff;
if (node == null) {
node = rnds.slice(10, 16);
node[0] |= 0x01;
}
msecs += 12219292800000;
const t = (msecs & 0xfffffff) * 10000 + nsecs;
const tl = t >>> 0;
buf[offset++] = (tl >>> 24) & 0xff;
buf[offset++] = (tl >>> 16) & 0xff;
buf[offset++] = (tl >>> 8) & 0xff;
buf[offset++] = tl & 0xff;
const tmh = (((msecs / 0x10000000) | 0) * 625 + ((t / 0x100000000) | 0)) & 0xfffffff;
buf[offset++] = (tmh >>> 8) & 0xff;
buf[offset++] = tmh & 0xff;
buf[offset++] = ((tmh >>> 24) & 0xf) | 0x10;
buf[offset++] = (tmh >>> 16) & 0xff;
buf[offset++] = (clockseq >>> 8) | 0x80;
buf[offset++] = clockseq & 0xff;
for (let n = 0; n < 6; ++n) {
buf[offset++] = node[n];
}
return buf;
}
export default v1;

View File

@@ -0,0 +1,3 @@
import type { NonSharedArrayBuffer } from './types.js';
export default function v1ToV6(uuid: string): string;
export default function v1ToV6(uuid: Uint8Array): NonSharedArrayBuffer;

View File

@@ -0,0 +1,10 @@
import parse from './parse.js';
import { unsafeStringify } from './stringify.js';
export default function v1ToV6(uuid) {
const v1Bytes = typeof uuid === 'string' ? parse(uuid) : uuid;
const v6Bytes = _v1ToV6(v1Bytes);
return typeof uuid === 'string' ? unsafeStringify(v6Bytes) : v6Bytes;
}
function _v1ToV6(v1Bytes) {
return Uint8Array.of(((v1Bytes[6] & 0x0f) << 4) | ((v1Bytes[7] >> 4) & 0x0f), ((v1Bytes[7] & 0x0f) << 4) | ((v1Bytes[4] & 0xf0) >> 4), ((v1Bytes[4] & 0x0f) << 4) | ((v1Bytes[5] & 0xf0) >> 4), ((v1Bytes[5] & 0x0f) << 4) | ((v1Bytes[0] & 0xf0) >> 4), ((v1Bytes[0] & 0x0f) << 4) | ((v1Bytes[1] & 0xf0) >> 4), ((v1Bytes[1] & 0x0f) << 4) | ((v1Bytes[2] & 0xf0) >> 4), 0x60 | (v1Bytes[2] & 0x0f), v1Bytes[3], v1Bytes[8], v1Bytes[9], v1Bytes[10], v1Bytes[11], v1Bytes[12], v1Bytes[13], v1Bytes[14], v1Bytes[15]);
}

View File

@@ -0,0 +1,9 @@
import type { UUIDTypes } from './types.js';
export { DNS, URL } from './v35.js';
declare function v3(value: string | Uint8Array, namespace: UUIDTypes, buf?: undefined, offset?: number): string;
declare function v3<TBuf extends Uint8Array = Uint8Array>(value: string | Uint8Array, namespace: UUIDTypes, buf: TBuf, offset?: number): TBuf;
declare namespace v3 {
var DNS: string;
var URL: string;
}
export default v3;

View File

@@ -0,0 +1,9 @@
import md5 from './md5.js';
import v35, { DNS, URL } from './v35.js';
export { DNS, URL } from './v35.js';
function v3(value, namespace, buf, offset) {
return v35(0x30, md5, value, namespace, buf, offset);
}
v3.DNS = DNS;
v3.URL = URL;
export default v3;

View File

@@ -0,0 +1,7 @@
import type { UUIDTypes } from './types.js';
export declare function stringToBytes(str: string): Uint8Array;
export declare const DNS = "6ba7b810-9dad-11d1-80b4-00c04fd430c8";
export declare const URL = "6ba7b811-9dad-11d1-80b4-00c04fd430c8";
type HashFunction = (bytes: Uint8Array) => Uint8Array;
export default function v35<TBuf extends Uint8Array = Uint8Array>(version: 0x30 | 0x50, hash: HashFunction, value: string | Uint8Array, namespace: UUIDTypes, buf?: TBuf, offset?: number): UUIDTypes<TBuf>;
export {};

View File

@@ -0,0 +1,39 @@
import parse from './parse.js';
import { unsafeStringify } from './stringify.js';
export function stringToBytes(str) {
str = unescape(encodeURIComponent(str));
const bytes = new Uint8Array(str.length);
for (let i = 0; i < str.length; ++i) {
bytes[i] = str.charCodeAt(i);
}
return bytes;
}
export const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8';
export const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8';
export default function v35(version, hash, value, namespace, buf, offset) {
const valueBytes = typeof value === 'string' ? stringToBytes(value) : value;
const namespaceBytes = typeof namespace === 'string' ? parse(namespace) : namespace;
if (typeof namespace === 'string') {
namespace = parse(namespace);
}
if (namespace?.length !== 16) {
throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)');
}
let bytes = new Uint8Array(16 + valueBytes.length);
bytes.set(namespaceBytes);
bytes.set(valueBytes, namespaceBytes.length);
bytes = hash(bytes);
bytes[6] = (bytes[6] & 0x0f) | version;
bytes[8] = (bytes[8] & 0x3f) | 0x80;
if (buf) {
offset ??= 0;
if (offset < 0 || offset + 16 > buf.length) {
throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);
}
for (let i = 0; i < 16; ++i) {
buf[offset + i] = bytes[i];
}
return buf;
}
return unsafeStringify(bytes);
}

View File

@@ -0,0 +1,4 @@
import type { Version4Options } from './types.js';
declare function v4(options?: Version4Options, buf?: undefined, offset?: number): string;
declare function v4<TBuf extends Uint8Array = Uint8Array>(options: Version4Options | undefined, buf: TBuf, offset?: number): TBuf;
export default v4;

View File

@@ -0,0 +1,29 @@
import rng from './rng.js';
import { unsafeStringify } from './stringify.js';
function v4(options, buf, offset) {
if (!buf && !options && crypto.randomUUID) {
return crypto.randomUUID();
}
return _v4(options, buf, offset);
}
function _v4(options, buf, offset) {
options = options || {};
const rnds = options.random ?? options.rng?.() ?? rng();
if (rnds.length < 16) {
throw new Error('Random bytes length must be >= 16');
}
rnds[6] = (rnds[6] & 0x0f) | 0x40;
rnds[8] = (rnds[8] & 0x3f) | 0x80;
if (buf) {
offset = offset || 0;
if (offset < 0 || offset + 16 > buf.length) {
throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);
}
for (let i = 0; i < 16; ++i) {
buf[offset + i] = rnds[i];
}
return buf;
}
return unsafeStringify(rnds);
}
export default v4;

View File

@@ -0,0 +1,9 @@
import type { UUIDTypes } from './types.js';
export { DNS, URL } from './v35.js';
declare function v5(value: string | Uint8Array, namespace: UUIDTypes, buf?: undefined, offset?: number): string;
declare function v5<TBuf extends Uint8Array = Uint8Array>(value: string | Uint8Array, namespace: UUIDTypes, buf: TBuf, offset?: number): TBuf;
declare namespace v5 {
var DNS: string;
var URL: string;
}
export default v5;

View File

@@ -0,0 +1,9 @@
import sha1 from './sha1.js';
import v35, { DNS, URL } from './v35.js';
export { DNS, URL } from './v35.js';
function v5(value, namespace, buf, offset) {
return v35(0x50, sha1, value, namespace, buf, offset);
}
v5.DNS = DNS;
v5.URL = URL;
export default v5;

View File

@@ -0,0 +1,4 @@
import type { Version6Options } from './types.js';
declare function v6(options?: Version6Options, buf?: undefined, offset?: number): string;
declare function v6<TBuf extends Uint8Array = Uint8Array>(options: Version6Options | undefined, buf: TBuf, offset?: number): TBuf;
export default v6;

View File

@@ -0,0 +1,20 @@
import { unsafeStringify } from './stringify.js';
import v1 from './v1.js';
import v1ToV6 from './v1ToV6.js';
function v6(options, buf, offset) {
options ??= {};
offset ??= 0;
let bytes = v1({ ...options, _v6: true }, new Uint8Array(16));
bytes = v1ToV6(bytes);
if (buf) {
if (offset < 0 || offset + 16 > buf.length) {
throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);
}
for (let i = 0; i < 16; i++) {
buf[offset + i] = bytes[i];
}
return buf;
}
return unsafeStringify(bytes);
}
export default v6;

View File

@@ -0,0 +1,2 @@
export default function v6ToV1(uuid: string): string;
export default function v6ToV1(uuid: Uint8Array): Uint8Array;

View File

@@ -0,0 +1,10 @@
import parse from './parse.js';
import { unsafeStringify } from './stringify.js';
export default function v6ToV1(uuid) {
const v6Bytes = typeof uuid === 'string' ? parse(uuid) : uuid;
const v1Bytes = _v6ToV1(v6Bytes);
return typeof uuid === 'string' ? unsafeStringify(v1Bytes) : v1Bytes;
}
function _v6ToV1(v6Bytes) {
return Uint8Array.of(((v6Bytes[3] & 0x0f) << 4) | ((v6Bytes[4] >> 4) & 0x0f), ((v6Bytes[4] & 0x0f) << 4) | ((v6Bytes[5] & 0xf0) >> 4), ((v6Bytes[5] & 0x0f) << 4) | (v6Bytes[6] & 0x0f), v6Bytes[7], ((v6Bytes[1] & 0x0f) << 4) | ((v6Bytes[2] & 0xf0) >> 4), ((v6Bytes[2] & 0x0f) << 4) | ((v6Bytes[3] & 0xf0) >> 4), 0x10 | ((v6Bytes[0] & 0xf0) >> 4), ((v6Bytes[0] & 0x0f) << 4) | ((v6Bytes[1] & 0xf0) >> 4), v6Bytes[8], v6Bytes[9], v6Bytes[10], v6Bytes[11], v6Bytes[12], v6Bytes[13], v6Bytes[14], v6Bytes[15]);
}

View File

@@ -0,0 +1,9 @@
import type { Version7Options } from './types.js';
type V7State = {
msecs?: number;
seq?: number;
};
declare function v7(options?: Version7Options, buf?: undefined, offset?: number): string;
declare function v7<TBuf extends Uint8Array = Uint8Array>(options: Version7Options | undefined, buf: TBuf, offset?: number): TBuf;
export declare function updateV7State(state: V7State, now: number, rnds: Uint8Array): V7State;
export default v7;

View File

@@ -0,0 +1,68 @@
import rng from './rng.js';
import { unsafeStringify } from './stringify.js';
const _state = {};
function v7(options, buf, offset) {
let bytes;
if (options) {
bytes = v7Bytes(options.random ?? options.rng?.() ?? rng(), options.msecs, options.seq, buf, offset);
}
else {
const now = Date.now();
const rnds = rng();
updateV7State(_state, now, rnds);
bytes = v7Bytes(rnds, _state.msecs, _state.seq, buf, offset);
}
return buf ?? unsafeStringify(bytes);
}
export function updateV7State(state, now, rnds) {
state.msecs ??= -Infinity;
state.seq ??= 0;
if (now > state.msecs) {
state.seq = v7Sequence(rnds);
state.msecs = now;
}
else {
state.seq = (state.seq + 1) | 0;
if (state.seq === 0) {
state.msecs++;
}
}
return state;
}
function v7Bytes(rnds, msecs, seq, buf, offset = 0) {
if (rnds.length < 16) {
throw new Error('Random bytes length must be >= 16');
}
if (!buf) {
buf = new Uint8Array(16);
offset = 0;
}
else {
if (offset < 0 || offset + 16 > buf.length) {
throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);
}
}
msecs ??= Date.now();
seq ??= v7Sequence(rnds);
buf[offset++] = (msecs / 0x10000000000) & 0xff;
buf[offset++] = (msecs / 0x100000000) & 0xff;
buf[offset++] = (msecs / 0x1000000) & 0xff;
buf[offset++] = (msecs / 0x10000) & 0xff;
buf[offset++] = (msecs / 0x100) & 0xff;
buf[offset++] = msecs & 0xff;
buf[offset++] = 0x70 | ((seq >>> 28) & 0x0f);
buf[offset++] = (seq >>> 20) & 0xff;
buf[offset++] = 0x80 | ((seq >>> 14) & 0x3f);
buf[offset++] = (seq >>> 6) & 0xff;
buf[offset++] = ((seq << 2) & 0xff) | (rnds[10] & 0x03);
buf[offset++] = rnds[11];
buf[offset++] = rnds[12];
buf[offset++] = rnds[13];
buf[offset++] = rnds[14];
buf[offset++] = rnds[15];
return buf;
}
function v7Sequence(rnds) {
return ((rnds[6] & 0x7f) << 24) | (rnds[7] << 16) | (rnds[8] << 8) | rnds[9];
}
export default v7;

View File

@@ -0,0 +1,2 @@
declare function validate(uuid: unknown): boolean;
export default validate;

View File

@@ -0,0 +1,5 @@
import REGEX from './regex.js';
function validate(uuid) {
return typeof uuid === 'string' && REGEX.test(uuid);
}
export default validate;

View File

@@ -0,0 +1,2 @@
declare function version(uuid: string): number;
export default version;

View File

@@ -0,0 +1,8 @@
import validate from './validate.js';
function version(uuid) {
if (!validate(uuid)) {
throw TypeError('Invalid UUID');
}
return parseInt(uuid.slice(14, 15), 16);
}
export default version;

View File

@@ -0,0 +1,23 @@
import Counter from './modules/Counter.js'; // wichtig mit Dateiendung, da kein Bundler
(() => {
// === DOM & VARS =======
const DOM = {
counters: Array.from(document.querySelectorAll('.counter')),
};
// === INIT =============
const init = () => {
DOM.counters.forEach((el) => {
Counter(el);
});
};
// === EVENTHANDLER =====
// === XHR/FETCH ========
// === FUNCTIONS ========
init();
})();

View File

@@ -0,0 +1,36 @@
import v4 from '../libs/uuid/v4.js';
const Counter = (elOrSelector = null) => {
// ===== DOM & VARS =====
// TODO: forEach for string selector
const module = elOrSelector || document.querySelector(elOrSelector);
const countEl = module.querySelector('input[id^="count"]');
const btnEl = module.querySelector('button[id^="incrementButton"]');
const id = v4();
countEl.id = `count-${id}`;
btnEl.id = `incrementButton-${id}`;
// console.log('id:', id);
let counter = { count: 0 };
// ===== INIT =====
const init = () => {
btnEl.addEventListener('click', onClickIncrement);
};
// ===== EVENT HANDLER =====
function onClickIncrement() {
let count = ++counter.count;
// count++;
countEl.value = counter.count;
}
// ===== CALL INIT =====
init();
};
export default Counter;

View File

@@ -0,0 +1,83 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Counter Example</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
<script src="assets/js/main.js" type="module"></script>
</head>
<body>
<main id="main">
<section class="section-hero">
<div class="container py-3">
<div class="col-12">
<div class="mb-3">
<h2>HERO</h2>
</div>
</div>
</div>
</section>
<section class="section-content">
<div class="container">
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Ipsum animi eaque doloremque error voluptate alias
dolorem esse qui voluptatum eius placeat unde consequuntur sequi dolor, repudiandae nobis. Excepturi,
dolores tenetur.
</p>
</div>
<div class="counter">
<div class="container py-5">
<h3>Counter</h3>
<div class="row mt-4">
<div class="col col-12 col-sm-10 col-lg-6">
<div class="input-group mb-3">
<span class="input-group-text">Count:</span>
<input
type="text"
id="count"
class="form-control input-count"
value="0"
readonly
aria-label="Counter" />
</div>
<button id="incrementButton" class="btn btn-primary w-100">Increment</button>
</div>
</div>
</div>
</div>
<!-- ▲ /counter ▲ -->
</section>
</main>
<footer>
<div class="container py-3 align-items-center">
<div class="col">
<p>&copy; copyright 2026 Donkey-Coders</p>
</div>
<div class="col">
<div class="counter">
<div class="container py-5">
<h3>Counter</h3>
<div class="row mt-4">
<div class="col col-12 col-sm-10 col-lg-6">
<div class="input-group mb-3">
<span class="input-group-text">Count:</span>
<input
type="text"
id="count-2"
class="form-control input-count"
value="0"
readonly
aria-label="Counter" />
</div>
<button id="incrementButton-2" class="btn btn-primary w-100">Increment</button>
</div>
</div>
</div>
</div>
<!-- ▲ /counter ▲ -->
</div>
</div>
</footer>
</body>
</html>

View File

@@ -0,0 +1,660 @@
{
"name": "webseite-html",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "webseite-html",
"version": "1.0.0",
"dependencies": {
"uuid": "^14.0.2"
},
"devDependencies": {
"http-server": "^14.1.1"
}
},
"node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"license": "MIT",
"dependencies": {
"color-convert": "^2.0.1"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/async": {
"version": "3.2.6",
"resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
"integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
"dev": true,
"license": "MIT"
},
"node_modules/basic-auth": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
"integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==",
"dev": true,
"license": "MIT",
"dependencies": {
"safe-buffer": "5.1.2"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/call-bind-apply-helpers": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/call-bound": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
"integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
"dev": true,
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
"get-intrinsic": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"color-name": "~1.1.4"
},
"engines": {
"node": ">=7.0.0"
}
},
"node_modules/color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true,
"license": "MIT"
},
"node_modules/corser": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz",
"integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4.0"
}
},
"node_modules/debug": {
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
"dev": true,
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
"dev": true,
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"es-errors": "^1.3.0",
"gopd": "^1.2.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-define-property": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-object-atoms": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz",
"integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==",
"dev": true,
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/eventemitter3": {
"version": "4.0.7",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
"integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
"dev": true,
"license": "MIT"
},
"node_modules/follow-redirects": {
"version": "1.16.0",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz",
"integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==",
"dev": true,
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"license": "MIT",
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"dev": true,
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-intrinsic": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
"es-define-property": "^1.0.1",
"es-errors": "^1.3.0",
"es-object-atoms": "^1.1.1",
"function-bind": "^1.1.2",
"get-proto": "^1.0.1",
"gopd": "^1.2.0",
"has-symbols": "^1.1.0",
"hasown": "^2.0.2",
"math-intrinsics": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
"dev": true,
"license": "MIT",
"dependencies": {
"dunder-proto": "^1.0.1",
"es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/has-symbols": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/hasown": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz",
"integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==",
"dev": true,
"license": "MIT",
"dependencies": {
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/he": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
"dev": true,
"license": "MIT",
"bin": {
"he": "bin/he"
}
},
"node_modules/html-encoding-sniffer": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz",
"integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==",
"dev": true,
"license": "MIT",
"dependencies": {
"whatwg-encoding": "^2.0.0"
},
"engines": {
"node": ">=12"
}
},
"node_modules/http-proxy": {
"version": "1.18.1",
"resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
"integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"eventemitter3": "^4.0.0",
"follow-redirects": "^1.0.0",
"requires-port": "^1.0.0"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/http-server": {
"version": "14.1.1",
"resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz",
"integrity": "sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==",
"dev": true,
"license": "MIT",
"dependencies": {
"basic-auth": "^2.0.1",
"chalk": "^4.1.2",
"corser": "^2.0.1",
"he": "^1.2.0",
"html-encoding-sniffer": "^3.0.0",
"http-proxy": "^1.18.1",
"mime": "^1.6.0",
"minimist": "^1.2.6",
"opener": "^1.5.1",
"portfinder": "^1.0.28",
"secure-compare": "3.0.1",
"union": "~0.5.0",
"url-join": "^4.0.1"
},
"bin": {
"http-server": "bin/http-server"
},
"engines": {
"node": ">=12"
}
},
"node_modules/iconv-lite": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
"dev": true,
"license": "MIT",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/mime": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
"dev": true,
"license": "MIT",
"bin": {
"mime": "cli.js"
},
"engines": {
"node": ">=4"
}
},
"node_modules/minimist": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
"dev": true,
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true,
"license": "MIT"
},
"node_modules/object-inspect": {
"version": "1.13.4",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
"integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/opener": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz",
"integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==",
"dev": true,
"license": "(WTFPL OR MIT)",
"bin": {
"opener": "bin/opener-bin.js"
}
},
"node_modules/portfinder": {
"version": "1.0.38",
"resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.38.tgz",
"integrity": "sha512-rEwq/ZHlJIKw++XtLAO8PPuOQA/zaPJOZJ37BVuN97nLpMJeuDVLVGRwbFoBgLudgdTMP2hdRJP++H+8QOA3vg==",
"dev": true,
"license": "MIT",
"dependencies": {
"async": "^3.2.6",
"debug": "^4.3.6"
},
"engines": {
"node": ">= 10.12"
}
},
"node_modules/qs": {
"version": "6.15.3",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.15.3.tgz",
"integrity": "sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"es-define-property": "^1.0.1",
"side-channel": "^1.1.1"
},
"engines": {
"node": ">=0.6"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/requires-port": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
"dev": true,
"license": "MIT"
},
"node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"dev": true,
"license": "MIT"
},
"node_modules/safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
"dev": true,
"license": "MIT"
},
"node_modules/secure-compare": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz",
"integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==",
"dev": true,
"license": "MIT"
},
"node_modules/side-channel": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz",
"integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"object-inspect": "^1.13.4",
"side-channel-list": "^1.0.1",
"side-channel-map": "^1.0.1",
"side-channel-weakmap": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-list": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz",
"integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==",
"dev": true,
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"object-inspect": "^1.13.4"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-map": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
"integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
"dev": true,
"license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.5",
"object-inspect": "^1.13.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-weakmap": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
"integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
"dev": true,
"license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.5",
"object-inspect": "^1.13.3",
"side-channel-map": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"license": "MIT",
"dependencies": {
"has-flag": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/union": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz",
"integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==",
"dev": true,
"dependencies": {
"qs": "^6.4.0"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/url-join": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz",
"integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==",
"dev": true,
"license": "MIT"
},
"node_modules/uuid": {
"version": "14.0.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.2.tgz",
"integrity": "sha512-xZe/16rV4aa+HGSOCiY2YeLT1OybRLrrkL/Rqaq7p7GMVXjFh+6wN4oMYgjFmnSnhY8t6Xpdl2l9qmnHYuMHwQ==",
"funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
],
"license": "MIT",
"bin": {
"uuid": "dist-node/bin/uuid"
}
},
"node_modules/whatwg-encoding": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz",
"integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==",
"deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation",
"dev": true,
"license": "MIT",
"dependencies": {
"iconv-lite": "0.6.3"
},
"engines": {
"node": ">=12"
}
}
}
}

View File

@@ -0,0 +1,17 @@
{
"name": "webseite-html",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "npx http-server -c-1 -p 3000"
},
"keywords": [],
"type": "commonjs",
"devDependencies": {
"http-server": "^14.1.1"
},
"dependencies": {
"uuid": "^14.0.2"
}
}

View File

@@ -0,0 +1,15 @@
export { default as MAX } from './max.js';
export { default as NIL } from './nil.js';
export { default as parse } from './parse.js';
export { default as stringify } from './stringify.js';
export type * from './types.js';
export { default as v1 } from './v1.js';
export { default as v1ToV6 } from './v1ToV6.js';
export { default as v3 } from './v3.js';
export { default as v4 } from './v4.js';
export { default as v5 } from './v5.js';
export { default as v6 } from './v6.js';
export { default as v6ToV1 } from './v6ToV1.js';
export { default as v7 } from './v7.js';
export { default as validate } from './validate.js';
export { default as version } from './version.js';

View File

@@ -0,0 +1,14 @@
export { default as MAX } from './max.js';
export { default as NIL } from './nil.js';
export { default as parse } from './parse.js';
export { default as stringify } from './stringify.js';
export { default as v1 } from './v1.js';
export { default as v1ToV6 } from './v1ToV6.js';
export { default as v3 } from './v3.js';
export { default as v4 } from './v4.js';
export { default as v5 } from './v5.js';
export { default as v6 } from './v6.js';
export { default as v6ToV1 } from './v6ToV1.js';
export { default as v7 } from './v7.js';
export { default as validate } from './validate.js';
export { default as version } from './version.js';

View File

@@ -0,0 +1,2 @@
declare const _default: "ffffffff-ffff-ffff-ffff-ffffffffffff";
export default _default;

View File

@@ -0,0 +1 @@
export default 'ffffffff-ffff-ffff-ffff-ffffffffffff';

View File

@@ -0,0 +1,2 @@
declare function md5(bytes: Uint8Array): Uint8Array;
export default md5;

View File

@@ -0,0 +1,135 @@
function md5(bytes) {
const words = uint8ToUint32(bytes);
const md5Bytes = wordsToMd5(words, bytes.length * 8);
return uint32ToUint8(md5Bytes);
}
function uint32ToUint8(input) {
const bytes = new Uint8Array(input.length * 4);
for (let i = 0; i < input.length * 4; i++) {
bytes[i] = (input[i >> 2] >>> ((i % 4) * 8)) & 0xff;
}
return bytes;
}
function getOutputLength(inputLength8) {
return (((inputLength8 + 64) >>> 9) << 4) + 14 + 1;
}
function wordsToMd5(x, len) {
const xpad = new Uint32Array(getOutputLength(len)).fill(0);
xpad.set(x);
xpad[len >> 5] |= 0x80 << (len % 32);
xpad[xpad.length - 1] = len;
x = xpad;
let a = 1732584193;
let b = -271733879;
let c = -1732584194;
let d = 271733878;
for (let i = 0; i < x.length; i += 16) {
const olda = a;
const oldb = b;
const oldc = c;
const oldd = d;
a = md5ff(a, b, c, d, x[i], 7, -680876936);
d = md5ff(d, a, b, c, x[i + 1], 12, -389564586);
c = md5ff(c, d, a, b, x[i + 2], 17, 606105819);
b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330);
a = md5ff(a, b, c, d, x[i + 4], 7, -176418897);
d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426);
c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341);
b = md5ff(b, c, d, a, x[i + 7], 22, -45705983);
a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416);
d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417);
c = md5ff(c, d, a, b, x[i + 10], 17, -42063);
b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162);
a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682);
d = md5ff(d, a, b, c, x[i + 13], 12, -40341101);
c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290);
b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329);
a = md5gg(a, b, c, d, x[i + 1], 5, -165796510);
d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632);
c = md5gg(c, d, a, b, x[i + 11], 14, 643717713);
b = md5gg(b, c, d, a, x[i], 20, -373897302);
a = md5gg(a, b, c, d, x[i + 5], 5, -701558691);
d = md5gg(d, a, b, c, x[i + 10], 9, 38016083);
c = md5gg(c, d, a, b, x[i + 15], 14, -660478335);
b = md5gg(b, c, d, a, x[i + 4], 20, -405537848);
a = md5gg(a, b, c, d, x[i + 9], 5, 568446438);
d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690);
c = md5gg(c, d, a, b, x[i + 3], 14, -187363961);
b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501);
a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467);
d = md5gg(d, a, b, c, x[i + 2], 9, -51403784);
c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473);
b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734);
a = md5hh(a, b, c, d, x[i + 5], 4, -378558);
d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463);
c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562);
b = md5hh(b, c, d, a, x[i + 14], 23, -35309556);
a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060);
d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353);
c = md5hh(c, d, a, b, x[i + 7], 16, -155497632);
b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640);
a = md5hh(a, b, c, d, x[i + 13], 4, 681279174);
d = md5hh(d, a, b, c, x[i], 11, -358537222);
c = md5hh(c, d, a, b, x[i + 3], 16, -722521979);
b = md5hh(b, c, d, a, x[i + 6], 23, 76029189);
a = md5hh(a, b, c, d, x[i + 9], 4, -640364487);
d = md5hh(d, a, b, c, x[i + 12], 11, -421815835);
c = md5hh(c, d, a, b, x[i + 15], 16, 530742520);
b = md5hh(b, c, d, a, x[i + 2], 23, -995338651);
a = md5ii(a, b, c, d, x[i], 6, -198630844);
d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415);
c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905);
b = md5ii(b, c, d, a, x[i + 5], 21, -57434055);
a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571);
d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606);
c = md5ii(c, d, a, b, x[i + 10], 15, -1051523);
b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799);
a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359);
d = md5ii(d, a, b, c, x[i + 15], 10, -30611744);
c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380);
b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649);
a = md5ii(a, b, c, d, x[i + 4], 6, -145523070);
d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379);
c = md5ii(c, d, a, b, x[i + 2], 15, 718787259);
b = md5ii(b, c, d, a, x[i + 9], 21, -343485551);
a = safeAdd(a, olda);
b = safeAdd(b, oldb);
c = safeAdd(c, oldc);
d = safeAdd(d, oldd);
}
return Uint32Array.of(a, b, c, d);
}
function uint8ToUint32(input) {
if (input.length === 0) {
return new Uint32Array();
}
const output = new Uint32Array(getOutputLength(input.length * 8)).fill(0);
for (let i = 0; i < input.length; i++) {
output[i >> 2] |= (input[i] & 0xff) << ((i % 4) * 8);
}
return output;
}
function safeAdd(x, y) {
const lsw = (x & 0xffff) + (y & 0xffff);
const msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xffff);
}
function bitRotateLeft(num, cnt) {
return (num << cnt) | (num >>> (32 - cnt));
}
function md5cmn(q, a, b, x, s, t) {
return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b);
}
function md5ff(a, b, c, d, x, s, t) {
return md5cmn((b & c) | (~b & d), a, b, x, s, t);
}
function md5gg(a, b, c, d, x, s, t) {
return md5cmn((b & d) | (c & ~d), a, b, x, s, t);
}
function md5hh(a, b, c, d, x, s, t) {
return md5cmn(b ^ c ^ d, a, b, x, s, t);
}
function md5ii(a, b, c, d, x, s, t) {
return md5cmn(c ^ (b | ~d), a, b, x, s, t);
}
export default md5;

View File

@@ -0,0 +1,2 @@
declare const _default: "00000000-0000-0000-0000-000000000000";
export default _default;

View File

@@ -0,0 +1 @@
export default '00000000-0000-0000-0000-000000000000';

View File

@@ -0,0 +1,3 @@
import type { NonSharedArrayBuffer } from './types.js';
declare function parse(uuid: string): NonSharedArrayBuffer;
export default parse;

View File

@@ -0,0 +1,9 @@
import validate from './validate.js';
function parse(uuid) {
if (!validate(uuid)) {
throw TypeError('Invalid UUID');
}
let v;
return Uint8Array.of((v = parseInt(uuid.slice(0, 8), 16)) >>> 24, (v >>> 16) & 0xff, (v >>> 8) & 0xff, v & 0xff, (v = parseInt(uuid.slice(9, 13), 16)) >>> 8, v & 0xff, (v = parseInt(uuid.slice(14, 18), 16)) >>> 8, v & 0xff, (v = parseInt(uuid.slice(19, 23), 16)) >>> 8, v & 0xff, ((v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000) & 0xff, (v / 0x100000000) & 0xff, (v >>> 24) & 0xff, (v >>> 16) & 0xff, (v >>> 8) & 0xff, v & 0xff);
}
export default parse;

View File

@@ -0,0 +1,2 @@
declare const _default: RegExp;
export default _default;

View File

@@ -0,0 +1 @@
export default /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/i;

View File

@@ -0,0 +1 @@
export default function rng(): Uint8Array;

View File

@@ -0,0 +1,4 @@
const rnds8 = new Uint8Array(16);
export default function rng() {
return crypto.getRandomValues(rnds8);
}

View File

@@ -0,0 +1,2 @@
declare function sha1(bytes: Uint8Array): Uint8Array;
export default sha1;

View File

@@ -0,0 +1,70 @@
function f(s, x, y, z) {
switch (s) {
case 0:
return (x & y) ^ (~x & z);
case 1:
return x ^ y ^ z;
case 2:
return (x & y) ^ (x & z) ^ (y & z);
case 3:
return x ^ y ^ z;
}
}
function ROTL(x, n) {
return (x << n) | (x >>> (32 - n));
}
function sha1(bytes) {
const K = [0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6];
const H = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0];
const newBytes = new Uint8Array(bytes.length + 1);
newBytes.set(bytes);
newBytes[bytes.length] = 0x80;
bytes = newBytes;
const l = bytes.length / 4 + 2;
const N = Math.ceil(l / 16);
const M = new Array(N);
for (let i = 0; i < N; ++i) {
const arr = new Uint32Array(16);
for (let j = 0; j < 16; ++j) {
arr[j] =
(bytes[i * 64 + j * 4] << 24) |
(bytes[i * 64 + j * 4 + 1] << 16) |
(bytes[i * 64 + j * 4 + 2] << 8) |
bytes[i * 64 + j * 4 + 3];
}
M[i] = arr;
}
M[N - 1][14] = ((bytes.length - 1) * 8) / 2 ** 32;
M[N - 1][14] = Math.floor(M[N - 1][14]);
M[N - 1][15] = ((bytes.length - 1) * 8) & 0xffffffff;
for (let i = 0; i < N; ++i) {
const W = new Uint32Array(80);
for (let t = 0; t < 16; ++t) {
W[t] = M[i][t];
}
for (let t = 16; t < 80; ++t) {
W[t] = ROTL(W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16], 1);
}
let a = H[0];
let b = H[1];
let c = H[2];
let d = H[3];
let e = H[4];
for (let t = 0; t < 80; ++t) {
const s = Math.floor(t / 20);
const T = (ROTL(a, 5) + f(s, b, c, d) + e + K[s] + W[t]) >>> 0;
e = d;
d = c;
c = ROTL(b, 30) >>> 0;
b = a;
a = T;
}
H[0] = (H[0] + a) >>> 0;
H[1] = (H[1] + b) >>> 0;
H[2] = (H[2] + c) >>> 0;
H[3] = (H[3] + d) >>> 0;
H[4] = (H[4] + e) >>> 0;
}
return Uint8Array.of(H[0] >> 24, H[0] >> 16, H[0] >> 8, H[0], H[1] >> 24, H[1] >> 16, H[1] >> 8, H[1], H[2] >> 24, H[2] >> 16, H[2] >> 8, H[2], H[3] >> 24, H[3] >> 16, H[3] >> 8, H[3], H[4] >> 24, H[4] >> 16, H[4] >> 8, H[4]);
}
export default sha1;

View File

@@ -0,0 +1,3 @@
export declare function unsafeStringify(arr: Uint8Array, offset?: number): string;
declare function stringify(arr: Uint8Array, offset?: number): string;
export default stringify;

View File

@@ -0,0 +1,35 @@
import validate from './validate.js';
const byteToHex = [];
for (let i = 0; i < 256; ++i) {
byteToHex.push((i + 0x100).toString(16).slice(1));
}
export function unsafeStringify(arr, offset = 0) {
return (byteToHex[arr[offset + 0]] +
byteToHex[arr[offset + 1]] +
byteToHex[arr[offset + 2]] +
byteToHex[arr[offset + 3]] +
'-' +
byteToHex[arr[offset + 4]] +
byteToHex[arr[offset + 5]] +
'-' +
byteToHex[arr[offset + 6]] +
byteToHex[arr[offset + 7]] +
'-' +
byteToHex[arr[offset + 8]] +
byteToHex[arr[offset + 9]] +
'-' +
byteToHex[arr[offset + 10]] +
byteToHex[arr[offset + 11]] +
byteToHex[arr[offset + 12]] +
byteToHex[arr[offset + 13]] +
byteToHex[arr[offset + 14]] +
byteToHex[arr[offset + 15]]).toLowerCase();
}
function stringify(arr, offset = 0) {
const uuid = unsafeStringify(arr, offset);
if (!validate(uuid)) {
throw TypeError('Stringified UUID is invalid');
}
return uuid;
}
export default stringify;

View File

@@ -0,0 +1,22 @@
export type UUIDTypes<TBuf extends Uint8Array = Uint8Array> = string | TBuf;
export type Version1Options = {
node?: Uint8Array;
clockseq?: number;
random?: Uint8Array;
rng?: () => Uint8Array;
msecs?: number;
nsecs?: number;
_v6?: boolean;
};
export type Version4Options = {
random?: Uint8Array;
rng?: () => Uint8Array;
};
export type Version6Options = Version1Options;
export type Version7Options = {
random?: Uint8Array;
msecs?: number;
seq?: number;
rng?: () => Uint8Array;
};
export type NonSharedArrayBuffer = ReturnType<typeof Uint8Array.of>;

View File

@@ -0,0 +1 @@
export {};

View File

@@ -0,0 +1,70 @@
import * as assert from 'node:assert/strict';
import v1 from './v1.js';
import v3 from './v3.js';
import v4 from './v4.js';
import v5 from './v5.js';
import v6 from './v6.js';
import v7 from './v7.js';
function usage() {
console.log('Usage:');
console.log(' uuid');
console.log(' uuid v1');
console.log(' uuid v3 <name> <namespace uuid>');
console.log(' uuid v4');
console.log(' uuid v5 <name> <namespace uuid>');
console.log(' uuid v6');
console.log(' uuid v7');
console.log(' uuid --help');
console.log('\nNote: <namespace uuid> may be "URL" or "DNS" to use the corresponding UUIDs defined by RFC9562');
}
const args = process.argv.slice(2);
if (args.indexOf('--help') >= 0) {
usage();
process.exit(0);
}
const version = args.shift() || 'v4';
switch (version) {
case 'v1':
console.log(v1());
break;
case 'v3': {
const name = args.shift();
let namespace = args.shift();
assert.ok(name != null, 'v3 name not specified');
assert.ok(namespace != null, 'v3 namespace not specified');
if (namespace === 'URL') {
namespace = v3.URL;
}
if (namespace === 'DNS') {
namespace = v3.DNS;
}
console.log(v3(name, namespace));
break;
}
case 'v4':
console.log(v4());
break;
case 'v5': {
const name = args.shift();
let namespace = args.shift();
assert.ok(name != null, 'v5 name not specified');
assert.ok(namespace != null, 'v5 namespace not specified');
if (namespace === 'URL') {
namespace = v5.URL;
}
if (namespace === 'DNS') {
namespace = v5.DNS;
}
console.log(v5(name, namespace));
break;
}
case 'v6':
console.log(v6());
break;
case 'v7':
console.log(v7());
break;
default:
usage();
process.exit(1);
}

View File

@@ -0,0 +1,11 @@
import type { Version1Options } from './types.js';
type V1State = {
node?: Uint8Array;
clockseq?: number;
msecs?: number;
nsecs?: number;
};
declare function v1(options?: Version1Options, buf?: undefined, offset?: number): string;
declare function v1<Buf extends Uint8Array = Uint8Array>(options: Version1Options | undefined, buf: Buf, offset?: number): Buf;
export declare function updateV1State(state: V1State, now: number, rnds: Uint8Array): V1State;
export default v1;

View File

@@ -0,0 +1,87 @@
import rng from './rng.js';
import { unsafeStringify } from './stringify.js';
const _state = {};
function v1(options, buf, offset) {
let bytes;
const isV6 = options?._v6 ?? false;
if (options) {
const optionsKeys = Object.keys(options);
if (optionsKeys.length === 1 && optionsKeys[0] === '_v6') {
options = undefined;
}
}
if (options) {
bytes = v1Bytes(options.random ?? options.rng?.() ?? rng(), options.msecs, options.nsecs, options.clockseq, options.node, buf, offset);
}
else {
const now = Date.now();
const rnds = rng();
updateV1State(_state, now, rnds);
bytes = v1Bytes(rnds, _state.msecs, _state.nsecs, isV6 ? undefined : _state.clockseq, isV6 ? undefined : _state.node, buf, offset);
}
return buf ?? unsafeStringify(bytes);
}
export function updateV1State(state, now, rnds) {
state.msecs ??= -Infinity;
state.nsecs ??= 0;
if (now === state.msecs) {
state.nsecs++;
if (state.nsecs >= 10000) {
state.node = undefined;
state.nsecs = 0;
}
}
else if (now > state.msecs) {
state.nsecs = 0;
}
else if (now < state.msecs) {
state.node = undefined;
}
if (!state.node) {
state.node = rnds.slice(10, 16);
state.node[0] |= 0x01;
state.clockseq = ((rnds[8] << 8) | rnds[9]) & 0x3fff;
}
state.msecs = now;
return state;
}
function v1Bytes(rnds, msecs, nsecs, clockseq, node, buf, offset = 0) {
if (rnds.length < 16) {
throw new Error('Random bytes length must be >= 16');
}
if (!buf) {
buf = new Uint8Array(16);
offset = 0;
}
else {
if (offset < 0 || offset + 16 > buf.length) {
throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);
}
}
msecs ??= Date.now();
nsecs ??= 0;
clockseq ??= ((rnds[8] << 8) | rnds[9]) & 0x3fff;
if (node == null) {
node = rnds.slice(10, 16);
node[0] |= 0x01;
}
msecs += 12219292800000;
const t = (msecs & 0xfffffff) * 10000 + nsecs;
const tl = t >>> 0;
buf[offset++] = (tl >>> 24) & 0xff;
buf[offset++] = (tl >>> 16) & 0xff;
buf[offset++] = (tl >>> 8) & 0xff;
buf[offset++] = tl & 0xff;
const tmh = (((msecs / 0x10000000) | 0) * 625 + ((t / 0x100000000) | 0)) & 0xfffffff;
buf[offset++] = (tmh >>> 8) & 0xff;
buf[offset++] = tmh & 0xff;
buf[offset++] = ((tmh >>> 24) & 0xf) | 0x10;
buf[offset++] = (tmh >>> 16) & 0xff;
buf[offset++] = (clockseq >>> 8) | 0x80;
buf[offset++] = clockseq & 0xff;
for (let n = 0; n < 6; ++n) {
buf[offset++] = node[n];
}
return buf;
}
export default v1;

View File

@@ -0,0 +1,3 @@
import type { NonSharedArrayBuffer } from './types.js';
export default function v1ToV6(uuid: string): string;
export default function v1ToV6(uuid: Uint8Array): NonSharedArrayBuffer;

View File

@@ -0,0 +1,10 @@
import parse from './parse.js';
import { unsafeStringify } from './stringify.js';
export default function v1ToV6(uuid) {
const v1Bytes = typeof uuid === 'string' ? parse(uuid) : uuid;
const v6Bytes = _v1ToV6(v1Bytes);
return typeof uuid === 'string' ? unsafeStringify(v6Bytes) : v6Bytes;
}
function _v1ToV6(v1Bytes) {
return Uint8Array.of(((v1Bytes[6] & 0x0f) << 4) | ((v1Bytes[7] >> 4) & 0x0f), ((v1Bytes[7] & 0x0f) << 4) | ((v1Bytes[4] & 0xf0) >> 4), ((v1Bytes[4] & 0x0f) << 4) | ((v1Bytes[5] & 0xf0) >> 4), ((v1Bytes[5] & 0x0f) << 4) | ((v1Bytes[0] & 0xf0) >> 4), ((v1Bytes[0] & 0x0f) << 4) | ((v1Bytes[1] & 0xf0) >> 4), ((v1Bytes[1] & 0x0f) << 4) | ((v1Bytes[2] & 0xf0) >> 4), 0x60 | (v1Bytes[2] & 0x0f), v1Bytes[3], v1Bytes[8], v1Bytes[9], v1Bytes[10], v1Bytes[11], v1Bytes[12], v1Bytes[13], v1Bytes[14], v1Bytes[15]);
}

View File

@@ -0,0 +1,9 @@
import type { UUIDTypes } from './types.js';
export { DNS, URL } from './v35.js';
declare function v3(value: string | Uint8Array, namespace: UUIDTypes, buf?: undefined, offset?: number): string;
declare function v3<TBuf extends Uint8Array = Uint8Array>(value: string | Uint8Array, namespace: UUIDTypes, buf: TBuf, offset?: number): TBuf;
declare namespace v3 {
var DNS: string;
var URL: string;
}
export default v3;

View File

@@ -0,0 +1,9 @@
import md5 from './md5.js';
import v35, { DNS, URL } from './v35.js';
export { DNS, URL } from './v35.js';
function v3(value, namespace, buf, offset) {
return v35(0x30, md5, value, namespace, buf, offset);
}
v3.DNS = DNS;
v3.URL = URL;
export default v3;

View File

@@ -0,0 +1,7 @@
import type { UUIDTypes } from './types.js';
export declare function stringToBytes(str: string): Uint8Array;
export declare const DNS = "6ba7b810-9dad-11d1-80b4-00c04fd430c8";
export declare const URL = "6ba7b811-9dad-11d1-80b4-00c04fd430c8";
type HashFunction = (bytes: Uint8Array) => Uint8Array;
export default function v35<TBuf extends Uint8Array = Uint8Array>(version: 0x30 | 0x50, hash: HashFunction, value: string | Uint8Array, namespace: UUIDTypes, buf?: TBuf, offset?: number): UUIDTypes<TBuf>;
export {};

View File

@@ -0,0 +1,39 @@
import parse from './parse.js';
import { unsafeStringify } from './stringify.js';
export function stringToBytes(str) {
str = unescape(encodeURIComponent(str));
const bytes = new Uint8Array(str.length);
for (let i = 0; i < str.length; ++i) {
bytes[i] = str.charCodeAt(i);
}
return bytes;
}
export const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8';
export const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8';
export default function v35(version, hash, value, namespace, buf, offset) {
const valueBytes = typeof value === 'string' ? stringToBytes(value) : value;
const namespaceBytes = typeof namespace === 'string' ? parse(namespace) : namespace;
if (typeof namespace === 'string') {
namespace = parse(namespace);
}
if (namespace?.length !== 16) {
throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)');
}
let bytes = new Uint8Array(16 + valueBytes.length);
bytes.set(namespaceBytes);
bytes.set(valueBytes, namespaceBytes.length);
bytes = hash(bytes);
bytes[6] = (bytes[6] & 0x0f) | version;
bytes[8] = (bytes[8] & 0x3f) | 0x80;
if (buf) {
offset ??= 0;
if (offset < 0 || offset + 16 > buf.length) {
throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);
}
for (let i = 0; i < 16; ++i) {
buf[offset + i] = bytes[i];
}
return buf;
}
return unsafeStringify(bytes);
}

View File

@@ -0,0 +1,4 @@
import type { Version4Options } from './types.js';
declare function v4(options?: Version4Options, buf?: undefined, offset?: number): string;
declare function v4<TBuf extends Uint8Array = Uint8Array>(options: Version4Options | undefined, buf: TBuf, offset?: number): TBuf;
export default v4;

View File

@@ -0,0 +1,29 @@
import rng from './rng.js';
import { unsafeStringify } from './stringify.js';
function v4(options, buf, offset) {
if (!buf && !options && crypto.randomUUID) {
return crypto.randomUUID();
}
return _v4(options, buf, offset);
}
function _v4(options, buf, offset) {
options = options || {};
const rnds = options.random ?? options.rng?.() ?? rng();
if (rnds.length < 16) {
throw new Error('Random bytes length must be >= 16');
}
rnds[6] = (rnds[6] & 0x0f) | 0x40;
rnds[8] = (rnds[8] & 0x3f) | 0x80;
if (buf) {
offset = offset || 0;
if (offset < 0 || offset + 16 > buf.length) {
throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);
}
for (let i = 0; i < 16; ++i) {
buf[offset + i] = rnds[i];
}
return buf;
}
return unsafeStringify(rnds);
}
export default v4;

View File

@@ -0,0 +1,9 @@
import type { UUIDTypes } from './types.js';
export { DNS, URL } from './v35.js';
declare function v5(value: string | Uint8Array, namespace: UUIDTypes, buf?: undefined, offset?: number): string;
declare function v5<TBuf extends Uint8Array = Uint8Array>(value: string | Uint8Array, namespace: UUIDTypes, buf: TBuf, offset?: number): TBuf;
declare namespace v5 {
var DNS: string;
var URL: string;
}
export default v5;

View File

@@ -0,0 +1,9 @@
import sha1 from './sha1.js';
import v35, { DNS, URL } from './v35.js';
export { DNS, URL } from './v35.js';
function v5(value, namespace, buf, offset) {
return v35(0x50, sha1, value, namespace, buf, offset);
}
v5.DNS = DNS;
v5.URL = URL;
export default v5;

View File

@@ -0,0 +1,4 @@
import type { Version6Options } from './types.js';
declare function v6(options?: Version6Options, buf?: undefined, offset?: number): string;
declare function v6<TBuf extends Uint8Array = Uint8Array>(options: Version6Options | undefined, buf: TBuf, offset?: number): TBuf;
export default v6;

View File

@@ -0,0 +1,20 @@
import { unsafeStringify } from './stringify.js';
import v1 from './v1.js';
import v1ToV6 from './v1ToV6.js';
function v6(options, buf, offset) {
options ??= {};
offset ??= 0;
let bytes = v1({ ...options, _v6: true }, new Uint8Array(16));
bytes = v1ToV6(bytes);
if (buf) {
if (offset < 0 || offset + 16 > buf.length) {
throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);
}
for (let i = 0; i < 16; i++) {
buf[offset + i] = bytes[i];
}
return buf;
}
return unsafeStringify(bytes);
}
export default v6;

View File

@@ -0,0 +1,2 @@
export default function v6ToV1(uuid: string): string;
export default function v6ToV1(uuid: Uint8Array): Uint8Array;

View File

@@ -0,0 +1,10 @@
import parse from './parse.js';
import { unsafeStringify } from './stringify.js';
export default function v6ToV1(uuid) {
const v6Bytes = typeof uuid === 'string' ? parse(uuid) : uuid;
const v1Bytes = _v6ToV1(v6Bytes);
return typeof uuid === 'string' ? unsafeStringify(v1Bytes) : v1Bytes;
}
function _v6ToV1(v6Bytes) {
return Uint8Array.of(((v6Bytes[3] & 0x0f) << 4) | ((v6Bytes[4] >> 4) & 0x0f), ((v6Bytes[4] & 0x0f) << 4) | ((v6Bytes[5] & 0xf0) >> 4), ((v6Bytes[5] & 0x0f) << 4) | (v6Bytes[6] & 0x0f), v6Bytes[7], ((v6Bytes[1] & 0x0f) << 4) | ((v6Bytes[2] & 0xf0) >> 4), ((v6Bytes[2] & 0x0f) << 4) | ((v6Bytes[3] & 0xf0) >> 4), 0x10 | ((v6Bytes[0] & 0xf0) >> 4), ((v6Bytes[0] & 0x0f) << 4) | ((v6Bytes[1] & 0xf0) >> 4), v6Bytes[8], v6Bytes[9], v6Bytes[10], v6Bytes[11], v6Bytes[12], v6Bytes[13], v6Bytes[14], v6Bytes[15]);
}

Some files were not shown because too many files have changed in this diff Show More