coursecode 0.1.0
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/LICENSE +21 -0
- package/README.md +322 -0
- package/THIRD_PARTY_NOTICES.md +22 -0
- package/bin/cli.js +331 -0
- package/framework/assets/logo-coursecode-black.svg +14 -0
- package/framework/assets/logo-coursecode-white.svg +14 -0
- package/framework/assets/logo-coursecode.svg +14 -0
- package/framework/css/01-base.css +160 -0
- package/framework/css/02-layout.css +499 -0
- package/framework/css/accessibility.css +834 -0
- package/framework/css/components/accordions.css +710 -0
- package/framework/css/components/assessments.css +520 -0
- package/framework/css/components/audio-player.css +570 -0
- package/framework/css/components/badges.css +80 -0
- package/framework/css/components/breadcrumbs.css +87 -0
- package/framework/css/components/buttons.css +707 -0
- package/framework/css/components/callouts.css +1280 -0
- package/framework/css/components/cards.css +475 -0
- package/framework/css/components/carousel.css +193 -0
- package/framework/css/components/checkbox-group.css +123 -0
- package/framework/css/components/checklist.css +203 -0
- package/framework/css/components/collapse.css +96 -0
- package/framework/css/components/comparison.css +33 -0
- package/framework/css/components/content-image.css +36 -0
- package/framework/css/components/document-gallery.css +425 -0
- package/framework/css/components/dropdown.css +115 -0
- package/framework/css/components/embed-frame.css +142 -0
- package/framework/css/components/engagement.css +412 -0
- package/framework/css/components/features.css +35 -0
- package/framework/css/components/flip-cards.css +253 -0
- package/framework/css/components/footer.css +353 -0
- package/framework/css/components/forms.css +294 -0
- package/framework/css/components/hero.css +216 -0
- package/framework/css/components/images.css +528 -0
- package/framework/css/components/interactive-timeline.css +274 -0
- package/framework/css/components/intro-cards.css +30 -0
- package/framework/css/components/lightbox.css +666 -0
- package/framework/css/components/loading.css +65 -0
- package/framework/css/components/modals.css +235 -0
- package/framework/css/components/notifications.css +107 -0
- package/framework/css/components/quote.css +150 -0
- package/framework/css/components/sidebar.css +684 -0
- package/framework/css/components/slide-header.css +52 -0
- package/framework/css/components/spinner.css +62 -0
- package/framework/css/components/stats.css +44 -0
- package/framework/css/components/steps.css +232 -0
- package/framework/css/components/tables.css +90 -0
- package/framework/css/components/tabs.css +347 -0
- package/framework/css/components/timeline.css +154 -0
- package/framework/css/components/toggle.css +95 -0
- package/framework/css/components/tooltip.css +226 -0
- package/framework/css/components/video-player.css +438 -0
- package/framework/css/design-tokens.css +707 -0
- package/framework/css/framework.css +86 -0
- package/framework/css/interactions/accessibility.css +75 -0
- package/framework/css/interactions/base.css +92 -0
- package/framework/css/interactions/drag-drop.css +295 -0
- package/framework/css/interactions/fill-in-the-blank.css +236 -0
- package/framework/css/interactions/hotspots.css +69 -0
- package/framework/css/interactions/index.css +45 -0
- package/framework/css/interactions/interactive-image.css +359 -0
- package/framework/css/interactions/likert.css +126 -0
- package/framework/css/interactions/matching.css +354 -0
- package/framework/css/interactions/numeric-input.css +78 -0
- package/framework/css/interactions/sequencing.css +378 -0
- package/framework/css/interactions/true-false.css +177 -0
- package/framework/css/layouts/article.css +258 -0
- package/framework/css/layouts/base.css +30 -0
- package/framework/css/layouts/canvas.css +38 -0
- package/framework/css/layouts/focused.css +236 -0
- package/framework/css/layouts/index.css +29 -0
- package/framework/css/layouts/presentation.css +191 -0
- package/framework/css/layouts/traditional.css +52 -0
- package/framework/css/responsive.css +439 -0
- package/framework/css/utilities/accessibility-utils.css +59 -0
- package/framework/css/utilities/animations.css +419 -0
- package/framework/css/utilities/borders.css +72 -0
- package/framework/css/utilities/colors.css +76 -0
- package/framework/css/utilities/container.css +46 -0
- package/framework/css/utilities/decorative.css +442 -0
- package/framework/css/utilities/display.css +257 -0
- package/framework/css/utilities/flexbox.css +80 -0
- package/framework/css/utilities/grid.css +69 -0
- package/framework/css/utilities/icons.css +534 -0
- package/framework/css/utilities/lists.css +190 -0
- package/framework/css/utilities/spacing.css +167 -0
- package/framework/css/utilities/tables.css +81 -0
- package/framework/css/utilities/typography.css +159 -0
- package/framework/css/utilities/visibility.css +117 -0
- package/framework/docs/COURSE_AUTHORING_GUIDE.md +1773 -0
- package/framework/docs/COURSE_OUTLINE_GUIDE.md +725 -0
- package/framework/docs/COURSE_OUTLINE_TEMPLATE.md +161 -0
- package/framework/docs/DATA_MODEL.md +409 -0
- package/framework/docs/FRAMEWORK_GUIDE.md +1088 -0
- package/framework/docs/USER_GUIDE.md +583 -0
- package/framework/docs/examples/cloudflare-channel-relay.js +169 -0
- package/framework/docs/examples/cloudflare-data-worker.js +102 -0
- package/framework/docs/examples/cloudflare-error-worker.js +228 -0
- package/framework/index.html +175 -0
- package/framework/js/app/AppActions.js +410 -0
- package/framework/js/app/AppState.js +225 -0
- package/framework/js/app/AppUI.js +616 -0
- package/framework/js/assessment/AssessmentActions.js +615 -0
- package/framework/js/assessment/AssessmentFactory.js +471 -0
- package/framework/js/assessment/AssessmentState.js +322 -0
- package/framework/js/assessment/AssessmentUI.js +451 -0
- package/framework/js/automation/api-engagement.js +196 -0
- package/framework/js/automation/api-interactions.js +167 -0
- package/framework/js/automation/api.js +242 -0
- package/framework/js/automation/index.js +41 -0
- package/framework/js/components/interactions/drag-drop.js +884 -0
- package/framework/js/components/interactions/fill-in.js +535 -0
- package/framework/js/components/interactions/hotspot.js +702 -0
- package/framework/js/components/interactions/interaction-base.js +511 -0
- package/framework/js/components/interactions/likert.js +301 -0
- package/framework/js/components/interactions/matching.js +699 -0
- package/framework/js/components/interactions/multiple-choice.js +377 -0
- package/framework/js/components/interactions/numeric.js +271 -0
- package/framework/js/components/interactions/sequencing.js +423 -0
- package/framework/js/components/interactions/true-false.js +241 -0
- package/framework/js/components/ui-components/accordion.js +442 -0
- package/framework/js/components/ui-components/alert.js +88 -0
- package/framework/js/components/ui-components/audio-player.js +1193 -0
- package/framework/js/components/ui-components/callout.js +121 -0
- package/framework/js/components/ui-components/carousel.js +145 -0
- package/framework/js/components/ui-components/checkbox-group.js +87 -0
- package/framework/js/components/ui-components/checklist.js +40 -0
- package/framework/js/components/ui-components/collapse.js +114 -0
- package/framework/js/components/ui-components/comparison.js +30 -0
- package/framework/js/components/ui-components/conditional-display.js +150 -0
- package/framework/js/components/ui-components/content-image.js +41 -0
- package/framework/js/components/ui-components/dropdown.js +262 -0
- package/framework/js/components/ui-components/embed-frame.js +274 -0
- package/framework/js/components/ui-components/features.js +33 -0
- package/framework/js/components/ui-components/flip-card.js +230 -0
- package/framework/js/components/ui-components/form-validator.js +76 -0
- package/framework/js/components/ui-components/hero.js +49 -0
- package/framework/js/components/ui-components/index.js +12 -0
- package/framework/js/components/ui-components/interactive-image.js +235 -0
- package/framework/js/components/ui-components/interactive-timeline.js +285 -0
- package/framework/js/components/ui-components/intro-cards.js +35 -0
- package/framework/js/components/ui-components/lightbox.js +652 -0
- package/framework/js/components/ui-components/modal.js +386 -0
- package/framework/js/components/ui-components/notifications.js +145 -0
- package/framework/js/components/ui-components/progress.js +88 -0
- package/framework/js/components/ui-components/quote.js +41 -0
- package/framework/js/components/ui-components/stats.js +33 -0
- package/framework/js/components/ui-components/steps.js +41 -0
- package/framework/js/components/ui-components/tabs.js +255 -0
- package/framework/js/components/ui-components/timeline.js +42 -0
- package/framework/js/components/ui-components/toggle-group.js +73 -0
- package/framework/js/components/ui-components/tooltip.js +458 -0
- package/framework/js/components/ui-components/value-display.js +133 -0
- package/framework/js/components/ui-components/video-player.js +686 -0
- package/framework/js/core/component-catalog.js +121 -0
- package/framework/js/core/event-bus.js +178 -0
- package/framework/js/core/interaction-catalog.js +149 -0
- package/framework/js/dev/runtime-linter.js +1725 -0
- package/framework/js/drivers/cmi5-driver.js +768 -0
- package/framework/js/drivers/driver-factory.js +77 -0
- package/framework/js/drivers/driver-interface.js +110 -0
- package/framework/js/drivers/http-driver-base.js +241 -0
- package/framework/js/drivers/lti-driver.js +508 -0
- package/framework/js/drivers/proxy-driver.js +444 -0
- package/framework/js/drivers/scorm-12-driver.js +560 -0
- package/framework/js/drivers/scorm-2004-driver.js +775 -0
- package/framework/js/drivers/scorm-driver-base.js +112 -0
- package/framework/js/engagement/engagement-manager.js +404 -0
- package/framework/js/engagement/engagement-progress.js +191 -0
- package/framework/js/engagement/engagement-trackers.js +215 -0
- package/framework/js/engagement/requirement-strategies.js +268 -0
- package/framework/js/main.js +727 -0
- package/framework/js/managers/accessibility-manager.js +499 -0
- package/framework/js/managers/assessment-manager.js +230 -0
- package/framework/js/managers/audio-manager.js +944 -0
- package/framework/js/managers/comment-manager.js +88 -0
- package/framework/js/managers/flag-manager.js +86 -0
- package/framework/js/managers/interaction-manager.js +254 -0
- package/framework/js/managers/interaction-registry.js +96 -0
- package/framework/js/managers/objective-manager.js +423 -0
- package/framework/js/managers/score-manager.js +441 -0
- package/framework/js/managers/video-manager.js +536 -0
- package/framework/js/navigation/Breadcrumbs.js +234 -0
- package/framework/js/navigation/NavigationActions.js +1132 -0
- package/framework/js/navigation/NavigationState.js +276 -0
- package/framework/js/navigation/NavigationUI.js +574 -0
- package/framework/js/navigation/document-gallery.js +357 -0
- package/framework/js/navigation/navigation-helpers.js +175 -0
- package/framework/js/navigation/navigation-validators.js +174 -0
- package/framework/js/state/index.js +8 -0
- package/framework/js/state/lms-connection.js +482 -0
- package/framework/js/state/lms-error-utils.js +58 -0
- package/framework/js/state/state-commits.js +200 -0
- package/framework/js/state/state-domains.js +86 -0
- package/framework/js/state/state-manager.js +502 -0
- package/framework/js/state/state-validation.js +311 -0
- package/framework/js/state/transaction-log.js +41 -0
- package/framework/js/state/xapi-statement-service.js +325 -0
- package/framework/js/utilities/access-control.js +99 -0
- package/framework/js/utilities/breakpoint-manager.js +315 -0
- package/framework/js/utilities/canvas-slide.js +35 -0
- package/framework/js/utilities/conditional-display.js +388 -0
- package/framework/js/utilities/course-channel.js +214 -0
- package/framework/js/utilities/course-helpers.js +420 -0
- package/framework/js/utilities/data-reporter.js +273 -0
- package/framework/js/utilities/error-reporter.js +313 -0
- package/framework/js/utilities/hotspot-helper.js +341 -0
- package/framework/js/utilities/icons.js +348 -0
- package/framework/js/utilities/logger.js +92 -0
- package/framework/js/utilities/markdown-renderer.js +45 -0
- package/framework/js/utilities/scroll-tracker.js +68 -0
- package/framework/js/utilities/ui-initializer.js +146 -0
- package/framework/js/utilities/utilities.js +293 -0
- package/framework/js/utilities/view-manager.js +227 -0
- package/framework/js/validation/html-validators.js +422 -0
- package/framework/js/validation/scorm-validators.js +438 -0
- package/framework/js/vendor/pipwerks.js +931 -0
- package/framework/scripts/generate-narration.js +629 -0
- package/framework/scripts/tts-providers/azure-provider.js +178 -0
- package/framework/scripts/tts-providers/base-provider.js +81 -0
- package/framework/scripts/tts-providers/deepgram-provider.js +135 -0
- package/framework/scripts/tts-providers/elevenlabs-provider.js +148 -0
- package/framework/scripts/tts-providers/google-provider.js +272 -0
- package/framework/scripts/tts-providers/index.js +158 -0
- package/framework/scripts/tts-providers/openai-provider.js +143 -0
- package/framework/version.json +63 -0
- package/lib/authoring-api.js +919 -0
- package/lib/build-linter.js +450 -0
- package/lib/build-packaging.js +186 -0
- package/lib/build.js +88 -0
- package/lib/cloud.js +691 -0
- package/lib/convert.js +341 -0
- package/lib/course-parser.js +936 -0
- package/lib/course-writer.js +258 -0
- package/lib/create.js +248 -0
- package/lib/css-index.js +237 -0
- package/lib/dev.js +51 -0
- package/lib/export-content.js +1246 -0
- package/lib/headless-browser.js +413 -0
- package/lib/import.js +377 -0
- package/lib/index.js +80 -0
- package/lib/info.js +79 -0
- package/lib/interaction-formatters.js +568 -0
- package/lib/manifest/cmi5-manifest.js +63 -0
- package/lib/manifest/lti-tool-config.js +53 -0
- package/lib/manifest/manifest-factory.js +99 -0
- package/lib/manifest/scorm-12-manifest.js +61 -0
- package/lib/manifest/scorm-2004-manifest.js +94 -0
- package/lib/manifest/scorm-proxy-manifest.js +104 -0
- package/lib/manifest-parser.js +96 -0
- package/lib/mcp-prompts.js +753 -0
- package/lib/mcp-server.js +316 -0
- package/lib/narration.js +53 -0
- package/lib/pdf-structure.js +142 -0
- package/lib/preview-export.js +231 -0
- package/lib/preview-routes-api.js +662 -0
- package/lib/preview-routes-editing.js +159 -0
- package/lib/preview-routes-lms.js +230 -0
- package/lib/preview-server.js +564 -0
- package/lib/project-utils.js +269 -0
- package/lib/proxy-templates/proxy.html +68 -0
- package/lib/proxy-templates/scorm-bridge.js +112 -0
- package/lib/scaffold.js +193 -0
- package/lib/schema-extractor.js +361 -0
- package/lib/slide-source-editor.js +586 -0
- package/lib/stub-player/app-viewer.js +195 -0
- package/lib/stub-player/app.js +370 -0
- package/lib/stub-player/catalog-panel.js +312 -0
- package/lib/stub-player/config-panel.js +1303 -0
- package/lib/stub-player/content-generator.js +586 -0
- package/lib/stub-player/content-viewer.js +173 -0
- package/lib/stub-player/debug-panel.js +420 -0
- package/lib/stub-player/edit-mode.js +922 -0
- package/lib/stub-player/edit-utils.js +400 -0
- package/lib/stub-player/header-bar.js +354 -0
- package/lib/stub-player/interaction-editor.js +210 -0
- package/lib/stub-player/interactions-panel.js +565 -0
- package/lib/stub-player/lms-api.js +1094 -0
- package/lib/stub-player/login-screen.js +74 -0
- package/lib/stub-player/outline-mode.js +689 -0
- package/lib/stub-player/styles/_assessments-panel.css +245 -0
- package/lib/stub-player/styles/_base.css +89 -0
- package/lib/stub-player/styles/_catalog-icons.css +96 -0
- package/lib/stub-player/styles/_catalog-panel.css +291 -0
- package/lib/stub-player/styles/_config-panel.css +636 -0
- package/lib/stub-player/styles/_content-viewer.css +834 -0
- package/lib/stub-player/styles/_debug-panel.css +576 -0
- package/lib/stub-player/styles/_edit-mode.css +128 -0
- package/lib/stub-player/styles/_header-bar.css +343 -0
- package/lib/stub-player/styles/_interaction-editor.css +140 -0
- package/lib/stub-player/styles/_interactions-panel.css +1038 -0
- package/lib/stub-player/styles/_login-screen.css +102 -0
- package/lib/stub-player/styles/_outline-mode.css +752 -0
- package/lib/stub-player/styles.css +15 -0
- package/lib/stub-player.js +160 -0
- package/lib/test-data-reporting.js +176 -0
- package/lib/test-error-reporting.js +146 -0
- package/lib/token.js +86 -0
- package/lib/upgrade.js +257 -0
- package/lib/validation-rules.js +517 -0
- package/lib/vite-plugin-content-discovery.js +296 -0
- package/package.json +108 -0
- package/schemas/XMLSchema.dtd +402 -0
- package/schemas/adlcp_v1p3.xsd +111 -0
- package/schemas/adlnav_v1p3.xsd +61 -0
- package/schemas/adlseq_v1p3.xsd +93 -0
- package/schemas/common/anyElement.xsd +27 -0
- package/schemas/common/dataTypes.xsd +138 -0
- package/schemas/common/elementNames.xsd +767 -0
- package/schemas/common/elementTypes.xsd +786 -0
- package/schemas/common/rootElement.xsd +31 -0
- package/schemas/common/vocabTypes.xsd +345 -0
- package/schemas/common/vocabValues.xsd +257 -0
- package/schemas/datatypes.dtd +203 -0
- package/schemas/ims_xml.xsd +35 -0
- package/schemas/imscp_v1p1.xsd +368 -0
- package/schemas/imsss_v1p0.xsd +67 -0
- package/schemas/imsss_v1p0auxresource.xsd +19 -0
- package/schemas/imsss_v1p0control.xsd +20 -0
- package/schemas/imsss_v1p0delivery.xsd +17 -0
- package/schemas/imsss_v1p0limit.xsd +47 -0
- package/schemas/imsss_v1p0objective.xsd +67 -0
- package/schemas/imsss_v1p0random.xsd +16 -0
- package/schemas/imsss_v1p0rollup.xsd +46 -0
- package/schemas/imsss_v1p0seqrule.xsd +108 -0
- package/schemas/imsss_v1p0util.xsd +94 -0
- package/schemas/license.txt +17 -0
- package/schemas/lom.xsd +102 -0
- package/schemas/lomCustom.xsd +62 -0
- package/schemas/lomLoose.xsd +62 -0
- package/schemas/lomStrict.xsd +62 -0
- package/schemas/xml.xsd +81 -0
- package/template/.env.example +92 -0
- package/template/course/assets/audio/example-intro.mp3 +0 -0
- package/template/course/assets/audio/example-ui-demo--compact-player.mp3 +0 -0
- package/template/course/assets/audio/example-ui-demo--demo-modal.mp3 +0 -0
- package/template/course/assets/audio/example-ui-demo--full-player.mp3 +0 -0
- package/template/course/assets/docs/example_md_1.md +39 -0
- package/template/course/assets/docs/example_md_2.md +41 -0
- package/template/course/assets/docs/example_pdf_1_thumbnail.png +0 -0
- package/template/course/assets/docs/example_pdf_2.pdf +0 -0
- package/template/course/assets/images/course-architecture.svg +36 -0
- package/template/course/assets/images/logo.svg +14 -0
- package/template/course/assets/widgets/counter-demo.html +190 -0
- package/template/course/assets/widgets/gravity-painter.html +384 -0
- package/template/course/course-config.js +539 -0
- package/template/course/icons.js +19 -0
- package/template/course/interactions/PLUGIN_GUIDE.md +97 -0
- package/template/course/slides/example-course-structure.js +138 -0
- package/template/course/slides/example-final-exam.js +144 -0
- package/template/course/slides/example-finishing.js +127 -0
- package/template/course/slides/example-interactions-showcase.js +615 -0
- package/template/course/slides/example-preview-tour.js +129 -0
- package/template/course/slides/example-remedial.js +143 -0
- package/template/course/slides/example-summary.js +103 -0
- package/template/course/slides/example-ui-showcase.js +1805 -0
- package/template/course/slides/example-welcome.js +123 -0
- package/template/course/slides/example-workflow.js +140 -0
- package/template/course/theme.css +165 -0
- package/template/eslint.config.js +47 -0
- package/template/package.json +28 -0
- package/template/vite.config.js +339 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file manifest-factory.js
|
|
3
|
+
* @description Factory for generating format-specific manifests.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { generateScorm2004Manifest } from './scorm-2004-manifest.js';
|
|
7
|
+
import { generateScorm12Manifest } from './scorm-12-manifest.js';
|
|
8
|
+
import { generateCmi5Manifest } from './cmi5-manifest.js';
|
|
9
|
+
import { generateScorm12ProxyManifest, generateScorm2004ProxyManifest } from './scorm-proxy-manifest.js';
|
|
10
|
+
import { generateLtiToolConfig } from './lti-tool-config.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Generates the appropriate manifest based on format.
|
|
14
|
+
* @param {string} format - 'scorm2004' | 'scorm1.2' | 'cmi5' | 'scorm1.2-proxy' | 'scorm2004-proxy' | 'cmi5-remote' | 'lti'
|
|
15
|
+
* @param {Object} config - Course configuration
|
|
16
|
+
* @param {string[]} files - List of files to include
|
|
17
|
+
* @param {Object} options - Additional options (externalUrl for proxy/remote)
|
|
18
|
+
* @returns {{ filename: string, content: string }} Manifest filename and content
|
|
19
|
+
*/
|
|
20
|
+
export function generateManifest(format, config, files, options = {}) {
|
|
21
|
+
switch (format) {
|
|
22
|
+
case 'cmi5':
|
|
23
|
+
return {
|
|
24
|
+
filename: 'cmi5.xml',
|
|
25
|
+
content: generateCmi5Manifest(config, files)
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
case 'cmi5-remote':
|
|
29
|
+
return {
|
|
30
|
+
filename: 'cmi5.xml',
|
|
31
|
+
content: generateCmi5Manifest(config, files, { externalUrl: options.externalUrl })
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
case 'scorm1.2':
|
|
35
|
+
return {
|
|
36
|
+
filename: 'imsmanifest.xml',
|
|
37
|
+
content: generateScorm12Manifest(config, files)
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
case 'scorm1.2-proxy':
|
|
41
|
+
return {
|
|
42
|
+
filename: 'imsmanifest.xml',
|
|
43
|
+
content: generateScorm12ProxyManifest(config)
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
case 'scorm2004-proxy':
|
|
47
|
+
return {
|
|
48
|
+
filename: 'imsmanifest.xml',
|
|
49
|
+
content: generateScorm2004ProxyManifest(config)
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
case 'lti':
|
|
53
|
+
return {
|
|
54
|
+
filename: 'lti-tool-config.json',
|
|
55
|
+
content: generateLtiToolConfig(config, options)
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
case 'scorm2004':
|
|
59
|
+
default:
|
|
60
|
+
return {
|
|
61
|
+
filename: 'imsmanifest.xml',
|
|
62
|
+
content: generateScorm2004Manifest(config, files)
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Gets the schema files needed for the format.
|
|
69
|
+
* @param {string} format - 'scorm2004' | 'scorm1.2' | 'cmi5'
|
|
70
|
+
* @returns {string[]} List of schema file patterns to copy
|
|
71
|
+
*/
|
|
72
|
+
export function getSchemaFiles(format) {
|
|
73
|
+
switch (format) {
|
|
74
|
+
case 'cmi5':
|
|
75
|
+
case 'lti':
|
|
76
|
+
// cmi5 and LTI don't require schema files in the package
|
|
77
|
+
return [];
|
|
78
|
+
|
|
79
|
+
case 'scorm1.2':
|
|
80
|
+
// SCORM 1.2 schema files
|
|
81
|
+
return [
|
|
82
|
+
'imscp_rootv1p1p2.xsd',
|
|
83
|
+
'adlcp_rootv1p2.xsd',
|
|
84
|
+
'ims_xml.xsd'
|
|
85
|
+
];
|
|
86
|
+
|
|
87
|
+
case 'scorm2004':
|
|
88
|
+
default:
|
|
89
|
+
// SCORM 2004 4th Edition schema files
|
|
90
|
+
return [
|
|
91
|
+
'imscp_v1p1.xsd',
|
|
92
|
+
'adlcp_v1p3.xsd',
|
|
93
|
+
'imsss_v1p0.xsd',
|
|
94
|
+
'adlseq_v1p3.xsd',
|
|
95
|
+
'adlnav_v1p3.xsd',
|
|
96
|
+
'lom.xsd'
|
|
97
|
+
];
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file scorm-12-manifest.js
|
|
3
|
+
* @description Generates imsmanifest.xml for SCORM 1.2 packages.
|
|
4
|
+
*
|
|
5
|
+
* SCORM 1.2 uses a simpler manifest structure without:
|
|
6
|
+
* - Sequencing rules (imsss namespace)
|
|
7
|
+
* - Navigation controls (adlnav namespace)
|
|
8
|
+
* - 4th Edition schema references
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Generates the SCORM 1.2 manifest.
|
|
13
|
+
* @param {Object} config - Course configuration
|
|
14
|
+
* @param {string[]} files - List of files to include in the manifest
|
|
15
|
+
* @returns {string} The manifest XML
|
|
16
|
+
*/
|
|
17
|
+
export function generateScorm12Manifest(config, files) {
|
|
18
|
+
const resourceFiles = files.filter(f =>
|
|
19
|
+
f !== 'imsmanifest.xml' &&
|
|
20
|
+
!f.endsWith('.xsd') &&
|
|
21
|
+
!f.endsWith('.dtd') &&
|
|
22
|
+
!f.startsWith('common/')
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
const fileEntries = resourceFiles.map(f => ` <file href="${f}"/>`).join('\n');
|
|
26
|
+
|
|
27
|
+
// SCORM 1.2 uses ADLCP 1.2 schema and doesn't include sequencing
|
|
28
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
29
|
+
<!-- SCORM 1.2 manifest - GENERATED FILE - DO NOT EDIT MANUALLY -->
|
|
30
|
+
<manifest identifier="${config.title.replace(/[^a-zA-Z0-9]/g, '-')}"
|
|
31
|
+
version="${config.version}"
|
|
32
|
+
xmlns="http://www.imsproject.org/xsd/imscp_rootv1p1p2"
|
|
33
|
+
xmlns:adlcp="http://www.adlnet.org/xsd/adlcp_rootv1p2"
|
|
34
|
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
35
|
+
xsi:schemaLocation="
|
|
36
|
+
http://www.imsproject.org/xsd/imscp_rootv1p1p2 imscp_rootv1p1p2.xsd
|
|
37
|
+
http://www.adlnet.org/xsd/adlcp_rootv1p2 adlcp_rootv1p2.xsd">
|
|
38
|
+
|
|
39
|
+
<metadata>
|
|
40
|
+
<schema>ADL SCORM</schema>
|
|
41
|
+
<schemaversion>1.2</schemaversion>
|
|
42
|
+
</metadata>
|
|
43
|
+
|
|
44
|
+
<organizations default="org-1">
|
|
45
|
+
<organization identifier="org-1">
|
|
46
|
+
<title>${config.title}</title>
|
|
47
|
+
<item identifier="item-1" identifierref="res-1" isvisible="true">
|
|
48
|
+
<title>${config.title}</title>
|
|
49
|
+
<adlcp:masteryscore>80</adlcp:masteryscore>
|
|
50
|
+
</item>
|
|
51
|
+
</organization>
|
|
52
|
+
</organizations>
|
|
53
|
+
|
|
54
|
+
<resources>
|
|
55
|
+
<resource identifier="res-1" type="webcontent" adlcp:scormtype="sco" href="index.html">
|
|
56
|
+
${fileEntries}
|
|
57
|
+
</resource>
|
|
58
|
+
</resources>
|
|
59
|
+
</manifest>
|
|
60
|
+
`;
|
|
61
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file scorm-2004-manifest.js
|
|
3
|
+
* @description Generates imsmanifest.xml for SCORM 2004 4th Edition packages.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Generates the SCORM 2004 4th Edition manifest.
|
|
8
|
+
* @param {Object} config - Course configuration
|
|
9
|
+
* @param {string[]} files - List of files to include in the manifest
|
|
10
|
+
* @returns {string} The manifest XML
|
|
11
|
+
*/
|
|
12
|
+
export function generateScorm2004Manifest(config, files) {
|
|
13
|
+
const resourceFiles = files.filter(f =>
|
|
14
|
+
f !== 'imsmanifest.xml' &&
|
|
15
|
+
!f.endsWith('.xsd') &&
|
|
16
|
+
!f.endsWith('.dtd') &&
|
|
17
|
+
!f.startsWith('common/')
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
const fileEntries = resourceFiles.map(f => ` <file href="${f}"/>`).join('\n');
|
|
21
|
+
|
|
22
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
23
|
+
<!-- SCORM 2004 4th Edition manifest - GENERATED FILE - DO NOT EDIT MANUALLY -->
|
|
24
|
+
<manifest identifier="${config.title.replace(/[^a-zA-Z0-9]/g, '-')}"
|
|
25
|
+
version="${config.version}"
|
|
26
|
+
xmlns="http://www.imsglobal.org/xsd/imscp_v1p1"
|
|
27
|
+
xmlns:imscp="http://www.imsglobal.org/xsd/imscp_v1p1"
|
|
28
|
+
xmlns:imsss="http://www.imsglobal.org/xsd/imsss"
|
|
29
|
+
xmlns:adlcp="http://www.adlnet.org/xsd/adlcp_v1p3"
|
|
30
|
+
xmlns:adlseq="http://www.adlnet.org/xsd/adlseq_v1p3"
|
|
31
|
+
xmlns:adlnav="http://www.adlnet.org/xsd/adlnav_v1p3"
|
|
32
|
+
xmlns:lom="http://ltsc.ieee.org/xsd/LOM"
|
|
33
|
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
34
|
+
xsi:schemaLocation="
|
|
35
|
+
http://www.imsglobal.org/xsd/imscp_v1p1 imscp_v1p1.xsd
|
|
36
|
+
http://www.imsglobal.org/xsd/imsss imsss_v1p0.xsd
|
|
37
|
+
http://www.adlnet.org/xsd/adlcp_v1p3 adlcp_v1p3.xsd
|
|
38
|
+
http://www.adlnet.org/xsd/adlseq_v1p3 adlseq_v1p3.xsd
|
|
39
|
+
http://www.adlnet.org/xsd/adlnav_v1p3 adlnav_v1p3.xsd
|
|
40
|
+
http://ltsc.ieee.org/xsd/LOM lom.xsd"
|
|
41
|
+
xml:base="./">
|
|
42
|
+
|
|
43
|
+
<metadata>
|
|
44
|
+
<schema>ADL SCORM</schema>
|
|
45
|
+
<schemaversion>2004 4th Edition</schemaversion>
|
|
46
|
+
<lom:lom>
|
|
47
|
+
<lom:general>
|
|
48
|
+
<lom:title><lom:string language="${config.language}">${config.title}</lom:string></lom:title>
|
|
49
|
+
<lom:description><lom:string language="${config.language}">${config.description}</lom:string></lom:description>
|
|
50
|
+
<lom:language>${config.language}</lom:language>
|
|
51
|
+
</lom:general>
|
|
52
|
+
<lom:lifecycle>
|
|
53
|
+
<lom:version><lom:string>${config.version}</lom:string></lom:version>
|
|
54
|
+
<lom:contribute>
|
|
55
|
+
<lom:role>
|
|
56
|
+
<lom:source><lom:string>LOMv1.0</lom:string></lom:source>
|
|
57
|
+
<lom:value><lom:string>author</lom:string></lom:value>
|
|
58
|
+
</lom:role>
|
|
59
|
+
<lom:entity>${config.author}</lom:entity>
|
|
60
|
+
</lom:contribute>
|
|
61
|
+
</lom:lifecycle>
|
|
62
|
+
<lom:technical>
|
|
63
|
+
<lom:format>text/html</lom:format>
|
|
64
|
+
</lom:technical>
|
|
65
|
+
</lom:lom>
|
|
66
|
+
</metadata>
|
|
67
|
+
|
|
68
|
+
<organizations default="org-1">
|
|
69
|
+
<organization identifier="org-1" adlseq:objectivesGlobalToSystem="false">
|
|
70
|
+
<title>${config.title}</title>
|
|
71
|
+
<item identifier="item-1" identifierref="res-1" isvisible="true">
|
|
72
|
+
<title>${config.title}</title>
|
|
73
|
+
<imsss:sequencing>
|
|
74
|
+
<imsss:controlMode choiceExit="true" forwardOnly="false"/>
|
|
75
|
+
<imsss:deliveryControls tracked="true" completionSetByContent="true" objectiveSetByContent="true"/>
|
|
76
|
+
<adlnav:presentation>
|
|
77
|
+
<adlnav:navigationInterface>
|
|
78
|
+
<adlnav:hideLMSUI>continue</adlnav:hideLMSUI>
|
|
79
|
+
<adlnav:hideLMSUI>previous</adlnav:hideLMSUI>
|
|
80
|
+
</adlnav:navigationInterface>
|
|
81
|
+
</adlnav:presentation>
|
|
82
|
+
</imsss:sequencing>
|
|
83
|
+
</item>
|
|
84
|
+
</organization>
|
|
85
|
+
</organizations>
|
|
86
|
+
|
|
87
|
+
<resources>
|
|
88
|
+
<resource identifier="res-1" type="webcontent" adlcp:scormType="sco" href="index.html">
|
|
89
|
+
${fileEntries}
|
|
90
|
+
</resource>
|
|
91
|
+
</resources>
|
|
92
|
+
</manifest>
|
|
93
|
+
`;
|
|
94
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file scorm-proxy-manifest.js
|
|
3
|
+
* @description Generates minimal SCORM manifest for proxy packages.
|
|
4
|
+
*
|
|
5
|
+
* Proxy packages contain only:
|
|
6
|
+
* - proxy.html (entry point)
|
|
7
|
+
* - scorm-bridge.js (postMessage → SCORM bridge)
|
|
8
|
+
* - pipwerks.js (SCORM API wrapper)
|
|
9
|
+
*
|
|
10
|
+
* Works for both SCORM 1.2 and 2004 - pipwerks auto-detects.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Generate SCORM 1.2 proxy manifest
|
|
15
|
+
* @param {Object} config - Course configuration
|
|
16
|
+
* @returns {string} imsmanifest.xml content
|
|
17
|
+
*/
|
|
18
|
+
export function generateScorm12ProxyManifest(config) {
|
|
19
|
+
const identifier = config.identifier ||
|
|
20
|
+
config.title.replace(/[^a-zA-Z0-9]/g, '_').toLowerCase();
|
|
21
|
+
|
|
22
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
23
|
+
<!-- SCORM 1.2 Proxy Manifest - Generated by CourseCode -->
|
|
24
|
+
<manifest identifier="${identifier}_proxy" version="1.0"
|
|
25
|
+
xmlns="http://www.imsproject.org/xsd/imscp_rootv1p1p2"
|
|
26
|
+
xmlns:adlcp="http://www.adlnet.org/xsd/adlcp_rootv1p2">
|
|
27
|
+
|
|
28
|
+
<metadata>
|
|
29
|
+
<schema>ADL SCORM</schema>
|
|
30
|
+
<schemaversion>1.2</schemaversion>
|
|
31
|
+
</metadata>
|
|
32
|
+
|
|
33
|
+
<organizations default="org_${identifier}">
|
|
34
|
+
<organization identifier="org_${identifier}">
|
|
35
|
+
<title>${escapeXml(config.title)}</title>
|
|
36
|
+
<item identifier="item_${identifier}" identifierref="res_${identifier}">
|
|
37
|
+
<title>${escapeXml(config.title)}</title>
|
|
38
|
+
</item>
|
|
39
|
+
</organization>
|
|
40
|
+
</organizations>
|
|
41
|
+
|
|
42
|
+
<resources>
|
|
43
|
+
<resource identifier="res_${identifier}" type="webcontent" adlcp:scormtype="sco" href="proxy.html">
|
|
44
|
+
<file href="proxy.html"/>
|
|
45
|
+
<file href="scorm-bridge.js"/>
|
|
46
|
+
<file href="pipwerks.js"/>
|
|
47
|
+
</resource>
|
|
48
|
+
</resources>
|
|
49
|
+
</manifest>`;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Generate SCORM 2004 proxy manifest
|
|
54
|
+
* @param {Object} config - Course configuration
|
|
55
|
+
* @returns {string} imsmanifest.xml content
|
|
56
|
+
*/
|
|
57
|
+
export function generateScorm2004ProxyManifest(config) {
|
|
58
|
+
const identifier = config.identifier ||
|
|
59
|
+
config.title.replace(/[^a-zA-Z0-9]/g, '_').toLowerCase();
|
|
60
|
+
|
|
61
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
62
|
+
<!-- SCORM 2004 Proxy Manifest - Generated by CourseCode -->
|
|
63
|
+
<manifest identifier="${identifier}_proxy" version="1.0"
|
|
64
|
+
xmlns="http://www.imsglobal.org/xsd/imscp_v1p1"
|
|
65
|
+
xmlns:adlcp="http://www.adlnet.org/xsd/adlcp_v1p3"
|
|
66
|
+
xmlns:adlseq="http://www.adlnet.org/xsd/adlseq_v1p3"
|
|
67
|
+
xmlns:adlnav="http://www.adlnet.org/xsd/adlnav_v1p3"
|
|
68
|
+
xmlns:imsss="http://www.imsglobal.org/xsd/imsss">
|
|
69
|
+
|
|
70
|
+
<metadata>
|
|
71
|
+
<schema>ADL SCORM</schema>
|
|
72
|
+
<schemaversion>2004 4th Edition</schemaversion>
|
|
73
|
+
</metadata>
|
|
74
|
+
|
|
75
|
+
<organizations default="org_${identifier}">
|
|
76
|
+
<organization identifier="org_${identifier}">
|
|
77
|
+
<title>${escapeXml(config.title)}</title>
|
|
78
|
+
<item identifier="item_${identifier}" identifierref="res_${identifier}">
|
|
79
|
+
<title>${escapeXml(config.title)}</title>
|
|
80
|
+
</item>
|
|
81
|
+
</organization>
|
|
82
|
+
</organizations>
|
|
83
|
+
|
|
84
|
+
<resources>
|
|
85
|
+
<resource identifier="res_${identifier}" type="webcontent" adlcp:scormType="sco" href="proxy.html">
|
|
86
|
+
<file href="proxy.html"/>
|
|
87
|
+
<file href="scorm-bridge.js"/>
|
|
88
|
+
<file href="pipwerks.js"/>
|
|
89
|
+
</resource>
|
|
90
|
+
</resources>
|
|
91
|
+
</manifest>`;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Escape special XML characters
|
|
96
|
+
*/
|
|
97
|
+
function escapeXml(str) {
|
|
98
|
+
return String(str)
|
|
99
|
+
.replace(/&/g, '&')
|
|
100
|
+
.replace(/</g, '<')
|
|
101
|
+
.replace(/>/g, '>')
|
|
102
|
+
.replace(/"/g, '"')
|
|
103
|
+
.replace(/'/g, ''');
|
|
104
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* manifest-parser.js - Parse SCORM imsmanifest.xml and cmi5.xml files
|
|
3
|
+
*
|
|
4
|
+
* Extracts key metadata for preview export and other tools.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Parse imsmanifest.xml content and extract key fields
|
|
9
|
+
* @param {string} xmlContent - Raw XML content of imsmanifest.xml
|
|
10
|
+
* @returns {{ identifier: string, title: string, launchFile: string, version: string | null }}
|
|
11
|
+
*/
|
|
12
|
+
export function parseManifest(xmlContent) {
|
|
13
|
+
// Extract manifest identifier
|
|
14
|
+
const identifierMatch = xmlContent.match(/<manifest\s+[^>]*identifier=["']([^"']+)["']/);
|
|
15
|
+
const identifier = identifierMatch ? identifierMatch[1] : 'unknown-course';
|
|
16
|
+
|
|
17
|
+
// Extract version from manifest element
|
|
18
|
+
const versionMatch = xmlContent.match(/<manifest\s+[^>]*version=["']([^"']+)["']/);
|
|
19
|
+
const version = versionMatch ? versionMatch[1] : null;
|
|
20
|
+
|
|
21
|
+
// Extract title from metadata (LOM format)
|
|
22
|
+
// Look for: <lom:general><lom:title><lom:string>Title</lom:string></lom:title></lom:general>
|
|
23
|
+
let title = 'SCORM Course';
|
|
24
|
+
const lomTitleMatch = xmlContent.match(/<lom:title>\s*<lom:string[^>]*>([^<]+)<\/lom:string>/);
|
|
25
|
+
if (lomTitleMatch) {
|
|
26
|
+
title = lomTitleMatch[1].trim();
|
|
27
|
+
} else {
|
|
28
|
+
// Fallback: try organization title
|
|
29
|
+
const orgTitleMatch = xmlContent.match(/<organization[^>]*>[\s\S]*?<title>([^<]+)<\/title>/);
|
|
30
|
+
if (orgTitleMatch) {
|
|
31
|
+
title = orgTitleMatch[1].trim();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Extract launch file from resource href
|
|
36
|
+
// Look for: <resource ... adlcp:scormType="sco" ... href="index.html">
|
|
37
|
+
let launchFile = 'index.html';
|
|
38
|
+
const resourceMatch = xmlContent.match(/<resource[^>]*adlcp:scormType=["']sco["'][^>]*href=["']([^"']+)["']/);
|
|
39
|
+
if (resourceMatch) {
|
|
40
|
+
launchFile = resourceMatch[1];
|
|
41
|
+
} else {
|
|
42
|
+
// Try alternate ordering (href before scormType)
|
|
43
|
+
const altMatch = xmlContent.match(/<resource[^>]*href=["']([^"']+)["'][^>]*adlcp:scormType=["']sco["']/);
|
|
44
|
+
if (altMatch) {
|
|
45
|
+
launchFile = altMatch[1];
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
identifier,
|
|
51
|
+
title,
|
|
52
|
+
launchFile,
|
|
53
|
+
version
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Parse cmi5.xml content and extract key fields
|
|
59
|
+
* @param {string} xmlContent - Raw XML content of cmi5.xml
|
|
60
|
+
* @returns {{ identifier: string, title: string, launchFile: string, version: string | null }}
|
|
61
|
+
*/
|
|
62
|
+
export function parseCmi5Manifest(xmlContent) {
|
|
63
|
+
// Extract course id
|
|
64
|
+
const idMatch = xmlContent.match(/<course\s+id=["']([^"']+)["']/);
|
|
65
|
+
const identifier = idMatch ? idMatch[1] : 'unknown-course';
|
|
66
|
+
|
|
67
|
+
// Extract title from course > title > langstring
|
|
68
|
+
let title = 'cmi5 Course';
|
|
69
|
+
const titleMatch = xmlContent.match(/<course[^>]*>[\s\S]*?<title>\s*<langstring[^>]*>([^<]+)<\/langstring>/i);
|
|
70
|
+
if (titleMatch) {
|
|
71
|
+
title = titleMatch[1].trim();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Extract launch URL from first AU
|
|
75
|
+
let launchFile = 'index.html';
|
|
76
|
+
const urlMatch = xmlContent.match(/<au[^>]*>[\s\S]*?<url>([^<]+)<\/url>/i);
|
|
77
|
+
if (urlMatch) {
|
|
78
|
+
launchFile = urlMatch[1].trim();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
identifier,
|
|
83
|
+
title,
|
|
84
|
+
launchFile,
|
|
85
|
+
version: null
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Sanitize identifier for use as localStorage key
|
|
91
|
+
* @param {string} identifier - Raw manifest identifier
|
|
92
|
+
* @returns {string} - Safe key for localStorage
|
|
93
|
+
*/
|
|
94
|
+
export function sanitizeIdentifier(identifier) {
|
|
95
|
+
return identifier.replace(/[^a-zA-Z0-9_-]/g, '_').substring(0, 64);
|
|
96
|
+
}
|