@memizy/oqse 0.1.4 → 0.1.6
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/dist/index.cjs +1 -1
- package/dist/index.js +221 -225
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`zod`);function t(e){return e.type===`note`}function n(e){return e.type===`flashcard`}function r(e){return e.type===`true-false`}function i(e){return e.type===`mcq-single`}function a(e){return e.type===`mcq-multi`}function o(e){return e.type===`short-answer`}function ee(e){return e.type===`fill-in-blanks`}function te(e){return e.type===`fill-in-select`}function ne(e){return e.type===`match-pairs`}function re(e){return e.type===`match-complex`}function ie(e){return e.type===`sort-items`}function ae(e){return e.type===`slider`}function oe(e){return e.type===`pin-on-image`}function se(e){return e.type===`categorize`}function ce(e){return e.type===`timeline`}function le(e){return e.type===`matrix`}function ue(e){return e.type===`math-input`}function de(e){return e.type===`diagram-label`}function fe(e){return e.type===`open-ended`}function pe(e){return e.type===`numeric-input`}function me(e){return e.type===`pin-on-model`}function he(e){return e.type===`chess-puzzle`}function s(e){return[`note`,`flashcard`,`mcq-single`,`short-answer`].includes(e.type)}function ge(e){return!s(e)}var c=[`render`,`edit`,`validate`,`import`,`export`],l=[`markdown`,`math`,`rtl`,`html`,`syntax-highlighting`,`mermaid`,`smiles`,`abc-notation`,`text-to-speech`,`voice-input`,`handwriting-recognition`],u=[`hints`,`explanation`,`incorrectFeedback`,`sources`,`relatedItems`,`dependencyItems`,`timeLimit`,`lang`,`topic`,`pedagogy`],d=[`description`,`thumbnail`,`subject`,`language`,`author`,`contributors`,`license`,`ageRestriction`,`tags`,`tagDefinitions`,`sourceMaterials`,`estimatedTime`,`prerequisites`,`translations`,`relatedSets`];function f(e){return/^\d+\.\d+$/.test(e)}function _e(e){return/^\d+\.\d+\.\d+(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?(\+[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$/.test(e)}function p(e,t){let[n=0,r=0]=e.split(`.`).map(Number),[i=0,a=0]=t.split(`.`).map(Number);return n===i?r-a:n-i}function ve(e){if(typeof e!=`object`||!e)return!1;let t=e,n=t.author;return typeof t.version==`string`&&typeof t.id==`string`&&typeof t.appName==`string`&&t.appName!==``&&(n===void 0||typeof n==`object`&&!!n)&&typeof t.capabilities==`object`&&t.capabilities!==null&&Array.isArray(t.capabilities.actions)}function ye(e,t){return!(!f(e)||t.minOqseVersion&&f(t.minOqseVersion)&&p(e,t.minOqseVersion)<0||t.maxOqseVersion&&f(t.maxOqseVersion)&&p(e,t.maxOqseVersion)>0)}var be=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/i;function xe(e){return typeof e==`string`&&be.test(e)}var m=[];for(let e=0;e<256;++e)m.push((e+256).toString(16).slice(1));function Se(e,t=0){return(m[e[t+0]]+m[e[t+1]]+m[e[t+2]]+m[e[t+3]]+`-`+m[e[t+4]]+m[e[t+5]]+`-`+m[e[t+6]]+m[e[t+7]]+`-`+m[e[t+8]]+m[e[t+9]]+`-`+m[e[t+10]]+m[e[t+11]]+m[e[t+12]]+m[e[t+13]]+m[e[t+14]]+m[e[t+15]]).toLowerCase()}var h,Ce=new Uint8Array(16);function we(){if(!h){if(typeof crypto>`u`||!crypto.getRandomValues)throw Error(`crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported`);h=crypto.getRandomValues.bind(crypto)}return h(Ce)}var g={};function Te(e,t,n){let r;if(e)r=De(e.random??e.rng?.()??we(),e.msecs,e.seq,t,n);else{let e=Date.now(),i=we();Ee(g,e,i),r=De(i,g.msecs,g.seq,t,n)}return t??Se(r)}function Ee(e,t,n){return e.msecs??=-1/0,e.seq??=0,t>e.msecs?(e.seq=n[6]<<23|n[7]<<16|n[8]<<8|n[9],e.msecs=t):(e.seq=e.seq+1|0,e.seq===0&&e.msecs++),e}function De(e,t,n,r,i=0){if(e.length<16)throw Error(`Random bytes length must be >= 16`);if(!r)r=new Uint8Array(16),i=0;else if(i<0||i+16>r.length)throw RangeError(`UUID byte range ${i}:${i+15} is out of buffer bounds`);return t??=Date.now(),n??=e[6]*127<<24|e[7]<<16|e[8]<<8|e[9],r[i++]=t/1099511627776&255,r[i++]=t/4294967296&255,r[i++]=t/16777216&255,r[i++]=t/65536&255,r[i++]=t/256&255,r[i++]=t&255,r[i++]=112|n>>>28&15,r[i++]=n>>>20&255,r[i++]=128|n>>>14&63,r[i++]=n>>>6&255,r[i++]=n<<2&255|e[10]&3,r[i++]=e[11],r[i++]=e[12],r[i++]=e[13],r[i++]=e[14],r[i++]=e[15],r}function Oe(e){return xe(e)}function ke(){return Te()}function _(e,t=10,n=0){if(n>t)throw Error(`OQSE Security Error: Maximum nesting depth exceeded limit of ${t} levels.`);if(typeof e==`object`&&e){let r=Array.isArray(e)?e:Object.values(e);for(let e of r)_(e,t,n+1)}}function Ae(e){return e.issues.map(e=>{let t=``;return e.path.forEach((n,r)=>{if(typeof n==`number`)t+=`[${n}]`;else{let i=r===0||typeof e.path[r-1]==`number`;t+=(i?``:`.`)+String(n)}}),t?`${t}: ${e.message}`:e.message})}var v=e.z.string().uuid({message:`Invalid UUID format`}),y=e.z.string().min(2,`Language code must have at least 2 characters`).regex(/^[a-z]{2,3}(-[A-Z][a-z]{3})?(-[A-Z]{2})?$/,`Invalid BCP 47 format (e.g. "cs", "en-US")`),b=e.z.string().min(1,`License identifier must not be empty`),x=e.z.string().regex(/^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}:\d{2}(\.\d{3})?(Z|[+-]\d{2}:\d{2})?)?$/,`Invalid ISO 8601 format (e.g. "2025-11-21T14:30:00Z")`),S=e.z.string().url({message:`Must be a valid absolute URL`}),C=e.z.string().regex(/^[a-z0-9_-]+$/,`Asset key must contain only lowercase letters, numbers, hyphens and underscores`),w=e.z.string().min(1,`Text must not be empty`),T=e.z.string().min(1,`Content must not be empty`),E=e.z.string().max(1e4,`Question must not be longer than 10000 characters`).optional(),D=e.z.string().regex(/^[a-zA-Z0-9_-]{1,64}$/,`Token must be alphanumeric, max 64 chars`),O=e.z.object({lang:y,value:e.z.string().min(1,`Subtitle URI must not be empty`).regex(/\.(vtt|srt)(\?.*)?$/i,`Subtitle URI must end with .vtt or .srt`),label:e.z.string().optional(),kind:e.z.enum([`captions`,`subtitles`,`descriptions`]).optional()}),k=e.z.object({type:e.z.enum([`image`,`audio`,`video`,`model`]),value:e.z.string().min(1,`Media URI must not be empty`),mimeType:e.z.string().optional(),altText:e.z.string().optional(),transcript:T.optional(),caption:T.optional(),width:e.z.number().int().positive().optional(),height:e.z.number().int().positive().optional(),start:e.z.number().nonnegative().optional(),end:e.z.number().positive().optional(),loop:e.z.boolean().optional(),subtitles:e.z.array(O).optional(),license:b.optional(),attribution:e.z.string().optional(),checksums:e.z.record(e.z.string(),e.z.string()).optional()}).refine(e=>e.start!==void 0&&e.end!==void 0?e.start<e.end:!0,{message:`Start time must be less than end time`,path:[`end`]}).refine(e=>!(e.type===`image`&&!e.altText),{message:`Images must have alternative text (altText) defined for accessibility`,path:[`altText`]}),A=e.z.record(C,k),j=e.z.object({name:w,role:e.z.string().optional(),email:e.z.string().email(`Invalid email format`).optional(),url:S.optional()}),M=e.z.enum([`url`,`doi`,`isbn`,`pdf`,`textbook`,`video`,`audio`,`image`,`model`,`other`]),N=e.z.object({id:w,type:M,value:w,title:w,description:e.z.string().optional(),authors:e.z.array(w).optional(),publishedDate:x.optional(),retrievedAt:x.optional(),license:b.optional()}).refine(e=>{if([`url`,`pdf`,`video`,`audio`,`image`].includes(e.type))try{return new URL(e.value),!0}catch{return!1}return!0},{message:`For url, pdf, video, audio and image types, value must be a valid URL`,path:[`value`]}),P=e.z.object({id:w,location:e.z.string().optional(),quote:T.optional()}),je=e.z.object({wikidataId:e.z.string().regex(/^Q\d+$/,`Wikidata ID must have format Q followed by number`).optional(),description:e.z.string().optional()}),Me=e.z.record(e.z.string(),je),F=e.z.object({features:e.z.array(e.z.string().refine(e=>l.includes(e)||e.startsWith(`x-`),{message:`Feature must be an official key or have prefix "x-"`})).optional(),latexPackages:e.z.array(e.z.string().min(1,`Package name must not be empty`)).optional(),itemProperties:e.z.array(e.z.string().refine(e=>u.includes(e)||e.startsWith(`x-`),{message:`Item property must be an official key or have prefix "x-"`})).optional(),metaProperties:e.z.array(e.z.string().refine(e=>d.includes(e)||e.startsWith(`x-`),{message:`Meta property must be an official key or have prefix "x-"`})).optional()}),Ne=e.z.object({lang:y,id:v,title:w,downloadUrl:S.optional()}),I=e.z.object({id:v,title:w,downloadUrl:S.optional()}),Pe=e.z.enum([`remember`,`understand`,`apply`,`analyze`,`evaluate`,`create`]),Fe=e.z.enum([`low`,`medium`,`high`]),Ie=e.z.object({bloomLevel:Pe.optional(),irtDifficulty:e.z.number().optional(),irtDiscrimination:e.z.number().optional(),irtGuessing:e.z.number().min(0).max(1,`IRT guessing must be between 0 and 1`).optional(),avgTime:e.z.number().positive().optional(),cognitiveLoad:Fe.optional(),partialCredit:e.z.boolean().optional(),penaltyPerWrong:e.z.number().min(0).max(1,`Penalty must be between 0 and 1`).optional()}),L=e.z.object({id:v,language:y,title:w.max(500,`Title must not be longer than 500 characters`),description:T.max(5e3,`Description must not be longer than 5000 characters`).optional(),thumbnail:C.optional(),assets:A.optional(),ageMin:e.z.number().int().nonnegative().optional(),ageMax:e.z.number().int().nonnegative().optional(),subject:e.z.string().optional(),createdAt:x,updatedAt:x,author:j.optional(),contributors:e.z.array(j).optional(),license:b.optional(),licenseUrl:S.optional(),requirements:F.optional(),tags:e.z.array(w).optional(),tagDefinitions:Me.optional(),translations:e.z.array(Ne).optional(),sourceMaterials:e.z.array(N).optional(),estimatedTime:e.z.number().positive().optional(),prerequisites:e.z.array(I).optional(),relatedSets:e.z.array(I).optional(),customData:e.z.record(e.z.string(),e.z.unknown()).optional(),appSpecific:e.z.record(e.z.string(),e.z.unknown()).optional()}).refine(e=>e.ageMin!==void 0&&e.ageMax!==void 0?e.ageMin<=e.ageMax:!0,{message:`Minimum age (ageMin) must be less than or equal to maximum age (ageMax)`,path:[`ageMax`]}).refine(e=>new Date(e.createdAt)<=new Date(e.updatedAt),{message:`Creation date (createdAt) must be before or equal to update date (updatedAt)`,path:[`updatedAt`]}),R=e.z.object({id:v,type:e.z.string(),assets:A.optional(),lang:y.optional(),tags:e.z.array(w).optional(),topic:w.optional(),difficulty:e.z.number().int().min(1,`Difficulty must be at least 1`).max(5,`Difficulty must be at most 5`).optional(),timeLimit:e.z.number().positive(`Time limit must be a positive number`).optional(),hints:e.z.array(T.max(2e3,`Hint must not be longer than 2000 characters`)).max(20,`Maximum 20 hints per item`).optional(),explanation:T.max(1e4,`Explanation must not be longer than 10000 characters`).optional(),incorrectFeedback:T.optional(),sources:e.z.array(P).optional(),relatedItems:e.z.array(v).optional(),dependencyItems:e.z.array(v).optional(),pedagogy:Ie.optional(),customData:e.z.record(e.z.string(),e.z.unknown()).optional(),appSpecific:e.z.record(e.z.string(),e.z.unknown()).optional()}),Le=e.z.object({options:e.z.array(T).min(1,`Must have at least 1 option`),correctIndex:e.z.number().int().nonnegative()}).refine(e=>e.correctIndex<e.options.length,{message:`Correct answer index references non-existent option`,path:[`correctIndex`]}),z=e.z.object({type:e.z.literal(`rect`),label:e.z.string().optional(),x:e.z.number().min(0).max(100,`X must be in range 0-100%`),y:e.z.number().min(0).max(100,`Y must be in range 0-100%`),width:e.z.number().min(0).max(100,`Width must be in range 0-100%`),height:e.z.number().min(0).max(100,`Height must be in range 0-100%`)}),B=e.z.object({type:e.z.literal(`circle`),label:e.z.string().optional(),x:e.z.number().min(0).max(100,`X must be in range 0-100%`),y:e.z.number().min(0).max(100,`Y must be in range 0-100%`),radius:e.z.number().min(0).max(100,`Radius must be in range 0-100%`)}),V=e.z.object({type:e.z.literal(`polygon`),label:e.z.string().optional(),points:e.z.array(e.z.object({x:e.z.number().min(0).max(100),y:e.z.number().min(0).max(100)})).min(3,`Polygon must have at least 3 points`)}),H=e.z.object({type:e.z.literal(`mesh`),label:e.z.string().optional(),targetName:w}),Re=e.z.discriminatedUnion(`type`,[z,B,V,H]),ze=e.z.discriminatedUnion(`type`,[z,B,V]),U=e.z.object({x:e.z.number(),y:e.z.number(),z:e.z.number()}),W=e.z.object({position:U.optional(),target:U.optional()}),Be=e.z.object({id:w,text:T,correctCategoryIndex:e.z.number().int().nonnegative()}),Ve=e.z.enum([`year`,`month`,`day`,`datetime`]),He=e.z.object({id:w,text:T,date:x,precision:Ve.optional()}),Ue=e.z.union([z.extend({correctLabelIndex:e.z.number().int().nonnegative()}),B.extend({correctLabelIndex:e.z.number().int().nonnegative()}),V.extend({correctLabelIndex:e.z.number().int().nonnegative()})]),We=e.z.object({label:w,percentage:e.z.number().min(0,`Percentage must be non-negative`).max(100,`Percentage must not exceed 100`),description:e.z.string().optional()}),Ge=e.z.object({criteria:e.z.array(We).min(1,`Rubric must have at least 1 criterion`)}).refine(e=>e.criteria.reduce((e,t)=>e+t.percentage,0)>0,{message:`Sum of percentages of all criteria must be greater than 0`,path:[`criteria`]}),Ke=e.z.object({min:e.z.number(),max:e.z.number()}).refine(e=>e.min<=e.max,{message:`Minimum value must be less than or equal to maximum value`,path:[`max`]}),qe=R.extend({type:e.z.literal(`note`),title:e.z.string().optional(),content:T.max(1e4,`Content must not be longer than 10000 characters`),hiddenContent:T.max(1e4,`Content must not be longer than 10000 characters`).optional()}),Je=R.extend({type:e.z.literal(`flashcard`),front:T.max(1e4,`Front side must not be longer than 10000 characters`),back:T.max(1e4,`Back side must not be longer than 10000 characters`)}),Ye=R.extend({type:e.z.literal(`true-false`),question:T.max(1e4,`Question must not be longer than 10000 characters`),answer:e.z.boolean()}),Xe=R.extend({type:e.z.literal(`mcq-single`),question:T.max(1e4,`Question must not be longer than 10000 characters`),options:e.z.array(T.max(2e3,`Option must not be longer than 2000 characters`)).min(2,`Question must have at least 2 options`).max(100,`Maximum 100 options`),correctIndex:e.z.number().int().nonnegative(),shuffleOptions:e.z.boolean().optional(),optionExplanations:e.z.array(e.z.union([T,e.z.null()])).optional()}).refine(e=>e.correctIndex<e.options.length,{message:`Correct answer index references non-existent option`,path:[`correctIndex`]}).refine(e=>e.optionExplanations?e.optionExplanations.length===e.options.length:!0,{message:`Number of option explanations must match number of options`,path:[`optionExplanations`]}).refine(e=>new Set(e.options.map(e=>e.toLowerCase())).size===e.options.length,{message:`Options must not contain duplicates (case-insensitive)`,path:[`options`]}),Ze=R.extend({type:e.z.literal(`mcq-multi`),question:T.max(1e4,`Question must not be longer than 10000 characters`),options:e.z.array(T.max(2e3,`Option must not be longer than 2000 characters`)).min(2,`Question must have at least 2 options`).max(100,`Maximum 100 options`),correctIndices:e.z.array(e.z.number().int().nonnegative()).min(1,`Must have at least 1 correct answer`),minSelections:e.z.number().int().positive().optional(),maxSelections:e.z.number().int().positive().optional(),shuffleOptions:e.z.boolean().optional(),optionExplanations:e.z.array(e.z.union([T,e.z.null()])).optional()}).refine(e=>e.correctIndices.every(t=>t<e.options.length),{message:`Some of correct answer indices reference non-existent option`,path:[`correctIndices`]}).refine(e=>new Set(e.correctIndices).size===e.correctIndices.length,{message:`Correct answer indices contain duplicates`,path:[`correctIndices`]}).refine(e=>e.minSelections&&e.maxSelections?e.minSelections<=e.maxSelections:!0,{message:`Minimum number of selections must be less than or equal to maximum`,path:[`maxSelections`]}).refine(e=>e.maxSelections?e.maxSelections<=e.options.length:!0,{message:`Maximum number of selections must not exceed number of options`,path:[`maxSelections`]}).refine(e=>e.minSelections?e.minSelections<=e.options.length:!0,{message:`minSelections cannot be greater than the number of options`,path:[`minSelections`]}).refine(e=>e.optionExplanations?e.optionExplanations.length===e.options.length:!0,{message:`Number of option explanations must match number of options`,path:[`optionExplanations`]}).refine(e=>new Set(e.options.map(e=>e.toLowerCase())).size===e.options.length,{message:`Options must not contain duplicates (case-insensitive)`,path:[`options`]}),Qe=R.extend({type:e.z.literal(`short-answer`),question:T.max(1e4,`Question must not be longer than 10000 characters`),answers:e.z.array(w).min(1,`Must have at least 1 correct answer`),caseSensitive:e.z.boolean().optional(),trimWhitespace:e.z.boolean().optional(),acceptPartial:e.z.boolean().optional(),ignoreDiacritics:e.z.boolean().optional()}),$e=R.extend({type:e.z.literal(`fill-in-blanks`),question:E,text:T.max(1e4,`Text must not be longer than 10000 characters`),blanks:e.z.record(D,e.z.array(w).min(1,`Each blank must have at least 1 correct answer`)),caseSensitive:e.z.boolean().optional(),trimWhitespace:e.z.boolean().optional()}).refine(e=>Object.keys(e.blanks).length>0,{message:`Text must contain at least 1 blank to fill`,path:[`blanks`]}).refine(e=>{let t=/<blank:([a-zA-Z0-9_-]{1,64})\s*\/>/g,n=new Set,r;for(;(r=t.exec(e.text))!==null;)r[1]&&n.add(r[1]);let i=new Set(Object.keys(e.blanks));for(let e of n)if(!i.has(e))return!1;for(let e of i)if(!n.has(e))return!1;return!0},{message:`All tokens in text must have definition in blanks and all definitions must be used in text`,path:[`blanks`]}),et=R.extend({type:e.z.literal(`fill-in-select`),question:E,text:T.max(1e4,`Text must not be longer than 10000 characters`),blanks:e.z.record(D,Le)}).refine(e=>Object.keys(e.blanks).length>0,{message:`Text must contain at least 1 blank to select`,path:[`blanks`]}).refine(e=>{let t=/<blank:([a-zA-Z0-9_-]{1,64})\s*\/>/g,n=new Set,r;for(;(r=t.exec(e.text))!==null;)r[1]&&n.add(r[1]);let i=new Set(Object.keys(e.blanks));for(let e of n)if(!i.has(e))return!1;for(let e of i)if(!n.has(e))return!1;return!0},{message:`All tokens in text must have definition in blanks and all definitions must be used in text`,path:[`blanks`]}),tt=R.extend({type:e.z.literal(`match-pairs`),question:E,prompts:e.z.array(T).min(2,`Must have at least 2 pairs to match`).max(100,`Maximum 100 pairs`),matches:e.z.array(T).min(2,`Must have at least 2 pairs to match`).max(100,`Maximum 100 pairs`)}).refine(e=>e.prompts.length===e.matches.length,{message:`Number of prompts must match number of matches`,path:[`matches`]}),nt=R.extend({type:e.z.literal(`match-complex`),question:E,leftItems:e.z.array(T).min(1,`Must have at least 1 item on left`),rightItems:e.z.array(T).min(1,`Must have at least 1 item on right`),connections:e.z.array(e.z.tuple([e.z.number().int().nonnegative(),e.z.number().int().nonnegative()])).min(1,`Must have at least 1 connection`),minCorrect:e.z.number().int().positive().optional()}).refine(e=>e.connections.every(([t,n])=>t<e.leftItems.length&&n<e.rightItems.length),{message:`Some connection references non-existent item`,path:[`connections`]}).refine(e=>new Set(e.connections.map(e=>`${e[0]}-${e[1]}`)).size===e.connections.length,{message:`Connections contain duplicates`,path:[`connections`]}).refine(e=>e.minCorrect?e.minCorrect<=e.connections.length:!0,{message:`Minimum correct answers must not exceed total number of connections`,path:[`minCorrect`]}),rt=R.extend({type:e.z.literal(`sort-items`),question:T.max(1e4,`Question must not be longer than 10000 characters`),items:e.z.array(T).min(2,`Must have at least 2 items to sort`)}),it=R.extend({type:e.z.literal(`slider`),question:T.max(1e4,`Question must not be longer than 10000 characters`),min:e.z.number(),max:e.z.number(),step:e.z.number().positive(`Step must be a positive number`),correctAnswer:e.z.number(),tolerance:e.z.number().nonnegative(`Tolerance must be non-negative`),unit:e.z.string().optional()}).refine(e=>e.min<e.max,{message:`Minimum value must be less than maximum value`,path:[`max`]}).refine(e=>e.correctAnswer>=e.min&&e.correctAnswer<=e.max,{message:`Correct answer must be in range min-max`,path:[`correctAnswer`]}).refine(e=>{let t=(e.correctAnswer-e.min)/e.step;return Math.abs(t-Math.round(t))<1e-4},{message:`Correct answer must be reachable by defined step`,path:[`correctAnswer`]}).refine(e=>e.tolerance<=(e.max-e.min)/2,{message:`Tolerance must not be greater than half of value range`,path:[`tolerance`]}),at=R.extend({type:e.z.literal(`pin-on-image`),question:T.max(1e4,`Question must not be longer than 10000 characters`),targetAsset:C,hotspots:e.z.array(ze).min(1,`Must have at least 1 hotspot`),multipleCorrect:e.z.boolean().optional(),minCorrect:e.z.number().int().positive().optional()}).refine(e=>e.minCorrect?e.minCorrect<=e.hotspots.length:!0,{message:`Minimum correct answers must not exceed number of hotspots`,path:[`minCorrect`]}),ot=R.extend({type:e.z.literal(`categorize`),question:T.max(1e4,`Question must not be longer than 10000 characters`),categories:e.z.array(w).min(2,`Must have at least 2 categories`),items:e.z.array(Be).min(1,`Must have at least 1 item to categorize`)}).refine(e=>new Set(e.categories.map(e=>e.toLowerCase())).size===e.categories.length,{message:`Categories must not contain duplicates (case-insensitive)`,path:[`categories`]}).refine(e=>e.items.every(t=>t.correctCategoryIndex<e.categories.length),{message:`Some item references non-existent category`,path:[`items`]}),st=R.extend({type:e.z.literal(`timeline`),question:T.max(1e4,`Question must not be longer than 10000 characters`),events:e.z.array(He).min(2,`Must have at least 2 events`),randomize:e.z.boolean().optional()}),ct=R.extend({type:e.z.literal(`matrix`),question:T.max(1e4,`Question must not be longer than 10000 characters`),rows:e.z.array(w).min(1,`Must have at least 1 row`),columns:e.z.array(w).min(1,`Must have at least 1 column`),correctCells:e.z.array(e.z.tuple([e.z.number().int().nonnegative(),e.z.number().int().nonnegative()])).min(1,`Must have at least 1 correct cell`),multiplePerRow:e.z.boolean().optional()}).refine(e=>e.correctCells.every(([t,n])=>t<e.rows.length&&n<e.columns.length),{message:`Some cell coordinates reference non-existent row or column`,path:[`correctCells`]}).refine(e=>new Set(e.correctCells.map(e=>`${e[0]}-${e[1]}`)).size===e.correctCells.length,{message:`Correct cells contain duplicates`,path:[`correctCells`]}).refine(e=>{if(!e.multiplePerRow){let t=new Map;for(let[n]of e.correctCells)t.set(n,(t.get(n)||0)+1);return Array.from(t.values()).every(e=>e<=1)}return!0},{message:`If multiplePerRow is false, each row may have maximum 1 correct cell`,path:[`correctCells`]}),lt=R.extend({type:e.z.literal(`math-input`),question:T.max(1e4,`Question must not be longer than 10000 characters`),correctAnswer:w,alternativeAnswers:e.z.array(w).optional(),tolerance:e.z.number().nonnegative().optional()}),ut=R.extend({type:e.z.literal(`diagram-label`),question:T.max(1e4,`Question must not be longer than 10000 characters`),targetAsset:C,labels:e.z.array(T).min(1,`Must have at least 1 label`),caseSensitive:e.z.boolean().optional(),requireTyping:e.z.boolean().optional(),zones:e.z.array(Ue).min(1,`Must have at least 1 zone`)}).refine(e=>e.zones.every(t=>t.correctLabelIndex<e.labels.length),{message:`Some zone references non-existent label`,path:[`zones`]}),dt=R.extend({type:e.z.literal(`open-ended`),question:T.max(1e4,`Question must not be longer than 10000 characters`),minWords:e.z.number().int().positive().optional(),maxWords:e.z.number().int().positive().optional(),sampleAnswer:T.optional(),rubric:Ge.optional()}).refine(e=>e.minWords&&e.maxWords?e.minWords<=e.maxWords:!0,{message:`Minimum word count must be less than or equal to maximum`,path:[`maxWords`]}),ft=R.extend({type:e.z.literal(`numeric-input`),question:T.max(1e4,`Question must not be longer than 10000 characters`),value:e.z.number(),tolerance:e.z.number().nonnegative().optional(),range:Ke.optional(),unit:e.z.string().optional()}),pt=R.extend({type:e.z.literal(`pin-on-model`),question:T.max(1e4,`Question must not be longer than 10000 characters`),targetAsset:C,hotspots:e.z.array(H).min(1,`Must have at least 1 hotspot`),multipleCorrect:e.z.boolean().optional(),minCorrect:e.z.number().int().positive().optional(),camera:W.optional()}).refine(e=>e.minCorrect?e.minCorrect<=e.hotspots.length:!0,{message:`Minimum correct answers must not exceed number of hotspots`,path:[`minCorrect`]}),mt=R.extend({type:e.z.literal(`chess-puzzle`),question:T.max(1e4,`Question must not be longer than 10000 characters`),fen:w,answers:e.z.array(e.z.array(w).min(1,`Move sequence must not be empty`)).min(1,`Must have at least 1 correct move sequence`),elo:e.z.number().int().nonnegative(`ELO must be non-negative integer`).optional()}),G=e.z.discriminatedUnion(`type`,[qe,Je,Ye,Xe,Ze,Qe,$e,et,tt,nt,rt,it,at,ot,st,ct,lt,ut,dt,ft,pt,mt]),K=e.z.object({$schema:e.z.string().url().optional(),version:e.z.string().regex(/^\d+\.\d+$/,`Version must be in MAJOR.MINOR format (e.g. "0.1")`),meta:L,items:e.z.array(G).max(1e4,`Maximum 10000 items per set`)}).refine(e=>{let t=new Set(e.items.map(e=>e.id));for(let n of e.items){if(n.relatedItems){for(let e of n.relatedItems)if(!t.has(e)||n.id===e)return!1}if(n.dependencyItems){for(let e of n.dependencyItems)if(!t.has(e)||n.id===e)return!1}}return!0},{message:`Some item references non-existent relatedItems, dependencyItems, or references itself`,path:[`items`]}).refine(e=>e.meta.thumbnail&&e.meta.assets?e.meta.thumbnail in e.meta.assets:!0,{message:`Thumbnail references non-existent asset`,path:[`meta`,`thumbnail`]}).refine(e=>{let t=new Set((e.meta.sourceMaterials||[]).map(e=>e.id));for(let n of e.items)if(n.sources){for(let e of n.sources)if(!t.has(e.id))return!1}return!0},{message:`Some item references non-existent source material`,path:[`items`]});function ht(t){let n=t instanceof Error?t.message:`OQSE Security Error: Maximum nesting depth exceeded limit of 10 levels.`;return new e.z.ZodError([{code:e.z.ZodIssueCode.custom,message:n,path:[]}])}function gt(e){return _(e,10),K.parse(e)}function _t(e){try{_(e,10)}catch(e){return{success:!1,error:ht(e)}}let t=K.safeParse(e);return t.success?{success:!0,data:t.data}:{success:!1,error:t.error}}function vt(e){return _(e,10),G.parse(e)}function yt(e){try{_(e,10)}catch(e){return{success:!1,error:ht(e)}}let t=G.safeParse(e);return t.success?{success:!0,data:t.data}:{success:!1,error:t.error}}var q=e.z.string().min(1,`Value must not be empty`).trim(),bt=e.z.string().regex(/^[a-zA-Z]{2,8}(-[a-zA-Z0-9\-]+)*$/,`Must be a valid BCP 47 locale (e.g., "en", "cs")`),J=e.z.string().url(`Must be a valid absolute URL`).refine(e=>e.startsWith(`http://`)||e.startsWith(`https://`),{message:`URL must use http or https scheme`}),xt=e.z.string().regex(/^urn:uuid:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,`Must be a valid URN UUID (urn:uuid:...)`),Y=e.z.string().regex(/^\d+\.\d+$/,`Version must be in MAJOR.MINOR format (e.g. "0.1")`),St=[`note`,`flashcard`,`true-false`,`mcq-single`,`mcq-multi`,`short-answer`,`fill-in-blanks`,`fill-in-select`,`match-pairs`,`match-complex`,`sort-items`,`slider`,`pin-on-image`,`categorize`,`timeline`,`matrix`,`math-input`,`diagram-label`,`open-ended`,`numeric-input`,`pin-on-model`,`chess-puzzle`],Ct=q.refine(e=>St.includes(e)||e.startsWith(`x-`),{message:`Custom types MUST use the "x-" prefix`}),wt=e.z.string().refine(e=>c.includes(e)||e.startsWith(`x-`),{message:`Action must be one of [render, edit, validate, import, export] or have prefix "x-"`}),Tt=e.z.enum([`game`,`fun`,`drill`]),Et=e.z.enum([`low`,`medium`,`high`]),Dt=e.z.string().refine(e=>l.includes(e)||e.startsWith(`x-`),{message:`Feature must be one of official keys or have prefix "x-"`}),Ot=e.z.string().refine(e=>u.includes(e)||e.startsWith(`x-`),{message:`Item property must be an official key or have prefix "x-"`}),kt=e.z.string().refine(e=>d.includes(e)||e.startsWith(`x-`),{message:`Meta property must be an official key or have prefix "x-"`});function X(t){return e.z.union([e.z.tuple([e.z.literal(`*`)]),e.z.array(t),e.z.null()])}var At=e.z.string().refine(e=>e.startsWith(`image/`),{message:`Must be a valid image MIME type (image/...)`}),jt=e.z.string().refine(e=>e.startsWith(`audio/`),{message:`Must be a valid audio MIME type (audio/...)`}),Mt=e.z.string().refine(e=>e.startsWith(`video/`),{message:`Must be a valid video MIME type (video/...)`}),Nt=e.z.string().refine(e=>e.startsWith(`model/`)||e===`application/octet-stream`,{message:`Must be a valid 3D model MIME type (model/... or application/octet-stream)`}),Pt=e.z.object({image:X(At).optional(),audio:X(jt).optional(),video:X(Mt).optional(),model:X(Nt).optional()}),Ft=F.extend({actions:e.z.array(wt).min(1,`Application must support at least one action`),types:X(Ct).optional(),assets:Pt.optional()}).superRefine((t,n)=>{(t.actions.includes(`render`)||t.actions.includes(`edit`))&&(!Array.isArray(t.types)||t.types.length===0)&&n.addIssue({code:e.z.ZodIssueCode.custom,message:`types array MUST be declared and non-empty when actions include "render" or "edit"`,path:[`types`]})}),Z=e.z.object({$schema:J.optional(),id:e.z.union([J,xt]),appName:q.max(200,`Name must not be longer than 200 characters`),version:Y,pluginVersion:e.z.string().optional(),minOqseVersion:Y.optional(),maxOqseVersion:Y.optional(),capabilities:Ft,author:j.optional(),contributors:e.z.array(j).optional(),license:e.z.string().max(100,`License must not be longer than 100 characters`).optional(),licenseUrl:J.optional(),locales:e.z.array(bt).optional(),description:e.z.string().max(5e3,`Description must not be longer than 5000 characters`).optional(),emoji:e.z.string().optional(),tags:e.z.array(q).optional(),studyMode:Tt.optional(),questionDensity:Et.optional(),appSpecific:e.z.record(e.z.string(),e.z.unknown()).optional()}).refine(e=>{if(!e.minOqseVersion||!e.maxOqseVersion)return!0;let t=e.minOqseVersion.split(`.`),n=e.maxOqseVersion.split(`.`),r=Number(t[0]),i=Number(t[1]),a=Number(n[0]),o=Number(n[1]);return r===a?i<=o:r<a},{message:`minOqseVersion must not be greater than maxOqseVersion`,path:[`minOqseVersion`]});function It(e){return Z.parse(e)}function Lt(e){return Z.safeParse(e)}function Rt(e){return Z.safeParse(e).success}var zt=e.z.object({attempts:e.z.number().int().nonnegative(),incorrect:e.z.number().int().nonnegative(),streak:e.z.number().int().nonnegative()}).refine(e=>e.incorrect<=e.attempts,{message:`incorrect cannot be higher than attempts`,path:[`incorrect`]}),Bt=e.z.object({isCorrect:e.z.boolean(),confidence:e.z.union([e.z.literal(1),e.z.literal(2),e.z.literal(3),e.z.literal(4)]).optional(),answeredAt:x,timeSpent:e.z.number().int().nonnegative().optional(),hintsUsed:e.z.number().int().nonnegative().default(0),isSkipped:e.z.boolean().optional()}),Vt=e.z.object({bucket:e.z.union([e.z.literal(0),e.z.literal(1),e.z.literal(2),e.z.literal(3),e.z.literal(4)]),nextReviewAt:x.optional(),stats:zt,lastAnswer:Bt.optional(),appSpecific:e.z.record(e.z.string(),e.z.unknown()).optional()}),Ht=e.z.object({setId:v,exportedAt:x,algorithm:e.z.string().regex(/^[a-z0-9-]+$/,`algorithm must be lowercase alphanumeric with hyphens format`).optional()}),Q=e.z.object({$schema:e.z.url().optional(),version:e.z.string().regex(/^\d+\.\d+$/,`Version must be in MAJOR.MINOR format`),meta:Ht,records:e.z.record(v,Vt)});function Ut(e){return Q.parse(e)}function Wt(e){return Q.safeParse(e)}var $=e.z.object(L.shape).pick({id:!0,title:!0,language:!0,updatedAt:!0,description:!0,author:!0,subject:!0,tags:!0,createdAt:!0,estimatedTime:!0,requirements:!0}).partial({createdAt:!0}).extend({url:S,$schema:e.z.string().url().optional()});function Gt(e){return $.parse(e)}function Kt(e){return $.safeParse(e)}function qt(e){let t={};return{text:e.replace(/<(asset|blank):([a-zA-Z0-9_-]+)\s*\/>/gi,(e,n,r)=>{let i=`[[__OQSE_TOKEN_${Math.random().toString(36).substring(2,15)}__]]`;return t[i]={type:n.toLowerCase(),key:r.toLowerCase(),originalTag:e},i}),tokens:t}}function Jt(e){let t=e.replace(/`{1,}[^`]*`{1,}/g,``).replace(/~{3,}[\s\S]*?~{3,}/g,``);if(/<[a-zA-Z\/][^>]*>/.test(t))throw Error(`OQSE Security Error: Raw HTML tags are not allowed in Tier 1 (Pure Markdown). If the set requires HTML formatting, it MUST declare the 'html' feature in meta.requirements.`)}function Yt(e,t,n){let r=e;for(let[e,i]of Object.entries(t)){let t=i.originalTag;i.type===`asset`&&n.assetReplacer?t=n.assetReplacer(i.key):i.type===`blank`&&n.blankReplacer&&(t=n.blankReplacer(i.key)),r=r.replace(e,t)}return r}function Xt(e,t,n){if(!e)return``;let r=t?.features?.includes(`html`)??!1,{text:i,tokens:a}=qt(e);r||Jt(i);let o=n.markdownParser(i);if(r){if(!n.htmlSanitizer)throw Error(`OQSE Security Error: Set requires 'html' (Tier 2), but no htmlSanitizer (like DOMPurify) was provided to the options.`);o=n.htmlSanitizer(o)}return Yt(o,a,n)}exports.AbsoluteURLSchema=S,exports.AssetDictionarySchema=A,exports.AssetKeySchema=C,exports.AudioMimeTypeSchema=jt,exports.BaseItemSchema=R,exports.BlankTokenSchema=D,exports.BloomLevelSchema=Pe,exports.CameraSetupSchema=W,exports.CategorizeItemObjectSchema=Be,exports.CategorizeItemSchema=ot,exports.ChessPuzzleItemSchema=mt,exports.CircleHotspotSchema=B,exports.CognitiveLoadSchema=Fe,exports.DiagramLabelItemSchema=ut,exports.DiagramZoneSchema=Ue,exports.FeatureFlagSchema=Dt,exports.FeatureProfileSchema=F,exports.FillInBlanksItemSchema=$e,exports.FillInSelectItemSchema=et,exports.FlashcardItemSchema=Je,exports.Hotspot2DSchema=ze,exports.HotspotObjectSchema=Re,exports.ISO8601DateTimeSchema=x,exports.ImageMimeTypeSchema=At,exports.ItemPropertyKeySchema=Ot,exports.LanguageCodeSchema=y,exports.LastAnswerObjectSchema=Bt,exports.LinkedSetObjectSchema=I,exports.MCQMultiItemSchema=Ze,exports.MCQSingleItemSchema=Xe,exports.ManifestAssetsSchema=Pt,exports.ManifestCapabilitiesSchema=Ft,exports.MatchComplexItemSchema=nt,exports.MatchPairsItemSchema=tt,exports.MathInputItemSchema=lt,exports.MatrixItemSchema=ct,exports.MediaObjectSchema=k,exports.MeshHotspotSchema=H,exports.MetaPropertyKeySchema=kt,exports.ModelMimeTypeSchema=Nt,exports.NoteItemSchema=qe,exports.NumericInputItemSchema=ft,exports.NumericRangeSchema=Ke,exports.OFFICIAL_ACTIONS=c,exports.OFFICIAL_FEATURE_KEYS=l,exports.OFFICIAL_ITEM_PROPERTIES=u,exports.OFFICIAL_META_PROPERTIES=d,exports.OQSEActionSchema=wt,exports.OQSEFileSchema=K,exports.OQSEHeaderSchema=$,exports.OQSEItemSchema=G,exports.OQSEManifestSchema=Z,exports.OQSEMetaSchema=L,exports.OQSEProgressSchema=Q,exports.OQSEQuestionDensitySchema=Et,exports.OQSEStudyModeSchema=Tt,exports.OpenEndedItemSchema=dt,exports.OptionalRichContentSchema=E,exports.PedagogySchema=Ie,exports.PersonObjectSchema=j,exports.PinOnImageItemSchema=at,exports.PinOnModelItemSchema=pt,exports.PlainTextSchema=w,exports.PolygonHotspotSchema=V,exports.ProgressMetaSchema=Ht,exports.ProgressRecordSchema=Vt,exports.RectHotspotSchema=z,exports.RichContentSchema=T,exports.RubricCriterionSchema=We,exports.RubricSchema=Ge,exports.SPDXLicenseSchema=b,exports.SelectBlankObjectSchema=Le,exports.ShortAnswerItemSchema=Qe,exports.SliderItemSchema=it,exports.SortItemsItemSchema=rt,exports.SourceMaterialSchema=N,exports.SourceMaterialTypeSchema=M,exports.SourceReferenceSchema=P,exports.StatsObjectSchema=zt,exports.SubtitleTrackSchema=O,exports.TagDefinitionDictionarySchema=Me,exports.TagDefinitionSchema=je,exports.TimelineEventSchema=He,exports.TimelineItemSchema=st,exports.TimelinePrecisionSchema=Ve,exports.TranslationObjectSchema=Ne,exports.TrueFalseItemSchema=Ye,exports.UUIDSchema=v,exports.Vector3Schema=U,exports.VideoMimeTypeSchema=Mt,exports.compareManifestVersions=p,exports.detokenizeOqseTags=Yt,exports.formatOQSEErrors=Ae,exports.generateUUID=ke,exports.isCategorize=se,exports.isChessPuzzle=he,exports.isCoreItem=s,exports.isDiagramLabel=de,exports.isExtendedItem=ge,exports.isFillInBlanks=ee,exports.isFillInSelect=te,exports.isFlashcard=n,exports.isMCQMulti=a,exports.isMCQSingle=i,exports.isMatchComplex=re,exports.isMatchPairs=ne,exports.isMathInput=ue,exports.isMatrix=le,exports.isNote=t,exports.isNumericInput=pe,exports.isOQSEManifest=ve,exports.isOpenEnded=fe,exports.isPinOnImage=oe,exports.isPinOnModel=me,exports.isShortAnswer=o,exports.isSlider=ae,exports.isSortItems=ie,exports.isTimeline=ce,exports.isTrueFalse=r,exports.isValidManifestVersion=f,exports.isValidOQSEManifest=Rt,exports.isValidSemVer=_e,exports.isValidUUID=Oe,exports.isVersionCompatible=ye,exports.prepareRichTextForDisplay=Xt,exports.safeValidateOQSEFile=_t,exports.safeValidateOQSEHeader=Kt,exports.safeValidateOQSEItem=yt,exports.safeValidateOQSEManifest=Lt,exports.safeValidateOQSEProgress=Wt,exports.tokenizeOqseTags=qt,exports.validateJsonDepth=_,exports.validateOQSEFile=gt,exports.validateOQSEHeader=Gt,exports.validateOQSEItem=vt,exports.validateOQSEManifest=It,exports.validateOQSEProgress=Ut,exports.validateTier1Markdown=Jt;
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`zod`);function t(e){return e.type===`note`}function n(e){return e.type===`flashcard`}function r(e){return e.type===`true-false`}function i(e){return e.type===`mcq-single`}function a(e){return e.type===`mcq-multi`}function o(e){return e.type===`short-answer`}function ee(e){return e.type===`fill-in-blanks`}function te(e){return e.type===`fill-in-select`}function ne(e){return e.type===`match-pairs`}function re(e){return e.type===`match-complex`}function ie(e){return e.type===`sort-items`}function ae(e){return e.type===`slider`}function oe(e){return e.type===`pin-on-image`}function se(e){return e.type===`categorize`}function ce(e){return e.type===`timeline`}function le(e){return e.type===`matrix`}function ue(e){return e.type===`math-input`}function de(e){return e.type===`diagram-label`}function fe(e){return e.type===`open-ended`}function pe(e){return e.type===`numeric-input`}function me(e){return e.type===`pin-on-model`}function he(e){return e.type===`chess-puzzle`}function s(e){return[`note`,`flashcard`,`mcq-single`,`short-answer`].includes(e.type)}function ge(e){return!s(e)}var c=[`render`,`edit`,`validate`,`import`,`export`],l=[`markdown`,`math`,`rtl`,`html`,`syntax-highlighting`,`mermaid`,`smiles`,`abc-notation`,`text-to-speech`,`voice-input`,`handwriting-recognition`],u=[`hints`,`explanation`,`incorrectFeedback`,`sources`,`relatedItems`,`dependencyItems`,`timeLimit`,`lang`,`topic`,`pedagogy`],d=[`description`,`thumbnail`,`subject`,`language`,`author`,`contributors`,`license`,`ageRestriction`,`tags`,`tagDefinitions`,`sourceMaterials`,`estimatedTime`,`prerequisites`,`translations`,`relatedSets`];function f(e){return/^\d+\.\d+$/.test(e)}function _e(e){return/^\d+\.\d+\.\d+(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?(\+[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$/.test(e)}function p(e,t){let[n=0,r=0]=e.split(`.`).map(Number),[i=0,a=0]=t.split(`.`).map(Number);return n===i?r-a:n-i}function ve(e){if(typeof e!=`object`||!e)return!1;let t=e,n=t.author;return typeof t.version==`string`&&typeof t.id==`string`&&typeof t.appName==`string`&&t.appName!==``&&(n===void 0||typeof n==`object`&&!!n)&&typeof t.capabilities==`object`&&t.capabilities!==null&&Array.isArray(t.capabilities.actions)}function ye(e,t){return!(!f(e)||t.minOqseVersion&&f(t.minOqseVersion)&&p(e,t.minOqseVersion)<0||t.maxOqseVersion&&f(t.maxOqseVersion)&&p(e,t.maxOqseVersion)>0)}var be=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/i;function xe(e){return typeof e==`string`&&be.test(e)}var m=[];for(let e=0;e<256;++e)m.push((e+256).toString(16).slice(1));function Se(e,t=0){return(m[e[t+0]]+m[e[t+1]]+m[e[t+2]]+m[e[t+3]]+`-`+m[e[t+4]]+m[e[t+5]]+`-`+m[e[t+6]]+m[e[t+7]]+`-`+m[e[t+8]]+m[e[t+9]]+`-`+m[e[t+10]]+m[e[t+11]]+m[e[t+12]]+m[e[t+13]]+m[e[t+14]]+m[e[t+15]]).toLowerCase()}var Ce=new Uint8Array(16);function we(){return crypto.getRandomValues(Ce)}var h={};function Te(e,t,n){let r;if(e)r=De(e.random??e.rng?.()??we(),e.msecs,e.seq,t,n);else{let e=Date.now(),i=we();Ee(h,e,i),r=De(i,h.msecs,h.seq,t,n)}return t??Se(r)}function Ee(e,t,n){return e.msecs??=-1/0,e.seq??=0,t>e.msecs?(e.seq=n[6]<<23|n[7]<<16|n[8]<<8|n[9],e.msecs=t):(e.seq=e.seq+1|0,e.seq===0&&e.msecs++),e}function De(e,t,n,r,i=0){if(e.length<16)throw Error(`Random bytes length must be >= 16`);if(!r)r=new Uint8Array(16),i=0;else if(i<0||i+16>r.length)throw RangeError(`UUID byte range ${i}:${i+15} is out of buffer bounds`);return t??=Date.now(),n??=e[6]*127<<24|e[7]<<16|e[8]<<8|e[9],r[i++]=t/1099511627776&255,r[i++]=t/4294967296&255,r[i++]=t/16777216&255,r[i++]=t/65536&255,r[i++]=t/256&255,r[i++]=t&255,r[i++]=112|n>>>28&15,r[i++]=n>>>20&255,r[i++]=128|n>>>14&63,r[i++]=n>>>6&255,r[i++]=n<<2&255|e[10]&3,r[i++]=e[11],r[i++]=e[12],r[i++]=e[13],r[i++]=e[14],r[i++]=e[15],r}function Oe(e){return xe(e)}function ke(){return Te()}function g(e,t=10,n=0){if(n>t)throw Error(`OQSE Security Error: Maximum nesting depth exceeded limit of ${t} levels.`);if(typeof e==`object`&&e){let r=Array.isArray(e)?e:Object.values(e);for(let e of r)g(e,t,n+1)}}function Ae(e){return e.issues.map(e=>{let t=``;return e.path.forEach((n,r)=>{if(typeof n==`number`)t+=`[${n}]`;else{let i=r===0||typeof e.path[r-1]==`number`;t+=(i?``:`.`)+String(n)}}),t?`${t}: ${e.message}`:e.message})}var _=e.z.string().uuid({message:`Invalid UUID format`}),v=e.z.string().min(2,`Language code must have at least 2 characters`).regex(/^[a-z]{2,3}(-[A-Z][a-z]{3})?(-[A-Z]{2})?$/,`Invalid BCP 47 format (e.g. "cs", "en-US")`),y=e.z.string().min(1,`License identifier must not be empty`),b=e.z.string().regex(/^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}:\d{2}(\.\d{3})?(Z|[+-]\d{2}:\d{2})?)?$/,`Invalid ISO 8601 format (e.g. "2025-11-21T14:30:00Z")`),x=e.z.string().url({message:`Must be a valid absolute URL`}),S=e.z.string().regex(/^[a-z0-9_-]+$/,`Asset key must contain only lowercase letters, numbers, hyphens and underscores`),C=e.z.string().min(1,`Text must not be empty`),w=e.z.string().min(1,`Content must not be empty`),T=e.z.string().max(1e4,`Question must not be longer than 10000 characters`).optional(),E=e.z.string().regex(/^[a-zA-Z0-9_-]{1,64}$/,`Token must be alphanumeric, max 64 chars`),D=e.z.object({lang:v,value:e.z.string().min(1,`Subtitle URI must not be empty`).regex(/\.(vtt|srt)(\?.*)?$/i,`Subtitle URI must end with .vtt or .srt`),label:e.z.string().optional(),kind:e.z.enum([`captions`,`subtitles`,`descriptions`]).optional()}),O=e.z.object({type:e.z.enum([`image`,`audio`,`video`,`model`]),value:e.z.string().min(1,`Media URI must not be empty`),mimeType:e.z.string().optional(),altText:e.z.string().optional(),transcript:w.optional(),caption:w.optional(),width:e.z.number().int().positive().optional(),height:e.z.number().int().positive().optional(),start:e.z.number().nonnegative().optional(),end:e.z.number().positive().optional(),loop:e.z.boolean().optional(),subtitles:e.z.array(D).optional(),license:y.optional(),attribution:e.z.string().optional(),checksums:e.z.record(e.z.string(),e.z.string()).optional()}).refine(e=>e.start!==void 0&&e.end!==void 0?e.start<e.end:!0,{message:`Start time must be less than end time`,path:[`end`]}).refine(e=>!(e.type===`image`&&!e.altText),{message:`Images must have alternative text (altText) defined for accessibility`,path:[`altText`]}),k=e.z.record(S,O),A=e.z.object({name:C,role:e.z.string().optional(),email:e.z.string().email(`Invalid email format`).optional(),url:x.optional()}),j=e.z.enum([`url`,`doi`,`isbn`,`pdf`,`textbook`,`video`,`audio`,`image`,`model`,`other`]),M=e.z.object({id:C,type:j,value:C,title:C,description:e.z.string().optional(),authors:e.z.array(C).optional(),publishedDate:b.optional(),retrievedAt:b.optional(),license:y.optional()}).refine(e=>{if([`url`,`pdf`,`video`,`audio`,`image`].includes(e.type))try{return new URL(e.value),!0}catch{return!1}return!0},{message:`For url, pdf, video, audio and image types, value must be a valid URL`,path:[`value`]}),N=e.z.object({id:C,location:e.z.string().optional(),quote:w.optional()}),P=e.z.object({wikidataId:e.z.string().regex(/^Q\d+$/,`Wikidata ID must have format Q followed by number`).optional(),description:e.z.string().optional()}),je=e.z.record(e.z.string(),P),F=e.z.object({features:e.z.array(e.z.string().refine(e=>l.includes(e)||e.startsWith(`x-`),{message:`Feature must be an official key or have prefix "x-"`})).optional(),latexPackages:e.z.array(e.z.string().min(1,`Package name must not be empty`)).optional(),itemProperties:e.z.array(e.z.string().refine(e=>u.includes(e)||e.startsWith(`x-`),{message:`Item property must be an official key or have prefix "x-"`})).optional(),metaProperties:e.z.array(e.z.string().refine(e=>d.includes(e)||e.startsWith(`x-`),{message:`Meta property must be an official key or have prefix "x-"`})).optional()}),Me=e.z.object({lang:v,id:_,title:C,downloadUrl:x.optional()}),I=e.z.object({id:_,title:C,downloadUrl:x.optional()}),Ne=e.z.enum([`remember`,`understand`,`apply`,`analyze`,`evaluate`,`create`]),Pe=e.z.enum([`low`,`medium`,`high`]),Fe=e.z.object({bloomLevel:Ne.optional(),irtDifficulty:e.z.number().optional(),irtDiscrimination:e.z.number().optional(),irtGuessing:e.z.number().min(0).max(1,`IRT guessing must be between 0 and 1`).optional(),avgTime:e.z.number().positive().optional(),cognitiveLoad:Pe.optional(),partialCredit:e.z.boolean().optional(),penaltyPerWrong:e.z.number().min(0).max(1,`Penalty must be between 0 and 1`).optional()}),L=e.z.object({id:_,language:v,title:C.max(500,`Title must not be longer than 500 characters`),description:w.max(5e3,`Description must not be longer than 5000 characters`).optional(),thumbnail:S.optional(),assets:k.optional(),ageMin:e.z.number().int().nonnegative().optional(),ageMax:e.z.number().int().nonnegative().optional(),subject:e.z.string().optional(),createdAt:b,updatedAt:b,author:A.optional(),contributors:e.z.array(A).optional(),license:y.optional(),licenseUrl:x.optional(),requirements:F.optional(),tags:e.z.array(C).optional(),tagDefinitions:je.optional(),translations:e.z.array(Me).optional(),sourceMaterials:e.z.array(M).optional(),estimatedTime:e.z.number().positive().optional(),prerequisites:e.z.array(I).optional(),relatedSets:e.z.array(I).optional(),customData:e.z.record(e.z.string(),e.z.unknown()).optional(),appSpecific:e.z.record(e.z.string(),e.z.unknown()).optional()}).refine(e=>e.ageMin!==void 0&&e.ageMax!==void 0?e.ageMin<=e.ageMax:!0,{message:`Minimum age (ageMin) must be less than or equal to maximum age (ageMax)`,path:[`ageMax`]}).refine(e=>new Date(e.createdAt)<=new Date(e.updatedAt),{message:`Creation date (createdAt) must be before or equal to update date (updatedAt)`,path:[`updatedAt`]}),R=e.z.object({id:_,type:e.z.string(),assets:k.optional(),lang:v.optional(),tags:e.z.array(C).optional(),topic:C.optional(),difficulty:e.z.number().int().min(1,`Difficulty must be at least 1`).max(5,`Difficulty must be at most 5`).optional(),timeLimit:e.z.number().positive(`Time limit must be a positive number`).optional(),hints:e.z.array(w.max(2e3,`Hint must not be longer than 2000 characters`)).max(20,`Maximum 20 hints per item`).optional(),explanation:w.max(1e4,`Explanation must not be longer than 10000 characters`).optional(),incorrectFeedback:w.optional(),sources:e.z.array(N).optional(),relatedItems:e.z.array(_).optional(),dependencyItems:e.z.array(_).optional(),pedagogy:Fe.optional(),customData:e.z.record(e.z.string(),e.z.unknown()).optional(),appSpecific:e.z.record(e.z.string(),e.z.unknown()).optional()}),Ie=e.z.object({options:e.z.array(w).min(1,`Must have at least 1 option`),correctIndex:e.z.number().int().nonnegative()}).refine(e=>e.correctIndex<e.options.length,{message:`Correct answer index references non-existent option`,path:[`correctIndex`]}),z=e.z.object({type:e.z.literal(`rect`),label:e.z.string().optional(),x:e.z.number().min(0).max(100,`X must be in range 0-100%`),y:e.z.number().min(0).max(100,`Y must be in range 0-100%`),width:e.z.number().min(0).max(100,`Width must be in range 0-100%`),height:e.z.number().min(0).max(100,`Height must be in range 0-100%`)}),B=e.z.object({type:e.z.literal(`circle`),label:e.z.string().optional(),x:e.z.number().min(0).max(100,`X must be in range 0-100%`),y:e.z.number().min(0).max(100,`Y must be in range 0-100%`),radius:e.z.number().min(0).max(100,`Radius must be in range 0-100%`)}),V=e.z.object({type:e.z.literal(`polygon`),label:e.z.string().optional(),points:e.z.array(e.z.object({x:e.z.number().min(0).max(100),y:e.z.number().min(0).max(100)})).min(3,`Polygon must have at least 3 points`)}),H=e.z.object({type:e.z.literal(`mesh`),label:e.z.string().optional(),targetName:C}),Le=e.z.discriminatedUnion(`type`,[z,B,V,H]),Re=e.z.discriminatedUnion(`type`,[z,B,V]),U=e.z.object({x:e.z.number(),y:e.z.number(),z:e.z.number()}),ze=e.z.object({position:U.optional(),target:U.optional()}),Be=e.z.object({id:C,text:w,correctCategoryIndex:e.z.number().int().nonnegative()}),Ve=e.z.enum([`year`,`month`,`day`,`datetime`]),He=e.z.object({id:C,text:w,date:b,precision:Ve.optional()}),Ue=e.z.union([z.extend({correctLabelIndex:e.z.number().int().nonnegative()}),B.extend({correctLabelIndex:e.z.number().int().nonnegative()}),V.extend({correctLabelIndex:e.z.number().int().nonnegative()})]),We=e.z.object({label:C,percentage:e.z.number().min(0,`Percentage must be non-negative`).max(100,`Percentage must not exceed 100`),description:e.z.string().optional()}),Ge=e.z.object({criteria:e.z.array(We).min(1,`Rubric must have at least 1 criterion`)}).refine(e=>e.criteria.reduce((e,t)=>e+t.percentage,0)>0,{message:`Sum of percentages of all criteria must be greater than 0`,path:[`criteria`]}),W=e.z.object({min:e.z.number(),max:e.z.number()}).refine(e=>e.min<=e.max,{message:`Minimum value must be less than or equal to maximum value`,path:[`max`]}),Ke=R.extend({type:e.z.literal(`note`),title:e.z.string().optional(),content:w.max(1e4,`Content must not be longer than 10000 characters`),hiddenContent:w.max(1e4,`Content must not be longer than 10000 characters`).optional()}),qe=R.extend({type:e.z.literal(`flashcard`),front:w.max(1e4,`Front side must not be longer than 10000 characters`),back:w.max(1e4,`Back side must not be longer than 10000 characters`)}),Je=R.extend({type:e.z.literal(`true-false`),question:w.max(1e4,`Question must not be longer than 10000 characters`),answer:e.z.boolean()}),Ye=R.extend({type:e.z.literal(`mcq-single`),question:w.max(1e4,`Question must not be longer than 10000 characters`),options:e.z.array(w.max(2e3,`Option must not be longer than 2000 characters`)).min(2,`Question must have at least 2 options`).max(100,`Maximum 100 options`),correctIndex:e.z.number().int().nonnegative(),shuffleOptions:e.z.boolean().optional(),optionExplanations:e.z.array(e.z.union([w,e.z.null()])).optional()}).refine(e=>e.correctIndex<e.options.length,{message:`Correct answer index references non-existent option`,path:[`correctIndex`]}).refine(e=>e.optionExplanations?e.optionExplanations.length===e.options.length:!0,{message:`Number of option explanations must match number of options`,path:[`optionExplanations`]}).refine(e=>new Set(e.options.map(e=>e.toLowerCase())).size===e.options.length,{message:`Options must not contain duplicates (case-insensitive)`,path:[`options`]}),Xe=R.extend({type:e.z.literal(`mcq-multi`),question:w.max(1e4,`Question must not be longer than 10000 characters`),options:e.z.array(w.max(2e3,`Option must not be longer than 2000 characters`)).min(2,`Question must have at least 2 options`).max(100,`Maximum 100 options`),correctIndices:e.z.array(e.z.number().int().nonnegative()).min(1,`Must have at least 1 correct answer`),minSelections:e.z.number().int().positive().optional(),maxSelections:e.z.number().int().positive().optional(),shuffleOptions:e.z.boolean().optional(),optionExplanations:e.z.array(e.z.union([w,e.z.null()])).optional()}).refine(e=>e.correctIndices.every(t=>t<e.options.length),{message:`Some of correct answer indices reference non-existent option`,path:[`correctIndices`]}).refine(e=>new Set(e.correctIndices).size===e.correctIndices.length,{message:`Correct answer indices contain duplicates`,path:[`correctIndices`]}).refine(e=>e.minSelections&&e.maxSelections?e.minSelections<=e.maxSelections:!0,{message:`Minimum number of selections must be less than or equal to maximum`,path:[`maxSelections`]}).refine(e=>e.maxSelections?e.maxSelections<=e.options.length:!0,{message:`Maximum number of selections must not exceed number of options`,path:[`maxSelections`]}).refine(e=>e.minSelections?e.minSelections<=e.options.length:!0,{message:`minSelections cannot be greater than the number of options`,path:[`minSelections`]}).refine(e=>e.optionExplanations?e.optionExplanations.length===e.options.length:!0,{message:`Number of option explanations must match number of options`,path:[`optionExplanations`]}).refine(e=>new Set(e.options.map(e=>e.toLowerCase())).size===e.options.length,{message:`Options must not contain duplicates (case-insensitive)`,path:[`options`]}),Ze=R.extend({type:e.z.literal(`short-answer`),question:w.max(1e4,`Question must not be longer than 10000 characters`),answers:e.z.array(C).min(1,`Must have at least 1 correct answer`),caseSensitive:e.z.boolean().optional(),trimWhitespace:e.z.boolean().optional(),acceptPartial:e.z.boolean().optional(),ignoreDiacritics:e.z.boolean().optional()}),Qe=R.extend({type:e.z.literal(`fill-in-blanks`),question:T,text:w.max(1e4,`Text must not be longer than 10000 characters`),blanks:e.z.record(E,e.z.array(C).min(1,`Each blank must have at least 1 correct answer`)),caseSensitive:e.z.boolean().optional(),trimWhitespace:e.z.boolean().optional()}).refine(e=>Object.keys(e.blanks).length>0,{message:`Text must contain at least 1 blank to fill`,path:[`blanks`]}).refine(e=>{let t=/<blank:([a-zA-Z0-9_-]{1,64})\s*\/>/g,n=new Set,r;for(;(r=t.exec(e.text))!==null;)r[1]&&n.add(r[1]);let i=new Set(Object.keys(e.blanks));for(let e of n)if(!i.has(e))return!1;for(let e of i)if(!n.has(e))return!1;return!0},{message:`All tokens in text must have definition in blanks and all definitions must be used in text`,path:[`blanks`]}),$e=R.extend({type:e.z.literal(`fill-in-select`),question:T,text:w.max(1e4,`Text must not be longer than 10000 characters`),blanks:e.z.record(E,Ie)}).refine(e=>Object.keys(e.blanks).length>0,{message:`Text must contain at least 1 blank to select`,path:[`blanks`]}).refine(e=>{let t=/<blank:([a-zA-Z0-9_-]{1,64})\s*\/>/g,n=new Set,r;for(;(r=t.exec(e.text))!==null;)r[1]&&n.add(r[1]);let i=new Set(Object.keys(e.blanks));for(let e of n)if(!i.has(e))return!1;for(let e of i)if(!n.has(e))return!1;return!0},{message:`All tokens in text must have definition in blanks and all definitions must be used in text`,path:[`blanks`]}),et=R.extend({type:e.z.literal(`match-pairs`),question:T,prompts:e.z.array(w).min(2,`Must have at least 2 pairs to match`).max(100,`Maximum 100 pairs`),matches:e.z.array(w).min(2,`Must have at least 2 pairs to match`).max(100,`Maximum 100 pairs`)}).refine(e=>e.prompts.length===e.matches.length,{message:`Number of prompts must match number of matches`,path:[`matches`]}),tt=R.extend({type:e.z.literal(`match-complex`),question:T,leftItems:e.z.array(w).min(1,`Must have at least 1 item on left`),rightItems:e.z.array(w).min(1,`Must have at least 1 item on right`),connections:e.z.array(e.z.tuple([e.z.number().int().nonnegative(),e.z.number().int().nonnegative()])).min(1,`Must have at least 1 connection`),minCorrect:e.z.number().int().positive().optional()}).refine(e=>e.connections.every(([t,n])=>t<e.leftItems.length&&n<e.rightItems.length),{message:`Some connection references non-existent item`,path:[`connections`]}).refine(e=>new Set(e.connections.map(e=>`${e[0]}-${e[1]}`)).size===e.connections.length,{message:`Connections contain duplicates`,path:[`connections`]}).refine(e=>e.minCorrect?e.minCorrect<=e.connections.length:!0,{message:`Minimum correct answers must not exceed total number of connections`,path:[`minCorrect`]}),nt=R.extend({type:e.z.literal(`sort-items`),question:w.max(1e4,`Question must not be longer than 10000 characters`),items:e.z.array(w).min(2,`Must have at least 2 items to sort`)}),rt=R.extend({type:e.z.literal(`slider`),question:w.max(1e4,`Question must not be longer than 10000 characters`),min:e.z.number(),max:e.z.number(),step:e.z.number().positive(`Step must be a positive number`),correctAnswer:e.z.number(),tolerance:e.z.number().nonnegative(`Tolerance must be non-negative`),unit:e.z.string().optional()}).refine(e=>e.min<e.max,{message:`Minimum value must be less than maximum value`,path:[`max`]}).refine(e=>e.correctAnswer>=e.min&&e.correctAnswer<=e.max,{message:`Correct answer must be in range min-max`,path:[`correctAnswer`]}).refine(e=>{let t=(e.correctAnswer-e.min)/e.step;return Math.abs(t-Math.round(t))<1e-4},{message:`Correct answer must be reachable by defined step`,path:[`correctAnswer`]}).refine(e=>e.tolerance<=(e.max-e.min)/2,{message:`Tolerance must not be greater than half of value range`,path:[`tolerance`]}),it=R.extend({type:e.z.literal(`pin-on-image`),question:w.max(1e4,`Question must not be longer than 10000 characters`),targetAsset:S,hotspots:e.z.array(Re).min(1,`Must have at least 1 hotspot`),multipleCorrect:e.z.boolean().optional(),minCorrect:e.z.number().int().positive().optional()}).refine(e=>e.minCorrect?e.minCorrect<=e.hotspots.length:!0,{message:`Minimum correct answers must not exceed number of hotspots`,path:[`minCorrect`]}),at=R.extend({type:e.z.literal(`categorize`),question:w.max(1e4,`Question must not be longer than 10000 characters`),categories:e.z.array(C).min(2,`Must have at least 2 categories`),items:e.z.array(Be).min(1,`Must have at least 1 item to categorize`)}).refine(e=>new Set(e.categories.map(e=>e.toLowerCase())).size===e.categories.length,{message:`Categories must not contain duplicates (case-insensitive)`,path:[`categories`]}).refine(e=>e.items.every(t=>t.correctCategoryIndex<e.categories.length),{message:`Some item references non-existent category`,path:[`items`]}),ot=R.extend({type:e.z.literal(`timeline`),question:w.max(1e4,`Question must not be longer than 10000 characters`),events:e.z.array(He).min(2,`Must have at least 2 events`),randomize:e.z.boolean().optional()}),st=R.extend({type:e.z.literal(`matrix`),question:w.max(1e4,`Question must not be longer than 10000 characters`),rows:e.z.array(C).min(1,`Must have at least 1 row`),columns:e.z.array(C).min(1,`Must have at least 1 column`),correctCells:e.z.array(e.z.tuple([e.z.number().int().nonnegative(),e.z.number().int().nonnegative()])).min(1,`Must have at least 1 correct cell`),multiplePerRow:e.z.boolean().optional()}).refine(e=>e.correctCells.every(([t,n])=>t<e.rows.length&&n<e.columns.length),{message:`Some cell coordinates reference non-existent row or column`,path:[`correctCells`]}).refine(e=>new Set(e.correctCells.map(e=>`${e[0]}-${e[1]}`)).size===e.correctCells.length,{message:`Correct cells contain duplicates`,path:[`correctCells`]}).refine(e=>{if(!e.multiplePerRow){let t=new Map;for(let[n]of e.correctCells)t.set(n,(t.get(n)||0)+1);return Array.from(t.values()).every(e=>e<=1)}return!0},{message:`If multiplePerRow is false, each row may have maximum 1 correct cell`,path:[`correctCells`]}),ct=R.extend({type:e.z.literal(`math-input`),question:w.max(1e4,`Question must not be longer than 10000 characters`),correctAnswer:C,alternativeAnswers:e.z.array(C).optional(),tolerance:e.z.number().nonnegative().optional()}),lt=R.extend({type:e.z.literal(`diagram-label`),question:w.max(1e4,`Question must not be longer than 10000 characters`),targetAsset:S,labels:e.z.array(w).min(1,`Must have at least 1 label`),caseSensitive:e.z.boolean().optional(),requireTyping:e.z.boolean().optional(),zones:e.z.array(Ue).min(1,`Must have at least 1 zone`)}).refine(e=>e.zones.every(t=>t.correctLabelIndex<e.labels.length),{message:`Some zone references non-existent label`,path:[`zones`]}),ut=R.extend({type:e.z.literal(`open-ended`),question:w.max(1e4,`Question must not be longer than 10000 characters`),minWords:e.z.number().int().positive().optional(),maxWords:e.z.number().int().positive().optional(),sampleAnswer:w.optional(),rubric:Ge.optional()}).refine(e=>e.minWords&&e.maxWords?e.minWords<=e.maxWords:!0,{message:`Minimum word count must be less than or equal to maximum`,path:[`maxWords`]}),dt=R.extend({type:e.z.literal(`numeric-input`),question:w.max(1e4,`Question must not be longer than 10000 characters`),value:e.z.number(),tolerance:e.z.number().nonnegative().optional(),range:W.optional(),unit:e.z.string().optional()}),ft=R.extend({type:e.z.literal(`pin-on-model`),question:w.max(1e4,`Question must not be longer than 10000 characters`),targetAsset:S,hotspots:e.z.array(H).min(1,`Must have at least 1 hotspot`),multipleCorrect:e.z.boolean().optional(),minCorrect:e.z.number().int().positive().optional(),camera:ze.optional()}).refine(e=>e.minCorrect?e.minCorrect<=e.hotspots.length:!0,{message:`Minimum correct answers must not exceed number of hotspots`,path:[`minCorrect`]}),pt=R.extend({type:e.z.literal(`chess-puzzle`),question:w.max(1e4,`Question must not be longer than 10000 characters`),fen:C,answers:e.z.array(e.z.array(C).min(1,`Move sequence must not be empty`)).min(1,`Must have at least 1 correct move sequence`),elo:e.z.number().int().nonnegative(`ELO must be non-negative integer`).optional()}),G=e.z.discriminatedUnion(`type`,[Ke,qe,Je,Ye,Xe,Ze,Qe,$e,et,tt,nt,rt,it,at,ot,st,ct,lt,ut,dt,ft,pt]),K=e.z.object({$schema:e.z.string().url().optional(),version:e.z.string().regex(/^\d+\.\d+$/,`Version must be in MAJOR.MINOR format (e.g. "0.1")`),meta:L,items:e.z.array(G).max(1e4,`Maximum 10000 items per set`)}).refine(e=>{let t=new Set(e.items.map(e=>e.id));for(let n of e.items){if(n.relatedItems){for(let e of n.relatedItems)if(!t.has(e)||n.id===e)return!1}if(n.dependencyItems){for(let e of n.dependencyItems)if(!t.has(e)||n.id===e)return!1}}return!0},{message:`Some item references non-existent relatedItems, dependencyItems, or references itself`,path:[`items`]}).refine(e=>e.meta.thumbnail&&e.meta.assets?e.meta.thumbnail in e.meta.assets:!0,{message:`Thumbnail references non-existent asset`,path:[`meta`,`thumbnail`]}).refine(e=>{let t=new Set((e.meta.sourceMaterials||[]).map(e=>e.id));for(let n of e.items)if(n.sources){for(let e of n.sources)if(!t.has(e.id))return!1}return!0},{message:`Some item references non-existent source material`,path:[`items`]});function mt(t){let n=t instanceof Error?t.message:`OQSE Security Error: Maximum nesting depth exceeded limit of 10 levels.`;return new e.z.ZodError([{code:e.z.ZodIssueCode.custom,message:n,path:[]}])}function ht(e){return g(e,10),K.parse(e)}function gt(e){try{g(e,10)}catch(e){return{success:!1,error:mt(e)}}let t=K.safeParse(e);return t.success?{success:!0,data:t.data}:{success:!1,error:t.error}}function _t(e){return g(e,10),G.parse(e)}function vt(e){try{g(e,10)}catch(e){return{success:!1,error:mt(e)}}let t=G.safeParse(e);return t.success?{success:!0,data:t.data}:{success:!1,error:t.error}}var q=e.z.string().min(1,`Value must not be empty`).trim(),yt=e.z.string().regex(/^[a-zA-Z]{2,8}(-[a-zA-Z0-9\-]+)*$/,`Must be a valid BCP 47 locale (e.g., "en", "cs")`),J=e.z.string().url(`Must be a valid absolute URL`).refine(e=>e.startsWith(`http://`)||e.startsWith(`https://`),{message:`URL must use http or https scheme`}),bt=e.z.string().regex(/^urn:uuid:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,`Must be a valid URN UUID (urn:uuid:...)`),Y=e.z.string().regex(/^\d+\.\d+$/,`Version must be in MAJOR.MINOR format (e.g. "0.1")`),xt=[`note`,`flashcard`,`true-false`,`mcq-single`,`mcq-multi`,`short-answer`,`fill-in-blanks`,`fill-in-select`,`match-pairs`,`match-complex`,`sort-items`,`slider`,`pin-on-image`,`categorize`,`timeline`,`matrix`,`math-input`,`diagram-label`,`open-ended`,`numeric-input`,`pin-on-model`,`chess-puzzle`],St=q.refine(e=>xt.includes(e)||e.startsWith(`x-`),{message:`Custom types MUST use the "x-" prefix`}),Ct=e.z.string().refine(e=>c.includes(e)||e.startsWith(`x-`),{message:`Action must be one of [render, edit, validate, import, export] or have prefix "x-"`}),wt=e.z.enum([`game`,`fun`,`drill`]),Tt=e.z.enum([`low`,`medium`,`high`]),Et=e.z.string().refine(e=>l.includes(e)||e.startsWith(`x-`),{message:`Feature must be one of official keys or have prefix "x-"`}),Dt=e.z.string().refine(e=>u.includes(e)||e.startsWith(`x-`),{message:`Item property must be an official key or have prefix "x-"`}),Ot=e.z.string().refine(e=>d.includes(e)||e.startsWith(`x-`),{message:`Meta property must be an official key or have prefix "x-"`});function X(t){return e.z.union([e.z.tuple([e.z.literal(`*`)]),e.z.array(t),e.z.null()])}var kt=e.z.string().refine(e=>e.startsWith(`image/`),{message:`Must be a valid image MIME type (image/...)`}),At=e.z.string().refine(e=>e.startsWith(`audio/`),{message:`Must be a valid audio MIME type (audio/...)`}),jt=e.z.string().refine(e=>e.startsWith(`video/`),{message:`Must be a valid video MIME type (video/...)`}),Mt=e.z.string().refine(e=>e.startsWith(`model/`)||e===`application/octet-stream`,{message:`Must be a valid 3D model MIME type (model/... or application/octet-stream)`}),Nt=e.z.object({image:X(kt).optional(),audio:X(At).optional(),video:X(jt).optional(),model:X(Mt).optional()}),Pt=F.extend({actions:e.z.array(Ct).min(1,`Application must support at least one action`),types:X(St).optional(),assets:Nt.optional()}).superRefine((t,n)=>{(t.actions.includes(`render`)||t.actions.includes(`edit`))&&(!Array.isArray(t.types)||t.types.length===0)&&n.addIssue({code:e.z.ZodIssueCode.custom,message:`types array MUST be declared and non-empty when actions include "render" or "edit"`,path:[`types`]})}),Z=e.z.object({$schema:J.optional(),id:e.z.union([J,bt]),appName:q.max(200,`Name must not be longer than 200 characters`),version:Y,pluginVersion:e.z.string().optional(),minOqseVersion:Y.optional(),maxOqseVersion:Y.optional(),capabilities:Pt,author:A.optional(),contributors:e.z.array(A).optional(),license:e.z.string().max(100,`License must not be longer than 100 characters`).optional(),licenseUrl:J.optional(),locales:e.z.array(yt).optional(),description:e.z.string().max(5e3,`Description must not be longer than 5000 characters`).optional(),emoji:e.z.string().optional(),tags:e.z.array(q).optional(),studyMode:wt.optional(),questionDensity:Tt.optional(),appSpecific:e.z.record(e.z.string(),e.z.unknown()).optional()}).refine(e=>{if(!e.minOqseVersion||!e.maxOqseVersion)return!0;let t=e.minOqseVersion.split(`.`),n=e.maxOqseVersion.split(`.`),r=Number(t[0]),i=Number(t[1]),a=Number(n[0]),o=Number(n[1]);return r===a?i<=o:r<a},{message:`minOqseVersion must not be greater than maxOqseVersion`,path:[`minOqseVersion`]});function Ft(e){return Z.parse(e)}function It(e){return Z.safeParse(e)}function Lt(e){return Z.safeParse(e).success}var Rt=e.z.object({attempts:e.z.number().int().nonnegative(),incorrect:e.z.number().int().nonnegative(),streak:e.z.number().int().nonnegative()}).refine(e=>e.incorrect<=e.attempts,{message:`incorrect cannot be higher than attempts`,path:[`incorrect`]}),zt=e.z.object({isCorrect:e.z.boolean(),confidence:e.z.union([e.z.literal(1),e.z.literal(2),e.z.literal(3),e.z.literal(4)]).optional(),answeredAt:b,timeSpent:e.z.number().int().nonnegative().optional(),hintsUsed:e.z.number().int().nonnegative().default(0),isSkipped:e.z.boolean().optional()}),Bt=e.z.object({bucket:e.z.union([e.z.literal(0),e.z.literal(1),e.z.literal(2),e.z.literal(3),e.z.literal(4)]),nextReviewAt:b.optional(),stats:Rt,lastAnswer:zt.optional(),appSpecific:e.z.record(e.z.string(),e.z.unknown()).optional()}),Vt=e.z.object({setId:_,exportedAt:b,algorithm:e.z.string().regex(/^[a-z0-9-]+$/,`algorithm must be lowercase alphanumeric with hyphens format`).optional()}),Q=e.z.object({$schema:e.z.url().optional(),version:e.z.string().regex(/^\d+\.\d+$/,`Version must be in MAJOR.MINOR format`),meta:Vt,records:e.z.record(_,Bt)});function Ht(e){return Q.parse(e)}function Ut(e){return Q.safeParse(e)}var $=e.z.object(L.shape).pick({id:!0,title:!0,language:!0,updatedAt:!0,description:!0,author:!0,subject:!0,tags:!0,createdAt:!0,estimatedTime:!0,requirements:!0}).partial({createdAt:!0}).extend({url:x,$schema:e.z.string().url().optional()});function Wt(e){return $.parse(e)}function Gt(e){return $.safeParse(e)}function Kt(e){let t={};return{text:e.replace(/<(asset|blank):([a-zA-Z0-9_-]+)\s*\/>/gi,(e,n,r)=>{let i=`[[__OQSE_TOKEN_${Math.random().toString(36).substring(2,15)}__]]`;return t[i]={type:n.toLowerCase(),key:r.toLowerCase(),originalTag:e},i}),tokens:t}}function qt(e){let t=e.replace(/`{1,}[^`]*`{1,}/g,``).replace(/~{3,}[\s\S]*?~{3,}/g,``);if(/<[a-zA-Z\/][^>]*>/.test(t))throw Error(`OQSE Security Error: Raw HTML tags are not allowed in Tier 1 (Pure Markdown). If the set requires HTML formatting, it MUST declare the 'html' feature in meta.requirements.`)}function Jt(e,t,n){let r=e;for(let[e,i]of Object.entries(t)){let t=i.originalTag;i.type===`asset`&&n.assetReplacer?t=n.assetReplacer(i.key):i.type===`blank`&&n.blankReplacer&&(t=n.blankReplacer(i.key)),r=r.replace(e,t)}return r}function Yt(e,t,n){if(!e)return``;let r=t?.features?.includes(`html`)??!1,{text:i,tokens:a}=Kt(e);r||qt(i);let o=n.markdownParser(i);if(r){if(!n.htmlSanitizer)throw Error(`OQSE Security Error: Set requires 'html' (Tier 2), but no htmlSanitizer (like DOMPurify) was provided to the options.`);o=n.htmlSanitizer(o)}return Jt(o,a,n)}exports.AbsoluteURLSchema=x,exports.AssetDictionarySchema=k,exports.AssetKeySchema=S,exports.AudioMimeTypeSchema=At,exports.BaseItemSchema=R,exports.BlankTokenSchema=E,exports.BloomLevelSchema=Ne,exports.CameraSetupSchema=ze,exports.CategorizeItemObjectSchema=Be,exports.CategorizeItemSchema=at,exports.ChessPuzzleItemSchema=pt,exports.CircleHotspotSchema=B,exports.CognitiveLoadSchema=Pe,exports.DiagramLabelItemSchema=lt,exports.DiagramZoneSchema=Ue,exports.FeatureFlagSchema=Et,exports.FeatureProfileSchema=F,exports.FillInBlanksItemSchema=Qe,exports.FillInSelectItemSchema=$e,exports.FlashcardItemSchema=qe,exports.Hotspot2DSchema=Re,exports.HotspotObjectSchema=Le,exports.ISO8601DateTimeSchema=b,exports.ImageMimeTypeSchema=kt,exports.ItemPropertyKeySchema=Dt,exports.LanguageCodeSchema=v,exports.LastAnswerObjectSchema=zt,exports.LinkedSetObjectSchema=I,exports.MCQMultiItemSchema=Xe,exports.MCQSingleItemSchema=Ye,exports.ManifestAssetsSchema=Nt,exports.ManifestCapabilitiesSchema=Pt,exports.MatchComplexItemSchema=tt,exports.MatchPairsItemSchema=et,exports.MathInputItemSchema=ct,exports.MatrixItemSchema=st,exports.MediaObjectSchema=O,exports.MeshHotspotSchema=H,exports.MetaPropertyKeySchema=Ot,exports.ModelMimeTypeSchema=Mt,exports.NoteItemSchema=Ke,exports.NumericInputItemSchema=dt,exports.NumericRangeSchema=W,exports.OFFICIAL_ACTIONS=c,exports.OFFICIAL_FEATURE_KEYS=l,exports.OFFICIAL_ITEM_PROPERTIES=u,exports.OFFICIAL_META_PROPERTIES=d,exports.OQSEActionSchema=Ct,exports.OQSEFileSchema=K,exports.OQSEHeaderSchema=$,exports.OQSEItemSchema=G,exports.OQSEManifestSchema=Z,exports.OQSEMetaSchema=L,exports.OQSEProgressSchema=Q,exports.OQSEQuestionDensitySchema=Tt,exports.OQSEStudyModeSchema=wt,exports.OpenEndedItemSchema=ut,exports.OptionalRichContentSchema=T,exports.PedagogySchema=Fe,exports.PersonObjectSchema=A,exports.PinOnImageItemSchema=it,exports.PinOnModelItemSchema=ft,exports.PlainTextSchema=C,exports.PolygonHotspotSchema=V,exports.ProgressMetaSchema=Vt,exports.ProgressRecordSchema=Bt,exports.RectHotspotSchema=z,exports.RichContentSchema=w,exports.RubricCriterionSchema=We,exports.RubricSchema=Ge,exports.SPDXLicenseSchema=y,exports.SelectBlankObjectSchema=Ie,exports.ShortAnswerItemSchema=Ze,exports.SliderItemSchema=rt,exports.SortItemsItemSchema=nt,exports.SourceMaterialSchema=M,exports.SourceMaterialTypeSchema=j,exports.SourceReferenceSchema=N,exports.StatsObjectSchema=Rt,exports.SubtitleTrackSchema=D,exports.TagDefinitionDictionarySchema=je,exports.TagDefinitionSchema=P,exports.TimelineEventSchema=He,exports.TimelineItemSchema=ot,exports.TimelinePrecisionSchema=Ve,exports.TranslationObjectSchema=Me,exports.TrueFalseItemSchema=Je,exports.UUIDSchema=_,exports.Vector3Schema=U,exports.VideoMimeTypeSchema=jt,exports.compareManifestVersions=p,exports.detokenizeOqseTags=Jt,exports.formatOQSEErrors=Ae,exports.generateUUID=ke,exports.isCategorize=se,exports.isChessPuzzle=he,exports.isCoreItem=s,exports.isDiagramLabel=de,exports.isExtendedItem=ge,exports.isFillInBlanks=ee,exports.isFillInSelect=te,exports.isFlashcard=n,exports.isMCQMulti=a,exports.isMCQSingle=i,exports.isMatchComplex=re,exports.isMatchPairs=ne,exports.isMathInput=ue,exports.isMatrix=le,exports.isNote=t,exports.isNumericInput=pe,exports.isOQSEManifest=ve,exports.isOpenEnded=fe,exports.isPinOnImage=oe,exports.isPinOnModel=me,exports.isShortAnswer=o,exports.isSlider=ae,exports.isSortItems=ie,exports.isTimeline=ce,exports.isTrueFalse=r,exports.isValidManifestVersion=f,exports.isValidOQSEManifest=Lt,exports.isValidSemVer=_e,exports.isValidUUID=Oe,exports.isVersionCompatible=ye,exports.prepareRichTextForDisplay=Yt,exports.safeValidateOQSEFile=gt,exports.safeValidateOQSEHeader=Gt,exports.safeValidateOQSEItem=vt,exports.safeValidateOQSEManifest=It,exports.safeValidateOQSEProgress=Ut,exports.tokenizeOqseTags=Kt,exports.validateJsonDepth=g,exports.validateOQSEFile=ht,exports.validateOQSEHeader=Wt,exports.validateOQSEItem=_t,exports.validateOQSEManifest=Ft,exports.validateOQSEProgress=Ht,exports.validateTier1Markdown=qt;
|
package/dist/index.js
CHANGED
|
@@ -160,23 +160,19 @@ function Se(e, t = 0) {
|
|
|
160
160
|
}
|
|
161
161
|
//#endregion
|
|
162
162
|
//#region node_modules/uuid/dist/rng.js
|
|
163
|
-
var
|
|
163
|
+
var Ce = new Uint8Array(16);
|
|
164
164
|
function we() {
|
|
165
|
-
|
|
166
|
-
if (typeof crypto > "u" || !crypto.getRandomValues) throw Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");
|
|
167
|
-
h = crypto.getRandomValues.bind(crypto);
|
|
168
|
-
}
|
|
169
|
-
return h(Ce);
|
|
165
|
+
return crypto.getRandomValues(Ce);
|
|
170
166
|
}
|
|
171
167
|
//#endregion
|
|
172
168
|
//#region node_modules/uuid/dist/v7.js
|
|
173
|
-
var
|
|
169
|
+
var h = {};
|
|
174
170
|
function Te(e, t, n) {
|
|
175
171
|
let r;
|
|
176
172
|
if (e) r = De(e.random ?? e.rng?.() ?? we(), e.msecs, e.seq, t, n);
|
|
177
173
|
else {
|
|
178
174
|
let e = Date.now(), i = we();
|
|
179
|
-
Ee(
|
|
175
|
+
Ee(h, e, i), r = De(i, h.msecs, h.seq, t, n);
|
|
180
176
|
}
|
|
181
177
|
return t ?? Se(r);
|
|
182
178
|
}
|
|
@@ -197,11 +193,11 @@ function Oe(e) {
|
|
|
197
193
|
function ke() {
|
|
198
194
|
return Te();
|
|
199
195
|
}
|
|
200
|
-
function
|
|
196
|
+
function g(e, t = 10, n = 0) {
|
|
201
197
|
if (n > t) throw Error(`OQSE Security Error: Maximum nesting depth exceeded limit of ${t} levels.`);
|
|
202
198
|
if (typeof e == "object" && e) {
|
|
203
199
|
let r = Array.isArray(e) ? e : Object.values(e);
|
|
204
|
-
for (let e of r)
|
|
200
|
+
for (let e of r) g(e, t, n + 1);
|
|
205
201
|
}
|
|
206
202
|
}
|
|
207
203
|
function Ae(e) {
|
|
@@ -218,8 +214,8 @@ function Ae(e) {
|
|
|
218
214
|
}
|
|
219
215
|
//#endregion
|
|
220
216
|
//#region src/oqseValidation.ts
|
|
221
|
-
var
|
|
222
|
-
lang:
|
|
217
|
+
var _ = e.string().uuid({ message: "Invalid UUID format" }), v = e.string().min(2, "Language code must have at least 2 characters").regex(/^[a-z]{2,3}(-[A-Z][a-z]{3})?(-[A-Z]{2})?$/, "Invalid BCP 47 format (e.g. \"cs\", \"en-US\")"), y = e.string().min(1, "License identifier must not be empty"), b = e.string().regex(/^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}:\d{2}(\.\d{3})?(Z|[+-]\d{2}:\d{2})?)?$/, "Invalid ISO 8601 format (e.g. \"2025-11-21T14:30:00Z\")"), x = e.string().url({ message: "Must be a valid absolute URL" }), S = e.string().regex(/^[a-z0-9_-]+$/, "Asset key must contain only lowercase letters, numbers, hyphens and underscores"), C = e.string().min(1, "Text must not be empty"), w = e.string().min(1, "Content must not be empty"), T = e.string().max(1e4, "Question must not be longer than 10000 characters").optional(), E = e.string().regex(/^[a-zA-Z0-9_-]{1,64}$/, "Token must be alphanumeric, max 64 chars"), D = e.object({
|
|
218
|
+
lang: v,
|
|
223
219
|
value: e.string().min(1, "Subtitle URI must not be empty").regex(/\.(vtt|srt)(\?.*)?$/i, "Subtitle URI must end with .vtt or .srt"),
|
|
224
220
|
label: e.string().optional(),
|
|
225
221
|
kind: e.enum([
|
|
@@ -227,7 +223,7 @@ var v = e.string().uuid({ message: "Invalid UUID format" }), y = e.string().min(
|
|
|
227
223
|
"subtitles",
|
|
228
224
|
"descriptions"
|
|
229
225
|
]).optional()
|
|
230
|
-
}),
|
|
226
|
+
}), O = e.object({
|
|
231
227
|
type: e.enum([
|
|
232
228
|
"image",
|
|
233
229
|
"audio",
|
|
@@ -237,15 +233,15 @@ var v = e.string().uuid({ message: "Invalid UUID format" }), y = e.string().min(
|
|
|
237
233
|
value: e.string().min(1, "Media URI must not be empty"),
|
|
238
234
|
mimeType: e.string().optional(),
|
|
239
235
|
altText: e.string().optional(),
|
|
240
|
-
transcript:
|
|
241
|
-
caption:
|
|
236
|
+
transcript: w.optional(),
|
|
237
|
+
caption: w.optional(),
|
|
242
238
|
width: e.number().int().positive().optional(),
|
|
243
239
|
height: e.number().int().positive().optional(),
|
|
244
240
|
start: e.number().nonnegative().optional(),
|
|
245
241
|
end: e.number().positive().optional(),
|
|
246
242
|
loop: e.boolean().optional(),
|
|
247
|
-
subtitles: e.array(
|
|
248
|
-
license:
|
|
243
|
+
subtitles: e.array(D).optional(),
|
|
244
|
+
license: y.optional(),
|
|
249
245
|
attribution: e.string().optional(),
|
|
250
246
|
checksums: e.record(e.string(), e.string()).optional()
|
|
251
247
|
}).refine((e) => e.start !== void 0 && e.end !== void 0 ? e.start < e.end : !0, {
|
|
@@ -254,12 +250,12 @@ var v = e.string().uuid({ message: "Invalid UUID format" }), y = e.string().min(
|
|
|
254
250
|
}).refine((e) => !(e.type === "image" && !e.altText), {
|
|
255
251
|
message: "Images must have alternative text (altText) defined for accessibility",
|
|
256
252
|
path: ["altText"]
|
|
257
|
-
}),
|
|
258
|
-
name:
|
|
253
|
+
}), k = e.record(S, O), A = e.object({
|
|
254
|
+
name: C,
|
|
259
255
|
role: e.string().optional(),
|
|
260
256
|
email: e.string().email("Invalid email format").optional(),
|
|
261
|
-
url:
|
|
262
|
-
}),
|
|
257
|
+
url: x.optional()
|
|
258
|
+
}), j = e.enum([
|
|
263
259
|
"url",
|
|
264
260
|
"doi",
|
|
265
261
|
"isbn",
|
|
@@ -270,16 +266,16 @@ var v = e.string().uuid({ message: "Invalid UUID format" }), y = e.string().min(
|
|
|
270
266
|
"image",
|
|
271
267
|
"model",
|
|
272
268
|
"other"
|
|
273
|
-
]),
|
|
274
|
-
id:
|
|
275
|
-
type:
|
|
276
|
-
value:
|
|
277
|
-
title:
|
|
269
|
+
]), M = e.object({
|
|
270
|
+
id: C,
|
|
271
|
+
type: j,
|
|
272
|
+
value: C,
|
|
273
|
+
title: C,
|
|
278
274
|
description: e.string().optional(),
|
|
279
|
-
authors: e.array(
|
|
280
|
-
publishedDate:
|
|
281
|
-
retrievedAt:
|
|
282
|
-
license:
|
|
275
|
+
authors: e.array(C).optional(),
|
|
276
|
+
publishedDate: b.optional(),
|
|
277
|
+
retrievedAt: b.optional(),
|
|
278
|
+
license: y.optional()
|
|
283
279
|
}).refine((e) => {
|
|
284
280
|
if ([
|
|
285
281
|
"url",
|
|
@@ -296,68 +292,68 @@ var v = e.string().uuid({ message: "Invalid UUID format" }), y = e.string().min(
|
|
|
296
292
|
}, {
|
|
297
293
|
message: "For url, pdf, video, audio and image types, value must be a valid URL",
|
|
298
294
|
path: ["value"]
|
|
299
|
-
}),
|
|
300
|
-
id:
|
|
295
|
+
}), N = e.object({
|
|
296
|
+
id: C,
|
|
301
297
|
location: e.string().optional(),
|
|
302
|
-
quote:
|
|
303
|
-
}),
|
|
298
|
+
quote: w.optional()
|
|
299
|
+
}), P = e.object({
|
|
304
300
|
wikidataId: e.string().regex(/^Q\d+$/, "Wikidata ID must have format Q followed by number").optional(),
|
|
305
301
|
description: e.string().optional()
|
|
306
|
-
}),
|
|
302
|
+
}), je = e.record(e.string(), P), F = e.object({
|
|
307
303
|
features: e.array(e.string().refine((e) => l.includes(e) || e.startsWith("x-"), { message: "Feature must be an official key or have prefix \"x-\"" })).optional(),
|
|
308
304
|
latexPackages: e.array(e.string().min(1, "Package name must not be empty")).optional(),
|
|
309
305
|
itemProperties: e.array(e.string().refine((e) => u.includes(e) || e.startsWith("x-"), { message: "Item property must be an official key or have prefix \"x-\"" })).optional(),
|
|
310
306
|
metaProperties: e.array(e.string().refine((e) => d.includes(e) || e.startsWith("x-"), { message: "Meta property must be an official key or have prefix \"x-\"" })).optional()
|
|
311
|
-
}),
|
|
312
|
-
lang:
|
|
313
|
-
id:
|
|
314
|
-
title:
|
|
315
|
-
downloadUrl:
|
|
307
|
+
}), Me = e.object({
|
|
308
|
+
lang: v,
|
|
309
|
+
id: _,
|
|
310
|
+
title: C,
|
|
311
|
+
downloadUrl: x.optional()
|
|
316
312
|
}), I = e.object({
|
|
317
|
-
id:
|
|
318
|
-
title:
|
|
319
|
-
downloadUrl:
|
|
320
|
-
}),
|
|
313
|
+
id: _,
|
|
314
|
+
title: C,
|
|
315
|
+
downloadUrl: x.optional()
|
|
316
|
+
}), Ne = e.enum([
|
|
321
317
|
"remember",
|
|
322
318
|
"understand",
|
|
323
319
|
"apply",
|
|
324
320
|
"analyze",
|
|
325
321
|
"evaluate",
|
|
326
322
|
"create"
|
|
327
|
-
]),
|
|
323
|
+
]), Pe = e.enum([
|
|
328
324
|
"low",
|
|
329
325
|
"medium",
|
|
330
326
|
"high"
|
|
331
|
-
]),
|
|
332
|
-
bloomLevel:
|
|
327
|
+
]), Fe = e.object({
|
|
328
|
+
bloomLevel: Ne.optional(),
|
|
333
329
|
irtDifficulty: e.number().optional(),
|
|
334
330
|
irtDiscrimination: e.number().optional(),
|
|
335
331
|
irtGuessing: e.number().min(0).max(1, "IRT guessing must be between 0 and 1").optional(),
|
|
336
332
|
avgTime: e.number().positive().optional(),
|
|
337
|
-
cognitiveLoad:
|
|
333
|
+
cognitiveLoad: Pe.optional(),
|
|
338
334
|
partialCredit: e.boolean().optional(),
|
|
339
335
|
penaltyPerWrong: e.number().min(0).max(1, "Penalty must be between 0 and 1").optional()
|
|
340
336
|
}), L = e.object({
|
|
341
|
-
id:
|
|
342
|
-
language:
|
|
343
|
-
title:
|
|
344
|
-
description:
|
|
345
|
-
thumbnail:
|
|
346
|
-
assets:
|
|
337
|
+
id: _,
|
|
338
|
+
language: v,
|
|
339
|
+
title: C.max(500, "Title must not be longer than 500 characters"),
|
|
340
|
+
description: w.max(5e3, "Description must not be longer than 5000 characters").optional(),
|
|
341
|
+
thumbnail: S.optional(),
|
|
342
|
+
assets: k.optional(),
|
|
347
343
|
ageMin: e.number().int().nonnegative().optional(),
|
|
348
344
|
ageMax: e.number().int().nonnegative().optional(),
|
|
349
345
|
subject: e.string().optional(),
|
|
350
|
-
createdAt:
|
|
351
|
-
updatedAt:
|
|
352
|
-
author:
|
|
353
|
-
contributors: e.array(
|
|
354
|
-
license:
|
|
355
|
-
licenseUrl:
|
|
346
|
+
createdAt: b,
|
|
347
|
+
updatedAt: b,
|
|
348
|
+
author: A.optional(),
|
|
349
|
+
contributors: e.array(A).optional(),
|
|
350
|
+
license: y.optional(),
|
|
351
|
+
licenseUrl: x.optional(),
|
|
356
352
|
requirements: F.optional(),
|
|
357
|
-
tags: e.array(
|
|
358
|
-
tagDefinitions:
|
|
359
|
-
translations: e.array(
|
|
360
|
-
sourceMaterials: e.array(
|
|
353
|
+
tags: e.array(C).optional(),
|
|
354
|
+
tagDefinitions: je.optional(),
|
|
355
|
+
translations: e.array(Me).optional(),
|
|
356
|
+
sourceMaterials: e.array(M).optional(),
|
|
361
357
|
estimatedTime: e.number().positive().optional(),
|
|
362
358
|
prerequisites: e.array(I).optional(),
|
|
363
359
|
relatedSets: e.array(I).optional(),
|
|
@@ -370,25 +366,25 @@ var v = e.string().uuid({ message: "Invalid UUID format" }), y = e.string().min(
|
|
|
370
366
|
message: "Creation date (createdAt) must be before or equal to update date (updatedAt)",
|
|
371
367
|
path: ["updatedAt"]
|
|
372
368
|
}), R = e.object({
|
|
373
|
-
id:
|
|
369
|
+
id: _,
|
|
374
370
|
type: e.string(),
|
|
375
|
-
assets:
|
|
376
|
-
lang:
|
|
377
|
-
tags: e.array(
|
|
378
|
-
topic:
|
|
371
|
+
assets: k.optional(),
|
|
372
|
+
lang: v.optional(),
|
|
373
|
+
tags: e.array(C).optional(),
|
|
374
|
+
topic: C.optional(),
|
|
379
375
|
difficulty: e.number().int().min(1, "Difficulty must be at least 1").max(5, "Difficulty must be at most 5").optional(),
|
|
380
376
|
timeLimit: e.number().positive("Time limit must be a positive number").optional(),
|
|
381
|
-
hints: e.array(
|
|
382
|
-
explanation:
|
|
383
|
-
incorrectFeedback:
|
|
384
|
-
sources: e.array(
|
|
385
|
-
relatedItems: e.array(
|
|
386
|
-
dependencyItems: e.array(
|
|
387
|
-
pedagogy:
|
|
377
|
+
hints: e.array(w.max(2e3, "Hint must not be longer than 2000 characters")).max(20, "Maximum 20 hints per item").optional(),
|
|
378
|
+
explanation: w.max(1e4, "Explanation must not be longer than 10000 characters").optional(),
|
|
379
|
+
incorrectFeedback: w.optional(),
|
|
380
|
+
sources: e.array(N).optional(),
|
|
381
|
+
relatedItems: e.array(_).optional(),
|
|
382
|
+
dependencyItems: e.array(_).optional(),
|
|
383
|
+
pedagogy: Fe.optional(),
|
|
388
384
|
customData: e.record(e.string(), e.unknown()).optional(),
|
|
389
385
|
appSpecific: e.record(e.string(), e.unknown()).optional()
|
|
390
|
-
}),
|
|
391
|
-
options: e.array(
|
|
386
|
+
}), Ie = e.object({
|
|
387
|
+
options: e.array(w).min(1, "Must have at least 1 option"),
|
|
392
388
|
correctIndex: e.number().int().nonnegative()
|
|
393
389
|
}).refine((e) => e.correctIndex < e.options.length, {
|
|
394
390
|
message: "Correct answer index references non-existent option",
|
|
@@ -416,13 +412,13 @@ var v = e.string().uuid({ message: "Invalid UUID format" }), y = e.string().min(
|
|
|
416
412
|
}), H = e.object({
|
|
417
413
|
type: e.literal("mesh"),
|
|
418
414
|
label: e.string().optional(),
|
|
419
|
-
targetName:
|
|
420
|
-
}),
|
|
415
|
+
targetName: C
|
|
416
|
+
}), Le = e.discriminatedUnion("type", [
|
|
421
417
|
z,
|
|
422
418
|
B,
|
|
423
419
|
V,
|
|
424
420
|
H
|
|
425
|
-
]),
|
|
421
|
+
]), Re = e.discriminatedUnion("type", [
|
|
426
422
|
z,
|
|
427
423
|
B,
|
|
428
424
|
V
|
|
@@ -430,12 +426,12 @@ var v = e.string().uuid({ message: "Invalid UUID format" }), y = e.string().min(
|
|
|
430
426
|
x: e.number(),
|
|
431
427
|
y: e.number(),
|
|
432
428
|
z: e.number()
|
|
433
|
-
}),
|
|
429
|
+
}), ze = e.object({
|
|
434
430
|
position: U.optional(),
|
|
435
431
|
target: U.optional()
|
|
436
432
|
}), Be = e.object({
|
|
437
|
-
id:
|
|
438
|
-
text:
|
|
433
|
+
id: C,
|
|
434
|
+
text: w,
|
|
439
435
|
correctCategoryIndex: e.number().int().nonnegative()
|
|
440
436
|
}), Ve = e.enum([
|
|
441
437
|
"year",
|
|
@@ -443,47 +439,47 @@ var v = e.string().uuid({ message: "Invalid UUID format" }), y = e.string().min(
|
|
|
443
439
|
"day",
|
|
444
440
|
"datetime"
|
|
445
441
|
]), He = e.object({
|
|
446
|
-
id:
|
|
447
|
-
text:
|
|
448
|
-
date:
|
|
442
|
+
id: C,
|
|
443
|
+
text: w,
|
|
444
|
+
date: b,
|
|
449
445
|
precision: Ve.optional()
|
|
450
446
|
}), Ue = e.union([
|
|
451
447
|
z.extend({ correctLabelIndex: e.number().int().nonnegative() }),
|
|
452
448
|
B.extend({ correctLabelIndex: e.number().int().nonnegative() }),
|
|
453
449
|
V.extend({ correctLabelIndex: e.number().int().nonnegative() })
|
|
454
450
|
]), We = e.object({
|
|
455
|
-
label:
|
|
451
|
+
label: C,
|
|
456
452
|
percentage: e.number().min(0, "Percentage must be non-negative").max(100, "Percentage must not exceed 100"),
|
|
457
453
|
description: e.string().optional()
|
|
458
454
|
}), Ge = e.object({ criteria: e.array(We).min(1, "Rubric must have at least 1 criterion") }).refine((e) => e.criteria.reduce((e, t) => e + t.percentage, 0) > 0, {
|
|
459
455
|
message: "Sum of percentages of all criteria must be greater than 0",
|
|
460
456
|
path: ["criteria"]
|
|
461
|
-
}),
|
|
457
|
+
}), W = e.object({
|
|
462
458
|
min: e.number(),
|
|
463
459
|
max: e.number()
|
|
464
460
|
}).refine((e) => e.min <= e.max, {
|
|
465
461
|
message: "Minimum value must be less than or equal to maximum value",
|
|
466
462
|
path: ["max"]
|
|
467
|
-
}),
|
|
463
|
+
}), Ke = R.extend({
|
|
468
464
|
type: e.literal("note"),
|
|
469
465
|
title: e.string().optional(),
|
|
470
|
-
content:
|
|
471
|
-
hiddenContent:
|
|
472
|
-
}),
|
|
466
|
+
content: w.max(1e4, "Content must not be longer than 10000 characters"),
|
|
467
|
+
hiddenContent: w.max(1e4, "Content must not be longer than 10000 characters").optional()
|
|
468
|
+
}), qe = R.extend({
|
|
473
469
|
type: e.literal("flashcard"),
|
|
474
|
-
front:
|
|
475
|
-
back:
|
|
476
|
-
}),
|
|
470
|
+
front: w.max(1e4, "Front side must not be longer than 10000 characters"),
|
|
471
|
+
back: w.max(1e4, "Back side must not be longer than 10000 characters")
|
|
472
|
+
}), Je = R.extend({
|
|
477
473
|
type: e.literal("true-false"),
|
|
478
|
-
question:
|
|
474
|
+
question: w.max(1e4, "Question must not be longer than 10000 characters"),
|
|
479
475
|
answer: e.boolean()
|
|
480
|
-
}),
|
|
476
|
+
}), Ye = R.extend({
|
|
481
477
|
type: e.literal("mcq-single"),
|
|
482
|
-
question:
|
|
483
|
-
options: e.array(
|
|
478
|
+
question: w.max(1e4, "Question must not be longer than 10000 characters"),
|
|
479
|
+
options: e.array(w.max(2e3, "Option must not be longer than 2000 characters")).min(2, "Question must have at least 2 options").max(100, "Maximum 100 options"),
|
|
484
480
|
correctIndex: e.number().int().nonnegative(),
|
|
485
481
|
shuffleOptions: e.boolean().optional(),
|
|
486
|
-
optionExplanations: e.array(e.union([
|
|
482
|
+
optionExplanations: e.array(e.union([w, e.null()])).optional()
|
|
487
483
|
}).refine((e) => e.correctIndex < e.options.length, {
|
|
488
484
|
message: "Correct answer index references non-existent option",
|
|
489
485
|
path: ["correctIndex"]
|
|
@@ -493,15 +489,15 @@ var v = e.string().uuid({ message: "Invalid UUID format" }), y = e.string().min(
|
|
|
493
489
|
}).refine((e) => new Set(e.options.map((e) => e.toLowerCase())).size === e.options.length, {
|
|
494
490
|
message: "Options must not contain duplicates (case-insensitive)",
|
|
495
491
|
path: ["options"]
|
|
496
|
-
}),
|
|
492
|
+
}), Xe = R.extend({
|
|
497
493
|
type: e.literal("mcq-multi"),
|
|
498
|
-
question:
|
|
499
|
-
options: e.array(
|
|
494
|
+
question: w.max(1e4, "Question must not be longer than 10000 characters"),
|
|
495
|
+
options: e.array(w.max(2e3, "Option must not be longer than 2000 characters")).min(2, "Question must have at least 2 options").max(100, "Maximum 100 options"),
|
|
500
496
|
correctIndices: e.array(e.number().int().nonnegative()).min(1, "Must have at least 1 correct answer"),
|
|
501
497
|
minSelections: e.number().int().positive().optional(),
|
|
502
498
|
maxSelections: e.number().int().positive().optional(),
|
|
503
499
|
shuffleOptions: e.boolean().optional(),
|
|
504
|
-
optionExplanations: e.array(e.union([
|
|
500
|
+
optionExplanations: e.array(e.union([w, e.null()])).optional()
|
|
505
501
|
}).refine((e) => e.correctIndices.every((t) => t < e.options.length), {
|
|
506
502
|
message: "Some of correct answer indices reference non-existent option",
|
|
507
503
|
path: ["correctIndices"]
|
|
@@ -523,19 +519,19 @@ var v = e.string().uuid({ message: "Invalid UUID format" }), y = e.string().min(
|
|
|
523
519
|
}).refine((e) => new Set(e.options.map((e) => e.toLowerCase())).size === e.options.length, {
|
|
524
520
|
message: "Options must not contain duplicates (case-insensitive)",
|
|
525
521
|
path: ["options"]
|
|
526
|
-
}),
|
|
522
|
+
}), Ze = R.extend({
|
|
527
523
|
type: e.literal("short-answer"),
|
|
528
|
-
question:
|
|
529
|
-
answers: e.array(
|
|
524
|
+
question: w.max(1e4, "Question must not be longer than 10000 characters"),
|
|
525
|
+
answers: e.array(C).min(1, "Must have at least 1 correct answer"),
|
|
530
526
|
caseSensitive: e.boolean().optional(),
|
|
531
527
|
trimWhitespace: e.boolean().optional(),
|
|
532
528
|
acceptPartial: e.boolean().optional(),
|
|
533
529
|
ignoreDiacritics: e.boolean().optional()
|
|
534
|
-
}),
|
|
530
|
+
}), Qe = R.extend({
|
|
535
531
|
type: e.literal("fill-in-blanks"),
|
|
536
|
-
question:
|
|
537
|
-
text:
|
|
538
|
-
blanks: e.record(
|
|
532
|
+
question: T,
|
|
533
|
+
text: w.max(1e4, "Text must not be longer than 10000 characters"),
|
|
534
|
+
blanks: e.record(E, e.array(C).min(1, "Each blank must have at least 1 correct answer")),
|
|
539
535
|
caseSensitive: e.boolean().optional(),
|
|
540
536
|
trimWhitespace: e.boolean().optional()
|
|
541
537
|
}).refine((e) => Object.keys(e.blanks).length > 0, {
|
|
@@ -551,11 +547,11 @@ var v = e.string().uuid({ message: "Invalid UUID format" }), y = e.string().min(
|
|
|
551
547
|
}, {
|
|
552
548
|
message: "All tokens in text must have definition in blanks and all definitions must be used in text",
|
|
553
549
|
path: ["blanks"]
|
|
554
|
-
}),
|
|
550
|
+
}), $e = R.extend({
|
|
555
551
|
type: e.literal("fill-in-select"),
|
|
556
|
-
question:
|
|
557
|
-
text:
|
|
558
|
-
blanks: e.record(
|
|
552
|
+
question: T,
|
|
553
|
+
text: w.max(1e4, "Text must not be longer than 10000 characters"),
|
|
554
|
+
blanks: e.record(E, Ie)
|
|
559
555
|
}).refine((e) => Object.keys(e.blanks).length > 0, {
|
|
560
556
|
message: "Text must contain at least 1 blank to select",
|
|
561
557
|
path: ["blanks"]
|
|
@@ -569,19 +565,19 @@ var v = e.string().uuid({ message: "Invalid UUID format" }), y = e.string().min(
|
|
|
569
565
|
}, {
|
|
570
566
|
message: "All tokens in text must have definition in blanks and all definitions must be used in text",
|
|
571
567
|
path: ["blanks"]
|
|
572
|
-
}),
|
|
568
|
+
}), et = R.extend({
|
|
573
569
|
type: e.literal("match-pairs"),
|
|
574
|
-
question:
|
|
575
|
-
prompts: e.array(
|
|
576
|
-
matches: e.array(
|
|
570
|
+
question: T,
|
|
571
|
+
prompts: e.array(w).min(2, "Must have at least 2 pairs to match").max(100, "Maximum 100 pairs"),
|
|
572
|
+
matches: e.array(w).min(2, "Must have at least 2 pairs to match").max(100, "Maximum 100 pairs")
|
|
577
573
|
}).refine((e) => e.prompts.length === e.matches.length, {
|
|
578
574
|
message: "Number of prompts must match number of matches",
|
|
579
575
|
path: ["matches"]
|
|
580
|
-
}),
|
|
576
|
+
}), tt = R.extend({
|
|
581
577
|
type: e.literal("match-complex"),
|
|
582
|
-
question:
|
|
583
|
-
leftItems: e.array(
|
|
584
|
-
rightItems: e.array(
|
|
578
|
+
question: T,
|
|
579
|
+
leftItems: e.array(w).min(1, "Must have at least 1 item on left"),
|
|
580
|
+
rightItems: e.array(w).min(1, "Must have at least 1 item on right"),
|
|
585
581
|
connections: e.array(e.tuple([e.number().int().nonnegative(), e.number().int().nonnegative()])).min(1, "Must have at least 1 connection"),
|
|
586
582
|
minCorrect: e.number().int().positive().optional()
|
|
587
583
|
}).refine((e) => e.connections.every(([t, n]) => t < e.leftItems.length && n < e.rightItems.length), {
|
|
@@ -593,13 +589,13 @@ var v = e.string().uuid({ message: "Invalid UUID format" }), y = e.string().min(
|
|
|
593
589
|
}).refine((e) => e.minCorrect ? e.minCorrect <= e.connections.length : !0, {
|
|
594
590
|
message: "Minimum correct answers must not exceed total number of connections",
|
|
595
591
|
path: ["minCorrect"]
|
|
596
|
-
}),
|
|
592
|
+
}), nt = R.extend({
|
|
597
593
|
type: e.literal("sort-items"),
|
|
598
|
-
question:
|
|
599
|
-
items: e.array(
|
|
600
|
-
}),
|
|
594
|
+
question: w.max(1e4, "Question must not be longer than 10000 characters"),
|
|
595
|
+
items: e.array(w).min(2, "Must have at least 2 items to sort")
|
|
596
|
+
}), rt = R.extend({
|
|
601
597
|
type: e.literal("slider"),
|
|
602
|
-
question:
|
|
598
|
+
question: w.max(1e4, "Question must not be longer than 10000 characters"),
|
|
603
599
|
min: e.number(),
|
|
604
600
|
max: e.number(),
|
|
605
601
|
step: e.number().positive("Step must be a positive number"),
|
|
@@ -621,20 +617,20 @@ var v = e.string().uuid({ message: "Invalid UUID format" }), y = e.string().min(
|
|
|
621
617
|
}).refine((e) => e.tolerance <= (e.max - e.min) / 2, {
|
|
622
618
|
message: "Tolerance must not be greater than half of value range",
|
|
623
619
|
path: ["tolerance"]
|
|
624
|
-
}),
|
|
620
|
+
}), it = R.extend({
|
|
625
621
|
type: e.literal("pin-on-image"),
|
|
626
|
-
question:
|
|
627
|
-
targetAsset:
|
|
628
|
-
hotspots: e.array(
|
|
622
|
+
question: w.max(1e4, "Question must not be longer than 10000 characters"),
|
|
623
|
+
targetAsset: S,
|
|
624
|
+
hotspots: e.array(Re).min(1, "Must have at least 1 hotspot"),
|
|
629
625
|
multipleCorrect: e.boolean().optional(),
|
|
630
626
|
minCorrect: e.number().int().positive().optional()
|
|
631
627
|
}).refine((e) => e.minCorrect ? e.minCorrect <= e.hotspots.length : !0, {
|
|
632
628
|
message: "Minimum correct answers must not exceed number of hotspots",
|
|
633
629
|
path: ["minCorrect"]
|
|
634
|
-
}),
|
|
630
|
+
}), at = R.extend({
|
|
635
631
|
type: e.literal("categorize"),
|
|
636
|
-
question:
|
|
637
|
-
categories: e.array(
|
|
632
|
+
question: w.max(1e4, "Question must not be longer than 10000 characters"),
|
|
633
|
+
categories: e.array(C).min(2, "Must have at least 2 categories"),
|
|
638
634
|
items: e.array(Be).min(1, "Must have at least 1 item to categorize")
|
|
639
635
|
}).refine((e) => new Set(e.categories.map((e) => e.toLowerCase())).size === e.categories.length, {
|
|
640
636
|
message: "Categories must not contain duplicates (case-insensitive)",
|
|
@@ -642,16 +638,16 @@ var v = e.string().uuid({ message: "Invalid UUID format" }), y = e.string().min(
|
|
|
642
638
|
}).refine((e) => e.items.every((t) => t.correctCategoryIndex < e.categories.length), {
|
|
643
639
|
message: "Some item references non-existent category",
|
|
644
640
|
path: ["items"]
|
|
645
|
-
}),
|
|
641
|
+
}), ot = R.extend({
|
|
646
642
|
type: e.literal("timeline"),
|
|
647
|
-
question:
|
|
643
|
+
question: w.max(1e4, "Question must not be longer than 10000 characters"),
|
|
648
644
|
events: e.array(He).min(2, "Must have at least 2 events"),
|
|
649
645
|
randomize: e.boolean().optional()
|
|
650
|
-
}),
|
|
646
|
+
}), st = R.extend({
|
|
651
647
|
type: e.literal("matrix"),
|
|
652
|
-
question:
|
|
653
|
-
rows: e.array(
|
|
654
|
-
columns: e.array(
|
|
648
|
+
question: w.max(1e4, "Question must not be longer than 10000 characters"),
|
|
649
|
+
rows: e.array(C).min(1, "Must have at least 1 row"),
|
|
650
|
+
columns: e.array(C).min(1, "Must have at least 1 column"),
|
|
655
651
|
correctCells: e.array(e.tuple([e.number().int().nonnegative(), e.number().int().nonnegative()])).min(1, "Must have at least 1 correct cell"),
|
|
656
652
|
multiplePerRow: e.boolean().optional()
|
|
657
653
|
}).refine((e) => e.correctCells.every(([t, n]) => t < e.rows.length && n < e.columns.length), {
|
|
@@ -670,58 +666,59 @@ var v = e.string().uuid({ message: "Invalid UUID format" }), y = e.string().min(
|
|
|
670
666
|
}, {
|
|
671
667
|
message: "If multiplePerRow is false, each row may have maximum 1 correct cell",
|
|
672
668
|
path: ["correctCells"]
|
|
673
|
-
}),
|
|
669
|
+
}), ct = R.extend({
|
|
674
670
|
type: e.literal("math-input"),
|
|
675
|
-
question:
|
|
676
|
-
correctAnswer:
|
|
677
|
-
alternativeAnswers: e.array(
|
|
671
|
+
question: w.max(1e4, "Question must not be longer than 10000 characters"),
|
|
672
|
+
correctAnswer: C,
|
|
673
|
+
alternativeAnswers: e.array(C).optional(),
|
|
678
674
|
tolerance: e.number().nonnegative().optional()
|
|
679
|
-
}),
|
|
675
|
+
}), lt = R.extend({
|
|
680
676
|
type: e.literal("diagram-label"),
|
|
681
|
-
question:
|
|
682
|
-
targetAsset:
|
|
683
|
-
labels: e.array(
|
|
677
|
+
question: w.max(1e4, "Question must not be longer than 10000 characters"),
|
|
678
|
+
targetAsset: S,
|
|
679
|
+
labels: e.array(w).min(1, "Must have at least 1 label"),
|
|
684
680
|
caseSensitive: e.boolean().optional(),
|
|
685
681
|
requireTyping: e.boolean().optional(),
|
|
686
682
|
zones: e.array(Ue).min(1, "Must have at least 1 zone")
|
|
687
683
|
}).refine((e) => e.zones.every((t) => t.correctLabelIndex < e.labels.length), {
|
|
688
684
|
message: "Some zone references non-existent label",
|
|
689
685
|
path: ["zones"]
|
|
690
|
-
}),
|
|
686
|
+
}), ut = R.extend({
|
|
691
687
|
type: e.literal("open-ended"),
|
|
692
|
-
question:
|
|
688
|
+
question: w.max(1e4, "Question must not be longer than 10000 characters"),
|
|
693
689
|
minWords: e.number().int().positive().optional(),
|
|
694
690
|
maxWords: e.number().int().positive().optional(),
|
|
695
|
-
sampleAnswer:
|
|
691
|
+
sampleAnswer: w.optional(),
|
|
696
692
|
rubric: Ge.optional()
|
|
697
693
|
}).refine((e) => e.minWords && e.maxWords ? e.minWords <= e.maxWords : !0, {
|
|
698
694
|
message: "Minimum word count must be less than or equal to maximum",
|
|
699
695
|
path: ["maxWords"]
|
|
700
|
-
}),
|
|
696
|
+
}), dt = R.extend({
|
|
701
697
|
type: e.literal("numeric-input"),
|
|
702
|
-
question:
|
|
698
|
+
question: w.max(1e4, "Question must not be longer than 10000 characters"),
|
|
703
699
|
value: e.number(),
|
|
704
700
|
tolerance: e.number().nonnegative().optional(),
|
|
705
|
-
range:
|
|
701
|
+
range: W.optional(),
|
|
706
702
|
unit: e.string().optional()
|
|
707
|
-
}),
|
|
703
|
+
}), ft = R.extend({
|
|
708
704
|
type: e.literal("pin-on-model"),
|
|
709
|
-
question:
|
|
710
|
-
targetAsset:
|
|
705
|
+
question: w.max(1e4, "Question must not be longer than 10000 characters"),
|
|
706
|
+
targetAsset: S,
|
|
711
707
|
hotspots: e.array(H).min(1, "Must have at least 1 hotspot"),
|
|
712
708
|
multipleCorrect: e.boolean().optional(),
|
|
713
709
|
minCorrect: e.number().int().positive().optional(),
|
|
714
|
-
camera:
|
|
710
|
+
camera: ze.optional()
|
|
715
711
|
}).refine((e) => e.minCorrect ? e.minCorrect <= e.hotspots.length : !0, {
|
|
716
712
|
message: "Minimum correct answers must not exceed number of hotspots",
|
|
717
713
|
path: ["minCorrect"]
|
|
718
|
-
}),
|
|
714
|
+
}), pt = R.extend({
|
|
719
715
|
type: e.literal("chess-puzzle"),
|
|
720
|
-
question:
|
|
721
|
-
fen:
|
|
722
|
-
answers: e.array(e.array(
|
|
716
|
+
question: w.max(1e4, "Question must not be longer than 10000 characters"),
|
|
717
|
+
fen: C,
|
|
718
|
+
answers: e.array(e.array(C).min(1, "Move sequence must not be empty")).min(1, "Must have at least 1 correct move sequence"),
|
|
723
719
|
elo: e.number().int().nonnegative("ELO must be non-negative integer").optional()
|
|
724
720
|
}), G = e.discriminatedUnion("type", [
|
|
721
|
+
Ke,
|
|
725
722
|
qe,
|
|
726
723
|
Je,
|
|
727
724
|
Ye,
|
|
@@ -742,8 +739,7 @@ var v = e.string().uuid({ message: "Invalid UUID format" }), y = e.string().min(
|
|
|
742
739
|
ut,
|
|
743
740
|
dt,
|
|
744
741
|
ft,
|
|
745
|
-
pt
|
|
746
|
-
mt
|
|
742
|
+
pt
|
|
747
743
|
]), K = e.object({
|
|
748
744
|
$schema: e.string().url().optional(),
|
|
749
745
|
version: e.string().regex(/^\d+\.\d+$/, "Version must be in MAJOR.MINOR format (e.g. \"0.1\")"),
|
|
@@ -776,7 +772,7 @@ var v = e.string().uuid({ message: "Invalid UUID format" }), y = e.string().min(
|
|
|
776
772
|
message: "Some item references non-existent source material",
|
|
777
773
|
path: ["items"]
|
|
778
774
|
});
|
|
779
|
-
function
|
|
775
|
+
function mt(t) {
|
|
780
776
|
let n = t instanceof Error ? t.message : "OQSE Security Error: Maximum nesting depth exceeded limit of 10 levels.";
|
|
781
777
|
return new e.ZodError([{
|
|
782
778
|
code: e.ZodIssueCode.custom,
|
|
@@ -784,16 +780,16 @@ function ht(t) {
|
|
|
784
780
|
path: []
|
|
785
781
|
}]);
|
|
786
782
|
}
|
|
787
|
-
function
|
|
788
|
-
return
|
|
783
|
+
function ht(e) {
|
|
784
|
+
return g(e, 10), K.parse(e);
|
|
789
785
|
}
|
|
790
|
-
function
|
|
786
|
+
function gt(e) {
|
|
791
787
|
try {
|
|
792
|
-
|
|
788
|
+
g(e, 10);
|
|
793
789
|
} catch (e) {
|
|
794
790
|
return {
|
|
795
791
|
success: !1,
|
|
796
|
-
error:
|
|
792
|
+
error: mt(e)
|
|
797
793
|
};
|
|
798
794
|
}
|
|
799
795
|
let t = K.safeParse(e);
|
|
@@ -805,16 +801,16 @@ function _t(e) {
|
|
|
805
801
|
error: t.error
|
|
806
802
|
};
|
|
807
803
|
}
|
|
808
|
-
function
|
|
809
|
-
return
|
|
804
|
+
function _t(e) {
|
|
805
|
+
return g(e, 10), G.parse(e);
|
|
810
806
|
}
|
|
811
|
-
function
|
|
807
|
+
function vt(e) {
|
|
812
808
|
try {
|
|
813
|
-
|
|
809
|
+
g(e, 10);
|
|
814
810
|
} catch (e) {
|
|
815
811
|
return {
|
|
816
812
|
success: !1,
|
|
817
|
-
error:
|
|
813
|
+
error: mt(e)
|
|
818
814
|
};
|
|
819
815
|
}
|
|
820
816
|
let t = G.safeParse(e);
|
|
@@ -828,7 +824,7 @@ function yt(e) {
|
|
|
828
824
|
}
|
|
829
825
|
//#endregion
|
|
830
826
|
//#region src/manifestValidation.ts
|
|
831
|
-
var q = e.string().min(1, "Value must not be empty").trim(),
|
|
827
|
+
var q = e.string().min(1, "Value must not be empty").trim(), yt = e.string().regex(/^[a-zA-Z]{2,8}(-[a-zA-Z0-9\-]+)*$/, "Must be a valid BCP 47 locale (e.g., \"en\", \"cs\")"), J = e.string().url("Must be a valid absolute URL").refine((e) => e.startsWith("http://") || e.startsWith("https://"), { message: "URL must use http or https scheme" }), bt = e.string().regex(/^urn:uuid:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i, "Must be a valid URN UUID (urn:uuid:...)"), Y = e.string().regex(/^\d+\.\d+$/, "Version must be in MAJOR.MINOR format (e.g. \"0.1\")"), xt = [
|
|
832
828
|
"note",
|
|
833
829
|
"flashcard",
|
|
834
830
|
"true-false",
|
|
@@ -851,15 +847,15 @@ var q = e.string().min(1, "Value must not be empty").trim(), bt = e.string().reg
|
|
|
851
847
|
"numeric-input",
|
|
852
848
|
"pin-on-model",
|
|
853
849
|
"chess-puzzle"
|
|
854
|
-
],
|
|
850
|
+
], St = q.refine((e) => xt.includes(e) || e.startsWith("x-"), { message: "Custom types MUST use the \"x-\" prefix" }), Ct = e.string().refine((e) => c.includes(e) || e.startsWith("x-"), { message: "Action must be one of [render, edit, validate, import, export] or have prefix \"x-\"" }), wt = e.enum([
|
|
855
851
|
"game",
|
|
856
852
|
"fun",
|
|
857
853
|
"drill"
|
|
858
|
-
]),
|
|
854
|
+
]), Tt = e.enum([
|
|
859
855
|
"low",
|
|
860
856
|
"medium",
|
|
861
857
|
"high"
|
|
862
|
-
]),
|
|
858
|
+
]), Et = e.string().refine((e) => l.includes(e) || e.startsWith("x-"), { message: "Feature must be one of official keys or have prefix \"x-\"" }), Dt = e.string().refine((e) => u.includes(e) || e.startsWith("x-"), { message: "Item property must be an official key or have prefix \"x-\"" }), Ot = e.string().refine((e) => d.includes(e) || e.startsWith("x-"), { message: "Meta property must be an official key or have prefix \"x-\"" });
|
|
863
859
|
function X(t) {
|
|
864
860
|
return e.union([
|
|
865
861
|
e.tuple([e.literal("*")]),
|
|
@@ -867,15 +863,15 @@ function X(t) {
|
|
|
867
863
|
e.null()
|
|
868
864
|
]);
|
|
869
865
|
}
|
|
870
|
-
var
|
|
871
|
-
image: X(
|
|
872
|
-
audio: X(
|
|
873
|
-
video: X(
|
|
874
|
-
model: X(
|
|
875
|
-
}),
|
|
876
|
-
actions: e.array(
|
|
877
|
-
types: X(
|
|
878
|
-
assets:
|
|
866
|
+
var kt = e.string().refine((e) => e.startsWith("image/"), { message: "Must be a valid image MIME type (image/...)" }), At = e.string().refine((e) => e.startsWith("audio/"), { message: "Must be a valid audio MIME type (audio/...)" }), jt = e.string().refine((e) => e.startsWith("video/"), { message: "Must be a valid video MIME type (video/...)" }), Mt = e.string().refine((e) => e.startsWith("model/") || e === "application/octet-stream", { message: "Must be a valid 3D model MIME type (model/... or application/octet-stream)" }), Nt = e.object({
|
|
867
|
+
image: X(kt).optional(),
|
|
868
|
+
audio: X(At).optional(),
|
|
869
|
+
video: X(jt).optional(),
|
|
870
|
+
model: X(Mt).optional()
|
|
871
|
+
}), Pt = F.extend({
|
|
872
|
+
actions: e.array(Ct).min(1, "Application must support at least one action"),
|
|
873
|
+
types: X(St).optional(),
|
|
874
|
+
assets: Nt.optional()
|
|
879
875
|
}).superRefine((t, n) => {
|
|
880
876
|
(t.actions.includes("render") || t.actions.includes("edit")) && (!Array.isArray(t.types) || t.types.length === 0) && n.addIssue({
|
|
881
877
|
code: e.ZodIssueCode.custom,
|
|
@@ -884,23 +880,23 @@ var At = e.string().refine((e) => e.startsWith("image/"), { message: "Must be a
|
|
|
884
880
|
});
|
|
885
881
|
}), Z = e.object({
|
|
886
882
|
$schema: J.optional(),
|
|
887
|
-
id: e.union([J,
|
|
883
|
+
id: e.union([J, bt]),
|
|
888
884
|
appName: q.max(200, "Name must not be longer than 200 characters"),
|
|
889
885
|
version: Y,
|
|
890
886
|
pluginVersion: e.string().optional(),
|
|
891
887
|
minOqseVersion: Y.optional(),
|
|
892
888
|
maxOqseVersion: Y.optional(),
|
|
893
|
-
capabilities:
|
|
894
|
-
author:
|
|
895
|
-
contributors: e.array(
|
|
889
|
+
capabilities: Pt,
|
|
890
|
+
author: A.optional(),
|
|
891
|
+
contributors: e.array(A).optional(),
|
|
896
892
|
license: e.string().max(100, "License must not be longer than 100 characters").optional(),
|
|
897
893
|
licenseUrl: J.optional(),
|
|
898
|
-
locales: e.array(
|
|
894
|
+
locales: e.array(yt).optional(),
|
|
899
895
|
description: e.string().max(5e3, "Description must not be longer than 5000 characters").optional(),
|
|
900
896
|
emoji: e.string().optional(),
|
|
901
897
|
tags: e.array(q).optional(),
|
|
902
|
-
studyMode:
|
|
903
|
-
questionDensity:
|
|
898
|
+
studyMode: wt.optional(),
|
|
899
|
+
questionDensity: Tt.optional(),
|
|
904
900
|
appSpecific: e.record(e.string(), e.unknown()).optional()
|
|
905
901
|
}).refine((e) => {
|
|
906
902
|
if (!e.minOqseVersion || !e.maxOqseVersion) return !0;
|
|
@@ -910,25 +906,25 @@ var At = e.string().refine((e) => e.startsWith("image/"), { message: "Must be a
|
|
|
910
906
|
message: "minOqseVersion must not be greater than maxOqseVersion",
|
|
911
907
|
path: ["minOqseVersion"]
|
|
912
908
|
});
|
|
913
|
-
function
|
|
909
|
+
function Ft(e) {
|
|
914
910
|
return Z.parse(e);
|
|
915
911
|
}
|
|
916
|
-
function
|
|
912
|
+
function It(e) {
|
|
917
913
|
return Z.safeParse(e);
|
|
918
914
|
}
|
|
919
|
-
function
|
|
915
|
+
function Lt(e) {
|
|
920
916
|
return Z.safeParse(e).success;
|
|
921
917
|
}
|
|
922
918
|
//#endregion
|
|
923
919
|
//#region src/progressValidation.ts
|
|
924
|
-
var
|
|
920
|
+
var Rt = e.object({
|
|
925
921
|
attempts: e.number().int().nonnegative(),
|
|
926
922
|
incorrect: e.number().int().nonnegative(),
|
|
927
923
|
streak: e.number().int().nonnegative()
|
|
928
924
|
}).refine((e) => e.incorrect <= e.attempts, {
|
|
929
925
|
message: "incorrect cannot be higher than attempts",
|
|
930
926
|
path: ["incorrect"]
|
|
931
|
-
}),
|
|
927
|
+
}), zt = e.object({
|
|
932
928
|
isCorrect: e.boolean(),
|
|
933
929
|
confidence: e.union([
|
|
934
930
|
e.literal(1),
|
|
@@ -936,11 +932,11 @@ var zt = e.object({
|
|
|
936
932
|
e.literal(3),
|
|
937
933
|
e.literal(4)
|
|
938
934
|
]).optional(),
|
|
939
|
-
answeredAt:
|
|
935
|
+
answeredAt: b,
|
|
940
936
|
timeSpent: e.number().int().nonnegative().optional(),
|
|
941
937
|
hintsUsed: e.number().int().nonnegative().default(0),
|
|
942
938
|
isSkipped: e.boolean().optional()
|
|
943
|
-
}),
|
|
939
|
+
}), Bt = e.object({
|
|
944
940
|
bucket: e.union([
|
|
945
941
|
e.literal(0),
|
|
946
942
|
e.literal(1),
|
|
@@ -948,24 +944,24 @@ var zt = e.object({
|
|
|
948
944
|
e.literal(3),
|
|
949
945
|
e.literal(4)
|
|
950
946
|
]),
|
|
951
|
-
nextReviewAt:
|
|
952
|
-
stats:
|
|
953
|
-
lastAnswer:
|
|
947
|
+
nextReviewAt: b.optional(),
|
|
948
|
+
stats: Rt,
|
|
949
|
+
lastAnswer: zt.optional(),
|
|
954
950
|
appSpecific: e.record(e.string(), e.unknown()).optional()
|
|
955
|
-
}),
|
|
956
|
-
setId:
|
|
957
|
-
exportedAt:
|
|
951
|
+
}), Vt = e.object({
|
|
952
|
+
setId: _,
|
|
953
|
+
exportedAt: b,
|
|
958
954
|
algorithm: e.string().regex(/^[a-z0-9-]+$/, "algorithm must be lowercase alphanumeric with hyphens format").optional()
|
|
959
955
|
}), Q = e.object({
|
|
960
956
|
$schema: e.url().optional(),
|
|
961
957
|
version: e.string().regex(/^\d+\.\d+$/, "Version must be in MAJOR.MINOR format"),
|
|
962
|
-
meta:
|
|
963
|
-
records: e.record(
|
|
958
|
+
meta: Vt,
|
|
959
|
+
records: e.record(_, Bt)
|
|
964
960
|
});
|
|
965
|
-
function
|
|
961
|
+
function Ht(e) {
|
|
966
962
|
return Q.parse(e);
|
|
967
963
|
}
|
|
968
|
-
function
|
|
964
|
+
function Ut(e) {
|
|
969
965
|
return Q.safeParse(e);
|
|
970
966
|
}
|
|
971
967
|
var $ = e.object(L.shape).pick({
|
|
@@ -981,18 +977,18 @@ var $ = e.object(L.shape).pick({
|
|
|
981
977
|
estimatedTime: !0,
|
|
982
978
|
requirements: !0
|
|
983
979
|
}).partial({ createdAt: !0 }).extend({
|
|
984
|
-
url:
|
|
980
|
+
url: x,
|
|
985
981
|
$schema: e.string().url().optional()
|
|
986
982
|
});
|
|
987
|
-
function
|
|
983
|
+
function Wt(e) {
|
|
988
984
|
return $.parse(e);
|
|
989
985
|
}
|
|
990
|
-
function
|
|
986
|
+
function Gt(e) {
|
|
991
987
|
return $.safeParse(e);
|
|
992
988
|
}
|
|
993
989
|
//#endregion
|
|
994
990
|
//#region src/richTextProcessor.ts
|
|
995
|
-
function
|
|
991
|
+
function Kt(e) {
|
|
996
992
|
let t = {};
|
|
997
993
|
return {
|
|
998
994
|
text: e.replace(/<(asset|blank):([a-zA-Z0-9_-]+)\s*\/>/gi, (e, n, r) => {
|
|
@@ -1006,11 +1002,11 @@ function qt(e) {
|
|
|
1006
1002
|
tokens: t
|
|
1007
1003
|
};
|
|
1008
1004
|
}
|
|
1009
|
-
function
|
|
1005
|
+
function qt(e) {
|
|
1010
1006
|
let t = e.replace(/`{1,}[^`]*`{1,}/g, "").replace(/~{3,}[\s\S]*?~{3,}/g, "");
|
|
1011
1007
|
if (/<[a-zA-Z\/][^>]*>/.test(t)) throw Error("OQSE Security Error: Raw HTML tags are not allowed in Tier 1 (Pure Markdown). If the set requires HTML formatting, it MUST declare the 'html' feature in meta.requirements.");
|
|
1012
1008
|
}
|
|
1013
|
-
function
|
|
1009
|
+
function Jt(e, t, n) {
|
|
1014
1010
|
let r = e;
|
|
1015
1011
|
for (let [e, i] of Object.entries(t)) {
|
|
1016
1012
|
let t = i.originalTag;
|
|
@@ -1018,16 +1014,16 @@ function Yt(e, t, n) {
|
|
|
1018
1014
|
}
|
|
1019
1015
|
return r;
|
|
1020
1016
|
}
|
|
1021
|
-
function
|
|
1017
|
+
function Yt(e, t, n) {
|
|
1022
1018
|
if (!e) return "";
|
|
1023
|
-
let r = t?.features?.includes("html") ?? !1, { text: i, tokens: a } =
|
|
1024
|
-
r ||
|
|
1019
|
+
let r = t?.features?.includes("html") ?? !1, { text: i, tokens: a } = Kt(e);
|
|
1020
|
+
r || qt(i);
|
|
1025
1021
|
let o = n.markdownParser(i);
|
|
1026
1022
|
if (r) {
|
|
1027
1023
|
if (!n.htmlSanitizer) throw Error("OQSE Security Error: Set requires 'html' (Tier 2), but no htmlSanitizer (like DOMPurify) was provided to the options.");
|
|
1028
1024
|
o = n.htmlSanitizer(o);
|
|
1029
1025
|
}
|
|
1030
|
-
return
|
|
1026
|
+
return Jt(o, a, n);
|
|
1031
1027
|
}
|
|
1032
1028
|
//#endregion
|
|
1033
|
-
export {
|
|
1029
|
+
export { x as AbsoluteURLSchema, k as AssetDictionarySchema, S as AssetKeySchema, At as AudioMimeTypeSchema, R as BaseItemSchema, E as BlankTokenSchema, Ne as BloomLevelSchema, ze as CameraSetupSchema, Be as CategorizeItemObjectSchema, at as CategorizeItemSchema, pt as ChessPuzzleItemSchema, B as CircleHotspotSchema, Pe as CognitiveLoadSchema, lt as DiagramLabelItemSchema, Ue as DiagramZoneSchema, Et as FeatureFlagSchema, F as FeatureProfileSchema, Qe as FillInBlanksItemSchema, $e as FillInSelectItemSchema, qe as FlashcardItemSchema, Re as Hotspot2DSchema, Le as HotspotObjectSchema, b as ISO8601DateTimeSchema, kt as ImageMimeTypeSchema, Dt as ItemPropertyKeySchema, v as LanguageCodeSchema, zt as LastAnswerObjectSchema, I as LinkedSetObjectSchema, Xe as MCQMultiItemSchema, Ye as MCQSingleItemSchema, Nt as ManifestAssetsSchema, Pt as ManifestCapabilitiesSchema, tt as MatchComplexItemSchema, et as MatchPairsItemSchema, ct as MathInputItemSchema, st as MatrixItemSchema, O as MediaObjectSchema, H as MeshHotspotSchema, Ot as MetaPropertyKeySchema, Mt as ModelMimeTypeSchema, Ke as NoteItemSchema, dt as NumericInputItemSchema, W as NumericRangeSchema, c as OFFICIAL_ACTIONS, l as OFFICIAL_FEATURE_KEYS, u as OFFICIAL_ITEM_PROPERTIES, d as OFFICIAL_META_PROPERTIES, Ct as OQSEActionSchema, K as OQSEFileSchema, $ as OQSEHeaderSchema, G as OQSEItemSchema, Z as OQSEManifestSchema, L as OQSEMetaSchema, Q as OQSEProgressSchema, Tt as OQSEQuestionDensitySchema, wt as OQSEStudyModeSchema, ut as OpenEndedItemSchema, T as OptionalRichContentSchema, Fe as PedagogySchema, A as PersonObjectSchema, it as PinOnImageItemSchema, ft as PinOnModelItemSchema, C as PlainTextSchema, V as PolygonHotspotSchema, Vt as ProgressMetaSchema, Bt as ProgressRecordSchema, z as RectHotspotSchema, w as RichContentSchema, We as RubricCriterionSchema, Ge as RubricSchema, y as SPDXLicenseSchema, Ie as SelectBlankObjectSchema, Ze as ShortAnswerItemSchema, rt as SliderItemSchema, nt as SortItemsItemSchema, M as SourceMaterialSchema, j as SourceMaterialTypeSchema, N as SourceReferenceSchema, Rt as StatsObjectSchema, D as SubtitleTrackSchema, je as TagDefinitionDictionarySchema, P as TagDefinitionSchema, He as TimelineEventSchema, ot as TimelineItemSchema, Ve as TimelinePrecisionSchema, Me as TranslationObjectSchema, Je as TrueFalseItemSchema, _ as UUIDSchema, U as Vector3Schema, jt as VideoMimeTypeSchema, p as compareManifestVersions, Jt as detokenizeOqseTags, Ae as formatOQSEErrors, ke as generateUUID, se as isCategorize, he as isChessPuzzle, s as isCoreItem, de as isDiagramLabel, ge as isExtendedItem, ee as isFillInBlanks, te as isFillInSelect, n as isFlashcard, a as isMCQMulti, i as isMCQSingle, re as isMatchComplex, ne as isMatchPairs, ue as isMathInput, le as isMatrix, t as isNote, pe as isNumericInput, ve as isOQSEManifest, fe as isOpenEnded, oe as isPinOnImage, me as isPinOnModel, o as isShortAnswer, ae as isSlider, ie as isSortItems, ce as isTimeline, r as isTrueFalse, f as isValidManifestVersion, Lt as isValidOQSEManifest, _e as isValidSemVer, Oe as isValidUUID, ye as isVersionCompatible, Yt as prepareRichTextForDisplay, gt as safeValidateOQSEFile, Gt as safeValidateOQSEHeader, vt as safeValidateOQSEItem, It as safeValidateOQSEManifest, Ut as safeValidateOQSEProgress, Kt as tokenizeOqseTags, g as validateJsonDepth, ht as validateOQSEFile, Wt as validateOQSEHeader, _t as validateOQSEItem, Ft as validateOQSEManifest, Ht as validateOQSEProgress, qt as validateTier1Markdown };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memizy/oqse",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "TypeScript SDK and Zod validators for the OQSE specification.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"vitest": "^4.1.4"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"uuid": "^
|
|
41
|
+
"uuid": "^14.0.0",
|
|
42
42
|
"zod": "^4.3.6"
|
|
43
43
|
}
|
|
44
44
|
}
|