github-actions[bot] commited on
Commit ·
9ff68eb
1
Parent(s): c39cc58
chore: include build artifacts for HF
Browse files- dist/index.mjs +1909 -0
dist/index.mjs
ADDED
|
@@ -0,0 +1,1909 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { Elysia } from "elysia";
|
| 2 |
+
import { logger } from "@chneau/elysia-logger";
|
| 3 |
+
import { cors } from "@elysiajs/cors";
|
| 4 |
+
import { css } from "@emotion/css";
|
| 5 |
+
import util from "node:util";
|
| 6 |
+
import * as txtgen from "txtgen";
|
| 7 |
+
import * as randomwordslugs from "random-word-slugs";
|
| 8 |
+
import axios, { AxiosError } from "axios";
|
| 9 |
+
import createError from "http-errors";
|
| 10 |
+
import { Hono } from "hono";
|
| 11 |
+
import { cors as cors$1 } from "hono/cors";
|
| 12 |
+
import { logger as logger$1 } from "hono/logger";
|
| 13 |
+
import { trimTrailingSlash } from "hono/trailing-slash";
|
| 14 |
+
import { proxy } from "hono/proxy";
|
| 15 |
+
import ky from "ky";
|
| 16 |
+
import { stream } from "hono/streaming";
|
| 17 |
+
import { alphabet, generateRandomString } from "oslo/crypto";
|
| 18 |
+
import random from "random-string-generator";
|
| 19 |
+
import * as fflate from "fflate";
|
| 20 |
+
import * as devalue from "devalue";
|
| 21 |
+
import { sValidator } from "@hono/standard-validator";
|
| 22 |
+
import * as v from "valibot";
|
| 23 |
+
import prettify from "html-prettify";
|
| 24 |
+
|
| 25 |
+
//#region ../../../packages/lib/env.runtime.ts
|
| 26 |
+
let ENV_VAR_DB = {};
|
| 27 |
+
/**
|
| 28 |
+
* Detects the current JavaScript runtime environment.
|
| 29 |
+
* Works for Bun, Node.js, Deno, or Browser contexts.
|
| 30 |
+
*/
|
| 31 |
+
function detectRuntime() {
|
| 32 |
+
if (typeof Bun !== "undefined" && typeof Bun.version === "string") return "bun";
|
| 33 |
+
if (typeof Deno !== "undefined" && typeof Deno.version === "object") return "deno";
|
| 34 |
+
if (typeof process !== "undefined" && typeof process.versions === "object" && !!process.versions.node) return "node";
|
| 35 |
+
if (typeof window !== "undefined" || typeof self !== "undefined") return "browser";
|
| 36 |
+
return "unknown";
|
| 37 |
+
}
|
| 38 |
+
/**
|
| 39 |
+
* Convenience boolean flags
|
| 40 |
+
*/
|
| 41 |
+
const IS_BUN = detectRuntime() === "bun";
|
| 42 |
+
const IS_NODE = detectRuntime() === "node";
|
| 43 |
+
const IS_DENO = detectRuntime() === "deno";
|
| 44 |
+
const IS_BROWSER = detectRuntime() === "browser";
|
| 45 |
+
const APP_ENV$1 = (IS_DENO || IS_BUN || IS_NODE ? process?.env?.APP_ENV : void 0) || ENV_VAR_DB?.APP_ENV;
|
| 46 |
+
const NODE_ENV = (IS_DENO || IS_BUN || IS_NODE ? process?.env?.NODE_ENV : void 0) || ENV_VAR_DB?.NODE_ENV;
|
| 47 |
+
async function set_env_var_db() {
|
| 48 |
+
try {
|
| 49 |
+
const ENV_VAR_JSON_DB = IS_DENO || IS_BUN || IS_NODE ? process?.env?.ENV_VAR_JSON_DB : import.meta.env.ENV_VAR_JSON_DB;
|
| 50 |
+
const ID = IS_DENO || IS_BUN || IS_NODE ? process?.env?.ID : import.meta.env.ID;
|
| 51 |
+
if (NODE_ENV === "production") {
|
| 52 |
+
if (!ENV_VAR_JSON_DB) {
|
| 53 |
+
console.log(`❌ ENV_VAR_JSON_DB:`, ENV_VAR_JSON_DB);
|
| 54 |
+
return;
|
| 55 |
+
}
|
| 56 |
+
if (ENV_VAR_JSON_DB) console.log(`✅ ENV_VAR_JSON_DB:`, ENV_VAR_JSON_DB);
|
| 57 |
+
}
|
| 58 |
+
if (!ENV_VAR_JSON_DB) return;
|
| 59 |
+
let R_ = await (await fetch(ENV_VAR_JSON_DB)).json();
|
| 60 |
+
if (!R_ || typeof R_ !== "object") return;
|
| 61 |
+
(() => {
|
| 62 |
+
if (!Array.isArray(R_) || !ID) return;
|
| 63 |
+
const _data = R_.find((xx) => xx?._ID === ID);
|
| 64 |
+
if (!_data) return;
|
| 65 |
+
const _new = { ..._data };
|
| 66 |
+
const _R_ = R_;
|
| 67 |
+
R_ = _new;
|
| 68 |
+
const app_env = _new.APP_ENV;
|
| 69 |
+
if (!app_env) return;
|
| 70 |
+
const __data = _R_.find((xx) => xx[`${app_env}`])?.[`${app_env}`];
|
| 71 |
+
if (typeof __data !== "object" || Array.isArray(__data)) return;
|
| 72 |
+
R_ = {
|
| 73 |
+
...R_,
|
| 74 |
+
...__data
|
| 75 |
+
};
|
| 76 |
+
})();
|
| 77 |
+
(() => {
|
| 78 |
+
if (typeof R_ !== "object" || Array.isArray(R_)) {
|
| 79 |
+
R_ = {};
|
| 80 |
+
return;
|
| 81 |
+
}
|
| 82 |
+
ENV_VAR_DB = R_;
|
| 83 |
+
set({ kv: R_ });
|
| 84 |
+
})();
|
| 85 |
+
function set(arg0) {
|
| 86 |
+
const { kv } = arg0;
|
| 87 |
+
const remoteEnvKV = kv;
|
| 88 |
+
for (const [key, value] of Object.entries(remoteEnvKV)) if (process && !process.env[key] && typeof value === "string" && !key.startsWith("_")) process.env[key] = value;
|
| 89 |
+
}
|
| 90 |
+
return R_;
|
| 91 |
+
} catch (error) {
|
| 92 |
+
console.error("❌ Failed to load remote env vars:", error);
|
| 93 |
+
}
|
| 94 |
+
}
|
| 95 |
+
const IS_CLOUDFLARE_WORKER = `${IS_BUN || IS_NODE ? process?.env?.IS_CLOUDFLARE_WORKER : void 0}` === "1";
|
| 96 |
+
const IS_VERCEL_WORKER = `${IS_BUN || IS_NODE ? process?.env?.IS_VERCEL_WORKER || process?.env?.VERCEL : void 0}` === "1";
|
| 97 |
+
const IS_SERVERLESS_ENV = `${IS_BUN || IS_NODE ? process?.env?.IS_SERVERLESS_ENV || process?.env?.VERCEL : void 0}` === "1";
|
| 98 |
+
const NITRO_PRESET = IS_DENO || IS_BUN || IS_NODE ? process?.env?.NITRO_PRESET : void 0;
|
| 99 |
+
const IS_RENDER_COM = (IS_DENO || IS_BUN || IS_NODE ? process?.env?.IS_RENDER_COM : void 0) === "1" || NITRO_PRESET === "render_com";
|
| 100 |
+
const IS_PROD = NODE_ENV === "production" || APP_ENV$1 && [
|
| 101 |
+
"prod",
|
| 102 |
+
"pre_prod",
|
| 103 |
+
"pprod"
|
| 104 |
+
].includes(APP_ENV$1);
|
| 105 |
+
async function browser_check_book() {
|
| 106 |
+
if (!IS_BROWSER) return;
|
| 107 |
+
const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
| 108 |
+
const isChromium = !!window.chrome;
|
| 109 |
+
const isFirefox = typeof window.InstallTrigger !== "undefined" || CSS.supports("-moz-appearance", "none");
|
| 110 |
+
const lowMemory = (navigator.deviceMemory ?? 8) <= 4;
|
| 111 |
+
const lowCPU = navigator.hardwareConcurrency <= 4;
|
| 112 |
+
/Android|iPhone|iPad|iPod|webOS|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) || "ontouchstart" in window && navigator.maxTouchPoints > 1 && /Windows/i.test(navigator.userAgent);
|
| 113 |
+
const mobileUA = /Android|iPhone|iPad|iPod|webOS|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
|
| 114 |
+
const isMobilePlatform = /Android|iPhone|iPad|iPod/i.test(navigator.platform ?? "");
|
| 115 |
+
return {
|
| 116 |
+
isChromium,
|
| 117 |
+
isFirefox,
|
| 118 |
+
lowCPU,
|
| 119 |
+
lowMemory,
|
| 120 |
+
prefersReducedMotion,
|
| 121 |
+
isMobile: mobileUA || isMobilePlatform,
|
| 122 |
+
animation_performance: checkAnimationPerformance
|
| 123 |
+
};
|
| 124 |
+
function checkAnimationPerformance() {
|
| 125 |
+
return new Promise((resolve) => {
|
| 126 |
+
if (document.hidden) document.addEventListener("visibilitychange", run, { once: true });
|
| 127 |
+
else run();
|
| 128 |
+
function run() {
|
| 129 |
+
let frameCount = 0;
|
| 130 |
+
let lastTime = performance.now();
|
| 131 |
+
const drops = [];
|
| 132 |
+
function measure(now) {
|
| 133 |
+
const delta = now - lastTime;
|
| 134 |
+
drops.push(delta);
|
| 135 |
+
lastTime = now;
|
| 136 |
+
frameCount++;
|
| 137 |
+
if (frameCount < 30) requestAnimationFrame(measure);
|
| 138 |
+
else resolve({ avg: drops.slice(5).reduce((a, b) => a + b, 0) / (drops.length - 5) });
|
| 139 |
+
}
|
| 140 |
+
requestAnimationFrame(measure);
|
| 141 |
+
}
|
| 142 |
+
});
|
| 143 |
+
}
|
| 144 |
+
}
|
| 145 |
+
const NS_runtime = {
|
| 146 |
+
detectRuntime,
|
| 147 |
+
IS_BUN,
|
| 148 |
+
IS_BROWSER,
|
| 149 |
+
IS_DENO,
|
| 150 |
+
IS_NODE,
|
| 151 |
+
IS_CLOUDFLARE_WORKER,
|
| 152 |
+
IS_VERCEL_WORKER,
|
| 153 |
+
IS_SERVERLESS_ENV,
|
| 154 |
+
IS_PROD,
|
| 155 |
+
IS_RENDER_COM,
|
| 156 |
+
browser_check_book,
|
| 157 |
+
set_env_var_db,
|
| 158 |
+
ENV_VAR_DB
|
| 159 |
+
};
|
| 160 |
+
|
| 161 |
+
//#endregion
|
| 162 |
+
//#region ../../../packages/lib/astro-environment.ts
|
| 163 |
+
const APP_ENV = () => {
|
| 164 |
+
if (IS_BUN || IS_NODE) return NS_runtime.ENV_VAR_DB?.APP_ENV || process?.env?.APP_ENV;
|
| 165 |
+
if (IS_BROWSER) return import.meta.env?.PUBLIC_APP_ENV;
|
| 166 |
+
};
|
| 167 |
+
const dev = APP_ENV() === "dev" || import.meta?.env?.DEV;
|
| 168 |
+
const browser = NS_runtime.IS_BROWSER || import.meta?.env?.SSR;
|
| 169 |
+
const version = "1";
|
| 170 |
+
|
| 171 |
+
//#endregion
|
| 172 |
+
//#region ../../../packages/lib/helpers/client/misc.ts
|
| 173 |
+
function isUrlEncoded(str) {
|
| 174 |
+
try {
|
| 175 |
+
return decodeURIComponent(str) !== str;
|
| 176 |
+
} catch (e) {
|
| 177 |
+
return false;
|
| 178 |
+
}
|
| 179 |
+
}
|
| 180 |
+
function F_is_within_range(arg0) {
|
| 181 |
+
const { value, min, max } = arg0;
|
| 182 |
+
const numValue = typeof value === "string" ? parseFloat(value) : value;
|
| 183 |
+
if (typeof numValue === "number" && !isNaN(numValue)) return numValue >= min && numValue <= max;
|
| 184 |
+
return false;
|
| 185 |
+
}
|
| 186 |
+
function F_scroll_to_top() {
|
| 187 |
+
window.scrollTo({
|
| 188 |
+
top: 0,
|
| 189 |
+
behavior: "smooth"
|
| 190 |
+
});
|
| 191 |
+
}
|
| 192 |
+
async function F_copy_to_clipboard(arg0) {
|
| 193 |
+
const { text } = arg0;
|
| 194 |
+
try {
|
| 195 |
+
await navigator.clipboard.writeText(text);
|
| 196 |
+
F_console_log({
|
| 197 |
+
ENV: "dev",
|
| 198 |
+
_browser: true,
|
| 199 |
+
_log: ["Text copied to clipboard:", text]
|
| 200 |
+
});
|
| 201 |
+
return true;
|
| 202 |
+
} catch (err) {
|
| 203 |
+
F_console_error({
|
| 204 |
+
ENV: "dev",
|
| 205 |
+
_browser: true,
|
| 206 |
+
_log: ["Failed to copy text:", err]
|
| 207 |
+
});
|
| 208 |
+
return false;
|
| 209 |
+
}
|
| 210 |
+
}
|
| 211 |
+
function F_console_log(arg0) {
|
| 212 |
+
const { ENV, _browser, _log, _off } = arg0;
|
| 213 |
+
if (_off) return;
|
| 214 |
+
switch (ENV) {
|
| 215 |
+
case "all":
|
| 216 |
+
if (_browser && browser) console.log(..._log);
|
| 217 |
+
else if (!_browser && !browser) console.log(..._log);
|
| 218 |
+
break;
|
| 219 |
+
case "dev":
|
| 220 |
+
if (dev) {
|
| 221 |
+
if (_browser && browser) console.log(..._log);
|
| 222 |
+
else if (!_browser && !browser) console.log(..._log);
|
| 223 |
+
}
|
| 224 |
+
break;
|
| 225 |
+
case "prod":
|
| 226 |
+
if (!dev) {
|
| 227 |
+
if (_browser && browser) console.log(..._log);
|
| 228 |
+
else if (!_browser && !browser) console.log(..._log);
|
| 229 |
+
}
|
| 230 |
+
break;
|
| 231 |
+
}
|
| 232 |
+
}
|
| 233 |
+
function F_console_warn(arg0) {
|
| 234 |
+
const { ENV, _browser, _log, _off } = arg0;
|
| 235 |
+
if (_off) return;
|
| 236 |
+
switch (ENV) {
|
| 237 |
+
case "all":
|
| 238 |
+
if (_browser && browser) console.warn(..._log);
|
| 239 |
+
else if (!browser && !_browser) console.warn(..._log);
|
| 240 |
+
break;
|
| 241 |
+
case "dev":
|
| 242 |
+
if (dev) {
|
| 243 |
+
if (_browser && browser) console.warn(..._log);
|
| 244 |
+
else if (!_browser && !browser) console.warn(..._log);
|
| 245 |
+
}
|
| 246 |
+
break;
|
| 247 |
+
case "prod":
|
| 248 |
+
if (!dev) {
|
| 249 |
+
if (_browser && browser) console.warn(..._log);
|
| 250 |
+
else if (!_browser && !browser) console.warn(..._log);
|
| 251 |
+
}
|
| 252 |
+
break;
|
| 253 |
+
}
|
| 254 |
+
}
|
| 255 |
+
function F_console_error(arg0) {
|
| 256 |
+
const { ENV, _browser, _log, _off } = arg0;
|
| 257 |
+
if (_off) return;
|
| 258 |
+
switch (ENV) {
|
| 259 |
+
case "all":
|
| 260 |
+
if (_browser && browser) console.error(..._log);
|
| 261 |
+
else if (!_browser && !browser) console.error(..._log);
|
| 262 |
+
break;
|
| 263 |
+
case "dev":
|
| 264 |
+
if (dev) {
|
| 265 |
+
if (_browser && browser) console.error(..._log);
|
| 266 |
+
else if (!_browser && !browser) console.error(..._log);
|
| 267 |
+
}
|
| 268 |
+
break;
|
| 269 |
+
case "prod":
|
| 270 |
+
if (version) {
|
| 271 |
+
if (_browser && browser) console.error(..._log);
|
| 272 |
+
else if (!_browser && !browser) console.error(..._log);
|
| 273 |
+
}
|
| 274 |
+
break;
|
| 275 |
+
}
|
| 276 |
+
}
|
| 277 |
+
function F_handle_dynamic_link_nav(arg0) {
|
| 278 |
+
const { href, _target, download } = arg0;
|
| 279 |
+
const a = document.createElement("a");
|
| 280 |
+
if (href) a.setAttribute("href", href);
|
| 281 |
+
if (_target) a.setAttribute("_target", _target);
|
| 282 |
+
a.click();
|
| 283 |
+
}
|
| 284 |
+
function F_handle_dynamic_form(arg0) {
|
| 285 |
+
const { form_action } = arg0;
|
| 286 |
+
const styles = css`
|
| 287 |
+
display: none;
|
| 288 |
+
`;
|
| 289 |
+
const form = document.createElement("form");
|
| 290 |
+
if (form_action) {
|
| 291 |
+
form.method = "post";
|
| 292 |
+
form.action = form_action;
|
| 293 |
+
}
|
| 294 |
+
form.classList.add(styles);
|
| 295 |
+
const body = document.querySelector("body");
|
| 296 |
+
if (body) {
|
| 297 |
+
body.append(form);
|
| 298 |
+
form.submit();
|
| 299 |
+
}
|
| 300 |
+
}
|
| 301 |
+
const F_is_even = (num) => num % 2 === 0;
|
| 302 |
+
const F_is_odd = (num) => num % 2 === 1;
|
| 303 |
+
function F_is_record(obj) {
|
| 304 |
+
return typeof obj === "object" && obj !== null && !Array.isArray(obj) && !!obj && obj.constructor === Object;
|
| 305 |
+
}
|
| 306 |
+
function F_create_dynamic_btn(arg0) {
|
| 307 |
+
const { attrs } = arg0;
|
| 308 |
+
const btn = document.createElement("button");
|
| 309 |
+
attrs.forEach((XX) => {
|
| 310 |
+
btn.setAttribute(XX.attr_name, XX.attr_value);
|
| 311 |
+
});
|
| 312 |
+
return btn;
|
| 313 |
+
}
|
| 314 |
+
function F_check_unique_obj_entry(arg0) {
|
| 315 |
+
const { _array, new_entry } = arg0;
|
| 316 |
+
if (!Array.isArray(_array) || !NS_Misc.F_is_record(new_entry)) throw new Error("Invalid input: expected an array and a non-null object.");
|
| 317 |
+
return {
|
| 318 |
+
is_duplicate: _array.some((existingEntry) => JSON.stringify(existingEntry) === JSON.stringify(new_entry)),
|
| 319 |
+
entry: new_entry
|
| 320 |
+
};
|
| 321 |
+
}
|
| 322 |
+
function F_convert_circular_structure_to_twin_string(arg0) {
|
| 323 |
+
const { circular_structure } = arg0;
|
| 324 |
+
return util.inspect(circular_structure, {
|
| 325 |
+
showHidden: false,
|
| 326 |
+
depth: 2,
|
| 327 |
+
colors: false,
|
| 328 |
+
compact: false,
|
| 329 |
+
breakLength: void 0
|
| 330 |
+
});
|
| 331 |
+
}
|
| 332 |
+
function add_zero_if_less_than_ten(number) {
|
| 333 |
+
if (number < 10) return "0" + number;
|
| 334 |
+
else return number.toString();
|
| 335 |
+
}
|
| 336 |
+
function F_extract_numbers_from_string_pattern(arg0) {
|
| 337 |
+
const { str } = arg0;
|
| 338 |
+
const matches = str.match(/\d+/g);
|
| 339 |
+
if (matches) return matches.map(Number);
|
| 340 |
+
return [];
|
| 341 |
+
}
|
| 342 |
+
function F_extract_number_from_end_string(arg0) {
|
| 343 |
+
const { str } = arg0;
|
| 344 |
+
if (!str) return null;
|
| 345 |
+
const match = str.match(/(\d+)$/);
|
| 346 |
+
if (match && match[1]) return parseInt(match[1], 10);
|
| 347 |
+
else return null;
|
| 348 |
+
}
|
| 349 |
+
function F_lock_scroll() {
|
| 350 |
+
window.scrollY;
|
| 351 |
+
document.body.style.overflow = "hidden";
|
| 352 |
+
}
|
| 353 |
+
function F_unlock_scroll() {
|
| 354 |
+
document.body.style.overflow = "";
|
| 355 |
+
delete document.body.dataset.scrollY;
|
| 356 |
+
}
|
| 357 |
+
function F_create_delay(arg0) {
|
| 358 |
+
const { ms } = arg0;
|
| 359 |
+
if (typeof ms !== "number") return;
|
| 360 |
+
return new Promise((r) => setTimeout(r, ms));
|
| 361 |
+
}
|
| 362 |
+
function F_shuffle_array(arg0) {
|
| 363 |
+
const { arr } = arg0;
|
| 364 |
+
for (let i = arr.length - 1; i > 0; i--) {
|
| 365 |
+
const j = Math.floor(Math.random() * (i + 1));
|
| 366 |
+
[arr[i], arr[j]] = [arr[j], arr[i]];
|
| 367 |
+
}
|
| 368 |
+
return arr;
|
| 369 |
+
}
|
| 370 |
+
function F_gen_placeholder_text(arg0) {
|
| 371 |
+
const { text } = arg0;
|
| 372 |
+
switch (text) {
|
| 373 |
+
case "word": return randomwordslugs.generateSlug(arg0.word_count, arg0.options);
|
| 374 |
+
case "sentence": return txtgen.sentence();
|
| 375 |
+
case "paragraph": return txtgen.paragraph();
|
| 376 |
+
case "article": return txtgen.article();
|
| 377 |
+
case "lorem": return txtgen.lorem(arg0.word_min, arg0.word_max);
|
| 378 |
+
}
|
| 379 |
+
}
|
| 380 |
+
function equals_ignore_str_case(a, b) {
|
| 381 |
+
return typeof a === "string" && typeof b === "string" && a.toLowerCase() === b.toLowerCase();
|
| 382 |
+
}
|
| 383 |
+
function flatten_object(obj, prefix = "") {
|
| 384 |
+
const result = {};
|
| 385 |
+
for (const key in obj) {
|
| 386 |
+
const fullKey = prefix ? `${prefix}.${key}` : key;
|
| 387 |
+
if (typeof obj[key] === "object" && obj[key] !== null && !Array.isArray(obj[key])) Object.assign(result, flatten_object(obj[key], fullKey));
|
| 388 |
+
else result[fullKey] = obj[key];
|
| 389 |
+
}
|
| 390 |
+
return result;
|
| 391 |
+
}
|
| 392 |
+
function F_remove_last_array_element(arg0) {
|
| 393 |
+
const { arr } = arg0;
|
| 394 |
+
if (arr.length > 0) arr.pop();
|
| 395 |
+
return arr;
|
| 396 |
+
}
|
| 397 |
+
function F_merge_arrays_by_keys(arg0) {
|
| 398 |
+
const { arrays, keys, deep_merge } = arg0;
|
| 399 |
+
const map = /* @__PURE__ */ new Map();
|
| 400 |
+
const make_key = (item) => keys.map((k) => String(item[k])).join("_");
|
| 401 |
+
for (const arr of arrays) for (const item of arr) {
|
| 402 |
+
const key = make_key(item);
|
| 403 |
+
if (map.has(key)) if (deep_merge) map.set(key, F_deep_merge({
|
| 404 |
+
target: map.get(key),
|
| 405 |
+
source: item,
|
| 406 |
+
array_strategy: deep_merge.array_strategy
|
| 407 |
+
}));
|
| 408 |
+
else map.set(key, {
|
| 409 |
+
...map.get(key),
|
| 410 |
+
...item
|
| 411 |
+
});
|
| 412 |
+
else map.set(key, { ...item });
|
| 413 |
+
}
|
| 414 |
+
return Array.from(map.values());
|
| 415 |
+
}
|
| 416 |
+
function F_deep_merge(arg0) {
|
| 417 |
+
const { target, source, array_strategy } = arg0;
|
| 418 |
+
const result = { ...target };
|
| 419 |
+
for (const key of Object.keys(source)) {
|
| 420 |
+
const src_val = source[key];
|
| 421 |
+
const tgt_val = result[key];
|
| 422 |
+
if (Array.isArray(src_val)) if (array_strategy === "concat") result[key] = Array.isArray(tgt_val) ? [...tgt_val, ...src_val] : [...src_val];
|
| 423 |
+
else result[key] = src_val;
|
| 424 |
+
else if (src_val && typeof src_val === "object" && !Array.isArray(src_val)) result[key] = F_deep_merge({
|
| 425 |
+
target: tgt_val ?? {},
|
| 426 |
+
source: src_val,
|
| 427 |
+
array_strategy
|
| 428 |
+
});
|
| 429 |
+
else result[key] = src_val;
|
| 430 |
+
}
|
| 431 |
+
return result;
|
| 432 |
+
}
|
| 433 |
+
/**
|
| 434 |
+
* Extracts the code inside a function as a string.
|
| 435 |
+
* Works for:
|
| 436 |
+
* - Regular functions
|
| 437 |
+
* - Arrow functions (block or expression body)
|
| 438 |
+
*/
|
| 439 |
+
function F_extract_function_body(arg0) {
|
| 440 |
+
const { fn } = arg0;
|
| 441 |
+
const fnString = fn.toString().trim();
|
| 442 |
+
if (fnString.includes("{")) return fnString.substring(fnString.indexOf("{") + 1, fnString.lastIndexOf("}")).trim();
|
| 443 |
+
const arrowIndex = fnString.indexOf("=>");
|
| 444 |
+
if (arrowIndex !== -1) return fnString.substring(arrowIndex + 2).trim().replace(/^(\(|\s)*return\s+/, "").trim();
|
| 445 |
+
return fnString;
|
| 446 |
+
}
|
| 447 |
+
/**
|
| 448 |
+
* Sets a cookie in the browser with a specified TTL (time-to-live)
|
| 449 |
+
*/
|
| 450 |
+
function set_dom_cookie(arg0) {
|
| 451 |
+
const { name, value, ttl, sameSite = "Lax", secure = true } = arg0;
|
| 452 |
+
let expires = "";
|
| 453 |
+
let milliseconds = 0;
|
| 454 |
+
switch (ttl.duration) {
|
| 455 |
+
case "seconds":
|
| 456 |
+
milliseconds = ttl.value * 1e3;
|
| 457 |
+
break;
|
| 458 |
+
case "minutes":
|
| 459 |
+
milliseconds = ttl.value * 60 * 1e3;
|
| 460 |
+
break;
|
| 461 |
+
case "hours":
|
| 462 |
+
milliseconds = ttl.value * 60 * 60 * 1e3;
|
| 463 |
+
break;
|
| 464 |
+
case "days":
|
| 465 |
+
milliseconds = ttl.value * 24 * 60 * 60 * 1e3;
|
| 466 |
+
break;
|
| 467 |
+
}
|
| 468 |
+
const date = /* @__PURE__ */ new Date();
|
| 469 |
+
date.setTime(date.getTime() + milliseconds);
|
| 470 |
+
expires = "; expires=" + date.toUTCString();
|
| 471 |
+
let cookieString = name + "=" + (value || "") + expires + "; path=/";
|
| 472 |
+
cookieString += "; SameSite=" + sameSite;
|
| 473 |
+
if (secure) cookieString += "; Secure";
|
| 474 |
+
document.cookie = cookieString;
|
| 475 |
+
}
|
| 476 |
+
/**
|
| 477 |
+
* Gets a cookie value by name from the browser
|
| 478 |
+
* @returns The cookie value if found, null otherwise
|
| 479 |
+
*/
|
| 480 |
+
function get_dom_cookie(name) {
|
| 481 |
+
const nameEQ = name + "=";
|
| 482 |
+
const cookies = document.cookie.split(";");
|
| 483 |
+
for (let i = 0; i < cookies.length; i++) {
|
| 484 |
+
let cookie = cookies[i];
|
| 485 |
+
if (!cookie) continue;
|
| 486 |
+
while (cookie.charAt(0) === " ") cookie = cookie.substring(1);
|
| 487 |
+
if (cookie.indexOf(nameEQ) === 0) return cookie.substring(nameEQ.length);
|
| 488 |
+
}
|
| 489 |
+
return null;
|
| 490 |
+
}
|
| 491 |
+
function F_is_fetch_response(obj) {
|
| 492 |
+
return obj && typeof obj.json === "function" && typeof obj.text === "function" && "ok" in obj && "status" in obj;
|
| 493 |
+
}
|
| 494 |
+
function F_update_page_title(newTitle) {
|
| 495 |
+
document.title = newTitle;
|
| 496 |
+
}
|
| 497 |
+
function F_update_meta_description(newDescription) {
|
| 498 |
+
const metaDescriptionTag = document.querySelector("meta[name=\"description\"]");
|
| 499 |
+
if (metaDescriptionTag) metaDescriptionTag.setAttribute("content", newDescription);
|
| 500 |
+
else {
|
| 501 |
+
const newMetaTag = document.createElement("meta");
|
| 502 |
+
newMetaTag.name = "description";
|
| 503 |
+
newMetaTag.content = newDescription;
|
| 504 |
+
document.head.appendChild(newMetaTag);
|
| 505 |
+
}
|
| 506 |
+
}
|
| 507 |
+
function F_update_open_graph_tags(metadata) {
|
| 508 |
+
const tags = {
|
| 509 |
+
"og:title": metadata.title,
|
| 510 |
+
"og:description": metadata.desc,
|
| 511 |
+
"og:image": metadata.image,
|
| 512 |
+
"og:image:alt": metadata.title && metadata.image && `${metadata.title} thumbnail`
|
| 513 |
+
};
|
| 514 |
+
for (const [property, content] of Object.entries(tags)) {
|
| 515 |
+
let element = content && document.querySelector(`meta[property="${property}"]`);
|
| 516 |
+
if (!element) continue;
|
| 517 |
+
if (content) element.setAttribute("content", content);
|
| 518 |
+
}
|
| 519 |
+
}
|
| 520 |
+
function F_get_inner_fn_content(arg0) {
|
| 521 |
+
const { fn } = arg0;
|
| 522 |
+
let FN_STRING = fn.toString();
|
| 523 |
+
FN_STRING = FN_STRING.slice(FN_STRING.indexOf("{") + 1, FN_STRING.lastIndexOf("}")).trim();
|
| 524 |
+
return FN_STRING;
|
| 525 |
+
}
|
| 526 |
+
/**
|
| 527 |
+
* Converts an array of name/value pairs into a single object.
|
| 528 |
+
*/
|
| 529 |
+
function F_obj_array_to_object(arg0) {
|
| 530 |
+
const { obj_array } = arg0;
|
| 531 |
+
return obj_array.reduce((acc, { name, value }) => {
|
| 532 |
+
acc[name] = value;
|
| 533 |
+
return acc;
|
| 534 |
+
}, {});
|
| 535 |
+
}
|
| 536 |
+
function F_get_mime_type(arg0) {
|
| 537 |
+
const { ext } = arg0;
|
| 538 |
+
return { mime_type: {
|
| 539 |
+
".html": "text/html",
|
| 540 |
+
".txt": "text/plain",
|
| 541 |
+
".xml": "application/xml",
|
| 542 |
+
".json": "application/json",
|
| 543 |
+
".csv": "text/csv",
|
| 544 |
+
".pdf": "application/pdf",
|
| 545 |
+
".js": "application/javascript",
|
| 546 |
+
".mjs": "application/javascript",
|
| 547 |
+
".css": "text/css",
|
| 548 |
+
".map": "application/json",
|
| 549 |
+
".png": "image/png",
|
| 550 |
+
".jpg": "image/jpeg",
|
| 551 |
+
".jpeg": "image/jpeg",
|
| 552 |
+
".gif": "image/gif",
|
| 553 |
+
".svg": "image/svg+xml",
|
| 554 |
+
".webp": "image/webp",
|
| 555 |
+
".avif": "image/avif",
|
| 556 |
+
".ico": "image/x-icon",
|
| 557 |
+
".mp3": "audio/mpeg",
|
| 558 |
+
".wav": "audio/wav",
|
| 559 |
+
".ogg": "audio/ogg",
|
| 560 |
+
".mp4": "video/mp4",
|
| 561 |
+
".webm": "video/webm",
|
| 562 |
+
".ogv": "video/ogg",
|
| 563 |
+
".m3u8": "application/vnd.apple.mpegurl",
|
| 564 |
+
".ts": "video/mp2t",
|
| 565 |
+
".woff": "font/woff",
|
| 566 |
+
".woff2": "font/woff2",
|
| 567 |
+
".ttf": "font/ttf",
|
| 568 |
+
".otf": "font/otf",
|
| 569 |
+
".zip": "application/zip",
|
| 570 |
+
".tar": "application/x-tar",
|
| 571 |
+
".gz": "application/gzip",
|
| 572 |
+
".wasm": "application/wasm"
|
| 573 |
+
}[!`${ext}`.startsWith(".") ? `.${ext}` : `${ext}`] || "application/octet-stream" };
|
| 574 |
+
}
|
| 575 |
+
const NS_Misc = {
|
| 576 |
+
F_is_within_range,
|
| 577 |
+
F_scroll_to_top,
|
| 578 |
+
F_copy_to_clipboard,
|
| 579 |
+
console: {
|
| 580 |
+
log: F_console_log,
|
| 581 |
+
warn: F_console_warn,
|
| 582 |
+
error: F_console_error
|
| 583 |
+
},
|
| 584 |
+
F_handle_dynamic_link_nav,
|
| 585 |
+
F_is_even,
|
| 586 |
+
F_is_odd,
|
| 587 |
+
F_is_record,
|
| 588 |
+
F_create_dynamic_btn,
|
| 589 |
+
F_check_unique_obj_entry,
|
| 590 |
+
F_convert_circular_structure_to_twin_string,
|
| 591 |
+
add_zero_if_less_than_ten,
|
| 592 |
+
F_extract_numbers_from_string_pattern,
|
| 593 |
+
F_handle_dynamic_form,
|
| 594 |
+
F_lock_scroll,
|
| 595 |
+
F_unlock_scroll,
|
| 596 |
+
F_create_delay,
|
| 597 |
+
F_shuffle_array,
|
| 598 |
+
F_gen_placeholder_text,
|
| 599 |
+
equals_ignore_str_case,
|
| 600 |
+
F_extract_number_from_end_string,
|
| 601 |
+
flatten_object,
|
| 602 |
+
F_remove_last_array_element,
|
| 603 |
+
F_merge_arrays_by_keys,
|
| 604 |
+
F_extract_function_body,
|
| 605 |
+
cookies: {
|
| 606 |
+
set_dom_cookie,
|
| 607 |
+
get_dom_cookie
|
| 608 |
+
},
|
| 609 |
+
F_is_fetch_response,
|
| 610 |
+
F_update_meta_description,
|
| 611 |
+
F_update_open_graph_tags,
|
| 612 |
+
F_update_page_title,
|
| 613 |
+
F_get_inner_fn_content,
|
| 614 |
+
isUrlEncoded,
|
| 615 |
+
F_obj_array_to_object,
|
| 616 |
+
F_get_mime_type
|
| 617 |
+
};
|
| 618 |
+
|
| 619 |
+
//#endregion
|
| 620 |
+
//#region ../../../packages/lib/helpers/client/error.ts
|
| 621 |
+
function F_collect_error_status_n_message(arg0) {
|
| 622 |
+
const { ERR } = arg0;
|
| 623 |
+
try {
|
| 624 |
+
const is_axios_err = ERR instanceof AxiosError;
|
| 625 |
+
let status = ERR?.status_code || ERR?.status || is_axios_err && ERR.response?.status || 500;
|
| 626 |
+
let message = ERR?.status_message || is_axios_err && (ERR.response?.data?.message || ERR.response?.data?.status_message || ERR.response?.statusText) || ERR?.message || ERR?.error || ERR?.code || "Unexpected error";
|
| 627 |
+
if (typeof ERR == "string" && ERR.length > 0) message = ERR;
|
| 628 |
+
if (message === "ECONNREFUSED") message = "network connection refused";
|
| 629 |
+
if (is_axios_err) {
|
| 630 |
+
const headers = ERR.response?.headers;
|
| 631 |
+
if (headers) {
|
| 632 |
+
status = headers["x-error-status"] || status;
|
| 633 |
+
message = headers["x-error-message"] || message;
|
| 634 |
+
}
|
| 635 |
+
}
|
| 636 |
+
status = parseInt(`${status}`);
|
| 637 |
+
if (typeof message !== "string") message = JSON.stringify(message);
|
| 638 |
+
message = String(message).trim();
|
| 639 |
+
return {
|
| 640 |
+
status,
|
| 641 |
+
message
|
| 642 |
+
};
|
| 643 |
+
} catch (error) {
|
| 644 |
+
return {
|
| 645 |
+
status: 500,
|
| 646 |
+
message: "Oops! Unexpected system error"
|
| 647 |
+
};
|
| 648 |
+
}
|
| 649 |
+
}
|
| 650 |
+
function F_collect_error_message(arg0) {
|
| 651 |
+
const { ERR } = arg0;
|
| 652 |
+
const { message } = F_collect_error_status_n_message({ ERR });
|
| 653 |
+
return { message };
|
| 654 |
+
}
|
| 655 |
+
function F_create_error(arg0) {
|
| 656 |
+
const { status, message, ERR } = arg0;
|
| 657 |
+
if (!message) switch (status) {
|
| 658 |
+
case 400: return new createError.BadRequest();
|
| 659 |
+
case 401: return new createError.Unauthorized();
|
| 660 |
+
case 402: return new createError.PaymentRequired();
|
| 661 |
+
case 403: return new createError.Forbidden();
|
| 662 |
+
case 404: return new createError.NotFound();
|
| 663 |
+
case 405: return new createError.MethodNotAllowed();
|
| 664 |
+
case 406: return new createError.NotAcceptable();
|
| 665 |
+
case 407: return new createError.ProxyAuthenticationRequired();
|
| 666 |
+
case 408: return new createError.RequestTimeout();
|
| 667 |
+
case 409: return new createError.Conflict();
|
| 668 |
+
case 410: return new createError.Gone();
|
| 669 |
+
case 411: return new createError.LengthRequired();
|
| 670 |
+
case 412: return new createError.PreconditionFailed();
|
| 671 |
+
case 413: return new createError.PayloadTooLarge();
|
| 672 |
+
case 414: return new createError.URITooLong();
|
| 673 |
+
case 415: return new createError.UnsupportedMediaType();
|
| 674 |
+
case 416: return new createError.RangeNotSatisfiable();
|
| 675 |
+
case 417: return new createError.ExpectationFailed();
|
| 676 |
+
case 418: return new createError.ImATeapot();
|
| 677 |
+
case 421: return new createError.MisdirectedRequest();
|
| 678 |
+
case 422: return new createError.UnprocessableEntity();
|
| 679 |
+
case 423: return new createError.Locked();
|
| 680 |
+
case 424: return new createError.FailedDependency();
|
| 681 |
+
case 425: return new createError.TooEarly();
|
| 682 |
+
case 426: return new createError.UpgradeRequired();
|
| 683 |
+
case 428: return new createError.PreconditionRequired();
|
| 684 |
+
case 429: return new createError.TooManyRequests();
|
| 685 |
+
case 431: return new createError.RequestHeaderFieldsTooLarge();
|
| 686 |
+
case 451: return new createError.UnavailableForLegalReasons();
|
| 687 |
+
case 500: return new createError.InternalServerError();
|
| 688 |
+
case 501: return new createError.NotImplemented();
|
| 689 |
+
case 502: return new createError.BadGateway();
|
| 690 |
+
case 503: return new createError.ServiceUnavailable();
|
| 691 |
+
case 504: return new createError.GatewayTimeout();
|
| 692 |
+
case 505: return new createError.HTTPVersionNotSupported();
|
| 693 |
+
case 506: return new createError.VariantAlsoNegotiates();
|
| 694 |
+
case 507: return new createError.InsufficientStorage();
|
| 695 |
+
case 508: return new createError.LoopDetected();
|
| 696 |
+
case 509: return new createError.BandwidthLimitExceeded();
|
| 697 |
+
case 510: return new createError.NotExtended();
|
| 698 |
+
case 511: return new createError.NetworkAuthenticationRequire();
|
| 699 |
+
}
|
| 700 |
+
if (ERR && !message) {
|
| 701 |
+
const { message } = F_collect_error_message({ ERR });
|
| 702 |
+
return createError(status, message);
|
| 703 |
+
}
|
| 704 |
+
return createError(status, message);
|
| 705 |
+
}
|
| 706 |
+
const NS_error = {
|
| 707 |
+
F_collect_error_status_n_message,
|
| 708 |
+
F_collect_error_message,
|
| 709 |
+
F_create_error
|
| 710 |
+
};
|
| 711 |
+
|
| 712 |
+
//#endregion
|
| 713 |
+
//#region ../../../packages/lib/helpers/server/routes-elysia.ts
|
| 714 |
+
function F_public_origin(c) {
|
| 715 |
+
return `${c.headers["x-forwarded-proto"] ?? "http"}://${c.headers["x-forwarded-host"] ?? c.headers.host}`;
|
| 716 |
+
}
|
| 717 |
+
const NS_routes_elysia = { F_public_origin };
|
| 718 |
+
|
| 719 |
+
//#endregion
|
| 720 |
+
//#region ../../../packages/lib/helpers/client/promise.ts
|
| 721 |
+
(IS_BUN || IS_NODE) && process?.env?.APP_ENV || NS_runtime.ENV_VAR_DB?.APP_ENV;
|
| 722 |
+
function F_catch_promise(arg0) {
|
| 723 |
+
const { promise } = arg0;
|
| 724 |
+
if (!promise) return Promise.resolve([/* @__PURE__ */ new Error("No promise provided"), void 0]);
|
| 725 |
+
return promise.then((data) => {
|
| 726 |
+
return [void 0, data];
|
| 727 |
+
}).catch((error) => {
|
| 728 |
+
return [error, void 0];
|
| 729 |
+
});
|
| 730 |
+
}
|
| 731 |
+
async function F_try_catch(arg0) {
|
| 732 |
+
const { logic } = arg0;
|
| 733 |
+
try {
|
| 734 |
+
return [void 0, await logic()];
|
| 735 |
+
} catch (error) {
|
| 736 |
+
return [error, void 0];
|
| 737 |
+
}
|
| 738 |
+
}
|
| 739 |
+
async function F_catch_fetch(arg0) {
|
| 740 |
+
const { promise, parse } = arg0;
|
| 741 |
+
try {
|
| 742 |
+
const response = await promise;
|
| 743 |
+
if (!response) throw new Error("Response is undefined");
|
| 744 |
+
if (!response.ok) {
|
| 745 |
+
const x_message = response.headers.get("x-error-message");
|
| 746 |
+
const { status, message } = NS_error.F_collect_error_status_n_message({ ERR: parse && [
|
| 747 |
+
"json",
|
| 748 |
+
"text",
|
| 749 |
+
"html"
|
| 750 |
+
].includes(parse) ? await response.clone().text() : response });
|
| 751 |
+
NS_Misc.console.warn({
|
| 752 |
+
ENV: "dev",
|
| 753 |
+
_browser: false,
|
| 754 |
+
_log: ["FETCH RES NOT OK ==>", response],
|
| 755 |
+
_off: true
|
| 756 |
+
});
|
| 757 |
+
return [createError(status, x_message || message || `HTTP Error: ${response.status} ${response.statusText}`), void 0];
|
| 758 |
+
}
|
| 759 |
+
if (parse === void 0) return [void 0, response];
|
| 760 |
+
let content;
|
| 761 |
+
switch (parse) {
|
| 762 |
+
case "json":
|
| 763 |
+
content = await response.json();
|
| 764 |
+
break;
|
| 765 |
+
case "blob":
|
| 766 |
+
content = await response.blob();
|
| 767 |
+
break;
|
| 768 |
+
case "arrayBuffer":
|
| 769 |
+
content = await response.arrayBuffer();
|
| 770 |
+
break;
|
| 771 |
+
case "html":
|
| 772 |
+
case "text":
|
| 773 |
+
content = await response.text();
|
| 774 |
+
break;
|
| 775 |
+
default: {
|
| 776 |
+
const _exhaustive = parse;
|
| 777 |
+
throw new Error(`Unhandled parse type: ${_exhaustive}`);
|
| 778 |
+
}
|
| 779 |
+
}
|
| 780 |
+
return [void 0, content];
|
| 781 |
+
} catch (error) {
|
| 782 |
+
return [error instanceof Error ? error : new Error(String(error)), void 0];
|
| 783 |
+
}
|
| 784 |
+
}
|
| 785 |
+
async function F_first_come_fetch_promise(arg0) {
|
| 786 |
+
const { fetch_batch, response_parse } = arg0;
|
| 787 |
+
let { timeoutMs } = arg0;
|
| 788 |
+
if (!timeoutMs) timeoutMs = 5e3;
|
| 789 |
+
const controllers = fetch_batch.map(() => new AbortController());
|
| 790 |
+
const fetchPromises = fetch_batch.map(async (xx, index) => {
|
| 791 |
+
const controller = controllers[index];
|
| 792 |
+
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
| 793 |
+
try {
|
| 794 |
+
const [_E, _R] = await NS_promise.F_catch_fetch({
|
| 795 |
+
promise: fetch(xx.endpoint, {
|
| 796 |
+
...xx.config || {},
|
| 797 |
+
signal: controller.signal
|
| 798 |
+
}),
|
| 799 |
+
parse: response_parse
|
| 800 |
+
});
|
| 801 |
+
clearTimeout(timeout);
|
| 802 |
+
if (_E) {
|
| 803 |
+
const { message } = NS_error.F_collect_error_message({ ERR: _E });
|
| 804 |
+
NS_Misc.console.warn({
|
| 805 |
+
ENV: "dev",
|
| 806 |
+
_browser: false,
|
| 807 |
+
_log: [
|
| 808 |
+
"\n",
|
| 809 |
+
"FETCH RES NOT OK ==>",
|
| 810 |
+
xx.endpoint,
|
| 811 |
+
message,
|
| 812 |
+
"\n"
|
| 813 |
+
],
|
| 814 |
+
_off: true
|
| 815 |
+
});
|
| 816 |
+
throw new Error(`Bad status from ${xx.endpoint}: ${message}`);
|
| 817 |
+
}
|
| 818 |
+
const response = _R;
|
| 819 |
+
return {
|
| 820 |
+
endpoint: xx.endpoint,
|
| 821 |
+
[response_parse === "json" ? "json" : response_parse === "blob" ? "blob" : response_parse === "arrayBuffer" ? "arrayBuffer" : response_parse === "html" ? "html" : "text"]: response
|
| 822 |
+
};
|
| 823 |
+
} catch (err) {
|
| 824 |
+
clearTimeout(timeout);
|
| 825 |
+
throw err;
|
| 826 |
+
}
|
| 827 |
+
});
|
| 828 |
+
try {
|
| 829 |
+
const result = await Promise.any(fetchPromises);
|
| 830 |
+
controllers.forEach((controller) => controller.abort());
|
| 831 |
+
return result;
|
| 832 |
+
} catch (err) {
|
| 833 |
+
throw new Error("All endpoints failed or timed out.");
|
| 834 |
+
}
|
| 835 |
+
}
|
| 836 |
+
async function F_fetch_ping(arg0) {
|
| 837 |
+
const { url, options, timeout = 5e3 } = arg0;
|
| 838 |
+
const controller = new AbortController();
|
| 839 |
+
const id = setTimeout(() => controller.abort(), timeout);
|
| 840 |
+
try {
|
| 841 |
+
const response = await fetch(url, {
|
| 842 |
+
...options,
|
| 843 |
+
signal: controller.signal
|
| 844 |
+
});
|
| 845 |
+
clearTimeout(id);
|
| 846 |
+
if (!response.ok) return {
|
| 847 |
+
success: false,
|
| 848 |
+
error: `HTTP error: ${response.status}`
|
| 849 |
+
};
|
| 850 |
+
return { success: true };
|
| 851 |
+
} catch (err) {
|
| 852 |
+
clearTimeout(id);
|
| 853 |
+
if (err?.name === "AbortError") return {
|
| 854 |
+
success: false,
|
| 855 |
+
error: "Request timed out"
|
| 856 |
+
};
|
| 857 |
+
return {
|
| 858 |
+
success: false,
|
| 859 |
+
error: err.message
|
| 860 |
+
};
|
| 861 |
+
}
|
| 862 |
+
}
|
| 863 |
+
async function F_fetch_ping_v2(arg0) {
|
| 864 |
+
const { url, options, timeout = 5e3, method = "get" } = arg0;
|
| 865 |
+
try {
|
| 866 |
+
const response = await (async () => {
|
| 867 |
+
switch (method.toLowerCase()) {
|
| 868 |
+
case "get": return ky.get(url, {
|
| 869 |
+
...options,
|
| 870 |
+
timeout
|
| 871 |
+
});
|
| 872 |
+
case "post": return ky.post(url, {
|
| 873 |
+
...options,
|
| 874 |
+
timeout
|
| 875 |
+
});
|
| 876 |
+
case "head": return ky.head(url, {
|
| 877 |
+
...options,
|
| 878 |
+
timeout
|
| 879 |
+
});
|
| 880 |
+
}
|
| 881 |
+
})();
|
| 882 |
+
if (!response) return {
|
| 883 |
+
success: false,
|
| 884 |
+
error: `Response undefined`
|
| 885 |
+
};
|
| 886 |
+
if (!response.ok) return {
|
| 887 |
+
success: false,
|
| 888 |
+
error: `HTTP error: ${response.status}`
|
| 889 |
+
};
|
| 890 |
+
return { success: true };
|
| 891 |
+
} catch (error) {
|
| 892 |
+
if (error.name && ["AbortError", "TimeoutError"].includes(error.name)) return {
|
| 893 |
+
success: false,
|
| 894 |
+
error: "Request timed out"
|
| 895 |
+
};
|
| 896 |
+
const { message } = NS_error.F_collect_error_message({ ERR: error });
|
| 897 |
+
return {
|
| 898 |
+
success: false,
|
| 899 |
+
error: message
|
| 900 |
+
};
|
| 901 |
+
}
|
| 902 |
+
}
|
| 903 |
+
const NS_promise = {
|
| 904 |
+
F_catch_promise,
|
| 905 |
+
F_catch_fetch,
|
| 906 |
+
F_try_catch,
|
| 907 |
+
F_first_come_fetch_promise,
|
| 908 |
+
F_fetch_ping,
|
| 909 |
+
F_fetch_ping_v2
|
| 910 |
+
};
|
| 911 |
+
|
| 912 |
+
//#endregion
|
| 913 |
+
//#region ../../../packages/lib/helpers/client/route.ts
|
| 914 |
+
function F_flat_url_slash(url) {
|
| 915 |
+
const protocolMatch = url.match(/^(https?:\/\/)/);
|
| 916 |
+
let protocol = "";
|
| 917 |
+
let restOfUrl = url;
|
| 918 |
+
if (protocolMatch) {
|
| 919 |
+
protocol = protocolMatch[0];
|
| 920 |
+
restOfUrl = url.slice(protocol.length);
|
| 921 |
+
}
|
| 922 |
+
restOfUrl = restOfUrl.replace(/\/+/g, "/");
|
| 923 |
+
return (protocol + restOfUrl).trim();
|
| 924 |
+
}
|
| 925 |
+
function F_remove_protocol(url) {
|
| 926 |
+
const protocolMatch = url.match(/^(https?:\/\/)/);
|
| 927 |
+
let protocol = "";
|
| 928 |
+
let restOfUrl = url;
|
| 929 |
+
if (protocolMatch) {
|
| 930 |
+
protocol = protocolMatch[0];
|
| 931 |
+
restOfUrl = url.slice(protocol.length);
|
| 932 |
+
}
|
| 933 |
+
return restOfUrl;
|
| 934 |
+
}
|
| 935 |
+
function F_remove_url_params(arg0) {
|
| 936 |
+
const { url, paramsToRemove } = arg0;
|
| 937 |
+
try {
|
| 938 |
+
const urlObj = new URL(url);
|
| 939 |
+
paramsToRemove.forEach((param) => {
|
| 940 |
+
urlObj.searchParams.delete(param);
|
| 941 |
+
});
|
| 942 |
+
return urlObj.toString();
|
| 943 |
+
} catch (err) {
|
| 944 |
+
return url;
|
| 945 |
+
}
|
| 946 |
+
}
|
| 947 |
+
function F_update_search_params(arg0) {
|
| 948 |
+
const { url, params } = arg0;
|
| 949 |
+
try {
|
| 950 |
+
const url_obj = new URL(url);
|
| 951 |
+
params.forEach(({ key, value }) => {
|
| 952 |
+
if (value === null || value === void 0) url_obj.searchParams.delete(key);
|
| 953 |
+
else url_obj.searchParams.set(key, `${value}`);
|
| 954 |
+
});
|
| 955 |
+
return url_obj.toString();
|
| 956 |
+
} catch (error) {
|
| 957 |
+
return url;
|
| 958 |
+
}
|
| 959 |
+
}
|
| 960 |
+
function F_is_url(str) {
|
| 961 |
+
if (typeof str !== "string") {
|
| 962 |
+
if (!(str instanceof URL)) return;
|
| 963 |
+
}
|
| 964 |
+
try {
|
| 965 |
+
if (new URL(str.toString()).protocol.startsWith("http")) return true;
|
| 966 |
+
else return false;
|
| 967 |
+
} catch (error) {
|
| 968 |
+
return false;
|
| 969 |
+
}
|
| 970 |
+
}
|
| 971 |
+
function F_remove_origin(arg0) {
|
| 972 |
+
const { url } = arg0;
|
| 973 |
+
try {
|
| 974 |
+
const url_o = new URL(url);
|
| 975 |
+
const url_origin = url_o.origin;
|
| 976 |
+
return url_o.href.slice(url_origin.length);
|
| 977 |
+
} catch (error) {
|
| 978 |
+
return;
|
| 979 |
+
}
|
| 980 |
+
}
|
| 981 |
+
const NS_routes_c = {
|
| 982 |
+
F_flat_url_slash,
|
| 983 |
+
F_remove_protocol,
|
| 984 |
+
F_remove_url_params,
|
| 985 |
+
F_update_search_params,
|
| 986 |
+
F_is_url,
|
| 987 |
+
F_remove_origin
|
| 988 |
+
};
|
| 989 |
+
|
| 990 |
+
//#endregion
|
| 991 |
+
//#region ../../../packages/lib/helpers/client/crypto.ts
|
| 992 |
+
function F_generate_oslo_id(arg0) {
|
| 993 |
+
let { length } = arg0;
|
| 994 |
+
if (!length || typeof length !== "number") length = 20;
|
| 995 |
+
return generateRandomString(length, alphabet("a-z", "0-9"));
|
| 996 |
+
}
|
| 997 |
+
function F_gen_random_string(arg0) {
|
| 998 |
+
let { length, type } = arg0;
|
| 999 |
+
if (!length) length = 32;
|
| 1000 |
+
if (!type) type = "alphanumeric";
|
| 1001 |
+
if (typeof type === "object" && type.scoped) type = `scoped:${type.scoped}`;
|
| 1002 |
+
return random(length, type);
|
| 1003 |
+
}
|
| 1004 |
+
function F_crypto_randomUUID(arg0) {
|
| 1005 |
+
let { length } = arg0;
|
| 1006 |
+
if (!length || length > 32) length = 36;
|
| 1007 |
+
const uuid = crypto.randomUUID();
|
| 1008 |
+
let newUUID = uuid.toString();
|
| 1009 |
+
if (newUUID.length !== length) newUUID = uuid.split("-").join("").slice(0, length + 1);
|
| 1010 |
+
return newUUID;
|
| 1011 |
+
}
|
| 1012 |
+
function F_base64_encode_unicode(arg0) {
|
| 1013 |
+
const { data_str, url_safe } = arg0;
|
| 1014 |
+
let _encode = btoa(encodeURIComponent(data_str).replace(/%([0-9A-F]{2})/g, (match, p1) => String.fromCharCode(parseInt(p1, 16))));
|
| 1015 |
+
if (url_safe) _encode = F_to_url_safe_base64_encode(_encode);
|
| 1016 |
+
return _encode;
|
| 1017 |
+
}
|
| 1018 |
+
function F_base64_decode_unicode(arg0) {
|
| 1019 |
+
const { data_str, _is_url_safe } = arg0;
|
| 1020 |
+
let _encode = data_str;
|
| 1021 |
+
if (_is_url_safe) _encode = F_decode_from_url_safe_base64_encode(_encode);
|
| 1022 |
+
return decodeURIComponent(atob(_encode).split("").map((c) => "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2)).join(""));
|
| 1023 |
+
}
|
| 1024 |
+
function F_b64_char_set() {
|
| 1025 |
+
const _b64chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
| 1026 |
+
const _b64lookup = {};
|
| 1027 |
+
for (let i = 0; i < 64; i++) _b64lookup[_b64chars[i]] = i;
|
| 1028 |
+
return {
|
| 1029 |
+
_b64chars,
|
| 1030 |
+
_b64lookup
|
| 1031 |
+
};
|
| 1032 |
+
}
|
| 1033 |
+
function F_base64_encode_unicode_v2(arg0) {
|
| 1034 |
+
const { data_str, url_safe } = arg0;
|
| 1035 |
+
const { _b64chars } = F_b64_char_set();
|
| 1036 |
+
const bytes = new TextEncoder().encode(data_str);
|
| 1037 |
+
let base64 = "";
|
| 1038 |
+
for (let i = 0; i < bytes.length; i += 3) {
|
| 1039 |
+
const a = bytes[i];
|
| 1040 |
+
const b = bytes[i + 1];
|
| 1041 |
+
const c = bytes[i + 2];
|
| 1042 |
+
if (a === void 0) continue;
|
| 1043 |
+
const triplet = (a ?? 0) << 16 | (b ?? 0) << 8 | (c ?? 0);
|
| 1044 |
+
base64 += (_b64chars[triplet >> 18 & 63] ?? "=") + (_b64chars[triplet >> 12 & 63] ?? "=") + (b !== void 0 ? _b64chars[triplet >> 6 & 63] ?? "=" : "=") + (c !== void 0 ? _b64chars[triplet & 63] ?? "=" : "=");
|
| 1045 |
+
}
|
| 1046 |
+
if (url_safe) base64 = F_to_url_safe_base64_encode(base64);
|
| 1047 |
+
return base64;
|
| 1048 |
+
}
|
| 1049 |
+
function F_base64_decode_unicode_v2(arg0) {
|
| 1050 |
+
let { data_str, _is_url_safe } = arg0;
|
| 1051 |
+
const { _b64lookup } = F_b64_char_set();
|
| 1052 |
+
if (_is_url_safe) data_str = F_decode_from_url_safe_base64_encode(data_str);
|
| 1053 |
+
const clean = data_str;
|
| 1054 |
+
const bytes = [];
|
| 1055 |
+
for (let i = 0; i < clean.length; i += 4) {
|
| 1056 |
+
const a = _b64lookup[clean[i] ?? ""] ?? 0;
|
| 1057 |
+
const b = _b64lookup[clean[i + 1] ?? ""] ?? 0;
|
| 1058 |
+
const c = _b64lookup[clean[i + 2] ?? ""] ?? 0;
|
| 1059 |
+
const d = _b64lookup[clean[i + 3] ?? ""] ?? 0;
|
| 1060 |
+
const triplet = a << 18 | b << 12 | (c ?? 0) << 6 | (d ?? 0);
|
| 1061 |
+
bytes.push(triplet >> 16 & 255);
|
| 1062 |
+
if (clean[i + 2] !== "=") bytes.push(triplet >> 8 & 255);
|
| 1063 |
+
if (clean[i + 3] !== "=") bytes.push(triplet & 255);
|
| 1064 |
+
}
|
| 1065 |
+
return new TextDecoder().decode(new Uint8Array(bytes));
|
| 1066 |
+
}
|
| 1067 |
+
function F_encode_unicode_v1(arg0) {
|
| 1068 |
+
const { data_payload, url_safe, encode } = arg0;
|
| 1069 |
+
const data_str = devalue.stringify(data_payload);
|
| 1070 |
+
if (!data_str || typeof data_str !== "string") throw new Error("data_str must be a string");
|
| 1071 |
+
const u8Buffer = fflate.strToU8(data_str);
|
| 1072 |
+
const compressed = fflate.compressSync(u8Buffer);
|
| 1073 |
+
const compressed_str = String.fromCharCode(...compressed);
|
| 1074 |
+
if (encode === "base64") return F_base64_encode_unicode_v2({
|
| 1075 |
+
data_str: compressed_str,
|
| 1076 |
+
url_safe
|
| 1077 |
+
});
|
| 1078 |
+
if (encode === "hex") {
|
| 1079 |
+
const bytes = new TextEncoder().encode(compressed_str);
|
| 1080 |
+
return Array.from(bytes).map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
| 1081 |
+
}
|
| 1082 |
+
let _ = compressed_str;
|
| 1083 |
+
if (encode === "plain" && url_safe) _ = encodeURIComponent(_);
|
| 1084 |
+
return _;
|
| 1085 |
+
}
|
| 1086 |
+
function F_decode_unicode_v1(arg0) {
|
| 1087 |
+
let { data_str, _is_url_safe, encoded } = arg0;
|
| 1088 |
+
const decoded = (() => {
|
| 1089 |
+
if (encoded === "hex") {
|
| 1090 |
+
const pairs = data_str.match(/.{1,2}/g) || [];
|
| 1091 |
+
const bytes = new Uint8Array(pairs.map((byte) => parseInt(byte, 16)));
|
| 1092 |
+
return new TextDecoder().decode(bytes);
|
| 1093 |
+
}
|
| 1094 |
+
if (encoded === "base64") return F_base64_decode_unicode_v2({
|
| 1095 |
+
data_str,
|
| 1096 |
+
_is_url_safe
|
| 1097 |
+
});
|
| 1098 |
+
if (encoded === "plain") {
|
| 1099 |
+
let _ = data_str;
|
| 1100 |
+
if (_is_url_safe) _ = decodeURIComponent(_);
|
| 1101 |
+
return _;
|
| 1102 |
+
}
|
| 1103 |
+
})();
|
| 1104 |
+
if (!decoded) return;
|
| 1105 |
+
const len = decoded.length;
|
| 1106 |
+
const bytes = new Uint8Array(len);
|
| 1107 |
+
for (let i = 0; i < len; i++) bytes[i] = decoded.charCodeAt(i);
|
| 1108 |
+
const decompressed = fflate.decompressSync(bytes);
|
| 1109 |
+
const decompressed_str = fflate.strFromU8(decompressed);
|
| 1110 |
+
return devalue.parse(decompressed_str);
|
| 1111 |
+
}
|
| 1112 |
+
function F_to_url_safe_base64_encode(base64Str) {
|
| 1113 |
+
return base64Str.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
| 1114 |
+
}
|
| 1115 |
+
function F_decode_from_url_safe_base64_encode(urlSafeStr) {
|
| 1116 |
+
let base64 = urlSafeStr.replace(/-/g, "+").replace(/_/g, "/");
|
| 1117 |
+
while (base64.length % 4 !== 0) base64 += "=";
|
| 1118 |
+
return base64;
|
| 1119 |
+
}
|
| 1120 |
+
function F_encode_to_light_URL(text) {
|
| 1121 |
+
if (typeof text !== "string") throw new Error("Input must be a string");
|
| 1122 |
+
const binary = text.split("").map((c) => c.charCodeAt(0).toString(2).padStart(16, "0")).join("");
|
| 1123 |
+
const byteCount = Math.ceil(binary.length / 8);
|
| 1124 |
+
const bytes = new Uint8Array(byteCount);
|
| 1125 |
+
for (let i = 0; i < binary.length; i += 8) {
|
| 1126 |
+
const byteString = binary.substr(i, 8);
|
| 1127 |
+
bytes[i / 8] = parseInt(byteString, 2);
|
| 1128 |
+
}
|
| 1129 |
+
return btoa(String.fromCharCode(...bytes)).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
| 1130 |
+
}
|
| 1131 |
+
function F_decode_from_light_URL(encoded) {
|
| 1132 |
+
if (!/^[A-Za-z0-9_-]*$/.test(encoded)) throw new Error("Invalid Base64URL format");
|
| 1133 |
+
let base64 = encoded.replace(/-/g, "+").replace(/_/g, "/");
|
| 1134 |
+
while (base64.length % 4) base64 += "=";
|
| 1135 |
+
const str = atob(base64);
|
| 1136 |
+
let binary = "";
|
| 1137 |
+
for (let i = 0; i < str.length; i++) binary += str.charCodeAt(i).toString(2).padStart(8, "0");
|
| 1138 |
+
const chunks = [];
|
| 1139 |
+
for (let i = 0; i < binary.length; i += 16) {
|
| 1140 |
+
const chunk = binary.substr(i, 16);
|
| 1141 |
+
const codePoint = parseInt(chunk, 2);
|
| 1142 |
+
if (isNaN(codePoint)) throw new Error("Invalid binary sequence detected");
|
| 1143 |
+
chunks.push(String.fromCharCode(codePoint));
|
| 1144 |
+
}
|
| 1145 |
+
return chunks.join("");
|
| 1146 |
+
}
|
| 1147 |
+
const NS_crypto_client = {
|
| 1148 |
+
F_generate_oslo_id,
|
| 1149 |
+
F_gen_random_string,
|
| 1150 |
+
F_crypto_randomUUID,
|
| 1151 |
+
F_base64_encode_unicode,
|
| 1152 |
+
F_base64_decode_unicode,
|
| 1153 |
+
F_base64_encode_unicode_v2,
|
| 1154 |
+
F_base64_decode_unicode_v2,
|
| 1155 |
+
F_encode_unicode_v1,
|
| 1156 |
+
F_decode_unicode_v1,
|
| 1157 |
+
F_encode_to_light_URL,
|
| 1158 |
+
F_decode_from_light_URL
|
| 1159 |
+
};
|
| 1160 |
+
|
| 1161 |
+
//#endregion
|
| 1162 |
+
//#region ../../../packages/lib/helpers/server/playback.ts
|
| 1163 |
+
const M3U8_MAGIC_TAG = "#EXTM3U";
|
| 1164 |
+
/**
|
| 1165 |
+
* Return true if other resolutions are found, false if only 360p or 720p are found
|
| 1166 |
+
*/
|
| 1167 |
+
function F_m3u8_has_other_resolutions(m3u8) {
|
| 1168 |
+
const regex360p = /\bRESOLUTION\s*=\s*[0-9]+x360\b/i;
|
| 1169 |
+
const regex720p = /\bRESOLUTION\s*=\s*[0-9]+x720\b/i;
|
| 1170 |
+
const regexOtherResolutions = /\bRESOLUTION\s*=\s*[0-9]+x(?!360|720)[0-9]+\b/i;
|
| 1171 |
+
const has360p = regex360p.test(m3u8);
|
| 1172 |
+
const has720p = regex720p.test(m3u8);
|
| 1173 |
+
return regexOtherResolutions.test(m3u8) || !has360p && !has720p;
|
| 1174 |
+
}
|
| 1175 |
+
function F_get_adaptive_res_status(m3u8) {
|
| 1176 |
+
const resRegex = /\bRESOLUTION\s*=\s*(\d+)x(\d+)\b/gi;
|
| 1177 |
+
const resolutions = [];
|
| 1178 |
+
let match;
|
| 1179 |
+
while ((match = resRegex.exec(m3u8)) !== null) {
|
| 1180 |
+
const width = parseInt(`${match[1] || 0}`, 10);
|
| 1181 |
+
const height = parseInt(`${match[2] || 0}`, 10);
|
| 1182 |
+
resolutions.push({
|
| 1183 |
+
width,
|
| 1184 |
+
height
|
| 1185 |
+
});
|
| 1186 |
+
}
|
| 1187 |
+
return F_classify_rxd({ dx: resolutions });
|
| 1188 |
+
}
|
| 1189 |
+
function F_classify_rxd(arg0) {
|
| 1190 |
+
const { dx } = arg0;
|
| 1191 |
+
let hasHighRes = false;
|
| 1192 |
+
let hasLowRes = false;
|
| 1193 |
+
let hasMidRes = false;
|
| 1194 |
+
for (let i = 0; i < dx.length; i++) {
|
| 1195 |
+
const xx = dx[i];
|
| 1196 |
+
const width = xx?.width;
|
| 1197 |
+
const height = xx?.height;
|
| 1198 |
+
if (typeof width !== "number" || typeof height !== "number") continue;
|
| 1199 |
+
if (width >= 1920 || height >= 1080) hasHighRes = true;
|
| 1200 |
+
if (height <= 700) hasLowRes = true;
|
| 1201 |
+
if (height == 360 || width == 640) hasLowRes = true;
|
| 1202 |
+
if (height > 700 && height < 1080 || width > 1e3 && width < 2e3) hasMidRes = true;
|
| 1203 |
+
}
|
| 1204 |
+
if (hasHighRes && hasMidRes && hasLowRes) return { fhd: true };
|
| 1205 |
+
if (hasMidRes && hasLowRes || hasMidRes && hasHighRes || hasHighRes && hasLowRes) return { hd: true };
|
| 1206 |
+
}
|
| 1207 |
+
/**
|
| 1208 |
+
* Returns true if the manifest contains:
|
| 1209 |
+
* 1. At least one resolution >= 1080p (1920+ width OR 1080+ height)
|
| 1210 |
+
* 2. At least one resolution 480p >= 720p (1280+ width OR 720+ height OR 640+ width)
|
| 1211 |
+
* 3. At least one resolution <= 480p (480 height or less)
|
| 1212 |
+
*/
|
| 1213 |
+
function F_m3u8_has_high_mid_low_resolutions(m3u8) {
|
| 1214 |
+
const resRegex = /\bRESOLUTION\s*=\s*(\d+)x(\d+)\b/gi;
|
| 1215 |
+
let hasHighRes = false;
|
| 1216 |
+
let hasLowRes = false;
|
| 1217 |
+
let hasMidRes = false;
|
| 1218 |
+
let match;
|
| 1219 |
+
while ((match = resRegex.exec(m3u8)) !== null) {
|
| 1220 |
+
const width = parseInt(`${match[1] || 0}`, 10);
|
| 1221 |
+
const height = parseInt(`${match[2] || 0}`, 10);
|
| 1222 |
+
if (width >= 1920 || height >= 1080) hasHighRes = true;
|
| 1223 |
+
if (height <= 600) hasLowRes = true;
|
| 1224 |
+
if (height == 360 || width == 640) hasLowRes = true;
|
| 1225 |
+
if (height > 600 && height < 1080 || width > 640 && width < 1920) hasMidRes = true;
|
| 1226 |
+
if (hasHighRes && hasLowRes && hasMidRes) return true;
|
| 1227 |
+
}
|
| 1228 |
+
return false;
|
| 1229 |
+
}
|
| 1230 |
+
function F_extract_resolutions_from_M3U8(arg0) {
|
| 1231 |
+
const { m3u8Content, baseUrl } = arg0;
|
| 1232 |
+
const results = [];
|
| 1233 |
+
const lines = m3u8Content.trim().split("\n");
|
| 1234 |
+
for (let i = 0; i < lines.length; i++) {
|
| 1235 |
+
const line = lines[i]?.trim() ?? "";
|
| 1236 |
+
if (line.startsWith("#EXT-X-STREAM-INF:")) {
|
| 1237 |
+
const streamInfo = {};
|
| 1238 |
+
const resolutionMatch = line.match(/RESOLUTION=(\d+x\d+)/);
|
| 1239 |
+
if (resolutionMatch) {
|
| 1240 |
+
const resolution = resolutionMatch[1];
|
| 1241 |
+
if (resolution) {
|
| 1242 |
+
const [width, height] = resolution.split("x").map(Number);
|
| 1243 |
+
streamInfo.resolution = resolution;
|
| 1244 |
+
streamInfo.width = width;
|
| 1245 |
+
streamInfo.height = height;
|
| 1246 |
+
}
|
| 1247 |
+
}
|
| 1248 |
+
const bandwidthMatch = line.match(/BANDWIDTH=(\d+)/);
|
| 1249 |
+
if (bandwidthMatch) {
|
| 1250 |
+
const bandwidth = bandwidthMatch[1] ? parseInt(bandwidthMatch[1]) : 0;
|
| 1251 |
+
streamInfo.bandwidth = bandwidth;
|
| 1252 |
+
streamInfo.bitrateMbps = parseFloat((bandwidth / 1e6).toFixed(2));
|
| 1253 |
+
}
|
| 1254 |
+
const framerateMatch = line.match(/FRAME-RATE=([\d.]+)/);
|
| 1255 |
+
if (framerateMatch) streamInfo.frameRate = parseFloat(framerateMatch[1] || "0");
|
| 1256 |
+
const codecsMatch = line.match(/CODECS="([^"]+)"/);
|
| 1257 |
+
if (codecsMatch) streamInfo.codecs = codecsMatch[1];
|
| 1258 |
+
if (i + 1 < lines.length) {
|
| 1259 |
+
const urlLine = lines[i + 1]?.trim();
|
| 1260 |
+
if (urlLine && !urlLine.startsWith("#")) {
|
| 1261 |
+
if (baseUrl && !urlLine.match(/^https?:\/\//)) streamInfo.url = new URL(urlLine, baseUrl).href;
|
| 1262 |
+
else streamInfo.url = urlLine;
|
| 1263 |
+
results.push(streamInfo);
|
| 1264 |
+
}
|
| 1265 |
+
}
|
| 1266 |
+
const level = streamInfo;
|
| 1267 |
+
streamInfo.qLevel = `${level.width}` === "3840" ? "4K" : `${level.width}` === "2048" ? "2K" : `${level.width}` === "1920" ? "1080P" : `${level.width}` === "1280" ? "720P" : `${level.width}` === "854" ? "480P" : `${level.width}` === "640" ? "360P" : `${level.height || level.quality}P`;
|
| 1268 |
+
}
|
| 1269 |
+
}
|
| 1270 |
+
let data = { rxd: results };
|
| 1271 |
+
if (results.length) {
|
| 1272 |
+
const __ = F_classify_rxd({ dx: results.map((xx) => {
|
| 1273 |
+
return {
|
| 1274 |
+
width: xx.width,
|
| 1275 |
+
height: xx.height
|
| 1276 |
+
};
|
| 1277 |
+
}) });
|
| 1278 |
+
if (__) data = {
|
| 1279 |
+
...data,
|
| 1280 |
+
...__
|
| 1281 |
+
};
|
| 1282 |
+
}
|
| 1283 |
+
return data;
|
| 1284 |
+
}
|
| 1285 |
+
async function F_transform_m3u8(arg0) {
|
| 1286 |
+
const { content, true_origin, true_base, proxy_base, proxima_commands, search_params } = arg0;
|
| 1287 |
+
if (!content || !content.trim() || !true_origin || !true_base || !proxy_base) return;
|
| 1288 |
+
const [ERROR, RESULT] = await NS_promise.F_try_catch({ logic: function() {
|
| 1289 |
+
return new URL(true_base, true_origin);
|
| 1290 |
+
} });
|
| 1291 |
+
if (ERROR || !RESULT) return;
|
| 1292 |
+
const true_url_o = RESULT;
|
| 1293 |
+
let line_array = content.split("\n");
|
| 1294 |
+
const is_media_playlist = content.includes("#EXTINF");
|
| 1295 |
+
line_array = await Promise.all(line_array.map(async (line, i) => {
|
| 1296 |
+
line = line.trim();
|
| 1297 |
+
if (line.startsWith("#") || line === "") return line;
|
| 1298 |
+
if (line.startsWith("//")) line = NS_routes_c.F_flat_url_slash(true_url_o.protocol + "/" + line);
|
| 1299 |
+
if (!line.startsWith("//") && !line.startsWith("http")) {
|
| 1300 |
+
if (line.startsWith("./")) line = line.slice(1);
|
| 1301 |
+
if (line.startsWith("/")) line = NS_routes_c.F_flat_url_slash(true_url_o.origin + "/" + line);
|
| 1302 |
+
else line = NS_routes_c.F_flat_url_slash(true_url_o.href + "/" + line);
|
| 1303 |
+
}
|
| 1304 |
+
await (async () => {
|
| 1305 |
+
if (RESULT && proxy_base.includes(RESULT.origin)) return;
|
| 1306 |
+
const data = {
|
| 1307 |
+
endpoint: line,
|
| 1308 |
+
commands: {
|
| 1309 |
+
...proxima_commands ? { ...proxima_commands } : {},
|
| 1310 |
+
m3u8_playlist_child: true,
|
| 1311 |
+
is_media_segment: is_media_playlist
|
| 1312 |
+
}
|
| 1313 |
+
};
|
| 1314 |
+
const encoded_data = NS_crypto_client.F_base64_encode_unicode_v2({
|
| 1315 |
+
data_str: devalue.stringify(data),
|
| 1316 |
+
url_safe: true
|
| 1317 |
+
});
|
| 1318 |
+
line = NS_routes_c.F_flat_url_slash(proxy_base + "/" + encoded_data);
|
| 1319 |
+
})();
|
| 1320 |
+
if (NS_routes_c.F_is_url(line) && NS_Misc.F_is_record(search_params)) for (const [k, v] of Object.entries(search_params)) {
|
| 1321 |
+
const _ = new URL(line);
|
| 1322 |
+
if (typeof k === "string" && typeof v === "string") _.searchParams.set(k, v);
|
| 1323 |
+
line = _.toString();
|
| 1324 |
+
}
|
| 1325 |
+
return line;
|
| 1326 |
+
}));
|
| 1327 |
+
return [...line_array].join("\n");
|
| 1328 |
+
}
|
| 1329 |
+
/**
|
| 1330 |
+
* Checks if a Response contains M3U8 content by inspecting its "magic" header.
|
| 1331 |
+
* Works even if Content-Type is missing or incorrect.
|
| 1332 |
+
*/
|
| 1333 |
+
async function F_is_M3U8_response(arg0) {
|
| 1334 |
+
const { response } = arg0;
|
| 1335 |
+
if (!response) return false;
|
| 1336 |
+
try {
|
| 1337 |
+
const reader = (typeof response.clone === "function" ? response.clone() : response).body?.getReader();
|
| 1338 |
+
if (!reader) return false;
|
| 1339 |
+
const { value, done } = await reader.read();
|
| 1340 |
+
reader.releaseLock();
|
| 1341 |
+
if (!value || done) return false;
|
| 1342 |
+
return new TextDecoder().decode(value.slice(0, 10)).trim().startsWith(M3U8_MAGIC_TAG);
|
| 1343 |
+
} catch (err) {
|
| 1344 |
+
console.error("Error identifying manifest content:", err);
|
| 1345 |
+
return false;
|
| 1346 |
+
}
|
| 1347 |
+
}
|
| 1348 |
+
async function F_transform_m3u8_v2(arg0) {
|
| 1349 |
+
const { content, true_origin, true_base, proxy_base, proxima_commands, search_params } = arg0;
|
| 1350 |
+
if (!content || !content.trim() || !true_origin || !true_base || !proxy_base) return;
|
| 1351 |
+
const [ERROR, RESULT] = await NS_promise.F_try_catch({ logic: function() {
|
| 1352 |
+
return new URL(true_base, true_origin);
|
| 1353 |
+
} });
|
| 1354 |
+
if (ERROR || !RESULT) return;
|
| 1355 |
+
const true_url_o = RESULT;
|
| 1356 |
+
const is_media_playlist = content.includes("#EXTINF");
|
| 1357 |
+
const transform_url = async (raw) => {
|
| 1358 |
+
let line = raw.trim();
|
| 1359 |
+
if (line.startsWith("//")) line = NS_routes_c.F_flat_url_slash(true_url_o.protocol + "/" + line);
|
| 1360 |
+
if (!line.startsWith("//") && !line.startsWith("http")) {
|
| 1361 |
+
if (line.startsWith("./")) line = line.slice(1);
|
| 1362 |
+
if (line.startsWith("/")) line = NS_routes_c.F_flat_url_slash(true_url_o.origin + "/" + line);
|
| 1363 |
+
else line = NS_routes_c.F_flat_url_slash(true_url_o.href + "/" + line);
|
| 1364 |
+
}
|
| 1365 |
+
if (!(RESULT && proxy_base.includes(RESULT.origin))) {
|
| 1366 |
+
const data = {
|
| 1367 |
+
endpoint: line,
|
| 1368 |
+
commands: {
|
| 1369 |
+
...proxima_commands ? { ...proxima_commands } : {},
|
| 1370 |
+
m3u8_playlist_child: true,
|
| 1371 |
+
is_media_segment: is_media_playlist
|
| 1372 |
+
}
|
| 1373 |
+
};
|
| 1374 |
+
const encoded_data = NS_crypto_client.F_base64_encode_unicode_v2({
|
| 1375 |
+
data_str: devalue.stringify(data),
|
| 1376 |
+
url_safe: true
|
| 1377 |
+
});
|
| 1378 |
+
line = NS_routes_c.F_flat_url_slash(proxy_base + "/" + encoded_data);
|
| 1379 |
+
}
|
| 1380 |
+
if (NS_routes_c.F_is_url(line) && NS_Misc.F_is_record(search_params)) for (const [k, v] of Object.entries(search_params)) {
|
| 1381 |
+
const _ = new URL(line);
|
| 1382 |
+
if (typeof k === "string" && typeof v === "string") _.searchParams.set(k, v);
|
| 1383 |
+
line = _.toString();
|
| 1384 |
+
}
|
| 1385 |
+
return line;
|
| 1386 |
+
};
|
| 1387 |
+
const URI_ATTR_RE = /URI="([^"]*)"/g;
|
| 1388 |
+
const transform_tag_uris = async (line) => {
|
| 1389 |
+
const matches = Array.from(line.matchAll(URI_ATTR_RE));
|
| 1390 |
+
if (matches.length === 0) return line;
|
| 1391 |
+
const replacements = await Promise.all(matches.map(async (m) => ({
|
| 1392 |
+
index: m.index,
|
| 1393 |
+
length: m[0].length,
|
| 1394 |
+
new_uri: m[1] ? await transform_url(m[1]) : m[1]
|
| 1395 |
+
})));
|
| 1396 |
+
let result = "";
|
| 1397 |
+
let cursor = 0;
|
| 1398 |
+
for (const r of replacements) {
|
| 1399 |
+
result += line.slice(cursor, r.index);
|
| 1400 |
+
result += `URI="${r.new_uri}"`;
|
| 1401 |
+
cursor = r.index + r.length;
|
| 1402 |
+
}
|
| 1403 |
+
result += line.slice(cursor);
|
| 1404 |
+
return result;
|
| 1405 |
+
};
|
| 1406 |
+
return [...await Promise.all(content.split("\n").map(async (raw_line) => {
|
| 1407 |
+
const line = raw_line.trim();
|
| 1408 |
+
if (line === "") return line;
|
| 1409 |
+
if (line.startsWith("#")) return line.includes("URI=") ? await transform_tag_uris(line) : line;
|
| 1410 |
+
return await transform_url(line);
|
| 1411 |
+
}))].join("\n");
|
| 1412 |
+
}
|
| 1413 |
+
function F_sbe_id(arg0) {
|
| 1414 |
+
const { film_id, film_type } = arg0;
|
| 1415 |
+
const title_id = `${film_type === "movie" ? "544" : film_type === "tv" ? "234" : film_type === "series" ? "651" : ""}${film_id}`;
|
| 1416 |
+
title_id.startsWith("544") || title_id.startsWith("234") || title_id.startsWith("651");
|
| 1417 |
+
return title_id;
|
| 1418 |
+
}
|
| 1419 |
+
const NS_playback_helper = {
|
| 1420 |
+
F_m3u8_has_other_resolutions,
|
| 1421 |
+
F_extract_resolutions_from_M3U8,
|
| 1422 |
+
F_transform_m3u8,
|
| 1423 |
+
M3U8_MAGIC_TAG,
|
| 1424 |
+
F_is_M3U8_response,
|
| 1425 |
+
F_m3u8_has_high_mid_low_resolutions,
|
| 1426 |
+
F_get_adaptive_res_status,
|
| 1427 |
+
F_transform_m3u8_v2,
|
| 1428 |
+
F_sbe_id
|
| 1429 |
+
};
|
| 1430 |
+
|
| 1431 |
+
//#endregion
|
| 1432 |
+
//#region ../../../packages/lib/helpers/server/proxima/unpack.ts
|
| 1433 |
+
const schema = v.object({
|
| 1434 |
+
proxima_endpoint: v.pipe(v.string("Invalid proxy endpoint"), v.nonEmpty("proxima endpoint cannot be empty")),
|
| 1435 |
+
proxima_commands: v.optional(v.pipe(v.string("Invalid proxima commands"), v.nonEmpty("proxima commands cannot be empty")))
|
| 1436 |
+
});
|
| 1437 |
+
const schema_2 = v.object({ proxima_encoded: v.pipe(v.string("Invalid proxy data"), v.nonEmpty("proxima data cannot be empty")) });
|
| 1438 |
+
async function F_unpack_proxima_endpoint(arg0) {
|
| 1439 |
+
const { proxima_endpoint } = arg0;
|
| 1440 |
+
const [E_, decoded_proxy_endpoint] = await NS_promise.F_catch_promise({ promise: (async () => {
|
| 1441 |
+
if (!proxima_endpoint) return;
|
| 1442 |
+
const fine_str = proxima_endpoint.replace(/[.:;|><?&$#@!]+$/g, "");
|
| 1443 |
+
const raw = NS_crypto_client.F_base64_decode_unicode_v2({
|
| 1444 |
+
data_str: fine_str.trim(),
|
| 1445 |
+
_is_url_safe: true
|
| 1446 |
+
});
|
| 1447 |
+
return new URL(decodeURI(raw));
|
| 1448 |
+
})() });
|
| 1449 |
+
if (E_) throw E_;
|
| 1450 |
+
if (!decoded_proxy_endpoint) throw Error("proxy endpoint failed validation");
|
| 1451 |
+
return { decoded_proxy_endpoint };
|
| 1452 |
+
}
|
| 1453 |
+
async function F_unpack_proxima_commands(arg0) {
|
| 1454 |
+
const { proxima_commands } = arg0;
|
| 1455 |
+
if (!proxima_commands) return;
|
| 1456 |
+
const [E_, decoded_proxy_commands] = await NS_promise.F_catch_promise({ promise: (async () => {
|
| 1457 |
+
const fine_str = proxima_commands.replace(/[.:;|><?&$#@!]+$/g, "");
|
| 1458 |
+
const data_str = NS_crypto_client.F_base64_decode_unicode_v2({
|
| 1459 |
+
data_str: fine_str.trim(),
|
| 1460 |
+
_is_url_safe: true
|
| 1461 |
+
});
|
| 1462 |
+
try {
|
| 1463 |
+
return devalue.parse(data_str);
|
| 1464 |
+
} catch (error) {
|
| 1465 |
+
return JSON.parse(data_str);
|
| 1466 |
+
}
|
| 1467 |
+
})() });
|
| 1468 |
+
if (E_) throw E_;
|
| 1469 |
+
if (proxima_commands && !decoded_proxy_commands) throw Error("proxy commands failed validation");
|
| 1470 |
+
return { decoded_proxy_commands };
|
| 1471 |
+
}
|
| 1472 |
+
async function F_unpack_proxima_encoded(arg0) {
|
| 1473 |
+
const { proxima_encoded } = arg0;
|
| 1474 |
+
if (!proxima_encoded) return;
|
| 1475 |
+
let [E_, decoded_proxima_data] = await NS_promise.F_catch_promise({ promise: (async () => {
|
| 1476 |
+
const fine_str = proxima_encoded.replace(/[.:;|><?&$#@!]+$/g, "");
|
| 1477 |
+
const data_str = NS_crypto_client.F_base64_decode_unicode_v2({
|
| 1478 |
+
data_str: fine_str.trim(),
|
| 1479 |
+
_is_url_safe: true
|
| 1480 |
+
});
|
| 1481 |
+
try {
|
| 1482 |
+
return devalue.parse(data_str);
|
| 1483 |
+
} catch (error) {
|
| 1484 |
+
return JSON.parse(data_str);
|
| 1485 |
+
}
|
| 1486 |
+
})() });
|
| 1487 |
+
if (E_) try {
|
| 1488 |
+
const decoded_payload = NS_crypto_client.F_decode_unicode_v1({
|
| 1489 |
+
data_str: proxima_encoded,
|
| 1490 |
+
_is_url_safe: true,
|
| 1491 |
+
encoded: "base64"
|
| 1492 |
+
});
|
| 1493 |
+
if (decoded_payload) decoded_proxima_data = decoded_payload;
|
| 1494 |
+
else throw E_;
|
| 1495 |
+
} catch {
|
| 1496 |
+
throw E_;
|
| 1497 |
+
}
|
| 1498 |
+
if (typeof decoded_proxima_data !== "object" || !decoded_proxima_data.endpoint || typeof decoded_proxima_data.endpoint !== "string" || decoded_proxima_data.commands && typeof decoded_proxima_data.commands !== "object") throw Error("proxy data failed validation");
|
| 1499 |
+
return {
|
| 1500 |
+
decoded_proxy_endpoint: new URL(decoded_proxima_data.endpoint),
|
| 1501 |
+
decoded_proxy_commands: decoded_proxima_data?.commands && NS_Misc.F_is_record(decoded_proxima_data.commands) ? decoded_proxima_data.commands : {}
|
| 1502 |
+
};
|
| 1503 |
+
}
|
| 1504 |
+
async function F_unpack_proxima_endpoint_n_commands(arg0) {
|
| 1505 |
+
const { proxima_encoded } = arg0;
|
| 1506 |
+
const [E_, decoded_proxima_data] = await NS_promise.F_catch_promise({ promise: NS_unpack_proxima.F_unpack_proxima_encoded({ proxima_encoded }) });
|
| 1507 |
+
if (E_) throw E_;
|
| 1508 |
+
return decoded_proxima_data;
|
| 1509 |
+
}
|
| 1510 |
+
const NS_unpack_proxima = {
|
| 1511 |
+
F_unpack_proxima_endpoint,
|
| 1512 |
+
F_unpack_proxima_commands,
|
| 1513 |
+
F_unpack_proxima_endpoint_n_commands,
|
| 1514 |
+
F_unpack_proxima_encoded,
|
| 1515 |
+
schema,
|
| 1516 |
+
schema_2
|
| 1517 |
+
};
|
| 1518 |
+
|
| 1519 |
+
//#endregion
|
| 1520 |
+
//#region ../../../packages/lib/helpers/client/proxy.ts
|
| 1521 |
+
const proxy_list_webshare_wootan = [
|
| 1522 |
+
"http://yeilvlkp:l2qdqued8u6d@31.59.20.176:6754",
|
| 1523 |
+
"http://yeilvlkp:l2qdqued8u6d@23.95.150.145:6114",
|
| 1524 |
+
"http://yeilvlkp:l2qdqued8u6d@198.23.239.134:6540",
|
| 1525 |
+
"http://yeilvlkp:l2qdqued8u6d@45.38.107.97:6014",
|
| 1526 |
+
"http://yeilvlkp:l2qdqued8u6d@107.172.163.27:6543",
|
| 1527 |
+
"http://yeilvlkp:l2qdqued8u6d@198.105.121.200:6462",
|
| 1528 |
+
"http://yeilvlkp:l2qdqued8u6d@64.137.96.74:6641",
|
| 1529 |
+
"http://yeilvlkp:l2qdqued8u6d@216.10.27.159:6837",
|
| 1530 |
+
"http://yeilvlkp:l2qdqued8u6d@142.111.67.146:5611",
|
| 1531 |
+
"http://yeilvlkp:l2qdqued8u6d@194.39.32.164:6461"
|
| 1532 |
+
];
|
| 1533 |
+
const F_get_random_proxy = (arg0) => {
|
| 1534 |
+
const { proxyList } = arg0;
|
| 1535 |
+
if (!proxyList || proxyList.length === 0) return null;
|
| 1536 |
+
let rawProxy = proxyList[Math.floor(Math.random() * proxyList.length)];
|
| 1537 |
+
if (!rawProxy) return;
|
| 1538 |
+
return F_breakdown_proxy_url(rawProxy);
|
| 1539 |
+
};
|
| 1540 |
+
function F_breakdown_proxy_url(proxy_string) {
|
| 1541 |
+
if (!proxy_string) return;
|
| 1542 |
+
proxy_string = proxy_string.replace(/^,+|,+$/g, "").trim();
|
| 1543 |
+
try {
|
| 1544 |
+
const parsed = new URL(proxy_string);
|
| 1545 |
+
return {
|
| 1546 |
+
server: `${parsed.protocol}//${parsed.host}`,
|
| 1547 |
+
username: decodeURIComponent(parsed.username),
|
| 1548 |
+
password: decodeURIComponent(parsed.password)
|
| 1549 |
+
};
|
| 1550 |
+
} catch (e) {
|
| 1551 |
+
console.error("Invalid Proxy URL:", proxy_string);
|
| 1552 |
+
return null;
|
| 1553 |
+
}
|
| 1554 |
+
}
|
| 1555 |
+
function F_get_random_proxy_auto() {
|
| 1556 |
+
const proxyList = proxy_list_webshare_wootan;
|
| 1557 |
+
if (!proxyList || proxyList.length === 0) return null;
|
| 1558 |
+
return F_get_random_proxy({ proxyList });
|
| 1559 |
+
}
|
| 1560 |
+
function modify_request_headers(arg0) {
|
| 1561 |
+
let { req_headers, new_headers, avoid_cert_val } = arg0;
|
| 1562 |
+
let req0_headers = { ...req_headers };
|
| 1563 |
+
const normalized_new_headers = Object.keys(new_headers).reduce((acc, key) => {
|
| 1564 |
+
acc[key.toLowerCase()] = new_headers[key];
|
| 1565 |
+
return acc;
|
| 1566 |
+
}, {});
|
| 1567 |
+
delete req0_headers["x-forwarded-for"];
|
| 1568 |
+
delete req0_headers["true-client-ip"];
|
| 1569 |
+
delete req0_headers["cf-ipcountry"];
|
| 1570 |
+
delete req0_headers["cf-connecting-ip"];
|
| 1571 |
+
delete req0_headers["x-request-start"];
|
| 1572 |
+
delete req0_headers["rndr-id"];
|
| 1573 |
+
delete req0_headers["render-proxy-ttl"];
|
| 1574 |
+
delete req0_headers["x-real-ip"];
|
| 1575 |
+
delete req0_headers["forwarded"];
|
| 1576 |
+
delete req0_headers["x-forwarded-host"];
|
| 1577 |
+
delete req0_headers["x-ip-token"];
|
| 1578 |
+
delete req0_headers["cf-visitor"];
|
| 1579 |
+
delete req0_headers["cf-ray"];
|
| 1580 |
+
delete req0_headers["cdn-loop"];
|
| 1581 |
+
delete req0_headers["x-invocation-id"];
|
| 1582 |
+
delete req0_headers["x-amzn-trace-id"];
|
| 1583 |
+
delete req0_headers["x-direct-url"];
|
| 1584 |
+
delete req0_headers["x-forwarded-port"];
|
| 1585 |
+
delete req0_headers["x-forwarded-proto"];
|
| 1586 |
+
delete req0_headers["x-request-id"];
|
| 1587 |
+
delete req0_headers["connection"];
|
| 1588 |
+
delete req0_headers["accept-encoding"];
|
| 1589 |
+
for (const [key, value] of Object.entries(req0_headers)) {
|
| 1590 |
+
const lower_key = key.toLowerCase();
|
| 1591 |
+
if (lower_key.startsWith("x-vercel")) delete req0_headers[key];
|
| 1592 |
+
if (lower_key.toLowerCase().startsWith("x-")) delete req0_headers[key];
|
| 1593 |
+
if (lower_key.toLowerCase().startsWith("eo-")) delete req0_headers[key];
|
| 1594 |
+
}
|
| 1595 |
+
if (avoid_cert_val) {
|
| 1596 |
+
delete req0_headers["referer"];
|
| 1597 |
+
delete req0_headers["origin"];
|
| 1598 |
+
delete req0_headers["host"];
|
| 1599 |
+
return req0_headers;
|
| 1600 |
+
}
|
| 1601 |
+
for (const [key, value] of Object.entries(req0_headers)) {
|
| 1602 |
+
const lower_key = key.toLowerCase();
|
| 1603 |
+
if ([
|
| 1604 |
+
"host",
|
| 1605 |
+
"origin",
|
| 1606 |
+
"referer"
|
| 1607 |
+
].includes(lower_key) && !normalized_new_headers[lower_key]) delete req0_headers[key];
|
| 1608 |
+
}
|
| 1609 |
+
new_headers = {
|
| 1610 |
+
...req0_headers,
|
| 1611 |
+
...normalized_new_headers
|
| 1612 |
+
};
|
| 1613 |
+
return new_headers;
|
| 1614 |
+
}
|
| 1615 |
+
const NS_proxy = {
|
| 1616 |
+
F_get_random_proxy,
|
| 1617 |
+
proxy_list_webshare_wootan,
|
| 1618 |
+
F_get_random_proxy_auto,
|
| 1619 |
+
modify_request_headers
|
| 1620 |
+
};
|
| 1621 |
+
|
| 1622 |
+
//#endregion
|
| 1623 |
+
//#region ../../../packages/lib/helpers/server/proxima/html.ts
|
| 1624 |
+
const REPO_ORIGIN$1 = () => NS_runtime.ENV_VAR_DB?.REPO_ORIGIN || (NS_runtime.IS_BUN || NS_runtime.IS_DENO || NS_runtime.IS_NODE ? process?.env?.REPO_ORIGIN : void 0);
|
| 1625 |
+
async function F_transform_html_content(arg0) {
|
| 1626 |
+
const cheerio = await import("cheerio");
|
| 1627 |
+
const { html, target_endpoint, proxima_commands, REQ_ORIGIN } = arg0;
|
| 1628 |
+
const $ = cheerio.load(html);
|
| 1629 |
+
$(`[href]`).each((i, el) => {
|
| 1630 |
+
const href = $(el).attr("href")?.trim();
|
| 1631 |
+
if (href && !href.startsWith("//") && !href.startsWith("http")) {
|
| 1632 |
+
const new_href = NS_routes_c.F_flat_url_slash(target_endpoint.origin + "/" + href);
|
| 1633 |
+
$(el).attr("href", new_href);
|
| 1634 |
+
}
|
| 1635 |
+
});
|
| 1636 |
+
$(`[src]`).each((i, el) => {
|
| 1637 |
+
const src = $(el).attr("src")?.trim();
|
| 1638 |
+
if (src && !src.startsWith("//") && !src.startsWith("http")) {
|
| 1639 |
+
const new_src = NS_routes_c.F_flat_url_slash(target_endpoint.origin + "/" + src);
|
| 1640 |
+
$(el).attr("src", new_src);
|
| 1641 |
+
}
|
| 1642 |
+
});
|
| 1643 |
+
if (proxima_commands?.monkey_patch && NS_Misc.F_is_record(proxima_commands.monkey_patch)) {
|
| 1644 |
+
const [ERROR, RESULT] = await NS_promise.F_catch_promise({ promise: axios({
|
| 1645 |
+
method: "POST",
|
| 1646 |
+
baseURL: REPO_ORIGIN$1(),
|
| 1647 |
+
url: "/sd/monkey-patch",
|
| 1648 |
+
data: {
|
| 1649 |
+
filename: "client-monkey-patch.ts",
|
| 1650 |
+
obfuscate: true,
|
| 1651 |
+
proxy_origin: proxima_commands.monkey_patch?.alpha_proxy || REQ_ORIGIN,
|
| 1652 |
+
monkey_config: proxima_commands.monkey_patch,
|
| 1653 |
+
use_fs: true,
|
| 1654 |
+
tool: "esbuild"
|
| 1655 |
+
}
|
| 1656 |
+
}) });
|
| 1657 |
+
if (ERROR) console.error({ ERROR });
|
| 1658 |
+
const data = RESULT?.data;
|
| 1659 |
+
if (typeof data === "string") $("head").prepend(`<script>${data}<\/script>`);
|
| 1660 |
+
}
|
| 1661 |
+
return prettify($.html());
|
| 1662 |
+
}
|
| 1663 |
+
const NS_html_proxima = { F_transform_html_content };
|
| 1664 |
+
|
| 1665 |
+
//#endregion
|
| 1666 |
+
//#region src/sub-router/proxima.ts
|
| 1667 |
+
process.env.X_OFFLINE;
|
| 1668 |
+
const APP_ORIGIN = () => NS_runtime.ENV_VAR_DB?.APP_ORIGIN || process?.env?.APP_ORIGIN;
|
| 1669 |
+
const REPO_ORIGIN = () => NS_runtime.ENV_VAR_DB?.REPO_ORIGIN || process.env.REPO_ORIGIN;
|
| 1670 |
+
const sub_router = new Hono().basePath("/proxima");
|
| 1671 |
+
sub_router.get("/:proxima_encoded", sValidator("param", NS_unpack_proxima.schema_2, (result, c) => {
|
| 1672 |
+
if (!result.success) {
|
| 1673 |
+
const message = result.error[0].message;
|
| 1674 |
+
return c.text(message, 400);
|
| 1675 |
+
}
|
| 1676 |
+
}), async (ctx) => {
|
| 1677 |
+
const params = ctx.req.valid("param");
|
| 1678 |
+
const query = ctx.req.query();
|
| 1679 |
+
const REQ0 = new URL(ctx.req.url);
|
| 1680 |
+
const REQ_ORIGIN = APP_ORIGIN() || REQ0.origin;
|
| 1681 |
+
const REQ_headers = ctx.req.raw.headers;
|
| 1682 |
+
const { proxima_encoded } = params;
|
| 1683 |
+
const _is_proxima_h = REQ0.pathname.includes("/proxima-h/");
|
| 1684 |
+
const [E_, R_] = await NS_promise.F_catch_promise({ promise: NS_unpack_proxima.F_unpack_proxima_endpoint_n_commands({ proxima_encoded }) });
|
| 1685 |
+
if (E_ || !R_) {
|
| 1686 |
+
const { status, message } = NS_error.F_collect_error_status_n_message({ ERR: E_ });
|
| 1687 |
+
return ctx.text(message, status);
|
| 1688 |
+
}
|
| 1689 |
+
const { decoded_proxy_endpoint, decoded_proxy_commands } = R_;
|
| 1690 |
+
decoded_proxy_commands?.iMovie_id || decoded_proxy_commands?.iFilm_id;
|
| 1691 |
+
decoded_proxy_commands?.season;
|
| 1692 |
+
decoded_proxy_commands?.episode;
|
| 1693 |
+
decoded_proxy_commands?.picture_quality;
|
| 1694 |
+
const og_endpoint = decoded_proxy_endpoint.href;
|
| 1695 |
+
if (query?.ops === "decode") return ctx.json({
|
| 1696 |
+
decoded_proxy_endpoint: og_endpoint,
|
| 1697 |
+
decoded_proxy_commands
|
| 1698 |
+
});
|
| 1699 |
+
const replace_response_content_with = decoded_proxy_commands?.replace_response_content_with;
|
| 1700 |
+
if (decoded_proxy_commands) delete decoded_proxy_commands.replace_response_content_with;
|
| 1701 |
+
const req0_headers_object = Object.fromEntries(REQ_headers.entries());
|
| 1702 |
+
const upstream_url = decoded_proxy_endpoint.href;
|
| 1703 |
+
const send_headers = NS_proxy.modify_request_headers({
|
| 1704 |
+
req_headers: req0_headers_object,
|
| 1705 |
+
new_headers: decoded_proxy_commands?.headers || decoded_proxy_commands?.header || {},
|
| 1706 |
+
avoid_cert_val: false
|
| 1707 |
+
});
|
| 1708 |
+
const fallback_env = "cloudflare";
|
| 1709 |
+
const fallback_proxy = await (async () => {
|
| 1710 |
+
if (REPO_ORIGIN() === REQ_ORIGIN) return;
|
| 1711 |
+
const _ = new URL("/proxima/multiverse/next", REPO_ORIGIN());
|
| 1712 |
+
_.searchParams.set("service_env", fallback_env);
|
| 1713 |
+
const [E_, R_] = await NS_promise.F_catch_promise({ promise: ky.get(_.toString()).json() });
|
| 1714 |
+
const proxy = R_?.data?.url;
|
| 1715 |
+
if (!proxy) return;
|
| 1716 |
+
const _u = new URL(REQ0.pathname, proxy);
|
| 1717 |
+
if (query?.ops) _u.searchParams.set("ops", query.ops);
|
| 1718 |
+
return _u.toString().replace("/proxima-h", "/proxima");
|
| 1719 |
+
})();
|
| 1720 |
+
const upstream_v2 = async () => {
|
| 1721 |
+
const _1 = await proxy(upstream_url, {
|
| 1722 |
+
headers: send_headers,
|
| 1723 |
+
method: decoded_proxy_commands?.method || "GET",
|
| 1724 |
+
body: decoded_proxy_commands?.upstream_payload ? JSON.stringify(decoded_proxy_commands.upstream_payload) : void 0
|
| 1725 |
+
});
|
| 1726 |
+
if (!_1 || !fallback_proxy) return _1;
|
| 1727 |
+
const content_length = _1.headers.get("content-length");
|
| 1728 |
+
if (_1.ok && content_length && parseInt(content_length) > 0) return _1;
|
| 1729 |
+
if (query?.ch !== "1") return _1;
|
| 1730 |
+
return _1;
|
| 1731 |
+
};
|
| 1732 |
+
const upstream = await upstream_v2();
|
| 1733 |
+
if (!upstream) return new Response("upstream undefined", { status: 500 });
|
| 1734 |
+
if (query?.ops === "raw") return upstream;
|
| 1735 |
+
if (query?.ops === "raw2") {
|
| 1736 |
+
const data = {
|
| 1737 |
+
app: "hono",
|
| 1738 |
+
REPO_ORIGIN: REPO_ORIGIN(),
|
| 1739 |
+
APP_ORIGIN: APP_ORIGIN(),
|
| 1740 |
+
fallback_env,
|
| 1741 |
+
fallback_proxy,
|
| 1742 |
+
status: upstream.status,
|
| 1743 |
+
headers: Object.fromEntries(upstream.headers.entries()),
|
| 1744 |
+
ok: upstream.ok
|
| 1745 |
+
};
|
| 1746 |
+
return ctx.json(data);
|
| 1747 |
+
}
|
| 1748 |
+
const content_length = upstream.headers.get("content-length");
|
| 1749 |
+
if (decoded_proxy_commands?.redirect_origin && ([
|
| 1750 |
+
"403",
|
| 1751 |
+
"500",
|
| 1752 |
+
"503",
|
| 1753 |
+
"429",
|
| 1754 |
+
"401",
|
| 1755 |
+
"404"
|
| 1756 |
+
].includes(`${upstream.status}`) || content_length && !parseInt(content_length)) && fallback_proxy) return ctx.redirect(fallback_proxy, 308);
|
| 1757 |
+
upstream.headers.delete("content-security-policy");
|
| 1758 |
+
upstream.headers.delete("x-frame-options");
|
| 1759 |
+
upstream.headers.delete("link");
|
| 1760 |
+
upstream.headers.delete("x-proxied-path");
|
| 1761 |
+
upstream.headers.delete("x-proxied-host");
|
| 1762 |
+
const resHeaders = new Headers(upstream.headers);
|
| 1763 |
+
const res_headers_obj = Object.fromEntries(resHeaders.entries());
|
| 1764 |
+
const content_type = resHeaders.get("content-type") ?? "";
|
| 1765 |
+
if (!upstream.ok) return upstream;
|
| 1766 |
+
if (replace_response_content_with) upstream.headers.delete("content-length");
|
| 1767 |
+
const is_part_m3u8 = decoded_proxy_commands?.m3u8_playlist_child || await NS_playback_helper.F_is_M3U8_response({ response: upstream.clone() }) || content_type?.includes("application/vnd.apple.mpegurl") || content_type?.includes("application/x-mpegurl") || decoded_proxy_endpoint.toString().includes(".m3u8");
|
| 1768 |
+
const is_m3u8 = content_type?.includes("application/vnd.apple.mpegurl") || content_type?.includes("application/x-mpegurl") || decoded_proxy_endpoint.toString().includes(".m3u8");
|
| 1769 |
+
if (!decoded_proxy_commands?.m3u8_playlist_child && content_type?.includes("text/html") && !is_part_m3u8) return stream(ctx, async (stream) => {
|
| 1770 |
+
ctx.header("Content-Encoding", "Identity");
|
| 1771 |
+
ctx.status(upstream.status);
|
| 1772 |
+
for (const key in res_headers_obj) if (Object.prototype.hasOwnProperty.call(res_headers_obj, key)) {
|
| 1773 |
+
const element = res_headers_obj[key];
|
| 1774 |
+
ctx.header(key, element);
|
| 1775 |
+
}
|
| 1776 |
+
set_manual_response_headers();
|
| 1777 |
+
stream.onAbort(() => {
|
| 1778 |
+
console.log("Aborted!");
|
| 1779 |
+
});
|
| 1780 |
+
await stream.write(await (async () => {
|
| 1781 |
+
let html = replace_response_content_with || await upstream.text();
|
| 1782 |
+
const [E_, rewritten] = await NS_promise.F_catch_promise({ promise: NS_html_proxima.F_transform_html_content({
|
| 1783 |
+
html,
|
| 1784 |
+
target_endpoint: decoded_proxy_endpoint,
|
| 1785 |
+
proxima_commands: decoded_proxy_commands,
|
| 1786 |
+
REQ_ORIGIN
|
| 1787 |
+
}) });
|
| 1788 |
+
return rewritten || "";
|
| 1789 |
+
})());
|
| 1790 |
+
});
|
| 1791 |
+
if (is_m3u8) {
|
| 1792 |
+
let m3u8_content = replace_response_content_with || await upstream.text();
|
| 1793 |
+
const [E_, R_] = await NS_promise.F_catch_promise({ promise: NS_playback_helper.F_transform_m3u8_v2({
|
| 1794 |
+
content: m3u8_content,
|
| 1795 |
+
true_origin: decoded_proxy_endpoint.origin,
|
| 1796 |
+
true_base: (() => {
|
| 1797 |
+
const _ = NS_Misc.F_remove_last_array_element({ arr: decoded_proxy_endpoint.pathname.split("/") }).join("/");
|
| 1798 |
+
if (!_ && decoded_proxy_endpoint.pathname) return "/";
|
| 1799 |
+
return _;
|
| 1800 |
+
})(),
|
| 1801 |
+
proxy_base: NS_routes_c.F_flat_url_slash(REQ_ORIGIN + (_is_proxima_h ? "/proxima-h" : "/proxima")),
|
| 1802 |
+
proxima_commands: decoded_proxy_commands ? { ...decoded_proxy_commands } : {},
|
| 1803 |
+
search_params: query.ch ? { ch: query.ch } : {}
|
| 1804 |
+
}) });
|
| 1805 |
+
m3u8_content = R_ || m3u8_content || "";
|
| 1806 |
+
if (query.ops === "get-master-resolutions") {
|
| 1807 |
+
const _ = NS_playback_helper.F_extract_resolutions_from_M3U8({ m3u8Content: m3u8_content });
|
| 1808 |
+
const play_resolutions = _?.rxd || [];
|
| 1809 |
+
const is_fhd = _?.fhd;
|
| 1810 |
+
const is_hd = _?.hd;
|
| 1811 |
+
return ctx.json({
|
| 1812 |
+
is_fhd,
|
| 1813 |
+
is_hd,
|
| 1814 |
+
resolutions: play_resolutions,
|
| 1815 |
+
content: m3u8_content
|
| 1816 |
+
});
|
| 1817 |
+
}
|
| 1818 |
+
ctx.status(upstream.status);
|
| 1819 |
+
for (const key in res_headers_obj) if (key in res_headers_obj) {
|
| 1820 |
+
const element = res_headers_obj[key];
|
| 1821 |
+
if (`${key}`.toLowerCase() == "content-length") continue;
|
| 1822 |
+
ctx.header(key, element);
|
| 1823 |
+
}
|
| 1824 |
+
set_manual_response_headers();
|
| 1825 |
+
return ctx.body(m3u8_content);
|
| 1826 |
+
}
|
| 1827 |
+
set_manual_response_headers();
|
| 1828 |
+
return upstream;
|
| 1829 |
+
function set_manual_response_headers() {
|
| 1830 |
+
if (decoded_proxy_commands.response_headers && NS_Misc.F_is_record(decoded_proxy_commands.response_headers)) for (const k in decoded_proxy_commands.response_headers) {
|
| 1831 |
+
const v = decoded_proxy_commands.response_headers[k];
|
| 1832 |
+
ctx.header(k, v);
|
| 1833 |
+
}
|
| 1834 |
+
}
|
| 1835 |
+
});
|
| 1836 |
+
const ProximaRouter = sub_router;
|
| 1837 |
+
|
| 1838 |
+
//#endregion
|
| 1839 |
+
//#region src/sub-router/hono.index.ts
|
| 1840 |
+
const app$1 = new Hono({ strict: true });
|
| 1841 |
+
app$1.use(trimTrailingSlash(), logger$1(), cors$1({
|
| 1842 |
+
origin: "*",
|
| 1843 |
+
allowHeaders: ["*"],
|
| 1844 |
+
exposeHeaders: ["*"]
|
| 1845 |
+
}));
|
| 1846 |
+
app$1.route("/", ProximaRouter);
|
| 1847 |
+
const HonoRouter = app$1;
|
| 1848 |
+
|
| 1849 |
+
//#endregion
|
| 1850 |
+
//#region src/index.ts
|
| 1851 |
+
await NS_runtime.set_env_var_db();
|
| 1852 |
+
const PORT = process.env.PORT;
|
| 1853 |
+
const app = new Elysia().use(cors({
|
| 1854 |
+
origin: "*",
|
| 1855 |
+
allowedHeaders: "*",
|
| 1856 |
+
methods: [
|
| 1857 |
+
"GET",
|
| 1858 |
+
"POST",
|
| 1859 |
+
"PUT",
|
| 1860 |
+
"DELETE",
|
| 1861 |
+
"OPTIONS",
|
| 1862 |
+
"HEAD"
|
| 1863 |
+
],
|
| 1864 |
+
exposeHeaders: "*"
|
| 1865 |
+
})).derive((ctx) => ({ publicOrigin: NS_routes_elysia.F_public_origin(ctx) })).use(logger()).onError(async ({ code, error }) => {
|
| 1866 |
+
let e_message = "";
|
| 1867 |
+
if (code === "VALIDATION") {
|
| 1868 |
+
e_message = error.message;
|
| 1869 |
+
try {
|
| 1870 |
+
e_message = JSON.parse(e_message).summary;
|
| 1871 |
+
} catch (err) {}
|
| 1872 |
+
}
|
| 1873 |
+
const err_d = NS_error.F_collect_error_status_n_message({ ERR: error });
|
| 1874 |
+
NS_Misc.console.error({
|
| 1875 |
+
ENV: "dev",
|
| 1876 |
+
_browser: false,
|
| 1877 |
+
_log: ["\n"]
|
| 1878 |
+
});
|
| 1879 |
+
NS_Misc.console.error({
|
| 1880 |
+
ENV: "dev",
|
| 1881 |
+
_browser: false,
|
| 1882 |
+
_log: [{
|
| 1883 |
+
code,
|
| 1884 |
+
e_message,
|
| 1885 |
+
...err_d
|
| 1886 |
+
}, "\n"]
|
| 1887 |
+
});
|
| 1888 |
+
return new Response(err_d.message, {
|
| 1889 |
+
status: err_d.status,
|
| 1890 |
+
headers: {
|
| 1891 |
+
"x-error-message": JSON.stringify(err_d.message),
|
| 1892 |
+
"x-error-status": err_d.status
|
| 1893 |
+
}
|
| 1894 |
+
});
|
| 1895 |
+
}).mount("/", HonoRouter.fetch).get("/", () => {
|
| 1896 |
+
return "🦊 Hello Rafiki 🍿";
|
| 1897 |
+
}).get("/foo", (ctx) => {
|
| 1898 |
+
const REQ_headers = ctx?.request?.headers;
|
| 1899 |
+
console.log("\n", "REQ_headers", REQ_headers, "\n");
|
| 1900 |
+
return "🦊 Hello Rafiki 🍿";
|
| 1901 |
+
}).listen({
|
| 1902 |
+
port: PORT || 7860,
|
| 1903 |
+
...NS_runtime.IS_PROD && { hostname: "0.0.0.0" },
|
| 1904 |
+
idleTimeout: 120
|
| 1905 |
+
});
|
| 1906 |
+
console.log(`🦊 Elysia is running at ${app.server?.hostname}:${app.server?.port}`);
|
| 1907 |
+
|
| 1908 |
+
//#endregion
|
| 1909 |
+
export { };
|