claude go reimplement

This commit is contained in:
tyler committed 2026-10-26 20:30:43 -07:00
1 parent 4bcb924158
commit f523c79618
83 files changed
+3714 -3454

No files matched your search

+5
View File
@@ -0,0 +1,5 @@
<nav class="chapter-nav" aria-label="Chapter">
<a class="chapter-prev" href="{prev_chapter_link}" rel="prev" aria-label="Previous chapter: {prev_chapter_name}"><span aria-hidden="true">&lsaquo;</span><span class="nav-name">{prev_chapter_name}</span></a>
<a class="chapter-current" href="{current_chapter_link}" title="Read the whole chapter">{current_chapter_name}</a>
<a class="chapter-next" href="{next_chapter_link}" rel="next" aria-label="Next chapter: {next_chapter_name}"><span class="nav-name">{next_chapter_name}</span><span aria-hidden="true">&rsaquo;</span></a>
</nav>
+27
View File
@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bible Dictionary - KJV API</title>
<link rel="stylesheet" href="/styles/page.css?v=__V__">
</head>
<body>
<header>
<a href="/">Home</a> <a href="/define">Dictionary</a>
<a href="/random?view=rich">Random Verse</a> <a href="/votd?view=rich">Verse of the Day</a>
</header>
<h2>Bible Dictionary</h2>
<form action="/define">
<label for="kw">Word lookup</label>
<input type="text" name="kw" id="kw" autocapitalize="off" autocomplete="off" enterkeyhint="search" placeholder="Enter a word to define...">
<div class="form-row"><b>View</b><br>
<label class="choice"><input type="radio" name="view" value="rich" checked="checked"> Rich</label>
<label class="choice"><input type="radio" name="view" value="plain"> Plain</label>
<label class="choice"><input type="radio" name="view" value="json"> JSON</label>
</div>
<input type="submit" value="Define">
</form>
<p>This tool uses an abridged 1828 Noah Webster dictionary.</p>
</body>
</html>
+24
View File
@@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Quick Search - KJV API</title>
<link rel="stylesheet" href="/styles/page.css?v=__V__">
<script src="/js/book_suggest.js?v=__V__" defer></script>
</head>
<body>
<header>
<a href="/">Home</a> <a href="/find">Quick Search</a>
<a href="/random?view=rich">Random Verse</a>
<a href="/votd?view=rich">Verse of the Day</a>
</header>
<h2>Quick Search</h2>
<form action="/find">
<label for="kw">Query</label>
<input type="text" name="kw" id="kw" data-book-suggest autocapitalize="off" autocomplete="off" enterkeyhint="search" placeholder="Enter verse reference or keywords...">
<input type="hidden" name="view" value="rich">
<input type="submit" value="Search">
</form>
</body>
</html>
+46
View File
@@ -0,0 +1,46 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>How to Be Saved - KJV API</title>
<link rel="stylesheet" href="/styles/page.css?v=__V__">
</head>
<body>
<header>
<a href="/">Home</a> <a href="/find">Quick Search</a>
<a href="/random?view=rich">Random Verse</a> <a href="/votd?view=rich">Verse of the Day</a>
</header>
<h2>How to Be Saved</h2>
<h3>1. Understand you are a sinner:</h3>
<p>No one is good enough to go to Heaven on their own merit. No matter how much good we do, we still come short.</p>
<p><b>Romans 3:23</b>(a) For all have sinned, and come short of the glory of God;</p>
<p><b>Romans 3:10</b> As it is written, There is none righteous, no, not one:</p>
<h3>2. Realize the penalty for your sin.</h3>
<p>There is a payment for our sin, which is eternal death in a place called Hell and the Lake of Fire.</p>
<p><b>Romans 6:23</b> For the wages of sin is death; but the gift of God is eternal life through Jesus Christ our Lord.</p>
<p><b>Revelation 20:14</b> And death and hell were cast into the lake of fire. This is the second death. And whosoever was not found written in the book of life was cast into the lake of fire.</p>
<h3>3. Believe that Christ died, was buried and rose from the grave as a payment for your sin.</h3>
<p>Salvation is simply putting your faith (or believing) that Jesus Christ paid for your sins.</p>
<p><b>Romans 5:8</b> But God commendeth his love toward us, in that, while we were yet sinners, Christ died for us.</p>
<p><b>John 3:16</b> For God so loved the world, that he gave his only begotten Son, that whosoever believeth in him should not perish, but have everlasting life.</p>
<p><b>1 Corinthians 15:3-4</b> ...Christ died for our sins according to the scriptures; And that he was buried, and that he rose again the third day according to the scriptures:</p>
<h3>4. Understand that salvation will last forever.</h3>
<p>Eternal life is a gift purchased by the blood of Jesus and offered freely to those who call upon Him. Anyone who believes on the Lord Jesus Christ will be saved forever. Being saved is a one time event.</p>
<p><b>Titus 1:2</b> In hope of eternal life, which God, that cannot lie, promised before the world began;</p>
<p><b>John 3:15-16</b> For God so loved the world, that he gave his only begotten Son, that whosoever believeth in him should not perish, but have everlasting life.</p>
<p>When God saves you he gives you eternal life; in other words, life that will last forever. So, when he saves you, it is forever. No matter what you do after you receive “the gift of eternal life” it can never end. Otherwise God lied, and we know that God “cannot lie”.</p>
<h3>5. Pray and ask Jesus Christ to save you.</h3>
<p><b>Romans 10:9-10</b> That if thou shalt confess with thy mouth the Lord Jesus, and shalt believe in thine heart that God hath raised him from the dead, thou shalt be saved. For with the heart man believeth unto righteousness; and with the mouth confession is made unto salvation. </p>
<p>Let us help you word a prayer. Realize it is not mere words that save, but your faith in Jesus Christ.</p>
<p><i>Dear Jesus, I know that I am a sinner, and I know I deserve to go to Hell. But I believe that you died on the cross, was buried, and rose from the grave to pay for my sins. Please save me and take me to Heaven when I die. Amen.</i></p>
</body>
</html>
+384
View File
@@ -0,0 +1,384 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>KJV API - Legacy Edition</title>
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
<link rel="stylesheet" href="/styles/page.css?v=__V__">
<script src="/js/collapsible.js?v=__V__" defer></script>
<style>
/* Home page layout */
.site-title {
margin: var(--space-md) 0 0.25rem;
}
.tagline {
margin: 0 0 var(--space-lg);
color: var(--color-text-muted);
}
.search-section {
background-color: var(--color-bg-secondary);
padding: var(--space-lg);
border-radius: var(--border-radius);
border: 1px solid var(--color-border);
margin-bottom: var(--space-xl);
box-shadow: 0 2px 8px var(--color-shadow);
}
.search-section form {
background: none;
border: none;
padding: 0;
margin: 0;
}
.search-row {
display: flex;
gap: var(--space-sm);
}
.search-row input[type=text] {
margin: 0;
flex: 1;
min-width: 0;
}
.quick-actions {
display: grid;
grid-template-columns: 1fr 1fr;
gap: var(--space-sm);
margin-top: var(--space-md);
}
.quick-btn {
background-color: var(--color-bg-tertiary);
color: var(--color-text-primary);
border: 1px solid var(--color-border);
padding: 0.7rem 1rem;
min-height: 44px;
border-radius: var(--border-radius-sm);
font-weight: 600;
text-align: center;
transition: background-color var(--transition-fast), border-color var(--transition-fast);
}
.quick-btn:hover {
background-color: var(--color-accent-primary);
border-color: var(--color-accent-primary);
color: var(--color-on-accent);
text-decoration: none;
}
.testament-header {
color: var(--color-accent-primary);
font-size: 1.6rem;
margin-top: var(--space-2xl);
margin-bottom: var(--space-sm);
font-weight: 700;
border-bottom: 2px solid var(--color-accent-primary);
padding-bottom: 0.5rem;
}
.category-header {
color: var(--color-text-secondary);
font-size: 1.05rem;
margin-top: var(--space-lg);
margin-bottom: var(--space-sm);
font-weight: 600;
}
/* Books: each book is a button; its chapter grid opens full-width underneath
the row it sits in (display: contents lets the chapter grid span the
book grid, and "dense" back-fills the gap with the following books). */
.book-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
grid-auto-flow: row dense;
gap: var(--space-sm);
}
.book-grid > div {
display: contents;
}
.book-button {
background-color: var(--color-bg-secondary);
border: 1px solid var(--color-border);
border-radius: var(--border-radius-sm);
padding: 0.7rem 0.9rem;
min-height: 44px;
text-align: left;
color: var(--color-text-primary);
cursor: pointer;
font-family: var(--font-ui);
font-weight: 600;
font-size: 0.95rem;
width: 100%;
margin: 0;
transition: background-color var(--transition-fast), border-color var(--transition-fast);
}
.book-button:hover,
.book-button.active {
background-color: var(--color-accent-primary);
color: var(--color-on-accent);
border-color: var(--color-accent-primary);
transform: none;
}
.chapter-grid {
display: none;
grid-column: 1 / -1;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 0.4rem;
padding: var(--space-md);
background-color: var(--color-bg-secondary);
border: 1px solid var(--color-accent-primary);
border-radius: var(--border-radius-sm);
}
.book-about {
grid-column: 1 / -1;
margin: 0 0 var(--space-xs);
font-size: 0.95rem;
line-height: 1.5;
color: var(--color-text-secondary);
}
.chapter-link {
background-color: var(--color-bg-tertiary);
border: 1px solid var(--color-border);
border-radius: var(--border-radius-sm);
min-height: 44px;
padding: 0.35rem 0.75rem 0.35rem 0.4rem;
display: flex;
align-items: center;
gap: 0.75rem;
color: var(--color-text-primary);
font-size: 0.95rem;
line-height: 1.35;
transition: background-color var(--transition-fast);
}
.chapter-num {
flex: 0 0 2.4rem;
text-align: center;
font-weight: 700;
color: var(--color-accent-primary);
}
.chapter-sum {
color: var(--color-text-secondary);
}
.chapter-link:hover {
background-color: var(--color-accent-primary);
color: var(--color-on-accent);
text-decoration: none;
}
.chapter-link:hover .chapter-num,
.chapter-link:hover .chapter-sum {
color: var(--color-on-accent);
}
.api-docs {
margin-top: var(--space-2xl);
border: 1px solid var(--color-border);
border-radius: var(--border-radius-sm);
background-color: var(--color-bg-secondary);
}
.api-docs summary {
padding: 0.9rem 1.1rem;
font-weight: 600;
cursor: pointer;
}
.api-docs pre {
margin: 0;
border: none;
border-top: 1px solid var(--color-border);
border-radius: 0 0 var(--border-radius-sm) var(--border-radius-sm);
}
@media (max-width: 480px) {
.book-grid {
grid-template-columns: repeat(2, 1fr);
}
.chapter-grid {
grid-template-columns: 1fr;
}
.search-row {
flex-direction: column;
}
.search-row input[type=submit] {
width: 100%;
}
}
</style>
<script src="/js/book_suggest.js?v=__V__" defer></script>
</head>
<body>
<div class="container">
<h1 class="site-title">KJV API <small>(Legacy edition)</small></h1>
<p class="tagline">King James Bible: search, read, and query by reference.</p>
<div class="search-section">
<form action="/find" role="search">
<label for="kw">Search Scripture</label>
<div class="search-row">
<input type="text" name="kw" id="kw" data-book-suggest autocapitalize="off" autocomplete="off" enterkeyhint="search" placeholder="Verse reference or keywords...">
<input type="hidden" name="view" value="rich">
<input type="submit" value="Search">
</div>
</form>
<div class="quick-actions">
<a href="/random?view=rich" class="quick-btn">Random Verse</a>
<a href="/votd?view=rich" class="quick-btn">Verse of the Day</a>
<a href="/plan" class="quick-btn">Make a Bible Reading Plan</a>
<a href="/saved" class="quick-btn">Saved Verses &amp; Notes</a>
<a href="#" class="quick-btn" id="continue-plan" hidden>Continue My Reading Plan</a>
</div>
</div>
<!-- OLD TESTAMENT -->
<h2 class="testament-header">Old Testament</h2>
{% for category, books in testament_data.OT.items() %}
<h3 class="category-header">{{ category }}</h3>
<div class="book-grid">
{% for book in books %}
<div>
<button class="book-button collapsible" data-book="{{ book.title }}">
{{ book.title }}
</button>
<div class="chapter-grid content">
{% if book.about %}<p class="book-about">{{ book.about }}</p>{% endif %}
{% for chapter in range(1, book.chapters + 1) %}
<a href="/show?kw={{ book.title }} {{ chapter }}&view=rich" class="chapter-link"><span class="chapter-num">{{ chapter }}</span>{% if book.summaries|length >= chapter %}<span class="chapter-sum">{{ book.summaries[chapter - 1] }}</span>{% endif %}</a>
{% endfor %}
</div>
</div>
{% endfor %}
</div>
{% endfor %}
<!-- NEW TESTAMENT -->
<h2 class="testament-header">New Testament</h2>
{% for category, books in testament_data.NT.items() %}
<h3 class="category-header">{{ category }}</h3>
<div class="book-grid">
{% for book in books %}
<div>
<button class="book-button collapsible" data-book="{{ book.title }}">
{{ book.title }}
</button>
<div class="chapter-grid content">
{% if book.about %}<p class="book-about">{{ book.about }}</p>{% endif %}
{% for chapter in range(1, book.chapters + 1) %}
<a href="/show?kw={{ book.title }} {{ chapter }}&view=rich" class="chapter-link"><span class="chapter-num">{{ chapter }}</span>{% if book.summaries|length >= chapter %}<span class="chapter-sum">{{ book.summaries[chapter - 1] }}</span>{% endif %}</a>
{% endfor %}
</div>
</div>
{% endfor %}
</div>
{% endfor %}
<!-- API DOCUMENTATION -->
<details class="api-docs">
<summary>API Documentation</summary>
<pre><code>API ENDPOINT SPECIFICATION v 0.3
================================
<a href="/find">/find</a> - Tries to show a verse, if it's not a verse
it will try to search your query. If it's a
single query it will try to find a definition
for the word as well. Only avaliable in "Rich"
and meant for interactive use/browsing
<a href="/random">/random</a> - outputs a random verse
<a href="/votd">/votd</a> - returns verse of the day
<a href="/search">/search</a> - returns a keyword search result set
<a href="/show">/show</a> - returns a verse or set of verses by name/location
<a href="/define">/define</a> - 1828 Noah Webster dictionary search
<a href="/seq">/seq</a> - Incremental sequence of Bible verses (per request)
URL PARAMETERS
==============
view=
- json - json-encoded response
- plain - very simple html response
- rich - pretty response with css and js
Required parameter
kw=
- Used with /search /show/ /define /find
- The keyword(s) of your query, separated by commas
-- ex ?kw=1cor5:1-5,2Peter2:5
getuid=
- Used only with /seq
- Set this to "true" to recieve a new UID for use with /seq?uid=
start=
- Used only with /seq
- You can use a ref like "1Cor5:1" to start there
instead of Genesis 1:1 as is the default
- Only used when creating a new UID
- If you want to "start in a new place" - just create a new UID
uid=
- Used only with /seq
- Required parameter for normal use of /seq
num=
- Used only with /seq
- You can get the "next # verses" in your sequence
FEATURES
========
- King James Only. (No heretical commentaries or false Bibles)
- High quality source documents
- Free
- Developer hates the sodomites
INTERACTIVE ENDPOINTS
=====================
The following endpoints will present you with a query box and
radio selector for choosing your output format.
- / (same function as /find)
- /search
- /define
- /show
EXAMPLES
========
api.tld/random
api.tld/votd?view=rich
api.tld/show?kw=john3:16,1john5:7&view=plain
BUGS
====
Suggestions, bug reports or improvements can be reported to <a href="https://nicecrew.digital/@tyler">@tyler@nicecrew.digital</a></code></pre>
</details>
</div>
<script>
try {
var plan = JSON.parse(localStorage.getItem('kjv.plan'));
if (plan && /^[0-9A-Z]+$/.test(plan.uid)) {
var link = document.getElementById('continue-plan');
link.href = '/plan/' + plan.uid + '?n=' + (parseInt(plan.n, 10) || 25);
link.hidden = false;
}
} catch (e) {}
</script>
</body>
</html>
+35
View File
@@ -0,0 +1,35 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="color-scheme" content="dark light">
<title>{title} - KJV API</title>
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
{css}
<script src="/js/verse_menu.js?v=__V__" defer></script>
<script src="/js/book_suggest.js?v=__V__" defer></script>
</head>
<body>
<header class="site-header">
<div class="site-bar">
<a class="brand" href="/">KJV API</a>
<nav class="site-links" aria-label="Site">
<a href="/random?view=rich">Random Verse</a>
<a href="/votd?view=rich">Verse of the Day</a>
<a href="/plan">Reading Plan</a>
<a href="/saved">Saved</a>
</nav>
</div>
<form class="search-form" action="/find" role="search">
<input type="text" name="kw" value="{query}" id="searchBar" data-book-suggest aria-label="Search scripture" placeholder="Verse reference or keywords..." autocapitalize="off" autocomplete="off" enterkeyhint="search">
<input type="hidden" name="view" value="rich">
<input type="submit" value="Search">
</form>
<div class="shortcode">
<button type="button" class="btn-small" onclick="make_shortcode()">Get shortcode</button>
<a id="context_href" href=""></a>
</div>
</header>
{chapter_nav}
<script src="/js/shortcode.js?v=__V__"></script>
+29
View File
@@ -0,0 +1,29 @@
<h2>On Reading the Holy Bible</h2>
<p>A common trap when reading the Bible is relying on external lenses
to look at the Bible through.</p>
<p>By external lense, we mean using an external data source such as
a dictionary like the 1828 Websters we provide
as a way to interpret the meaning of scripture.</p>
<p><b>This is wrong!</b></p>
<h3>How to read the King James Bible</h3>
<p>When we read the King James Bible, we need to as the following questions:</p>
<ol>
<li>Who is speaking?</li>
<li>Who is being spoken to?</li>
<li>When is this being spoken?</li>
<li>What are the definitions of the words?</li>
<li>Is it consistent with the rest of scripture?</li>
</ol>
<style>
html{
font-family: sans-serif;
font-size: 14pt;
width: 768px;
}
a {
color: #547720
}
</style>
+98
View File
@@ -0,0 +1,98 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Make a Bible Reading Plan - KJV API</title>
<link rel="stylesheet" href="/styles/page.css?v=__V__">
<style>
.fieldset { border: none; padding: 0; margin: 0 0 var(--space-lg); }
.fieldset legend { font-weight: 600; padding: 0; margin-bottom: 0.25rem; }
.inline-field { display: inline-block; width: 6rem; margin: 0 0.4rem; }
.inline-field input[type=text], input[type=number] {
min-height: 44px; padding: 0.4rem 0.6rem; font-size: 1rem; font-family: var(--font-ui);
background-color: var(--color-bg-primary); color: var(--color-text-primary);
border: 2px solid var(--color-border); border-radius: var(--border-radius-sm);
}
select {
min-height: 44px; font-size: 1rem; font-family: var(--font-ui); margin-left: 0.4rem;
background-color: var(--color-bg-primary); color: var(--color-text-primary);
border: 2px solid var(--color-border); border-radius: var(--border-radius-sm); padding: 0 0.5rem;
}
input[type=number] { width: 6rem; margin: 0 0.4rem; }
.quick-start { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 0.5rem; }
.quick-start button {
min-height: 40px; padding: 0.3rem 1rem; background-color: var(--color-bg-tertiary);
color: var(--color-text-primary); border: 1px solid var(--color-border);
}
.continue-box { display: none; background-color: var(--color-bg-secondary); border: 1px solid var(--color-accent-primary);
border-radius: var(--border-radius); padding: var(--space-md) var(--space-lg); margin: var(--space-md) 0; }
.continue-box a { font-weight: 600; }
</style>
<script src="/js/book_suggest.js?v=__V__" defer></script>
</head>
<body>
<header>
<a href="/">Home</a> <a href="/find">Quick Search</a>
<a href="/random?view=rich">Random Verse</a> <a href="/votd?view=rich">Verse of the Day</a>
<a href="/saved">Saved</a>
</header>
<h2>Make a Bible Reading Plan</h2>
<div class="continue-box" id="continue-box">
You already have a plan in this browser: <a id="continue-link" href="#">continue reading</a>.
</div>
<p>Pick where to start and how much to read each day. You'll get a page to bookmark; open it
each day to see today's reading, press <b>Done</b> when you've read it, and the plan moves on.
You can always go back to the previous reading or jump to any verse.</p>
<form action="/plan/new" method="post">
<div class="fieldset">
<label for="start">Start at</label>
<div class="quick-start">
<button type="button" data-start="Genesis 1:1">Genesis (whole Bible)</button>
<button type="button" data-start="Matthew 1:1">Matthew (New Testament)</button>
<button type="button" data-start="Psalms 1:1">Psalms</button>
<button type="button" data-start="John 1:1">John</button>
</div>
<input type="text" name="start" id="start" data-book-suggest placeholder="Genesis 1:1" autocapitalize="off" autocomplete="off">
</div>
<fieldset class="fieldset">
<legend>How much each day</legend>
<label class="choice"><input type="radio" name="pace" value="days" checked>
Finish the Bible in
<select name="days" aria-label="Finish in">
<option value="365" selected>1 year</option>
<option value="180">6 months</option>
<option value="90">90 days</option>
<option value="30">30 days</option>
</select>
</label><br>
<label class="choice"><input type="radio" name="pace" value="verses">
Read <input type="number" name="verses" value="30" min="1" max="500" aria-label="Verses per day"> verses a day
</label>
</fieldset>
<input type="submit" value="Create my plan">
</form>
<p>Your plan is saved on this server under a short code in the page address, so the bookmark
is all you need. Plans unused for 90 days are removed.</p>
<script>
var startInput = document.getElementById('start');
document.querySelectorAll('[data-start]').forEach(function (b) {
b.addEventListener('click', function () { startInput.value = b.getAttribute('data-start'); });
});
try {
var plan = JSON.parse(localStorage.getItem('kjv.plan'));
if (plan && /^[0-9A-Z]+$/.test(plan.uid)) {
document.getElementById('continue-link').href = '/plan/' + plan.uid + '?n=' + (parseInt(plan.n, 10) || 25);
document.getElementById('continue-box').style.display = 'block';
}
} catch (e) {}
</script>
</body>
</html>
+4
View File
@@ -0,0 +1,4 @@
<div class="verse-container" data-verse-id="{verse_id}">
<div class="verse-reference"><a href="/find?kw={chapter}&view=rich">{passage}</a></div>
<div class="verse-text">{text}</div>
</div>
+152
View File
@@ -0,0 +1,152 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Saved - KJV API</title>
<link rel="stylesheet" href="/styles/page.css?v=__V__">
<style>
.item { background-color: var(--color-bg-secondary); border: 1px solid var(--color-border);
border-left: 3px solid var(--color-accent-primary); border-radius: var(--border-radius-sm);
padding: var(--space-sm) var(--space-md); margin-bottom: var(--space-sm); }
.item .ref { font-weight: 700; }
.item .text { font-family: var(--font-scripture); margin: 0.25rem 0 0.5rem; color: var(--color-text-primary); }
.item p { margin: 0.25rem 0; }
.item button { min-height: 36px; padding: 0.2rem 0.9rem; font-size: 0.85rem;
background-color: var(--color-bg-tertiary); color: var(--color-text-primary); border: 1px solid var(--color-border); }
.item .mynote { white-space: pre-wrap; border-left: 3px solid #d9a93b; padding-left: 0.6rem; color: var(--color-text-secondary); }
.file-btn { display: inline-block; padding: 0.6rem 1.2rem; border: 1px solid var(--color-border); border-radius: var(--border-radius-sm);
background-color: var(--color-bg-tertiary); font-weight: 600; }
.empty { color: var(--color-text-muted); }
.note { font-size: 0.9rem; color: var(--color-text-muted); }
</style>
</head>
<body>
<header>
<a href="/">Home</a> <a href="/find">Quick Search</a> <a href="/plan">Reading Plan</a>
<a href="/random?view=rich">Random Verse</a> <a href="/votd?view=rich">Verse of the Day</a>
</header>
<h2>Saved</h2>
<p class="note">Saved in this browser only. Clearing site data or using another device starts fresh.</p>
<h3>Notes</h3>
<div id="notes"></div>
<h3>Favorite verses</h3>
<div id="fav"></div>
<h3>Definitions</h3>
<div id="defs"></div>
<h3>Cross references</h3>
<div id="xrefs"></div>
<h3>Backup</h3>
<p class="note">Browser storage can be cleared without warning. Download a copy of your notes and saved items, and restore it here or on another device.</p>
<p>
<button type="button" id="backup">Download backup</button>
<label class="choice"><input type="file" id="restore" accept="application/json,.json" hidden>
<span class="file-btn">Restore from backup</span></label>
</p>
<p class="note" id="backup-status" role="status"></p>
<script>
var KEYS = { notes: 'kjv.notes', fav: 'kjv.favorites', defs: 'kjv.definitions', xrefs: 'kjv.crossrefs' };
function load(key) {
try { var v = JSON.parse(localStorage.getItem(key)); return Array.isArray(v) ? v : []; }
catch (e) { return []; }
}
function el(tag, cls, text) {
var n = document.createElement(tag);
if (cls) n.className = cls;
if (text !== undefined) n.textContent = text;
return n;
}
function findUrl(ref) { return '/find?kw=' + encodeURIComponent(ref) + '&view=rich'; }
function render(key, targetId, emptyText, build) {
var target = document.getElementById(targetId);
target.textContent = '';
var list = load(key);
if (!list.length) { target.appendChild(el('p', 'empty', emptyText)); return; }
list.forEach(function (item, i) {
var box = el('div', 'item');
build(box, item);
var remove = el('button', '', 'Remove');
remove.type = 'button';
remove.addEventListener('click', function () {
var current = load(key);
current.splice(i, 1);
try { localStorage.setItem(key, JSON.stringify(current)); } catch (e) {}
render(key, targetId, emptyText, build);
});
box.appendChild(remove);
target.appendChild(box);
});
}
function refLink(ref) {
var a = el('a', 'ref', ref);
a.href = findUrl(ref);
return a;
}
function draw() {
render(KEYS.notes, 'notes', 'No notes yet. Tap a verse (or its \u22ef button) and choose Note.', function (box, n) {
box.appendChild(refLink(n.ref));
if (n.text) { box.appendChild(el('div', 'text', n.text)); }
box.appendChild(el('p', 'mynote', n.note));
});
render(KEYS.fav, 'fav', 'No favorites yet. Tap a verse and choose Favorite.', function (box, f) {
box.appendChild(refLink(f.ref));
box.appendChild(el('div', 'text', f.text));
});
render(KEYS.defs, 'defs', 'No saved definitions. Tap a verse, choose Define words, and save one.', function (box, d) {
box.appendChild(el('strong', '', d.word));
if (d.ref) { box.appendChild(document.createTextNode(' from ')); box.appendChild(refLink(d.ref)); }
(d.defs || []).forEach(function (t) { box.appendChild(el('p', '', t)); });
});
render(KEYS.xrefs, 'xrefs', 'No saved cross references. Tap a verse, choose Cross references, and save one.', function (box, x) {
box.appendChild(refLink(x.ref));
box.appendChild(el('span', 'note', ' (cross reference of ' + x.from + ')'));
box.appendChild(el('div', 'text', x.text));
});
}
draw();
document.getElementById('backup').addEventListener('click', function () {
var data = { kjv_backup: 1, saved: new Date().toISOString() };
Object.keys(KEYS).forEach(function (name) { data[name] = load(KEYS[name]); });
var blob = new Blob([JSON.stringify(data, null, 1)], { type: 'application/json' });
var link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = 'kjv-saved-' + new Date().toISOString().slice(0, 10) + '.json';
document.body.appendChild(link);
link.click();
link.remove();
setTimeout(function () { URL.revokeObjectURL(link.href); }, 1000);
});
document.getElementById('restore').addEventListener('change', function (event) {
var file = event.target.files[0];
var status = document.getElementById('backup-status');
if (!file) { return; }
var reader = new FileReader();
reader.onload = function () {
try {
var data = JSON.parse(reader.result);
if (!data || data.kjv_backup !== 1) { throw new Error('not a backup'); }
if (!confirm('Replace the notes and saved items in this browser with this backup?')) { return; }
Object.keys(KEYS).forEach(function (name) {
if (Array.isArray(data[name])) { localStorage.setItem(KEYS[name], JSON.stringify(data[name])); }
});
draw();
status.textContent = 'Backup restored.';
} catch (e) {
status.textContent = 'That file is not a valid backup.';
}
};
reader.readAsText(file);
event.target.value = '';
});
</script>
</body>
</html>
+30
View File
@@ -0,0 +1,30 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bible Search - KJV API</title>
<link rel="stylesheet" href="/styles/page.css?v=__V__">
</head>
<body>
<header>
<a href="/">Home</a> <a href="/find">Quick Search</a> <a href="/search">Bible Search</a>
<a href="/random?view=rich">Random Verse</a> <a href="/votd?view=rich">Verse of the Day</a>
</header>
<h2>Bible Search</h2>
<form action="/search">
<label for="kw">Key Words</label>
<input type="text" name="kw" id="kw" autocapitalize="off" autocomplete="off" enterkeyhint="search" placeholder="Enter search keywords...">
<div class="form-row"><b>View</b><br>
<label class="choice"><input type="radio" name="view" value="rich" checked="checked"> Rich</label>
<label class="choice"><input type="radio" name="view" value="plain"> Plain</label>
<label class="choice"><input type="radio" name="view" value="json"> JSON</label>
</div>
<input type="submit" value="Search">
</form>
<hr>
<p>You can use standard search operators such as <b>AND</b>, <b>OR</b>, and <b>NOT</b>.</p>
<p>Such as: "reprobate <b>NOT</b> silver".</p>
<p>Multiple word queries without operators will be assumed to be AND.</p>
</body>
</html>
+5
View File
@@ -0,0 +1,5 @@
<form action="/find">
<input type="text" name="kw">
<input type="hidden" name="view" value="rich"">
<input type="submit">
<form>
+27
View File
@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sequential Bible Viewer - KJV API</title>
<link rel="stylesheet" href="/styles/page.css?v=__V__">
</head>
<body>
<header>
<a href="/">Home</a> <a href="/find">Quick Search</a> <a href="/seq">Sequential Viewer</a>
<a href="/random?view=rich">Random Verse</a> <a href="/votd?view=rich">Verse of the Day</a>
</header>
<h2>Sequential Bible Viewer</h2>
<p>In order to use this, you first need a UID, which you can get by querying <code>/seq?getuid=true</code> and optionally include <code>&start=BIBLEREF</code> (where BIBLEREF is like 1Cor2:1) to set a start position other than Genesis 1:1.</p>
<p>After you have your UID, this will keep track of where you are at. Query <code>/seq?uid=YOURUID</code> and optionally include <code>&num=#</code> (where # is an integer of how many verses you want to include from your current position at a time)</p>
<p>The <code>&view=</code> argument works with this.</p>
<h4>Example Pleroma Bot shell script</h4>
<pre><code>#!/bin/sh
verse=$(curl -XGET https://bible.nicecrew.digital/seq?uid=MYUID?view=plain);
curl -XPOST -u biblebot:MYPASSWORD \
-H "Content-Type: application/json" \
-d '{"status": "'"${verse}"'"}' \
https://my.fediverse.tld/api/v1/statuses;
</code></pre>
</body>
</html>
+32
View File
@@ -0,0 +1,32 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Show Verse - KJV API</title>
<link rel="stylesheet" href="/styles/page.css?v=__V__">
<script src="/js/book_suggest.js?v=__V__" defer></script>
</head>
<body>
<header>
<a href="/">Home</a> <a href="/find">Quick Search</a> <a href="/show">Show Verse</a>
<a href="/random?view=rich">Random Verse</a> <a href="/votd?view=rich">Verse of the Day</a>
</header>
<h2>Show Verse</h2>
<form action="/show">
<label for="kw">Verse References</label>
<input type="text" name="kw" id="kw" data-book-suggest autocapitalize="off" autocomplete="off" enterkeyhint="search" placeholder="e.g., 1 John 5:7 or John3:16,2Peter2:1">
<div class="form-row"><b>View</b><br>
<label class="choice"><input type="radio" name="view" value="rich" checked="checked"> Rich</label>
<label class="choice"><input type="radio" name="view" value="plain"> Plain</label>
<label class="choice"><input type="radio" name="view" value="json"> JSON</label>
</div>
<input type="submit" value="Show">
</form>
<hr>
<p>You can search a Bible reference in this box, such as "1 John 5:7".</p>
<p>You can use abbreviations, but you may not get the result you are looking for.</p>
<p>Use a dash for the verse to get the entire chapter, e.g., "John 3:-"</p>
<p>You may return multiple verse groups by using a comma, e.g., "John3:16,2Peter2:1"</p>
</body>
</html>
+16
View File
@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../styles/votd.css">
<title style="visibility: hidden;">VOTD</title>
</head>
<body>
<div>
<h1 class="verse-title">1 Sneedalonians 4:2</h1>
<p class="verse-text">"Thou shalt do good CSS development for the glory of the LORD"</p>
</div>
</body>
</html>