feat(packages): ludic.photo - a camera's photographs: what the lens sees (the frustum and a line of sight over the ground and the trunks), a grade out of a hundred on size, framing, light and the moment weighted by how much subject there is, the frame's best subject and its tags, the roll with its order and pages, a buyer's price on the grade's curve, the best of each subject; the lens, the light and the market through ports; kept, full, deleted and sold as facts; the roll in its own save section

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-25 08:58:00 +03:00
parent 473552cc81
commit 24a35f1174
17 changed files with 975 additions and 0 deletions

View file

@ -0,0 +1,31 @@
# slug.ludic - a frame's tags as a file name: lower case letters and digits, words joined by dashes,
# at most 24 characters, so a folder of photographs browses well
const PHT_ALPHA: string = "0123456789abcdefghijklmnopqrstuvwxyz"
export function photo_slug(tags: string) -> string {
var out = ""
var n = 0
var i = 0
var last_dash = true
while i < len(tags) and n < 24 {
var c = tags[i]
if c >= 65 and c <= 90 { c = c + 32 }
var k = -1
if c >= 48 and c <= 57 { k = c - 48 }
if c >= 97 and c <= 122 { k = c - 97 + 10 }
if k >= 0 {
let ch: string = PHT_ALPHA[k..k + 1]
out = out + ch
last_dash = false
n += 1
} else if (c == 32 or c == 44) and not last_dash and n > 0 {
out = out + "-"
last_dash = true
n += 1
}
i += 1
}
while Text.ends_with(out, "-") { out = Text.slice(out, 0, len(out) - 1) }
if len(out) == 0 { return "photo" }
return out
}