feat: Upgrade to Astro with full PDPA compliance

PDPA Features:
 Cookie consent banner
 Consent logging API
 Admin dashboard
 Privacy Policy
 Terms & Conditions

Technical:
 Astro 5.x + Tailwind v4
 Docker on port 80
 SQLite database
 15 pages built

Ready for Easypanel deployment.
This commit is contained in:
Kunthawat
2026-03-12 10:01:04 +07:00
parent 668f69048f
commit 77ac4d2d05
13719 changed files with 307487 additions and 25765 deletions

View File

@@ -0,0 +1,76 @@
/**
* @import {Info, State} from 'mdast-util-to-markdown'
* @import {Definition, Parents} from 'mdast'
*/
import {checkQuote} from '../util/check-quote.js'
/**
* @param {Definition} node
* @param {Parents | undefined} _
* @param {State} state
* @param {Info} info
* @returns {string}
*/
export function definition(node, _, state, info) {
const quote = checkQuote(state)
const suffix = quote === '"' ? 'Quote' : 'Apostrophe'
const exit = state.enter('definition')
let subexit = state.enter('label')
const tracker = state.createTracker(info)
let value = tracker.move('[')
value += tracker.move(
state.safe(state.associationId(node), {
before: value,
after: ']',
...tracker.current()
})
)
value += tracker.move(']: ')
subexit()
if (
// If theres no url, or…
!node.url ||
// If there are control characters or whitespace.
/[\0- \u007F]/.test(node.url)
) {
subexit = state.enter('destinationLiteral')
value += tracker.move('<')
value += tracker.move(
state.safe(node.url, {before: value, after: '>', ...tracker.current()})
)
value += tracker.move('>')
} else {
// No whitespace, raw is prettier.
subexit = state.enter('destinationRaw')
value += tracker.move(
state.safe(node.url, {
before: value,
after: node.title ? ' ' : '\n',
...tracker.current()
})
)
}
subexit()
if (node.title) {
subexit = state.enter(`title${suffix}`)
value += tracker.move(' ' + quote)
value += tracker.move(
state.safe(node.title, {
before: value,
after: quote,
...tracker.current()
})
)
value += tracker.move(quote)
subexit()
}
exit()
return value
}