@vcgstudiosy-beep/dlof 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/dist/browser.d.ts +11 -0
- package/dist/browser.js +55 -0
- package/dist/dlof.browser.js +189 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +10 -1
- package/dist/player/renderPlayerHtml.d.ts +6 -4
- package/dist/player/renderPlayerHtml.js +169 -33
- package/dist/viewer/brand.d.ts +50 -0
- package/dist/viewer/brand.js +118 -0
- package/dist/viewer/renderContent.js +37 -14
- package/dist/viewer/renderViewerHtml.d.ts +3 -2
- package/dist/viewer/renderViewerHtml.js +18 -5
- package/dist/viewer/theme.d.ts +11 -1
- package/dist/viewer/theme.js +105 -43
- package/dist/zip/zipReaderBrowser.d.ts +12 -0
- package/dist/zip/zipReaderBrowser.js +82 -0
- package/package.json +11 -5
package/README.md
CHANGED
|
@@ -13,6 +13,7 @@ HTML تفاعليَّين يعملان بلا أي اعتمادية خارجية
|
|
|
13
13
|
- ✅ **تحقق (`validateDlof`)**: يطبّق القواعد الإلزامية في `docs/SPECIFICATION.md`.
|
|
14
14
|
- 🖼️ **عارض `dlofpkg`** (`renderViewerHtml`): يبني صفحة HTML واحدة مستقلة تعرض المحتوى، المرفقات، والتصميم المخصّص (template)، بدعم RTL كامل.
|
|
15
15
|
- ▶️ **مشغّل `dlof`** (`renderPlayerHtml`): تطبيق HTML/JS تفاعلي واحد لسلسلة/حلقة كاملة — تصفّح جانبي، أزرار التالي/السابق تتبع `loopLinks`، تشغيل الوسائط (`mediaRef`) بشريط تقدّم قابل للسحب، وحفظ آخر موضع تصفح في `localStorage`.
|
|
16
|
+
- 🎨 **هوية DLoF البصرية الأصلية**: العارض والمشغّل يستخدمان نفس ألوان وشعار تطبيق DLoF الرسمي (أخضر "Copper" وذهبي "Moss")، مع دعم تلقائي للوضع الليلي، وقائمة "الملفات" بنفس تصميم شاشة "ملفاتي" في التطبيق (بطاقة لكل ملف بأيقونة ولون حسب النوع، شارة المجال، حجم الملف، وبحث فوري).
|
|
16
17
|
- 🛠️ **CLI باسم `dlof`**: أوامر جاهزة للاستخدام من الطرفية.
|
|
17
18
|
- 🗜️ **قارئ/كاتب ZIP خاص بلا اعتماديات** (`readZip` / `writeZip`) مبني فوق `zlib` المدمجة في Node — متوافق تماماً مع أدوات `zip`/`unzip` القياسية.
|
|
18
19
|
|
|
@@ -87,7 +88,7 @@ src/
|
|
|
87
88
|
zip/ قارئ وكاتب ZIP خاص (يستخدم zlib المدمجة فقط)
|
|
88
89
|
packages/ قراءة/كتابة .dlofpkg و .dlofSeries
|
|
89
90
|
loop/ حلّ سلسلة الحلقة (previous/next) عبر loopLinks
|
|
90
|
-
viewer/ عارض HTML لمستند/حزمة واحدة
|
|
91
|
+
viewer/ عارض HTML لمستند/حزمة واحدة + الهوية البصرية (brand.ts: ألوان، شعار، تسميات المجالات، أيقونات الملفات)
|
|
91
92
|
player/ مشغّل HTML تفاعلي لسلسلة/حلقة كاملة
|
|
92
93
|
cli.ts أداة سطر الأوامر
|
|
93
94
|
```
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { parseDlof } from "./dlof/parseDlof";
|
|
2
|
+
import { renderViewerHtml } from "./viewer/renderViewerHtml";
|
|
3
|
+
import { DlofPkg } from "./types";
|
|
4
|
+
/**
|
|
5
|
+
* نسخة متوافقة مع المتصفح من readDlofPkg (راجع src/packages/dlofpkg.ts).
|
|
6
|
+
* تستقبل Uint8Array (من File/ArrayBuffer) بدل Buffer الخاص بـ Node.
|
|
7
|
+
*/
|
|
8
|
+
export declare function readDlofPkgBrowser(buf: Uint8Array): DlofPkg;
|
|
9
|
+
/** يقرأ ملف .dlofpkg الذي اختاره المستخدم عبر <input type="file"> ويحوّله مباشرة إلى HTML */
|
|
10
|
+
export declare function renderDlofPkgFile(file: File): Promise<string>;
|
|
11
|
+
export { renderViewerHtml, parseDlof };
|
package/dist/browser.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseDlof = exports.renderViewerHtml = void 0;
|
|
4
|
+
exports.readDlofPkgBrowser = readDlofPkgBrowser;
|
|
5
|
+
exports.renderDlofPkgFile = renderDlofPkgFile;
|
|
6
|
+
const zipReaderBrowser_1 = require("./zip/zipReaderBrowser");
|
|
7
|
+
const parseDlof_1 = require("./dlof/parseDlof");
|
|
8
|
+
Object.defineProperty(exports, "parseDlof", { enumerable: true, get: function () { return parseDlof_1.parseDlof; } });
|
|
9
|
+
const renderViewerHtml_1 = require("./viewer/renderViewerHtml");
|
|
10
|
+
Object.defineProperty(exports, "renderViewerHtml", { enumerable: true, get: function () { return renderViewerHtml_1.renderViewerHtml; } });
|
|
11
|
+
/**
|
|
12
|
+
* نسخة متوافقة مع المتصفح من readDlofPkg (راجع src/packages/dlofpkg.ts).
|
|
13
|
+
* تستقبل Uint8Array (من File/ArrayBuffer) بدل Buffer الخاص بـ Node.
|
|
14
|
+
*/
|
|
15
|
+
function readDlofPkgBrowser(buf) {
|
|
16
|
+
const entries = (0, zipReaderBrowser_1.readZipBrowser)(buf);
|
|
17
|
+
const dlofEntry = (0, zipReaderBrowser_1.findEntry)(entries, "package.dlof");
|
|
18
|
+
if (!dlofEntry) {
|
|
19
|
+
throw new Error('حزمة .dlofpkg غير صالحة: لا يحتوي على "package.dlof"');
|
|
20
|
+
}
|
|
21
|
+
const decoder = new TextDecoder("utf-8");
|
|
22
|
+
const document = (0, parseDlof_1.parseDlof)(decoder.decode(dlofEntry.data), "package.dlof");
|
|
23
|
+
const metaEntry = (0, zipReaderBrowser_1.findEntry)(entries, "meta.json");
|
|
24
|
+
let meta;
|
|
25
|
+
if (metaEntry) {
|
|
26
|
+
meta = JSON.parse(decoder.decode(metaEntry.data));
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
meta = {
|
|
30
|
+
id: document.id,
|
|
31
|
+
title: document.metadata.title,
|
|
32
|
+
domain: document.metadata.domain,
|
|
33
|
+
version: document.version,
|
|
34
|
+
author: document.metadata.author,
|
|
35
|
+
language: document.metadata.language,
|
|
36
|
+
createdAt: document.metadata.createdAt,
|
|
37
|
+
dlofpkg_version: "1.0",
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
const attachments = {};
|
|
41
|
+
for (const entry of entries) {
|
|
42
|
+
if (entry.isDirectory)
|
|
43
|
+
continue;
|
|
44
|
+
if (entry.name.startsWith("attachments/")) {
|
|
45
|
+
attachments[entry.name] = entry.data;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return { meta, document, attachments: attachments };
|
|
49
|
+
}
|
|
50
|
+
/** يقرأ ملف .dlofpkg الذي اختاره المستخدم عبر <input type="file"> ويحوّله مباشرة إلى HTML */
|
|
51
|
+
async function renderDlofPkgFile(file) {
|
|
52
|
+
const arrayBuffer = await file.arrayBuffer();
|
|
53
|
+
const pkg = readDlofPkgBrowser(new Uint8Array(arrayBuffer));
|
|
54
|
+
return (0, renderViewerHtml_1.renderViewerHtml)(pkg);
|
|
55
|
+
}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
"use strict";var DLOF=(()=>{var Q=Object.defineProperty;var jt=Object.getOwnPropertyDescriptor;var Gt=Object.getOwnPropertyNames;var Wt=Object.prototype.hasOwnProperty;var Kt=(e,t)=>{for(var r in t)Q(e,r,{get:t[r],enumerable:!0})},Yt=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of Gt(t))!Wt.call(e,i)&&i!==r&&Q(e,i,{get:()=>t[i],enumerable:!(n=jt(t,i))||n.enumerable});return e};var Jt=e=>Yt(Q({},"__esModule",{value:!0}),e);var Ie={};Kt(Ie,{parseDlof:()=>it,readDlofPkgBrowser:()=>qt,renderDlofPkgFile:()=>Ee,renderViewerHtml:()=>st});var y=Uint8Array,F=Uint16Array,Qt=Int32Array,xt=new y([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),wt=new y([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),_t=new y([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),bt=function(e,t){for(var r=new F(31),n=0;n<31;++n)r[n]=t+=1<<e[n-1];for(var i=new Qt(r[30]),n=1;n<30;++n)for(var o=r[n];o<r[n+1];++o)i[o]=o-r[n]<<5|n;return{b:r,r:i}},$t=bt(xt,2),kt=$t.b,te=$t.r;kt[28]=258,te[258]=28;var At=bt(wt,0),ee=At.b,Le=At.r,et=new F(32768);for(u=0;u<32768;++u)$=(u&43690)>>1|(u&21845)<<1,$=($&52428)>>2|($&13107)<<2,$=($&61680)>>4|($&3855)<<4,et[u]=(($&65280)>>8|($&255)<<8)>>1;var $,u,O=(function(e,t,r){for(var n=e.length,i=0,o=new F(t);i<n;++i)e[i]&&++o[e[i]-1];var a=new F(t);for(i=1;i<t;++i)a[i]=a[i-1]+o[i-1]<<1;var s;if(r){s=new F(1<<t);var v=15-t;for(i=0;i<n;++i)if(e[i])for(var p=i<<4|e[i],d=t-e[i],l=a[e[i]-1]++<<d,h=l|(1<<d)-1;l<=h;++l)s[et[l]>>v]=p}else for(s=new F(n),i=0;i<n;++i)e[i]&&(s[i]=et[a[e[i]-1]++]>>15-e[i]);return s}),R=new y(288);for(u=0;u<144;++u)R[u]=8;var u;for(u=144;u<256;++u)R[u]=9;var u;for(u=256;u<280;++u)R[u]=7;var u;for(u=280;u<288;++u)R[u]=8;var u,zt=new y(32);for(u=0;u<32;++u)zt[u]=5;var u;var re=O(R,9,1);var ne=O(zt,5,1),_=function(e){for(var t=e[0],r=1;r<e.length;++r)e[r]>t&&(t=e[r]);return t},x=function(e,t,r){var n=t/8|0;return(e[n]|e[n+1]<<8)>>(t&7)&r},tt=function(e,t){var r=t/8|0;return(e[r]|e[r+1]<<8|e[r+2]<<16)>>(t&7)},ie=function(e){return(e+7)/8|0},oe=function(e,t,r){return(t==null||t<0)&&(t=0),(r==null||r>e.length)&&(r=e.length),new y(e.subarray(t,r))};var ae=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],k=function(e,t,r){var n=new Error(t||ae[e]);if(n.code=e,Error.captureStackTrace&&Error.captureStackTrace(n,k),!r)throw n;return n},se=function(e,t,r,n){var i=e.length,o=n?n.length:0;if(!i||t.f&&!t.l)return r||new y(0);var a=!r,s=a||t.i!=2,v=t.i;a&&(r=new y(i*3));var p=function(mt){var gt=r.length;if(mt>gt){var yt=new y(Math.max(gt*2,mt));yt.set(r),r=yt}},d=t.f||0,l=t.p||0,h=t.b||0,b=t.l,N=t.d,C=t.m,S=t.n,X=i*8;do{if(!b){d=x(e,l,1);var V=x(e,l+1,3);if(l+=3,V)if(V==1)b=re,N=ne,C=9,S=5;else if(V==2){var G=x(e,l,31)+257,lt=x(e,l+10,15)+4,ft=G+x(e,l+5,31)+1;l+=14;for(var B=new y(ft),W=new y(19),g=0;g<lt;++g)W[_t[g]]=x(e,l+g*3,7);l+=lt*3;for(var ct=_(W),Zt=(1<<ct)-1,Pt=O(W,ct,1),g=0;g<ft;){var ut=Pt[x(e,l,Zt)];l+=ut&15;var w=ut>>4;if(w<16)B[g++]=w;else{var E=0,Z=0;for(w==16?(Z=3+x(e,l,3),l+=2,E=B[g-1]):w==17?(Z=3+x(e,l,7),l+=3):w==18&&(Z=11+x(e,l,127),l+=7);Z--;)B[g++]=E}}var pt=B.subarray(0,G),D=B.subarray(G);C=_(pt),S=_(D),b=O(pt,C,1),N=O(D,S,1)}else k(1);else{var w=ie(l)+4,H=e[w-4]|e[w-3]<<8,j=w+H;if(j>i){v&&k(0);break}s&&p(h+H),r.set(e.subarray(w,j),h),t.b=h+=H,t.p=l=j*8,t.f=d;continue}if(l>X){v&&k(0);break}}s&&p(h+131072);for(var Xt=(1<<C)-1,Vt=(1<<S)-1,K=l;;K=l){var E=b[tt(e,l)&Xt],I=E>>4;if(l+=E&15,l>X){v&&k(0);break}if(E||k(2),I<256)r[h++]=I;else if(I==256){K=l,b=null;break}else{var ht=I-254;if(I>264){var g=I-257,U=xt[g];ht=x(e,l,(1<<U)-1)+kt[g],l+=U}var Y=N[tt(e,l)&Vt],J=Y>>4;Y||k(3),l+=Y&15;var D=ee[J];if(J>3){var U=wt[J];D+=tt(e,l)&(1<<U)-1,l+=U}if(l>X){v&&k(0);break}s&&p(h+131072);var vt=h+ht;if(h<D){var dt=o-D,Ht=Math.min(D,vt);for(dt+h<0&&k(3);h<Ht;++h)r[h]=n[dt+h]}for(;h<vt;++h)r[h]=r[h-D]}}t.l=b,t.p=K,t.b=h,t.f=d,b&&(d=1,t.m=C,t.d=N,t.n=S)}while(!d);return h!=r.length&&a?oe(r,0,h):r.subarray(0,h)};var le=new y(0);function Dt(e,t){return se(e,{i:2},t&&t.out,t&&t.dictionary)}var fe=typeof TextDecoder<"u"&&new TextDecoder,ce=0;try{fe.decode(le,{stream:!0}),ce=1}catch{}var ue=101010256,pe=33639248;function L(e,t){return(e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24)>>>0}function T(e,t){return e[t]|e[t+1]<<8}function he(e,t,r){return new TextDecoder("utf-8").decode(e.subarray(t,r))}function Ct(e){let t=-1,r=22;for(let s=e.length-r;s>=0&&s>=e.length-r-65557;s--)if(L(e,s)===ue){t=s;break}if(t===-1)throw new Error("\u0645\u0644\u0641 ZIP \u063A\u064A\u0631 \u0635\u0627\u0644\u062D: \u0644\u0645 \u064A\u064F\u0639\u062B\u0631 \u0639\u0644\u0649 EOCD (\u0646\u0647\u0627\u064A\u0629 \u0627\u0644\u0641\u0647\u0631\u0633 \u0627\u0644\u0645\u0631\u0643\u0632\u064A)");let n=T(e,t+10),i=L(e,t+16),o=[],a=i;for(let s=0;s<n;s++){if(L(e,a)!==pe)throw new Error(`\u0631\u0623\u0633 \u0627\u0644\u0641\u0647\u0631\u0633 \u0627\u0644\u0645\u0631\u0643\u0632\u064A \u063A\u064A\u0631 \u0635\u0627\u0644\u062D \u0639\u0646\u062F \u0627\u0644\u0645\u0648\u0636\u0639 ${a}`);let v=T(e,a+10),p=L(e,a+20),d=L(e,a+24),l=T(e,a+28),h=T(e,a+30),b=T(e,a+32),N=L(e,a+42),C=he(e,a+46,a+46+l);o.push(ve(e,N,C,v,p,d)),a+=46+l+h+b}return o}function ve(e,t,r,n,i,o){let a=T(e,t+26),s=T(e,t+28),v=t+30+a+s,p=e.subarray(v,v+i),d;if(n===0)d=p;else if(n===8)d=Dt(p,{size:o});else throw new Error(`\u0623\u0633\u0644\u0648\u0628 \u0636\u063A\u0637 \u063A\u064A\u0631 \u0645\u062F\u0639\u0648\u0645: ${n}`);return{name:r,data:d,isDirectory:r.endsWith("/")}}function rt(e,t){return e.find(r=>r.name===t||r.name===`/${t}`)}var de={amp:"&",lt:"<",gt:">",quot:'"',apos:"'"};function Tt(e){return e.replace(/&(#x?[0-9a-fA-F]+|[a-zA-Z]+);/g,(t,r)=>{if(r[0]==="#"){let n=r[1]==="x"||r[1]==="X",i=parseInt(r.slice(n?2:1),n?16:10);return Number.isFinite(i)?String.fromCodePoint(i):t}return de[r]??t})}var nt=class{constructor(t){this.src=t;this.pos=0}eof(){return this.pos>=this.src.length}peek(t=1){return this.src.slice(this.pos,this.pos+t)}startsWith(t){return this.src.startsWith(t,this.pos)}};function A(e){for(;!e.eof()&&/\s/.test(e.peek());)e.pos++}function me(e){for(A(e);e.startsWith("<?");){let t=e.src.indexOf("?>",e.pos);e.pos=t===-1?e.src.length:t+2,A(e)}for(;;){if(e.startsWith("<!--")){let t=e.src.indexOf("-->",e.pos);e.pos=t===-1?e.src.length:t+3,A(e);continue}if(e.startsWith("<!DOCTYPE")){let t=e.src.indexOf(">",e.pos);e.pos=t===-1?e.src.length:t+1,A(e);continue}break}}function ge(e){let t=e.pos;for(;!e.eof()&&/[^\s/>]/.test(e.peek());)e.pos++;return e.src.slice(t,e.pos)}function ye(e){let t={};for(;A(e),!(e.eof()||e.peek()==="/"||e.peek()===">");){let r=e.pos;for(;!e.eof()&&/[^\s=/>]/.test(e.peek());)e.pos++;let n=e.src.slice(r,e.pos);if(A(e),e.peek()==="="){e.pos++,A(e);let i=e.peek(),o="";if(i==='"'||i==="'"){e.pos++;let a=e.pos,s=e.src.indexOf(i,e.pos),v=s===-1?e.src.length:s;o=e.src.slice(a,v),e.pos=v+1}else{let a=e.pos;for(;!e.eof()&&/[^\s/>]/.test(e.peek());)e.pos++;o=e.src.slice(a,e.pos)}n&&(t[n]=Tt(o))}else n&&(t[n]="")}return t}function Nt(e){let t=new nt(e);me(t);function r(){t.pos++;let n=ge(t),i=ye(t);A(t);let o={tag:n,attrs:i,children:[],text:""};if(t.peek(2)==="/>")return t.pos+=2,o;t.peek()===">"&&(t.pos+=1);let a=[];for(;!t.eof();){if(t.startsWith("<!--")){let p=t.src.indexOf("-->",t.pos);t.pos=p===-1?t.src.length:p+3;continue}if(t.startsWith("<![CDATA[")){let p=t.src.indexOf("]]>",t.pos),d=p===-1?t.src.length:p;a.push(t.src.slice(t.pos+9,d)),t.pos=p===-1?t.src.length:p+3;continue}if(t.startsWith("</")){let p=t.src.indexOf(">",t.pos);t.pos=p===-1?t.src.length:p+1;break}if(t.peek()==="<"){let p=r();o.children.push(p);continue}let s=t.src.indexOf("<",t.pos),v=s===-1?t.src.length:s;a.push(t.src.slice(t.pos,v)),t.pos=v}return o.text=Tt(a.join("")).trim(),o}if(A(t),t.eof()||t.peek()!=="<")throw new Error("\u0645\u0633\u062A\u0646\u062F XML \u063A\u064A\u0631 \u0635\u0627\u0644\u062D: \u0644\u0627 \u064A\u0648\u062C\u062F \u0639\u0646\u0635\u0631 \u062C\u0630\u0631");return r()}function m(e,t){return e?.children.find(r=>r.tag===t)}function P(e,t){return e?.children.filter(r=>r.tag===t)??[]}function f(e,t){let r=m(e,t);return r?r.text:void 0}function xe(e){let t=m(e,"metadata"),r=m(t,"tags"),n=r?P(r,"tag").map(i=>i.text):void 0;return{title:f(t,"title")??"",domain:f(t,"domain")??"custom",author:f(t,"author"),createdAt:f(t,"createdAt"),updatedAt:f(t,"updatedAt"),language:f(t,"language")??"ar",tags:n}}function we(e){let t=m(e,"loopLinks"),r=m(t,"previous"),n=m(t,"next"),i=r?{ref:r.attrs.ref??"",title:r.attrs.title}:void 0,o=n?{ref:n.attrs.ref??"",title:n.attrs.title}:void 0,a=(f(t,"loopRoot")??"false").trim().toLowerCase()==="true";return{previous:i,next:o,loopRoot:a}}function q(e){if(e===void 0||e==="")return;let t=Number(e);return Number.isFinite(t)?t:void 0}function be(e){let t=m(e,"content");if(!t)return{kind:"genericItem"};let r=m(t,"genericItem");if(r)return{kind:"genericItem",customType:r.attrs.customType,type:f(r,"type"),element:f(r,"element"),body:f(r,"body")};let n=m(t,"qaItem");if(n)return{kind:"qaItem",question:f(n,"question")??"",answer:f(n,"answer")??"",explanation:f(n,"explanation"),difficulty:f(n,"difficulty")};let i=m(t,"bookChapter");if(i)return{kind:"bookChapter",chapterTitle:f(i,"chapterTitle")??"",text:f(i,"text")??"",chapterNumber:q(f(i,"chapterNumber")),summary:f(i,"summary")};let o=m(t,"termDefinition");if(o)return{kind:"termDefinition",term:f(o,"term")??"",definition:f(o,"definition")??"",example:f(o,"example")};let a=m(t,"infoExplain");if(a)return{kind:"infoExplain",topic:f(a,"topic")??"",explanation:f(a,"explanation")??"",source:f(a,"source")};let s=m(t,"episodeItem");return s?{kind:"episodeItem",episodeNumber:q(f(s,"episodeNumber")),seasonNumber:q(f(s,"seasonNumber")),episodeTitle:f(s,"episodeTitle")??"",synopsis:f(s,"synopsis"),duration:q(f(s,"duration")),seriesTitle:f(s,"seriesTitle"),mediaRef:f(s,"mediaRef"),releaseDate:f(s,"releaseDate"),body:f(s,"body"),thumbnailBase64:f(s,"thumbnailBase64")}:{kind:"genericItem",body:t.text}}function $e(e){let t=m(e,"attachments");if(!t)return;let r=P(t,"attachment");if(r.length)return r.map(n=>({id:n.attrs.id??"",fileName:n.attrs.fileName??"",mimeType:n.attrs.mimeType??"application/octet-stream",kind:n.attrs.kind??"file",sizeBytes:q(n.attrs.sizeBytes),data:f(n,"data"),uri:f(n,"uri"),caption:f(n,"caption")}))}function ke(e){let t=m(e,"template");if(t)return{ref:t.attrs.ref,primaryColor:t.attrs.primaryColor,secondaryColor:t.attrs.secondaryColor,backgroundColor:t.attrs.backgroundColor,textColor:t.attrs.textColor,fontFamily:t.attrs.fontFamily,layout:t.attrs.layout,headerAttachmentRef:t.attrs.headerAttachmentRef}}function Ae(e){let t=m(e,"mediaFolder");if(!t)return;let r=P(t,"mediaFile");if(r.length)return r.map(n=>({path:n.attrs.path??"",kind:n.attrs.kind??"file",label:n.attrs.label}))}function it(e,t){let r=Nt(e);if(r.tag!=="documentLoop")throw new Error(`\u0645\u0644\u0641 dlof \u063A\u064A\u0631 \u0635\u0627\u0644\u062D: \u0627\u0644\u0639\u0646\u0635\u0631 \u0627\u0644\u062C\u0630\u0631 \u064A\u062C\u0628 \u0623\u0646 \u064A\u0643\u0648\u0646 <documentLoop> \u0648\u0644\u064A\u0633 <${r.tag}>`);return{version:r.attrs.version??"1.0",id:r.attrs.id??"",metadata:xe(r),loopLinks:we(r),content:be(r),attachments:$e(r),template:ke(r),mediaFolder:Ae(r),sourceFileName:t}}var M={primary:"#1D7A3F",secondary:"#D2A020",background:"#EDEFF7",surface:"#F9FAFD",surfaceVariant:"#E3E7F0",text:"#0B0B14",muted:"#5B5F6E",border:"rgba(11,11,20,.10)"},z={primary:"#4CC47B",secondary:"#E8C24A",background:"#0A0A14",surface:"#15151F",surfaceVariant:"#232336",text:"#ECEEF6",muted:"#9A9DB0",border:"rgba(236,238,246,.10)"};function ot(e=34,t=M.secondary,r){return`<svg width="${e}" height="${e}" viewBox="0 0 38 38" aria-hidden="true">
|
|
2
|
+
<circle cx="19" cy="19" r="16" fill="none" stroke="${t}" stroke-width="2.5" stroke-dasharray="6 3"/>
|
|
3
|
+
<circle cx="19" cy="19" r="8" fill="${r??t}" opacity="0.55"/>
|
|
4
|
+
<circle cx="19" cy="19" r="3.5" fill="${t}"/>
|
|
5
|
+
<path d="M19 7 L19 3 M19 35 L19 31 M7 19 L3 19 M35 19 L31 19" stroke="${t}" stroke-width="1.5" stroke-linecap="round"/>
|
|
6
|
+
</svg>`}var Et={education:"\u062A\u0639\u0644\u064A\u0645",book:"\u0643\u062A\u0627\u0628",infoApp:"\u062A\u0637\u0628\u064A\u0642 \u0645\u0639\u0644\u0648\u0645\u0627\u062A",infoLoop:"\u062D\u0644\u0642\u0629 \u0645\u0639\u0644\u0648\u0645\u0627\u062A",recipe:"\u0648\u0635\u0641\u0629 \u0637\u0639\u0627\u0645",journal:"\u064A\u0648\u0645\u064A\u0627\u062A",series:"\u0645\u0633\u0644\u0633\u0644 / \u0633\u0644\u0633\u0644\u0629",comic:"\u0642\u0635\u0629 \u0645\u0635\u0648\u0631\u0629",podcast:"\u0628\u0648\u062F\u0643\u0627\u0633\u062A",characters:"\u0634\u062E\u0635\u064A\u0627\u062A",custom:"\u0645\u062E\u0635\u0635"};function It(e){return e?Et[e]??e:Et.custom}var at={bookChapter:{label:"\u0641\u0635\u0644 \u0643\u062A\u0627\u0628",icon:"\u{1F4D6}",color:"#6A1B9A"},qaItem:{label:"\u0633\u0624\u0627\u0644 \u0648\u062C\u0648\u0627\u0628",icon:"\u2753",color:"#0277BD"},termDefinition:{label:"\u062A\u0639\u0631\u064A\u0641 \u0645\u0635\u0637\u0644\u062D",icon:"\u{1F524}",color:"#2E7D32"},infoExplain:{label:"\u0634\u0631\u062D \u0645\u0639\u0644\u0648\u0645\u0629",icon:"\u{1F4A1}",color:"#D2A020"},episodeItem:{label:"\u062D\u0644\u0642\u0629",icon:"\u{1F3AC}",color:"#2D5C6B"},genericItem:{label:"\u0639\u0646\u0635\u0631 \u0639\u0627\u0645",icon:"\u{1F4C4}",color:"#455A64"}};function Ft(e,t){let r=(e.split(".").pop()??"").toLowerCase(),n=t??"";return r==="dlof"||r==="dloftemplate"?{icon:"\u{1F501}",color:"#AA5B2E",label:"\u0645\u0644\u0641 DLoF"}:r==="dlofcomic"?{icon:"\u{1F4DA}",color:"#4B5D3A",label:"\u0642\u0635\u0629 \u0645\u0635\u0648\u0631\u0629"}:r==="dlofvideo"?{icon:"\u{1F4FA}",color:"#2D5C6B",label:"\u0645\u0633\u0644\u0633\u0644 \u0641\u064A\u062F\u064A\u0648"}:n.startsWith("image/")||["jpg","jpeg","png","webp","gif","bmp","heic","svg"].includes(r)?{icon:"\u{1F5BC}\uFE0F",color:"#2E7D32",label:"\u0635\u0648\u0631\u0629"}:n.startsWith("video/")||["mp4","mkv","webm","avi","mov","3gp"].includes(r)?{icon:"\u{1F3AC}",color:"#6A1B9A",label:"\u0641\u064A\u062F\u064A\u0648"}:n.startsWith("audio/")||["mp3","wav","ogg","m4a","flac","aac"].includes(r)?{icon:"\u{1F3B5}",color:"#0277BD",label:"\u0635\u0648\u062A"}:r==="pdf"?{icon:"\u{1F4D5}",color:"#C62828",label:"PDF"}:["zip","rar","7z","tar","gz"].includes(r)?{icon:"\u{1F5DC}\uFE0F",color:"#8D6E63",label:"\u0623\u0631\u0634\u064A\u0641"}:["xls","xlsx","csv","tsv"].includes(r)?{icon:"\u{1F4CA}",color:"#2E7D32",label:"\u062C\u062F\u0648\u0644 \u0628\u064A\u0627\u0646\u0627\u062A"}:["json","xml","yaml","yml","kt","java","py","js","ts","html","css"].includes(r)?{icon:"\u{1F9E9}",color:"#455A64",label:"\u0628\u064A\u0627\u0646\u0627\u062A/\u0643\u0648\u062F"}:["txt","md","doc","docx"].includes(r)?{icon:"\u{1F4C3}",color:"#1976D2",label:"\u0645\u0633\u062A\u0646\u062F"}:{icon:"\u{1F4C1}",color:"#757575",label:"\u0645\u0644\u0641"}}function Lt(e){if(e==null||Number.isNaN(e))return"";if(e<1024)return`${e} \u0628\u0627\u064A\u062A`;let t=e/1024;if(t<1024)return`${t.toFixed(1)} \u0643.\u0628`;let r=t/1024;return r<1024?`${r.toFixed(1)} \u0645.\u0628`:`${(r/1024).toFixed(2)} \u063A.\u0628`}var Mt={serif:"'Amiri', 'Noto Naskh Arabic', Georgia, serif","sans-serif":"'Tajawal', 'IBM Plex Sans Arabic', 'Segoe UI', sans-serif",monospace:"'Cascadia Code', 'Courier New', monospace",cursive:"'Aref Ruqaa', cursive"};function St(e){let t=e??{},r=!!(t.primaryColor||t.secondaryColor||t.backgroundColor||t.textColor),n=t.fontFamily?Mt[t.fontFamily]??t.fontFamily:Mt["sans-serif"];return{primaryColor:t.primaryColor??M.primary,secondaryColor:t.secondaryColor??M.secondary,backgroundColor:t.backgroundColor??M.background,textColor:t.textColor??M.text,fontFamily:n,layout:t.layout??"standard",custom:r}}function Bt(e){let t=e.custom?"":`
|
|
7
|
+
@media (prefers-color-scheme: dark) {
|
|
8
|
+
:root {
|
|
9
|
+
--primary: ${z.primary};
|
|
10
|
+
--secondary: ${z.secondary};
|
|
11
|
+
--bg: ${z.background};
|
|
12
|
+
--surface: ${z.surface};
|
|
13
|
+
--surface-variant: ${z.surfaceVariant};
|
|
14
|
+
--text: ${z.text};
|
|
15
|
+
--muted: ${z.muted};
|
|
16
|
+
--border: ${z.border};
|
|
17
|
+
}
|
|
18
|
+
}`;return`
|
|
19
|
+
:root {
|
|
20
|
+
--primary: ${e.primaryColor};
|
|
21
|
+
--secondary: ${e.secondaryColor};
|
|
22
|
+
--bg: ${e.backgroundColor};
|
|
23
|
+
--surface: color-mix(in srgb, ${e.backgroundColor} 92%, #fff 8%);
|
|
24
|
+
--surface-variant: color-mix(in srgb, ${e.backgroundColor} 85%, #000 6%);
|
|
25
|
+
--text: ${e.textColor};
|
|
26
|
+
--muted: color-mix(in srgb, ${e.textColor} 60%, transparent);
|
|
27
|
+
--border: color-mix(in srgb, ${e.textColor} 90%, transparent);
|
|
28
|
+
--font: ${e.fontFamily};
|
|
29
|
+
}
|
|
30
|
+
${t}
|
|
31
|
+
* { box-sizing: border-box; }
|
|
32
|
+
html, body {
|
|
33
|
+
margin: 0; padding: 0;
|
|
34
|
+
background: var(--bg);
|
|
35
|
+
color: var(--text);
|
|
36
|
+
font-family: var(--font);
|
|
37
|
+
direction: rtl;
|
|
38
|
+
}
|
|
39
|
+
body { min-height: 100vh; }
|
|
40
|
+
a { color: var(--primary); }
|
|
41
|
+
.app { max-width: 900px; margin: 0 auto; padding: 0 20px 64px; }
|
|
42
|
+
|
|
43
|
+
/* \u2500\u2500 \u0627\u0644\u062A\u0631\u0648\u064A\u0633\u0629: \u0634\u0639\u0627\u0631 \u0627\u0644\u062D\u0644\u0642\u0629 + \u0627\u0644\u0639\u0646\u0648\u0627\u0646 \u2500\u2500 */
|
|
44
|
+
.dlof-header {
|
|
45
|
+
display: flex; align-items: center; gap: 14px;
|
|
46
|
+
padding: 18px 4px 14px;
|
|
47
|
+
border-bottom: 1px solid var(--border);
|
|
48
|
+
margin-bottom: 20px;
|
|
49
|
+
}
|
|
50
|
+
.dlof-header .logo-title { font-size: 1.15rem; font-weight: 800; letter-spacing: .01em; }
|
|
51
|
+
.dlof-header .logo-title .accent { color: var(--secondary); }
|
|
52
|
+
.dlof-header .logo-sub { font-size: .78rem; color: var(--muted); margin-top: 2px; }
|
|
53
|
+
|
|
54
|
+
.badge {
|
|
55
|
+
display: inline-flex; align-items: center; gap: 4px;
|
|
56
|
+
background: var(--primary); color: #fff;
|
|
57
|
+
border-radius: 999px; padding: 3px 12px; font-size: .72rem; font-weight: 600;
|
|
58
|
+
margin-inline-end: 6px;
|
|
59
|
+
}
|
|
60
|
+
.badge.outline {
|
|
61
|
+
background: transparent; color: var(--secondary);
|
|
62
|
+
border: 1.4px solid var(--secondary);
|
|
63
|
+
}
|
|
64
|
+
.badge.ghost { background: var(--surface-variant); color: var(--text); font-weight: 500; }
|
|
65
|
+
|
|
66
|
+
.card {
|
|
67
|
+
background: var(--surface);
|
|
68
|
+
border: 1px solid var(--border);
|
|
69
|
+
border-radius: 16px;
|
|
70
|
+
padding: 20px 22px;
|
|
71
|
+
box-shadow: 0 1px 3px rgba(0,0,0,.06);
|
|
72
|
+
margin-bottom: 18px;
|
|
73
|
+
}
|
|
74
|
+
.card.magazine { border-inline-start: 6px solid var(--primary); }
|
|
75
|
+
.card.minimal { box-shadow: none; background: transparent; padding: 8px 0; border: none; }
|
|
76
|
+
|
|
77
|
+
h1 { font-size: 1.55rem; margin: .25em 0; }
|
|
78
|
+
h2 { font-size: 1.15rem; color: var(--primary); }
|
|
79
|
+
.meta-row {
|
|
80
|
+
display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
|
|
81
|
+
font-size: .82rem; color: var(--muted); margin-bottom: 12px;
|
|
82
|
+
}
|
|
83
|
+
.tag { font-size: .8rem; color: var(--muted); margin-inline-end: 8px; }
|
|
84
|
+
.body-text { white-space: pre-wrap; line-height: 1.9; }
|
|
85
|
+
|
|
86
|
+
/* \u2500\u2500 \u0642\u0627\u0626\u0645\u0629 "\u0627\u0644\u0645\u0644\u0641\u0627\u062A" \u2014 \u0628\u0637\u0627\u0642\u0627\u062A \u0645\u0637\u0627\u0628\u0642\u0629 \u0644\u0634\u0627\u0634\u0629 \u0645\u0644\u0641\u0627\u062A\u064A \u0641\u064A \u062A\u0637\u0628\u064A\u0642 Android \u2500\u2500 */
|
|
87
|
+
.files-section-title {
|
|
88
|
+
font-size: .78rem; font-weight: 700; color: var(--muted);
|
|
89
|
+
letter-spacing: .04em; margin: 22px 2px 10px;
|
|
90
|
+
}
|
|
91
|
+
.file-card {
|
|
92
|
+
display: flex; align-items: center; gap: 12px;
|
|
93
|
+
background: var(--surface); border: 1px solid var(--border);
|
|
94
|
+
border-radius: 14px; padding: 12px 14px; margin-bottom: 8px;
|
|
95
|
+
text-decoration: none; color: inherit;
|
|
96
|
+
}
|
|
97
|
+
.file-card .file-icon {
|
|
98
|
+
flex-shrink: 0; width: 42px; height: 42px; border-radius: 10px;
|
|
99
|
+
display: flex; align-items: center; justify-content: center; font-size: 1.25rem;
|
|
100
|
+
}
|
|
101
|
+
.file-card .file-info { flex: 1; min-width: 0; }
|
|
102
|
+
.file-card .file-name {
|
|
103
|
+
font-weight: 600; font-size: .95rem;
|
|
104
|
+
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
105
|
+
}
|
|
106
|
+
.file-card .file-meta { font-size: .76rem; color: var(--muted); margin-top: 2px; display: flex; gap: 8px; }
|
|
107
|
+
.attachment-preview { margin: 10px 0 18px; }
|
|
108
|
+
.attachment-preview img { max-width: 100%; border-radius: 12px; }
|
|
109
|
+
.attachment-preview video, .attachment-preview audio { width: 100%; border-radius: 12px; }
|
|
110
|
+
.attachment-caption { font-size: .78rem; color: var(--muted); margin-top: 4px; }
|
|
111
|
+
|
|
112
|
+
.footer-nav { display: flex; justify-content: space-between; gap: 12px; margin-top: 24px; }
|
|
113
|
+
.nav-btn {
|
|
114
|
+
flex: 1; text-align: center; padding: 13px 16px;
|
|
115
|
+
background: var(--primary); color: #fff; border-radius: 12px;
|
|
116
|
+
text-decoration: none; font-weight: 700; cursor: pointer; border: none;
|
|
117
|
+
font-family: var(--font); font-size: .95rem;
|
|
118
|
+
display: flex; align-items: center; justify-content: center; gap: 6px;
|
|
119
|
+
}
|
|
120
|
+
.nav-btn.secondary { background: var(--secondary); color: var(--text); }
|
|
121
|
+
.nav-btn:disabled { opacity: .35; cursor: not-allowed; }
|
|
122
|
+
`}function c(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}function ze(e){if(e.data)return`data:${e.mimeType};base64,${e.data}`;if(e.uri)return e.uri}function De(e){let t=ze(e),r=Ft(e.fileName,e.mimeType),n=Lt(e.sizeBytes),i=`<div class="file-card">
|
|
123
|
+
<div class="file-icon" style="background:${r.color}22;color:${r.color}">${r.icon}</div>
|
|
124
|
+
<div class="file-info">
|
|
125
|
+
<div class="file-name">${c(e.fileName)}</div>
|
|
126
|
+
<div class="file-meta"><span>${c(r.label)}</span>${n?`<span>${n}</span>`:""}</div>
|
|
127
|
+
</div>
|
|
128
|
+
</div>`;if(!t)return i;let o="";e.kind==="image"?o=`<div class="attachment-preview"><img src="${t}" alt="${c(e.fileName)}" loading="lazy"/></div>`:e.kind==="video"&&(o=`<div class="attachment-preview"><video controls src="${t}"></video></div>`);let a=e.caption?`<div class="attachment-caption">${c(e.caption)}</div>`:"";return`${i}${o}${a}`}function Ce(e){let t=e.content,r=at[t.kind]??at.genericItem,n=`<span class="badge outline">${r.icon} ${c(r.label)}</span>`;switch(t.kind){case"bookChapter":return`
|
|
129
|
+
<div style="margin-bottom:8px">${n}${t.chapterNumber!==void 0?`<span class="badge ghost">\u0627\u0644\u0641\u0635\u0644 ${t.chapterNumber}</span>`:""}</div>
|
|
130
|
+
<h1>${c(t.chapterTitle)}</h1>
|
|
131
|
+
${t.summary?`<p class="tag">${c(t.summary)}</p>`:""}
|
|
132
|
+
<div class="body-text">${c(t.text)}</div>`;case"qaItem":return`
|
|
133
|
+
<div style="margin-bottom:8px">${n}${t.difficulty?`<span class="badge ghost">${c(t.difficulty)}</span>`:""}</div>
|
|
134
|
+
<h2>\u2753 ${c(t.question)}</h2>
|
|
135
|
+
<div class="body-text">${c(t.answer)}</div>
|
|
136
|
+
${t.explanation?`<p class="tag">${c(t.explanation)}</p>`:""}`;case"termDefinition":return`
|
|
137
|
+
<div style="margin-bottom:8px">${n}</div>
|
|
138
|
+
<h1>${c(t.term)}</h1>
|
|
139
|
+
<div class="body-text">${c(t.definition)}</div>
|
|
140
|
+
${t.example?`<p class="tag">\u0645\u062B\u0627\u0644: ${c(t.example)}</p>`:""}`;case"infoExplain":return`
|
|
141
|
+
<div style="margin-bottom:8px">${n}</div>
|
|
142
|
+
<h1>${c(t.topic)}</h1>
|
|
143
|
+
<div class="body-text">${c(t.explanation)}</div>
|
|
144
|
+
${t.source?`<p class="tag">\u0627\u0644\u0645\u0635\u062F\u0631: ${c(t.source)}</p>`:""}`;case"episodeItem":return`
|
|
145
|
+
<div style="margin-bottom:8px">${n}</div>
|
|
146
|
+
<div class="tag">${t.seriesTitle?c(t.seriesTitle)+" \xB7 ":""}${t.seasonNumber!==void 0?"\u0627\u0644\u0645\u0648\u0633\u0645 "+t.seasonNumber+" \xB7 ":""}${t.episodeNumber!==void 0?"\u0627\u0644\u062D\u0644\u0642\u0629 "+t.episodeNumber:""}</div>
|
|
147
|
+
<h1>${c(t.episodeTitle)}</h1>
|
|
148
|
+
${t.synopsis?`<p class="tag">${c(t.synopsis)}</p>`:""}
|
|
149
|
+
${t.body?`<div class="body-text">${c(t.body)}</div>`:""}`;default:return`
|
|
150
|
+
<div style="margin-bottom:8px">${n}${t.type?`<span class="badge ghost">${c(t.type)}</span>`:""}</div>
|
|
151
|
+
<h1>${c(e.metadata.title||"\u0645\u0633\u062A\u0646\u062F")}</h1>
|
|
152
|
+
${t.element?`<p class="tag">${c(t.element)}</p>`:""}
|
|
153
|
+
${t.body?`<div class="body-text">${c(t.body)}</div>`:""}`}}function Ut(e,t){let r=(e.metadata.tags??[]).map(a=>`<span class="tag">#${c(a)}</span>`).join(""),n=`<div class="meta-row">${e.metadata.author?`<span>\u{1F464} ${c(e.metadata.author)}</span>`:""}${e.metadata.createdAt?`<span>\u{1F4C5} ${c(e.metadata.createdAt.slice(0,10))}</span>`:""}</div>`,i=e.attachments??[],o=i.length?`<div class="files-section-title">\u{1F4CE} \u0627\u0644\u0645\u0631\u0641\u0642\u0627\u062A (${i.length})</div>${i.map(De).join(`
|
|
154
|
+
`)}`:"";return`
|
|
155
|
+
<div class="card ${c(t)}">
|
|
156
|
+
${n}
|
|
157
|
+
${Ce(e)}
|
|
158
|
+
${r?`<div style="margin-top:10px">${r}</div>`:""}
|
|
159
|
+
</div>
|
|
160
|
+
${o}`}var Ot=["education","book","infoApp","infoLoop","series","custom"],Te=["image","video","file"],Ne=15*1024*1024;function Rt(e){let t=[],r=i=>t.push({level:"error",message:i}),n=i=>t.push({level:"warning",message:i});switch(e.version||r("\u0627\u0644\u0635\u0641\u0629 version \u0645\u0641\u0642\u0648\u062F\u0629 \u0639\u0644\u0649 <documentLoop>"),e.id||r("\u0627\u0644\u0635\u0641\u0629 id \u0645\u0641\u0642\u0648\u062F\u0629 \u0639\u0644\u0649 <documentLoop>"),e.metadata.title||r("\u0627\u0644\u0639\u0646\u0635\u0631 <title> \u0645\u0637\u0644\u0648\u0628 \u062F\u0627\u062E\u0644 <metadata>"),e.metadata.domain?Ot.includes(e.metadata.domain)||n(`\u0642\u064A\u0645\u0629 domain "${e.metadata.domain}" \u063A\u064A\u0631 \u0645\u0639\u0631\u0648\u0641\u0629 (\u0627\u0644\u0645\u062A\u0648\u0642\u0639 \u0623\u062D\u062F: ${Ot.join(", ")})`):r("\u0627\u0644\u0639\u0646\u0635\u0631 <domain> \u0645\u0637\u0644\u0648\u0628 \u062F\u0627\u062E\u0644 <metadata>"),!e.loopLinks.previous&&!e.loopLinks.next&&n("\u0644\u0627 \u064A\u0648\u062C\u062F previous \u0648\u0644\u0627 next: \u0647\u0630\u0627 \u0627\u0644\u0645\u0633\u062A\u0646\u062F \u062D\u0644\u0642\u0629 \u0648\u062D\u064A\u062F\u0629 \u0645\u0639\u0632\u0648\u0644\u0629"),e.content.kind){case"qaItem":e.content.question||r("qaItem: \u0627\u0644\u0639\u0646\u0635\u0631 <question> \u0645\u0637\u0644\u0648\u0628"),e.content.answer||r("qaItem: \u0627\u0644\u0639\u0646\u0635\u0631 <answer> \u0645\u0637\u0644\u0648\u0628");break;case"bookChapter":e.content.chapterTitle||r("bookChapter: \u0627\u0644\u0639\u0646\u0635\u0631 <chapterTitle> \u0645\u0637\u0644\u0648\u0628"),e.content.text||r("bookChapter: \u0627\u0644\u0639\u0646\u0635\u0631 <text> \u0645\u0637\u0644\u0648\u0628");break;case"termDefinition":e.content.term||r("termDefinition: \u0627\u0644\u0639\u0646\u0635\u0631 <term> \u0645\u0637\u0644\u0648\u0628"),e.content.definition||r("termDefinition: \u0627\u0644\u0639\u0646\u0635\u0631 <definition> \u0645\u0637\u0644\u0648\u0628");break;case"infoExplain":e.content.topic||r("infoExplain: \u0627\u0644\u0639\u0646\u0635\u0631 <topic> \u0645\u0637\u0644\u0648\u0628"),e.content.explanation||r("infoExplain: \u0627\u0644\u0639\u0646\u0635\u0631 <explanation> \u0645\u0637\u0644\u0648\u0628");break;case"episodeItem":e.content.episodeTitle||r("episodeItem: \u0627\u0644\u0639\u0646\u0635\u0631 <episodeTitle> \u0645\u0637\u0644\u0648\u0628");break}for(let i of e.attachments??[])if(i.id||r("attachment: \u0627\u0644\u0635\u0641\u0629 id \u0645\u0637\u0644\u0648\u0628\u0629"),i.fileName||r("attachment: \u0627\u0644\u0635\u0641\u0629 fileName \u0645\u0637\u0644\u0648\u0628\u0629"),Te.includes(i.kind)||n(`attachment "${i.id}": \u0642\u064A\u0645\u0629 kind "${i.kind}" \u063A\u064A\u0631 \u0645\u0639\u0631\u0648\u0641\u0629`),!i.data&&!i.uri&&r(`attachment "${i.id}": \u064A\u062C\u0628 \u062A\u0648\u0641\u064A\u0631 <data> \u0623\u0648 <uri>`),i.data){let o=Math.floor(i.data.length*3/4);o>Ne&&n(`attachment "${i.id}": \u0627\u0644\u062D\u062C\u0645 \u0627\u0644\u062A\u0642\u0631\u064A\u0628\u064A ${(o/1024/1024).toFixed(1)}MB \u064A\u062A\u062C\u0627\u0648\u0632 \u0627\u0644\u062D\u062F \u0627\u0644\u0645\u0648\u0635\u0649 \u0628\u0647 (15MB) \u0644\u0644\u062A\u0636\u0645\u064A\u0646 \u0627\u0644\u0645\u0628\u0627\u0634\u0631`)}return{valid:!t.some(i=>i.level==="error"),issues:t}}function st(e,t={}){let r="document"in e?e.document:e,n="meta"in e?e.meta:void 0,i=St(r.template),o=Rt(r),s=(t.showValidation??!0)&&o.issues.length?`<div class="card minimal" style="border:1px dashed ${o.valid?"var(--muted)":"#c62828"}; margin-top:8px">
|
|
161
|
+
<strong>${o.valid?"\u0645\u0644\u0627\u062D\u0638\u0627\u062A \u0627\u0644\u062A\u062D\u0642\u0642":"\u0623\u062E\u0637\u0627\u0621 \u0641\u064A \u0627\u0644\u0645\u0644\u0641"}</strong>
|
|
162
|
+
<ul>${o.issues.map(d=>`<li>[${d.level==="error"?"\u062E\u0637\u0623":"\u062A\u0646\u0628\u064A\u0647"}] ${c(d.message)}</li>`).join("")}</ul>
|
|
163
|
+
</div>`:"",v=n?`<div class="meta-row"><span class="badge ghost">\u062D\u0632\u0645\u0629 dlofpkg</span><span>\u0627\u0644\u0625\u0635\u062F\u0627\u0631 ${c(n.dlofpkg_version)}</span><span>\u0627\u0644\u0645\u0639\u0631\u0651\u0641: ${c(n.id)}</span></div>`:"",p=`<header class="dlof-header">
|
|
164
|
+
${ot(36,"var(--secondary)","var(--primary)")}
|
|
165
|
+
<div>
|
|
166
|
+
<div class="logo-title">DLoF <span class="accent">Viewer</span></div>
|
|
167
|
+
<div class="logo-sub">\u0635\u064A\u063A\u0629 \u062D\u0644\u0642\u0629 \u0627\u0644\u0645\u0633\u062A\u0646\u062F\u0627\u062A \u0627\u0644\u0645\u0633\u062A\u0648\u062F\u0639\u0629</div>
|
|
168
|
+
</div>
|
|
169
|
+
<div style="margin-inline-start:auto;display:flex;gap:6px">
|
|
170
|
+
<span class="badge">${c(It(r.metadata.domain))}</span>
|
|
171
|
+
${r.loopLinks.loopRoot?'<span class="badge outline">\u0628\u062F\u0627\u064A\u0629 \u0627\u0644\u062D\u0644\u0642\u0629</span>':""}
|
|
172
|
+
</div>
|
|
173
|
+
</header>`;return`<!DOCTYPE html>
|
|
174
|
+
<html lang="${c(r.metadata.language??"ar")}" dir="rtl">
|
|
175
|
+
<head>
|
|
176
|
+
<meta charset="UTF-8"/>
|
|
177
|
+
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
|
178
|
+
<title>${c(r.metadata.title||"\u0639\u0627\u0631\u0636 DLoF")}</title>
|
|
179
|
+
<style>${Bt(i)}</style>
|
|
180
|
+
</head>
|
|
181
|
+
<body>
|
|
182
|
+
<div class="app">
|
|
183
|
+
${p}
|
|
184
|
+
${v}
|
|
185
|
+
${Ut(r,i.layout)}
|
|
186
|
+
${s}
|
|
187
|
+
</div>
|
|
188
|
+
</body>
|
|
189
|
+
</html>`}function qt(e){let t=Ct(e),r=rt(t,"package.dlof");if(!r)throw new Error('\u062D\u0632\u0645\u0629 .dlofpkg \u063A\u064A\u0631 \u0635\u0627\u0644\u062D\u0629: \u0644\u0627 \u064A\u062D\u062A\u0648\u064A \u0639\u0644\u0649 "package.dlof"');let n=new TextDecoder("utf-8"),i=it(n.decode(r.data),"package.dlof"),o=rt(t,"meta.json"),a;o?a=JSON.parse(n.decode(o.data)):a={id:i.id,title:i.metadata.title,domain:i.metadata.domain,version:i.version,author:i.metadata.author,language:i.metadata.language,createdAt:i.metadata.createdAt,dlofpkg_version:"1.0"};let s={};for(let v of t)v.isDirectory||v.name.startsWith("attachments/")&&(s[v.name]=v.data);return{meta:a,document:i,attachments:s}}async function Ee(e){let t=await e.arrayBuffer(),r=qt(new Uint8Array(t));return st(r)}return Jt(Ie);})();
|
package/dist/index.d.ts
CHANGED
|
@@ -10,3 +10,4 @@ export { resolveLoopChain, buildNavigationMap, LoopChainEntry } from "./loop/loo
|
|
|
10
10
|
export { renderViewerHtml, ViewerOptions } from "./viewer/renderViewerHtml";
|
|
11
11
|
export { renderPlayerHtml, PlayerOptions } from "./player/renderPlayerHtml";
|
|
12
12
|
export { resolveTheme, ResolvedTheme } from "./viewer/theme";
|
|
13
|
+
export { BRAND_LIGHT, BRAND_DARK, DOMAIN_LABELS, CONTENT_KIND_INFO, domainLabel, fileTypeInfo, formatFileSize, loopLogoSvg, FileTypeInfo, } from "./viewer/brand";
|
package/dist/index.js
CHANGED
|
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.resolveTheme = exports.renderPlayerHtml = exports.renderViewerHtml = exports.buildNavigationMap = exports.resolveLoopChain = exports.writeZip = exports.findEntry = exports.readZip = exports.writeDlofSeries = exports.readDlofSeries = exports.buildDefaultMeta = exports.writeDlofPkg = exports.readDlofPkg = exports.validateDlof = exports.serializeDlof = exports.DLOF_EXTENSIONS = exports.isDlofFileName = exports.parseDlof = void 0;
|
|
17
|
+
exports.loopLogoSvg = exports.formatFileSize = exports.fileTypeInfo = exports.domainLabel = exports.CONTENT_KIND_INFO = exports.DOMAIN_LABELS = exports.BRAND_DARK = exports.BRAND_LIGHT = exports.resolveTheme = exports.renderPlayerHtml = exports.renderViewerHtml = exports.buildNavigationMap = exports.resolveLoopChain = exports.writeZip = exports.findEntry = exports.readZip = exports.writeDlofSeries = exports.readDlofSeries = exports.buildDefaultMeta = exports.writeDlofPkg = exports.readDlofPkg = exports.validateDlof = exports.serializeDlof = exports.DLOF_EXTENSIONS = exports.isDlofFileName = exports.parseDlof = void 0;
|
|
18
18
|
__exportStar(require("./types"), exports);
|
|
19
19
|
var parseDlof_1 = require("./dlof/parseDlof");
|
|
20
20
|
Object.defineProperty(exports, "parseDlof", { enumerable: true, get: function () { return parseDlof_1.parseDlof; } });
|
|
@@ -45,3 +45,12 @@ var renderPlayerHtml_1 = require("./player/renderPlayerHtml");
|
|
|
45
45
|
Object.defineProperty(exports, "renderPlayerHtml", { enumerable: true, get: function () { return renderPlayerHtml_1.renderPlayerHtml; } });
|
|
46
46
|
var theme_1 = require("./viewer/theme");
|
|
47
47
|
Object.defineProperty(exports, "resolveTheme", { enumerable: true, get: function () { return theme_1.resolveTheme; } });
|
|
48
|
+
var brand_1 = require("./viewer/brand");
|
|
49
|
+
Object.defineProperty(exports, "BRAND_LIGHT", { enumerable: true, get: function () { return brand_1.BRAND_LIGHT; } });
|
|
50
|
+
Object.defineProperty(exports, "BRAND_DARK", { enumerable: true, get: function () { return brand_1.BRAND_DARK; } });
|
|
51
|
+
Object.defineProperty(exports, "DOMAIN_LABELS", { enumerable: true, get: function () { return brand_1.DOMAIN_LABELS; } });
|
|
52
|
+
Object.defineProperty(exports, "CONTENT_KIND_INFO", { enumerable: true, get: function () { return brand_1.CONTENT_KIND_INFO; } });
|
|
53
|
+
Object.defineProperty(exports, "domainLabel", { enumerable: true, get: function () { return brand_1.domainLabel; } });
|
|
54
|
+
Object.defineProperty(exports, "fileTypeInfo", { enumerable: true, get: function () { return brand_1.fileTypeInfo; } });
|
|
55
|
+
Object.defineProperty(exports, "formatFileSize", { enumerable: true, get: function () { return brand_1.formatFileSize; } });
|
|
56
|
+
Object.defineProperty(exports, "loopLogoSvg", { enumerable: true, get: function () { return brand_1.loopLogoSvg; } });
|
|
@@ -5,9 +5,11 @@ export interface PlayerOptions {
|
|
|
5
5
|
title?: string;
|
|
6
6
|
}
|
|
7
7
|
/**
|
|
8
|
-
* مشغّل dlof: يبني تطبيق HTML/JS تفاعلي واحد لسلسلة أو حلقة كاملة من ملفات .dlof
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
8
|
+
* مشغّل dlof: يبني تطبيق HTML/JS تفاعلي واحد لسلسلة أو حلقة كاملة من ملفات .dlof،
|
|
9
|
+
* بنفس الهوية البصرية لتطبيق DLoF الأصلي. يوفر: قائمة "الملفات" الجانبية (مطابقة
|
|
10
|
+
* لشاشة "ملفاتي" في التطبيق: بطاقات بأيقونة/لون حسب نوع المحتوى، شارة المجال،
|
|
11
|
+
* وبحث فوري)، أزرار التالي/السابق (تتبع loopLinks)، تشغيل الوسائط المرجعية
|
|
12
|
+
* (mediaRef / mediaFolder) مع شريط تقدّم قابل للسحب، وحفظ آخر موضع تصفح في
|
|
13
|
+
* التخزين المحلي للمتصفح بين الجلسات.
|
|
12
14
|
*/
|
|
13
15
|
export declare function renderPlayerHtml(series: DlofSeries, options?: PlayerOptions): string;
|