@pie-players/pie-default-tool-loaders 0.3.64 → 0.3.65
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +80 -7
- package/dist/index.d.ts +11 -0
- package/dist/index.js +12 -0
- package/dist/packaged-tool-registry.d.ts +52 -0
- package/dist/packaged-tool-registry.js +96 -0
- package/dist/registrations/accessibility-tools.d.ts +34 -0
- package/dist/registrations/accessibility-tools.js +256 -0
- package/dist/registrations/calculator.d.ts +20 -0
- package/dist/registrations/calculator.js +228 -0
- package/dist/registrations/interaction-tools.d.ts +27 -0
- package/dist/registrations/interaction-tools.js +143 -0
- package/dist/registrations/measurement-tools.d.ts +24 -0
- package/dist/registrations/measurement-tools.js +130 -0
- package/dist/registrations/subject-specific-tools.d.ts +27 -0
- package/dist/registrations/subject-specific-tools.js +158 -0
- package/dist/registrations/tts.d.ts +21 -0
- package/dist/registrations/tts.js +184 -0
- package/dist/tool-placement.d.ts +29 -0
- package/dist/tool-placement.js +52 -0
- package/dist/tool-tag-map.d.ts +16 -0
- package/dist/tool-tag-map.js +27 -0
- package/dist/universal-supports.d.ts +33 -0
- package/dist/universal-supports.js +77 -0
- package/package.json +15 -13
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subject-Specific Tools Registrations
|
|
3
|
+
*
|
|
4
|
+
* Registers tools for specific subject areas:
|
|
5
|
+
* - Graph (graphing calculator/coordinate plane)
|
|
6
|
+
* - Periodic Table (chemistry reference)
|
|
7
|
+
*
|
|
8
|
+
* Maps to QTI 3.0 standard access features:
|
|
9
|
+
* - graphingCalculator (assessment tool)
|
|
10
|
+
* - graph (assessment tool)
|
|
11
|
+
* - periodicTable (assessment tool)
|
|
12
|
+
*/
|
|
13
|
+
import { hasMathContent, hasScienceContent, } from "@pie-players/pie-assessment-toolkit/tools/internal";
|
|
14
|
+
import { createToolElement, } from "@pie-players/pie-assessment-toolkit/tools/internal";
|
|
15
|
+
import { createScopedVisibilityBinding, syncButtonAndOverlayVisibility, } from "@pie-players/pie-assessment-toolkit/tools/internal";
|
|
16
|
+
/**
|
|
17
|
+
* Graph tool registration
|
|
18
|
+
*
|
|
19
|
+
* Provides graphing calculator and coordinate plane functionality.
|
|
20
|
+
* Context-smart: appears automatically for math content or when explicitly enabled.
|
|
21
|
+
*/
|
|
22
|
+
export const graphToolRegistration = {
|
|
23
|
+
toolId: "graph",
|
|
24
|
+
name: "Graph",
|
|
25
|
+
description: "Graphing calculator and coordinate plane",
|
|
26
|
+
icon: "chart-bar",
|
|
27
|
+
// Graph is a section-level floating tool.
|
|
28
|
+
supportedLevels: ["section"],
|
|
29
|
+
// PNP support IDs
|
|
30
|
+
// Maps to QTI 3.0 standard features: graph, graphingCalculator
|
|
31
|
+
pnpSupportIds: [
|
|
32
|
+
"graph", // QTI 3.0 standard (assessment.graph)
|
|
33
|
+
"graphingCalculator", // QTI 3.0 standard (assessment.graphingCalculator)
|
|
34
|
+
"coordinatePlane", // Common variant
|
|
35
|
+
"graphingTool", // Common variant
|
|
36
|
+
],
|
|
37
|
+
/**
|
|
38
|
+
* Pass 2: Graph is relevant when math content is present
|
|
39
|
+
*/
|
|
40
|
+
isVisibleInContext(context) {
|
|
41
|
+
return hasMathContent(context);
|
|
42
|
+
},
|
|
43
|
+
renderToolbar(context, toolbarContext) {
|
|
44
|
+
const visibility = createScopedVisibilityBinding(this.toolId, toolbarContext);
|
|
45
|
+
const button = {
|
|
46
|
+
toolId: this.toolId,
|
|
47
|
+
label: this.name,
|
|
48
|
+
icon: typeof this.icon === "function" ? this.icon(context) : this.icon,
|
|
49
|
+
disabled: false,
|
|
50
|
+
ariaLabel: "Graph - Graphing calculator",
|
|
51
|
+
tooltip: "Graph",
|
|
52
|
+
onClick: () => toolbarContext.toggleTool(this.toolId),
|
|
53
|
+
active: visibility.isActive(),
|
|
54
|
+
};
|
|
55
|
+
const componentOverrides = toolbarContext.componentOverrides ?? {};
|
|
56
|
+
const overlay = createToolElement(this.toolId, context, toolbarContext, componentOverrides);
|
|
57
|
+
overlay.setAttribute("tool-id", visibility.fullToolId);
|
|
58
|
+
return {
|
|
59
|
+
toolId: this.toolId,
|
|
60
|
+
button,
|
|
61
|
+
elements: [
|
|
62
|
+
{
|
|
63
|
+
element: overlay,
|
|
64
|
+
mount: "after-buttons",
|
|
65
|
+
shell: {
|
|
66
|
+
title: this.name,
|
|
67
|
+
draggable: true,
|
|
68
|
+
resizable: true,
|
|
69
|
+
closeable: true,
|
|
70
|
+
initialWidth: 920,
|
|
71
|
+
initialHeight: 680,
|
|
72
|
+
minWidth: 640,
|
|
73
|
+
minHeight: 500,
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
sync: () => {
|
|
78
|
+
syncButtonAndOverlayVisibility({
|
|
79
|
+
button,
|
|
80
|
+
overlay,
|
|
81
|
+
isActive: visibility.isActive,
|
|
82
|
+
});
|
|
83
|
+
},
|
|
84
|
+
subscribeActive: visibility.subscribeActive,
|
|
85
|
+
};
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
/**
|
|
89
|
+
* Periodic Table tool registration
|
|
90
|
+
*
|
|
91
|
+
* Provides chemistry periodic table reference.
|
|
92
|
+
* Context-smart: appears automatically for science content or when explicitly enabled.
|
|
93
|
+
*/
|
|
94
|
+
export const periodicTableToolRegistration = {
|
|
95
|
+
toolId: "periodicTable",
|
|
96
|
+
name: "Periodic Table",
|
|
97
|
+
description: "Chemistry periodic table reference",
|
|
98
|
+
icon: "beaker",
|
|
99
|
+
// Periodic table is a section-level floating tool.
|
|
100
|
+
supportedLevels: ["section"],
|
|
101
|
+
// PNP support IDs
|
|
102
|
+
// Maps to QTI 3.0 standard feature: periodicTable
|
|
103
|
+
pnpSupportIds: [
|
|
104
|
+
"periodicTable", // QTI 3.0 standard (assessment.periodicTable)
|
|
105
|
+
"chemistryReference", // Common variant
|
|
106
|
+
"elementReference", // Common variant
|
|
107
|
+
],
|
|
108
|
+
/**
|
|
109
|
+
* Pass 2: Periodic table is relevant when science content is present
|
|
110
|
+
*/
|
|
111
|
+
isVisibleInContext(context) {
|
|
112
|
+
return hasScienceContent(context);
|
|
113
|
+
},
|
|
114
|
+
renderToolbar(context, toolbarContext) {
|
|
115
|
+
const visibility = createScopedVisibilityBinding(this.toolId, toolbarContext);
|
|
116
|
+
const button = {
|
|
117
|
+
toolId: this.toolId,
|
|
118
|
+
label: this.name,
|
|
119
|
+
icon: typeof this.icon === "function" ? this.icon(context) : this.icon,
|
|
120
|
+
disabled: false,
|
|
121
|
+
ariaLabel: "Periodic table - Chemistry reference",
|
|
122
|
+
tooltip: "Periodic Table",
|
|
123
|
+
onClick: () => toolbarContext.toggleTool(this.toolId),
|
|
124
|
+
active: visibility.isActive(),
|
|
125
|
+
};
|
|
126
|
+
const componentOverrides = toolbarContext.componentOverrides ?? {};
|
|
127
|
+
const overlay = createToolElement(this.toolId, context, toolbarContext, componentOverrides);
|
|
128
|
+
overlay.setAttribute("tool-id", visibility.fullToolId);
|
|
129
|
+
return {
|
|
130
|
+
toolId: this.toolId,
|
|
131
|
+
button,
|
|
132
|
+
elements: [
|
|
133
|
+
{
|
|
134
|
+
element: overlay,
|
|
135
|
+
mount: "after-buttons",
|
|
136
|
+
shell: {
|
|
137
|
+
title: this.name,
|
|
138
|
+
draggable: true,
|
|
139
|
+
resizable: true,
|
|
140
|
+
closeable: true,
|
|
141
|
+
initialWidth: 1160,
|
|
142
|
+
initialHeight: 760,
|
|
143
|
+
minWidth: 920,
|
|
144
|
+
minHeight: 620,
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
],
|
|
148
|
+
sync: () => {
|
|
149
|
+
syncButtonAndOverlayVisibility({
|
|
150
|
+
button,
|
|
151
|
+
overlay,
|
|
152
|
+
isActive: visibility.isActive,
|
|
153
|
+
});
|
|
154
|
+
},
|
|
155
|
+
subscribeActive: visibility.subscribeActive,
|
|
156
|
+
};
|
|
157
|
+
},
|
|
158
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text-to-Speech (TTS) Tool Registration
|
|
3
|
+
*
|
|
4
|
+
* Registers the TTS tool for reading content aloud.
|
|
5
|
+
*
|
|
6
|
+
* Maps to QTI 3.0 standard access features:
|
|
7
|
+
* - textToSpeech (auditory support)
|
|
8
|
+
* - readAloud (auditory support)
|
|
9
|
+
*/
|
|
10
|
+
import type { ToolRegistration } from "@pie-players/pie-assessment-toolkit/tools/internal";
|
|
11
|
+
export declare const TOOL_ELEMENT_UNMOUNT_CALLBACK_PROP = "__pieToolElementUnmount";
|
|
12
|
+
export declare const TOOL_ACTIVE_CHANGE_EVENT = "pie-tool-active-change";
|
|
13
|
+
/**
|
|
14
|
+
* Text-to-Speech tool registration
|
|
15
|
+
*
|
|
16
|
+
* Supports:
|
|
17
|
+
* - Reading content aloud using browser TTS or external providers
|
|
18
|
+
* - Context-aware visibility (shows when readable text is available)
|
|
19
|
+
* - All levels except assessment and element
|
|
20
|
+
*/
|
|
21
|
+
export declare const ttsToolRegistration: ToolRegistration;
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text-to-Speech (TTS) Tool Registration
|
|
3
|
+
*
|
|
4
|
+
* Registers the TTS tool for reading content aloud.
|
|
5
|
+
*
|
|
6
|
+
* Maps to QTI 3.0 standard access features:
|
|
7
|
+
* - textToSpeech (auditory support)
|
|
8
|
+
* - readAloud (auditory support)
|
|
9
|
+
*/
|
|
10
|
+
import { hasReadableText } from "@pie-players/pie-assessment-toolkit/tools/internal";
|
|
11
|
+
import { createScopedToolId } from "@pie-players/pie-assessment-toolkit/tools/internal";
|
|
12
|
+
import { buildRuntimeTTSConfig, normalizeTTSLayoutMode, normalizeTTSSpeedControlOptions, resolveTTSHostToolbarLayout, resolveTTSLayoutMode, resolveTTSBackend, resolveTTSRuntimeSettings, resolveRuntimeProvider, resolveTransportMode, } from "@pie-players/pie-assessment-toolkit/tools/internal";
|
|
13
|
+
import { TTSToolProvider } from "@pie-players/pie-assessment-toolkit/tools/internal";
|
|
14
|
+
const inlineTTSControls = new Map();
|
|
15
|
+
export const TOOL_ELEMENT_UNMOUNT_CALLBACK_PROP = "__pieToolElementUnmount";
|
|
16
|
+
export const TOOL_ACTIVE_CHANGE_EVENT = "pie-tool-active-change";
|
|
17
|
+
/**
|
|
18
|
+
* Text-to-Speech tool registration
|
|
19
|
+
*
|
|
20
|
+
* Supports:
|
|
21
|
+
* - Reading content aloud using browser TTS or external providers
|
|
22
|
+
* - Context-aware visibility (shows when readable text is available)
|
|
23
|
+
* - All levels except assessment and element
|
|
24
|
+
*/
|
|
25
|
+
export const ttsToolRegistration = {
|
|
26
|
+
toolId: "textToSpeech",
|
|
27
|
+
name: "Text to Speech",
|
|
28
|
+
description: "Read content aloud",
|
|
29
|
+
icon: "volume-up",
|
|
30
|
+
provider: {
|
|
31
|
+
getProviderId: () => "tts",
|
|
32
|
+
createProvider: (config) => {
|
|
33
|
+
const settings = resolveTTSRuntimeSettings(config);
|
|
34
|
+
return new TTSToolProvider(resolveTTSBackend(settings));
|
|
35
|
+
},
|
|
36
|
+
getInitConfig: (config) => {
|
|
37
|
+
const settings = resolveTTSRuntimeSettings(config);
|
|
38
|
+
const backend = resolveTTSBackend(settings);
|
|
39
|
+
const serverProvider = resolveRuntimeProvider(settings, backend);
|
|
40
|
+
const transportMode = resolveTransportMode(settings, serverProvider);
|
|
41
|
+
return {
|
|
42
|
+
backend,
|
|
43
|
+
serverProvider,
|
|
44
|
+
transportMode,
|
|
45
|
+
...buildRuntimeTTSConfig(settings),
|
|
46
|
+
};
|
|
47
|
+
},
|
|
48
|
+
getAuthFetcher: (config) => {
|
|
49
|
+
const runtimeAuthFetcher = config?.provider?.runtime?.authFetcher;
|
|
50
|
+
return typeof runtimeAuthFetcher === "function"
|
|
51
|
+
? runtimeAuthFetcher
|
|
52
|
+
: undefined;
|
|
53
|
+
},
|
|
54
|
+
sanitizeConfig: (config) => {
|
|
55
|
+
const settings = config.settings && typeof config.settings === "object"
|
|
56
|
+
? { ...config.settings }
|
|
57
|
+
: undefined;
|
|
58
|
+
if (settings && "layoutMode" in settings) {
|
|
59
|
+
settings.layoutMode = normalizeTTSLayoutMode(settings.layoutMode);
|
|
60
|
+
}
|
|
61
|
+
if (settings && "speedOptions" in settings) {
|
|
62
|
+
settings.speedOptions = normalizeTTSSpeedControlOptions(settings.speedOptions);
|
|
63
|
+
}
|
|
64
|
+
const normalizedConfig = {
|
|
65
|
+
...config,
|
|
66
|
+
};
|
|
67
|
+
if ("layoutMode" in normalizedConfig) {
|
|
68
|
+
normalizedConfig.layoutMode = normalizeTTSLayoutMode(normalizedConfig.layoutMode);
|
|
69
|
+
}
|
|
70
|
+
if ("speedOptions" in normalizedConfig) {
|
|
71
|
+
normalizedConfig.speedOptions = normalizeTTSSpeedControlOptions(normalizedConfig.speedOptions);
|
|
72
|
+
}
|
|
73
|
+
if (settings) {
|
|
74
|
+
normalizedConfig.settings = settings;
|
|
75
|
+
}
|
|
76
|
+
return normalizedConfig;
|
|
77
|
+
},
|
|
78
|
+
lazy: true,
|
|
79
|
+
},
|
|
80
|
+
// TTS is inline-only and scoped to item/passage contexts.
|
|
81
|
+
supportedLevels: ["item", "passage"],
|
|
82
|
+
// PNP support IDs that enable this tool
|
|
83
|
+
// Maps to QTI 3.0 standard features: textToSpeech, readAloud
|
|
84
|
+
pnpSupportIds: [
|
|
85
|
+
"textToSpeech", // QTI 3.0 standard (auditory.textToSpeech)
|
|
86
|
+
"readAloud", // QTI 3.0 standard (auditory.readAloud)
|
|
87
|
+
"tts", // Common abbreviation
|
|
88
|
+
"speechOutput", // Common variant
|
|
89
|
+
],
|
|
90
|
+
/**
|
|
91
|
+
* Pass 2: Determine if TTS is relevant in this context
|
|
92
|
+
*
|
|
93
|
+
* TTS is relevant when:
|
|
94
|
+
* - Context contains readable text (at least 10 characters)
|
|
95
|
+
*/
|
|
96
|
+
isVisibleInContext(context) {
|
|
97
|
+
return hasReadableText(context);
|
|
98
|
+
},
|
|
99
|
+
renderToolbar(_context, toolbarContext) {
|
|
100
|
+
const resolveRuntimeSettings = () => resolveTTSRuntimeSettings(toolbarContext.toolkitCoordinator?.getToolConfig(this.toolId) ||
|
|
101
|
+
undefined);
|
|
102
|
+
const resolveElementSpeedOptions = () => {
|
|
103
|
+
const runtimeSettings = resolveRuntimeSettings();
|
|
104
|
+
return normalizeTTSSpeedControlOptions(runtimeSettings.speedOptions);
|
|
105
|
+
};
|
|
106
|
+
const resolveLayoutMode = () => resolveTTSLayoutMode(resolveRuntimeSettings());
|
|
107
|
+
const resolveHostLayout = () => resolveTTSHostToolbarLayout(resolveRuntimeSettings());
|
|
108
|
+
const fullToolId = createScopedToolId(this.toolId, toolbarContext.scope.level, toolbarContext.scope.scopeId);
|
|
109
|
+
const resolveControlSize = () => {
|
|
110
|
+
const raw = toolbarContext.ui?.size;
|
|
111
|
+
return raw === "sm" || raw === "lg" ? raw : "md";
|
|
112
|
+
};
|
|
113
|
+
const ensureElement = () => {
|
|
114
|
+
let element = inlineTTSControls.get(fullToolId);
|
|
115
|
+
if (element &&
|
|
116
|
+
typeof element.isConnected ===
|
|
117
|
+
"boolean" &&
|
|
118
|
+
!element.isConnected) {
|
|
119
|
+
inlineTTSControls.delete(fullToolId);
|
|
120
|
+
element = undefined;
|
|
121
|
+
}
|
|
122
|
+
if (!element) {
|
|
123
|
+
element = document.createElement("pie-tool-tts-inline");
|
|
124
|
+
element[TOOL_ELEMENT_UNMOUNT_CALLBACK_PROP] = () => {
|
|
125
|
+
if (inlineTTSControls.get(fullToolId) === element) {
|
|
126
|
+
inlineTTSControls.delete(fullToolId);
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
inlineTTSControls.set(fullToolId, element);
|
|
130
|
+
}
|
|
131
|
+
element.setAttribute("tool-id", fullToolId);
|
|
132
|
+
element.setAttribute("catalog-id", toolbarContext.catalogId || toolbarContext.itemId);
|
|
133
|
+
element.setAttribute("language", toolbarContext.language || "en-US");
|
|
134
|
+
element.setAttribute("size", resolveControlSize());
|
|
135
|
+
element.setAttribute("layout-mode", resolveLayoutMode());
|
|
136
|
+
element.speedOptions = resolveElementSpeedOptions();
|
|
137
|
+
element.showSingleSpeedOption =
|
|
138
|
+
resolveRuntimeSettings().showSingleSpeedOption === true;
|
|
139
|
+
return element;
|
|
140
|
+
};
|
|
141
|
+
const hostLayout = resolveHostLayout();
|
|
142
|
+
return {
|
|
143
|
+
toolId: this.toolId,
|
|
144
|
+
button: null,
|
|
145
|
+
elements: [
|
|
146
|
+
{
|
|
147
|
+
element: ensureElement(),
|
|
148
|
+
mount: hostLayout.mount,
|
|
149
|
+
layoutHints: {
|
|
150
|
+
controlsRow: {
|
|
151
|
+
reserveSpace: hostLayout.controlsRow.reserveSpace,
|
|
152
|
+
showWhenToolActive: hostLayout.controlsRow.expandWhenToolActive,
|
|
153
|
+
},
|
|
154
|
+
headerOverlay: {
|
|
155
|
+
showWhenToolActive: hostLayout.headerOverlay.expandWhenToolActive,
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
],
|
|
160
|
+
subscribeActive: (callback) => {
|
|
161
|
+
const element = ensureElement();
|
|
162
|
+
const handler = (event) => {
|
|
163
|
+
const detail = event.detail;
|
|
164
|
+
callback(detail?.active === true);
|
|
165
|
+
};
|
|
166
|
+
element.addEventListener(TOOL_ACTIVE_CHANGE_EVENT, handler);
|
|
167
|
+
return () => {
|
|
168
|
+
element.removeEventListener(TOOL_ACTIVE_CHANGE_EVENT, handler);
|
|
169
|
+
};
|
|
170
|
+
},
|
|
171
|
+
sync: () => {
|
|
172
|
+
const element = ensureElement();
|
|
173
|
+
element.setAttribute("tool-id", fullToolId);
|
|
174
|
+
element.setAttribute("catalog-id", toolbarContext.catalogId || toolbarContext.itemId);
|
|
175
|
+
element.setAttribute("language", toolbarContext.language || "en-US");
|
|
176
|
+
element.setAttribute("size", resolveControlSize());
|
|
177
|
+
element.setAttribute("layout-mode", resolveLayoutMode());
|
|
178
|
+
element.speedOptions = resolveElementSpeedOptions();
|
|
179
|
+
element.showSingleSpeedOption =
|
|
180
|
+
resolveRuntimeSettings().showSingleSpeedOption === true;
|
|
181
|
+
},
|
|
182
|
+
};
|
|
183
|
+
},
|
|
184
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Placement presets for the packaged capability set.
|
|
3
|
+
*
|
|
4
|
+
* Composition data for the same reason the tag map and the registrations are:
|
|
5
|
+
* they name capabilities. The toolkit keeps `DEFAULT_TOOL_PLACEMENT`, which is
|
|
6
|
+
* empty at every level and names none.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Every packaged capability at every level it supports. Prefer explicit host
|
|
10
|
+
* configuration over adopting this wholesale.
|
|
11
|
+
*/
|
|
12
|
+
export declare const PACKAGED_TOOL_PLACEMENT: {
|
|
13
|
+
readonly assessment: readonly ["theme"];
|
|
14
|
+
readonly section: readonly ["theme"];
|
|
15
|
+
readonly item: readonly ["textToSpeech", "highlighter", "annotationToolbar", "graph", "periodicTable"];
|
|
16
|
+
readonly passage: readonly ["textToSpeech", "highlighter", "annotationToolbar", "lineReader"];
|
|
17
|
+
readonly rubric: readonly ["textToSpeech", "highlighter", "annotationToolbar", "lineReader"];
|
|
18
|
+
readonly element: readonly ["calculator", "answerEliminator", "textToSpeech", "ruler", "protractor", "highlighter", "annotationToolbar", "graph", "periodicTable"];
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Each packaged capability once, at its usual assessment surface. Not
|
|
22
|
+
* exhaustive: `supportedLevels` still bounds where a capability can run, and a
|
|
23
|
+
* host can place them differently for its own UX.
|
|
24
|
+
*/
|
|
25
|
+
export declare const SECTION_PLAYER_PREFERRED_TOOL_PLACEMENT: {
|
|
26
|
+
section: string[];
|
|
27
|
+
item: string[];
|
|
28
|
+
passage: string[];
|
|
29
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Placement presets for the packaged capability set.
|
|
3
|
+
*
|
|
4
|
+
* Composition data for the same reason the tag map and the registrations are:
|
|
5
|
+
* they name capabilities. The toolkit keeps `DEFAULT_TOOL_PLACEMENT`, which is
|
|
6
|
+
* empty at every level and names none.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Every packaged capability at every level it supports. Prefer explicit host
|
|
10
|
+
* configuration over adopting this wholesale.
|
|
11
|
+
*/
|
|
12
|
+
export const PACKAGED_TOOL_PLACEMENT = {
|
|
13
|
+
assessment: ["theme"],
|
|
14
|
+
section: ["theme"],
|
|
15
|
+
item: [
|
|
16
|
+
"textToSpeech",
|
|
17
|
+
"highlighter",
|
|
18
|
+
"annotationToolbar",
|
|
19
|
+
"graph",
|
|
20
|
+
"periodicTable",
|
|
21
|
+
],
|
|
22
|
+
passage: ["textToSpeech", "highlighter", "annotationToolbar", "lineReader"],
|
|
23
|
+
rubric: ["textToSpeech", "highlighter", "annotationToolbar", "lineReader"],
|
|
24
|
+
element: [
|
|
25
|
+
"calculator",
|
|
26
|
+
"answerEliminator",
|
|
27
|
+
"textToSpeech",
|
|
28
|
+
"ruler",
|
|
29
|
+
"protractor",
|
|
30
|
+
"highlighter",
|
|
31
|
+
"annotationToolbar",
|
|
32
|
+
"graph",
|
|
33
|
+
"periodicTable",
|
|
34
|
+
],
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Each packaged capability once, at its usual assessment surface. Not
|
|
38
|
+
* exhaustive: `supportedLevels` still bounds where a capability can run, and a
|
|
39
|
+
* host can place them differently for its own UX.
|
|
40
|
+
*/
|
|
41
|
+
export const SECTION_PLAYER_PREFERRED_TOOL_PLACEMENT = {
|
|
42
|
+
section: [
|
|
43
|
+
"theme",
|
|
44
|
+
"graph",
|
|
45
|
+
"periodicTable",
|
|
46
|
+
"lineReader",
|
|
47
|
+
"ruler",
|
|
48
|
+
"protractor",
|
|
49
|
+
],
|
|
50
|
+
item: ["calculator", "textToSpeech", "answerEliminator", "annotationToolbar"],
|
|
51
|
+
passage: ["textToSpeech", "annotationToolbar"],
|
|
52
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ToolTagMap } from "@pie-players/pie-assessment-toolkit/tools/internal";
|
|
2
|
+
/**
|
|
3
|
+
* Element tag for each packaged tool.
|
|
4
|
+
*
|
|
5
|
+
* Composition data, not core data: it is a catalogue of which capabilities exist
|
|
6
|
+
* in a deployment and which element renders each. It lived in the toolkit, where
|
|
7
|
+
* a core module naming eleven capabilities meant a host could not add a twelfth
|
|
8
|
+
* without editing our package — the map was overridable, but its default was
|
|
9
|
+
* core-resident, so the core still had to know the names.
|
|
10
|
+
*
|
|
11
|
+
* `resolveToolTag` in the toolkit reads only the overrides it is handed, and
|
|
12
|
+
* `createPackagedToolRegistry` installs this map through
|
|
13
|
+
* `ToolRegistry.setComponentOverrides`. A host composing its own registry
|
|
14
|
+
* supplies its own map the same way.
|
|
15
|
+
*/
|
|
16
|
+
export declare const PACKAGED_TOOL_TAG_MAP: ToolTagMap;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Element tag for each packaged tool.
|
|
3
|
+
*
|
|
4
|
+
* Composition data, not core data: it is a catalogue of which capabilities exist
|
|
5
|
+
* in a deployment and which element renders each. It lived in the toolkit, where
|
|
6
|
+
* a core module naming eleven capabilities meant a host could not add a twelfth
|
|
7
|
+
* without editing our package — the map was overridable, but its default was
|
|
8
|
+
* core-resident, so the core still had to know the names.
|
|
9
|
+
*
|
|
10
|
+
* `resolveToolTag` in the toolkit reads only the overrides it is handed, and
|
|
11
|
+
* `createPackagedToolRegistry` installs this map through
|
|
12
|
+
* `ToolRegistry.setComponentOverrides`. A host composing its own registry
|
|
13
|
+
* supplies its own map the same way.
|
|
14
|
+
*/
|
|
15
|
+
export const PACKAGED_TOOL_TAG_MAP = {
|
|
16
|
+
calculator: "pie-tool-calculator",
|
|
17
|
+
textToSpeech: "pie-tool-text-to-speech",
|
|
18
|
+
ruler: "pie-tool-ruler",
|
|
19
|
+
protractor: "pie-tool-protractor",
|
|
20
|
+
answerEliminator: "pie-tool-answer-eliminator",
|
|
21
|
+
highlighter: "pie-tool-annotation-toolbar",
|
|
22
|
+
lineReader: "pie-tool-line-reader",
|
|
23
|
+
theme: "pie-tool-theme",
|
|
24
|
+
annotationToolbar: "pie-tool-annotation-toolbar",
|
|
25
|
+
graph: "pie-tool-graph",
|
|
26
|
+
periodicTable: "pie-tool-periodic-table",
|
|
27
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Named preset of the PNP support ids the packaged tool set treats as universal
|
|
3
|
+
* features — data, not a derivation.
|
|
4
|
+
*
|
|
5
|
+
* This list was previously computed at import time by unioning every registered
|
|
6
|
+
* tool's `pnpSupportIds`, which made registry membership decide eligibility tier
|
|
7
|
+
* and had to be corrected by a compile-time exclusion list no host could extend.
|
|
8
|
+
* The ids below are that computation's output, frozen: adopt it, extend it, or
|
|
9
|
+
* replace it alongside the district and test-administration configuration, the
|
|
10
|
+
* same way any other policy input is chosen.
|
|
11
|
+
*
|
|
12
|
+
* Two properties this list must keep:
|
|
13
|
+
*
|
|
14
|
+
* 1. **Universal features only.** An accommodation belongs here only if the
|
|
15
|
+
* program has decided it is universal — which is a decision about the
|
|
16
|
+
* program, not about the capability. TTS sits here because the packaged set
|
|
17
|
+
* treats it as a universal feature; it is a documented accommodation in
|
|
18
|
+
* other programs.
|
|
19
|
+
* 2. **No content-dependent capability.** A capability declaring
|
|
20
|
+
* `requiresAuthoredContent` needs an authored resource to have anything to
|
|
21
|
+
* show, so granting it wholesale grants an accommodation to learners who
|
|
22
|
+
* have no documented need for it. `tests/universal-supports.test.ts`
|
|
23
|
+
* enforces this against the registrations rather than against a name list.
|
|
24
|
+
*/
|
|
25
|
+
import type { PersonalNeedsProfile } from "@pie-players/pie-players-shared/types";
|
|
26
|
+
export declare const UNIVERSAL_SUPPORTS_PRESET: readonly string[];
|
|
27
|
+
/**
|
|
28
|
+
* Build a profile granting {@link UNIVERSAL_SUPPORTS_PRESET}.
|
|
29
|
+
*
|
|
30
|
+
* A fresh array per call: a profile flows into policy inputs that hosts mutate,
|
|
31
|
+
* and handing out a shared reference would let one host's edit reach another's.
|
|
32
|
+
*/
|
|
33
|
+
export declare function createUniversalPersonalNeedsProfile(): PersonalNeedsProfile;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Named preset of the PNP support ids the packaged tool set treats as universal
|
|
3
|
+
* features — data, not a derivation.
|
|
4
|
+
*
|
|
5
|
+
* This list was previously computed at import time by unioning every registered
|
|
6
|
+
* tool's `pnpSupportIds`, which made registry membership decide eligibility tier
|
|
7
|
+
* and had to be corrected by a compile-time exclusion list no host could extend.
|
|
8
|
+
* The ids below are that computation's output, frozen: adopt it, extend it, or
|
|
9
|
+
* replace it alongside the district and test-administration configuration, the
|
|
10
|
+
* same way any other policy input is chosen.
|
|
11
|
+
*
|
|
12
|
+
* Two properties this list must keep:
|
|
13
|
+
*
|
|
14
|
+
* 1. **Universal features only.** An accommodation belongs here only if the
|
|
15
|
+
* program has decided it is universal — which is a decision about the
|
|
16
|
+
* program, not about the capability. TTS sits here because the packaged set
|
|
17
|
+
* treats it as a universal feature; it is a documented accommodation in
|
|
18
|
+
* other programs.
|
|
19
|
+
* 2. **No content-dependent capability.** A capability declaring
|
|
20
|
+
* `requiresAuthoredContent` needs an authored resource to have anything to
|
|
21
|
+
* show, so granting it wholesale grants an accommodation to learners who
|
|
22
|
+
* have no documented need for it. `tests/universal-supports.test.ts`
|
|
23
|
+
* enforces this against the registrations rather than against a name list.
|
|
24
|
+
*/
|
|
25
|
+
export const UNIVERSAL_SUPPORTS_PRESET = Object.freeze([
|
|
26
|
+
"angleMeasurement",
|
|
27
|
+
"annotation",
|
|
28
|
+
"annotations",
|
|
29
|
+
"answerEliminator",
|
|
30
|
+
"answerMasking",
|
|
31
|
+
"basicCalculator",
|
|
32
|
+
"calculator",
|
|
33
|
+
"chemistryReference",
|
|
34
|
+
"choiceMasking",
|
|
35
|
+
"colorContrast",
|
|
36
|
+
"coordinatePlane",
|
|
37
|
+
"customColors",
|
|
38
|
+
"elementReference",
|
|
39
|
+
"graph",
|
|
40
|
+
"graphingCalculator",
|
|
41
|
+
"graphingTool",
|
|
42
|
+
"highContrast",
|
|
43
|
+
"highContrastDisplay",
|
|
44
|
+
"highlighter",
|
|
45
|
+
"highlighting",
|
|
46
|
+
"invertColors",
|
|
47
|
+
"lineReader",
|
|
48
|
+
"measurement",
|
|
49
|
+
"periodicTable",
|
|
50
|
+
"protractor",
|
|
51
|
+
"readAloud",
|
|
52
|
+
"readingGuide",
|
|
53
|
+
"readingMask",
|
|
54
|
+
"readingRuler",
|
|
55
|
+
"ruler",
|
|
56
|
+
"scientificCalculator",
|
|
57
|
+
"speechOutput",
|
|
58
|
+
"strikethrough",
|
|
59
|
+
"textHighlight",
|
|
60
|
+
"textToSpeech",
|
|
61
|
+
"theme",
|
|
62
|
+
"trackingGuide",
|
|
63
|
+
"tts",
|
|
64
|
+
]);
|
|
65
|
+
/**
|
|
66
|
+
* Build a profile granting {@link UNIVERSAL_SUPPORTS_PRESET}.
|
|
67
|
+
*
|
|
68
|
+
* A fresh array per call: a profile flows into policy inputs that hosts mutate,
|
|
69
|
+
* and handing out a shared reference would let one host's edit reach another's.
|
|
70
|
+
*/
|
|
71
|
+
export function createUniversalPersonalNeedsProfile() {
|
|
72
|
+
return {
|
|
73
|
+
supports: [...UNIVERSAL_SUPPORTS_PRESET],
|
|
74
|
+
prohibitedSupports: [],
|
|
75
|
+
activateAtInit: [],
|
|
76
|
+
};
|
|
77
|
+
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pie-players/pie-default-tool-loaders",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.65",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "
|
|
5
|
+
"description": "Composition layer for the packaged PIE assessment tools: registrations, tag map, placement presets, universal supports and lazy module loaders",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "git+https://github.com/pie-framework/pie-players.git",
|
|
@@ -32,19 +32,21 @@
|
|
|
32
32
|
"test": "bun test"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@pie-players/pie-
|
|
36
|
-
"@pie-players/pie-
|
|
37
|
-
"@pie-players/pie-tool-
|
|
38
|
-
"@pie-players/pie-tool-
|
|
39
|
-
"@pie-players/pie-tool-
|
|
40
|
-
"@pie-players/pie-tool-
|
|
41
|
-
"@pie-players/pie-tool-
|
|
42
|
-
"@pie-players/pie-tool-
|
|
43
|
-
"@pie-players/pie-tool-
|
|
44
|
-
"@pie-players/pie-tool-
|
|
35
|
+
"@pie-players/pie-assessment-toolkit": "0.3.65",
|
|
36
|
+
"@pie-players/pie-players-shared": "0.3.65",
|
|
37
|
+
"@pie-players/pie-tool-annotation-toolbar": "0.3.65",
|
|
38
|
+
"@pie-players/pie-tool-answer-eliminator": "0.3.65",
|
|
39
|
+
"@pie-players/pie-tool-calculator-desmos": "0.3.65",
|
|
40
|
+
"@pie-players/pie-tool-graph": "0.3.65",
|
|
41
|
+
"@pie-players/pie-tool-line-reader": "0.3.65",
|
|
42
|
+
"@pie-players/pie-tool-periodic-table": "0.3.65",
|
|
43
|
+
"@pie-players/pie-tool-protractor": "0.3.65",
|
|
44
|
+
"@pie-players/pie-tool-ruler": "0.3.65",
|
|
45
|
+
"@pie-players/pie-tool-theme": "0.3.65",
|
|
46
|
+
"@pie-players/pie-tool-tts-inline": "0.3.65"
|
|
45
47
|
},
|
|
46
48
|
"devDependencies": {
|
|
47
|
-
"@biomejs/biome": "^2.5.
|
|
49
|
+
"@biomejs/biome": "^2.5.7",
|
|
48
50
|
"typescript": "^5.9.3"
|
|
49
51
|
},
|
|
50
52
|
"homepage": "https://github.com/pie-framework/pie-players/tree/master/packages/default-tool-loaders#readme",
|