@examind/block-sdk 0.1.41 → 0.2.1

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.
Files changed (3) hide show
  1. package/dist/index.js +189 -70
  2. package/dist/index.mjs +189 -70
  3. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -104,9 +104,9 @@ var EssayQuestionNodeHandler = class extends NodeHandler {
104
104
  }
105
105
  };
106
106
 
107
- // src/typeGuards/isSerializedFillInTheBlankQuestionNode.ts
108
- function isSerializedFillInTheBlankQuestionNode(node) {
109
- return node?.type === "fill-in-the-blank-question" && "id" in node && typeof node.id === "string" && "pointsPerSpace" in node && typeof node.pointsPerSpace === "number" && "content" in node;
107
+ // src/typeGuards/isSerializedExcelQuestionNode.ts
108
+ function isSerializedExcelQuestionNode(node) {
109
+ return node?.type === "excel-question" && "id" in node && typeof node.id === "string" && "points" in node && typeof node.points === "number" && "data" in node && typeof node.data === "object";
110
110
  }
111
111
 
112
112
  // src/typeGuards/isSerializedParagraphNode.ts
@@ -139,6 +139,35 @@ function createHtmlFromNestedEditor(editor, metadata) {
139
139
  return createHtmlFromNestedNodes(rootNode.children, metadata);
140
140
  }
141
141
 
142
+ // src/exportToHtml/ExcelQuestionNodeHandler.ts
143
+ var ExcelQuestionNodeHandler = class extends NodeHandler {
144
+ processNode(node) {
145
+ if (!isSerializedExcelQuestionNode(node)) return null;
146
+ const data = {
147
+ ...node.data,
148
+ parts: node.data.parts.map((p) => ({
149
+ ...p,
150
+ objective: createHtmlFromNestedEditor(p.objective),
151
+ instructions: createHtmlFromNestedEditor(p.instructions),
152
+ tasks: p.tasks.map((t) => ({
153
+ ...t,
154
+ instructions: createHtmlFromNestedEditor(t.instructions),
155
+ steps: t.steps.map((s) => ({
156
+ ...s,
157
+ description: createHtmlFromNestedEditor(s.description)
158
+ }))
159
+ }))
160
+ }))
161
+ };
162
+ return `<x-excel id="${node.id}" data-x-prompt data-x-points="${node.points}"><x-data>${JSON.stringify(data)}</x-data></x-excel>`;
163
+ }
164
+ };
165
+
166
+ // src/typeGuards/isSerializedFillInTheBlankQuestionNode.ts
167
+ function isSerializedFillInTheBlankQuestionNode(node) {
168
+ return node?.type === "fill-in-the-blank-question" && "id" in node && typeof node.id === "string" && "pointsPerSpace" in node && typeof node.pointsPerSpace === "number" && "content" in node;
169
+ }
170
+
142
171
  // src/exportToHtml/FillInTheBlankQuestionNodeHandler.ts
143
172
  var FillInTheBlankQuestionNodeHandler = class extends NodeHandler {
144
173
  processNode(node) {
@@ -975,7 +1004,7 @@ var VariableNodeHandler = class extends NodeHandler {
975
1004
 
976
1005
  // src/exportToHtml/traverse.ts
977
1006
  var builder = new NodeHandlerChainBuilder();
978
- var nodeHandlerChain = builder.addHandler(CustomQuestionNodeHandler).addHandler(EssayQuestionNodeHandler).addHandler(FillInTheBlankQuestionNodeHandler).addHandler(FillInTheBlankSpaceNodeHandler).addHandler(FinancialStatementQuestionNodeHandler).addHandler(HeadingNodeHandler).addHandler(HorizontalRuleNodeHandler).addHandler(ImageNodeHandler).addHandler(JournalEntryQuestionNodeHandler).addHandler(LineBreakNodeHandler).addHandler(LinkNodeHandler).addHandler(ListNodeHandler).addHandler(ListItemNodeHandler).addHandler(MatchingQuestionNodeHandler).addHandler(MultipleOptionQuestionNodeHandler).addHandler(ParagraphNodeHandler).addHandler(ShortAnswerQuestionNodeHandler).addHandler(SimulationQuestionNodeHandler).addHandler(TableCellNodeHandler).addHandler(TableNodeHandler).addHandler(TableRowNodeHandler).addHandler(TextNodeHandler).addHandler(VariableNodeHandler).build();
1007
+ var nodeHandlerChain = builder.addHandler(CustomQuestionNodeHandler).addHandler(EssayQuestionNodeHandler).addHandler(ExcelQuestionNodeHandler).addHandler(FillInTheBlankQuestionNodeHandler).addHandler(FillInTheBlankSpaceNodeHandler).addHandler(FinancialStatementQuestionNodeHandler).addHandler(HeadingNodeHandler).addHandler(HorizontalRuleNodeHandler).addHandler(ImageNodeHandler).addHandler(JournalEntryQuestionNodeHandler).addHandler(LineBreakNodeHandler).addHandler(LinkNodeHandler).addHandler(ListNodeHandler).addHandler(ListItemNodeHandler).addHandler(MatchingQuestionNodeHandler).addHandler(MultipleOptionQuestionNodeHandler).addHandler(ParagraphNodeHandler).addHandler(ShortAnswerQuestionNodeHandler).addHandler(SimulationQuestionNodeHandler).addHandler(TableCellNodeHandler).addHandler(TableNodeHandler).addHandler(TableRowNodeHandler).addHandler(TextNodeHandler).addHandler(VariableNodeHandler).build();
979
1008
  var traverse = (node, metadata) => {
980
1009
  return nodeHandlerChain.handle(node, metadata);
981
1010
  };
@@ -994,7 +1023,7 @@ function exportToHtml(editorState) {
994
1023
  }
995
1024
 
996
1025
  // src/importFromHtml/index.ts
997
- var import_node_html_parser29 = require("node-html-parser");
1026
+ var import_node_html_parser31 = require("node-html-parser");
998
1027
 
999
1028
  // src/importFromHtml/createEmptyParagraphNode.ts
1000
1029
  function createEmptyParagraphNode(format = "") {
@@ -1273,10 +1302,6 @@ var EssayQuestionNodeHandler2 = class extends NodeHandler2 {
1273
1302
  }
1274
1303
  };
1275
1304
 
1276
- // src/importFromHtml/FillInTheBlankQuestionNodeHandler.ts
1277
- var import_nanoid2 = require("nanoid");
1278
- var import_node_html_parser5 = require("node-html-parser");
1279
-
1280
1305
  // src/importFromHtml/createNestedEditorFromHtml.ts
1281
1306
  function createNestedEditorFromHtml(node) {
1282
1307
  return {
@@ -1293,10 +1318,104 @@ function createNestedEditorFromHtml(node) {
1293
1318
  };
1294
1319
  }
1295
1320
 
1321
+ // src/importFromHtml/ExcelQuestionNodeHandler.ts
1322
+ var import_node_html_parser5 = require("node-html-parser");
1323
+ var TAG_X = "x-excel";
1324
+ function parseData(xDataString) {
1325
+ const xData = JSON.parse(xDataString);
1326
+ const parts = [];
1327
+ for (const xPart of xData.parts ?? []) {
1328
+ const tasks = [];
1329
+ for (const xTask of xPart.tasks ?? []) {
1330
+ const steps = [];
1331
+ for (const xStep of xTask.steps ?? []) {
1332
+ steps.push({
1333
+ id: xStep.id,
1334
+ description: createNestedEditorFromHtml(
1335
+ (0, import_node_html_parser5.parse)(xStep.description ?? "")
1336
+ )
1337
+ });
1338
+ }
1339
+ tasks.push({
1340
+ id: xTask.id,
1341
+ instructions: createNestedEditorFromHtml(
1342
+ (0, import_node_html_parser5.parse)(xTask.instructions ?? "")
1343
+ ),
1344
+ steps
1345
+ });
1346
+ }
1347
+ parts.push({
1348
+ id: xPart.id,
1349
+ objective: createNestedEditorFromHtml(
1350
+ (0, import_node_html_parser5.parse)(xPart.objective ?? "")
1351
+ ),
1352
+ instructions: createNestedEditorFromHtml(
1353
+ (0, import_node_html_parser5.parse)(xPart.instructions ?? "")
1354
+ ),
1355
+ onLoadActions: xPart.onLoadActions,
1356
+ onNextActions: xPart.onNextActions,
1357
+ tasks
1358
+ });
1359
+ }
1360
+ return {
1361
+ sourceFileName: xData.sourceFileName || "",
1362
+ transformations: xData.transformations || [],
1363
+ parts
1364
+ };
1365
+ }
1366
+ var ExcelQuestionNodeHandler2 = class extends NodeHandler2 {
1367
+ processNode(node) {
1368
+ if (!(node instanceof import_node_html_parser5.HTMLElement) || node.tagName !== TAG_X.toUpperCase()) {
1369
+ return null;
1370
+ }
1371
+ const xDataElement = node.querySelector("x-data");
1372
+ if (!xDataElement) {
1373
+ return null;
1374
+ }
1375
+ const data = parseData(
1376
+ xDataElement.innerHTML
1377
+ );
1378
+ const jsonNode = {
1379
+ id: node.getAttribute("id") || "",
1380
+ points: Number(node.getAttribute("data-x-points") || 1),
1381
+ data,
1382
+ active: data.parts.length > 0 ? data.parts[0].id : "",
1383
+ type: "excel-question",
1384
+ version: 1
1385
+ };
1386
+ return jsonNode;
1387
+ }
1388
+ };
1389
+
1390
+ // src/importFromHtml/ExcelWorksheetLinkNodeHandler.ts
1391
+ var import_node_html_parser6 = require("node-html-parser");
1392
+ var TAG = "x-worksheet-link";
1393
+ var ExcelWorksheetLinkNodeHandler = class extends NodeHandler2 {
1394
+ processNode(node) {
1395
+ if (!(node instanceof import_node_html_parser6.HTMLElement) || node.tagName !== TAG.toUpperCase()) {
1396
+ return null;
1397
+ }
1398
+ const url = node.getAttribute("x-data-name") || "";
1399
+ const linkNode = {
1400
+ detail: 0,
1401
+ format: 0,
1402
+ mode: "normal",
1403
+ style: "",
1404
+ text: node.text || url,
1405
+ dataName: url,
1406
+ type: "excel-worksheet-link",
1407
+ version: 1
1408
+ };
1409
+ return linkNode;
1410
+ }
1411
+ };
1412
+
1296
1413
  // src/importFromHtml/FillInTheBlankQuestionNodeHandler.ts
1414
+ var import_nanoid2 = require("nanoid");
1415
+ var import_node_html_parser7 = require("node-html-parser");
1297
1416
  var FillInTheBlankQuestionNodeHandler2 = class extends NodeHandler2 {
1298
1417
  processNode(node) {
1299
- if (!(node instanceof import_node_html_parser5.HTMLElement) || node.tagName !== "x-fill-in-the-blank".toUpperCase())
1418
+ if (!(node instanceof import_node_html_parser7.HTMLElement) || node.tagName !== "x-fill-in-the-blank".toUpperCase())
1300
1419
  return null;
1301
1420
  const jsonNode = {
1302
1421
  id: node.getAttribute("id") ?? (0, import_nanoid2.nanoid)(),
@@ -1313,7 +1432,7 @@ var FillInTheBlankQuestionNodeHandler2 = class extends NodeHandler2 {
1313
1432
 
1314
1433
  // src/importFromHtml/FillInTheBlankSpaceNodeHandler.ts
1315
1434
  var import_nanoid3 = require("nanoid");
1316
- var import_node_html_parser6 = require("node-html-parser");
1435
+ var import_node_html_parser8 = require("node-html-parser");
1317
1436
 
1318
1437
  // src/importFromHtml/parseErrorToleranceAttribute.ts
1319
1438
  function parseErrorToleranceAttribute(attr) {
@@ -1325,7 +1444,7 @@ function parseErrorToleranceAttribute(attr) {
1325
1444
  // src/importFromHtml/FillInTheBlankSpaceNodeHandler.ts
1326
1445
  var FillInTheBlankSpaceNodeHandler2 = class extends NodeHandler2 {
1327
1446
  processNode(node) {
1328
- if (!(node instanceof import_node_html_parser6.HTMLElement) || node.tagName !== "x-space".toUpperCase())
1447
+ if (!(node instanceof import_node_html_parser8.HTMLElement) || node.tagName !== "x-space".toUpperCase())
1329
1448
  return null;
1330
1449
  const spaceTypeAttr = node.getAttribute("data-x-type");
1331
1450
  const spaceType = spaceTypeAttr === "Text" || spaceTypeAttr === "Number" || spaceTypeAttr === "Dropdown" ? spaceTypeAttr : "Text";
@@ -1375,7 +1494,7 @@ var FillInTheBlankSpaceNodeHandler2 = class extends NodeHandler2 {
1375
1494
 
1376
1495
  // src/importFromHtml/FinancialStatementQuestionNodeHandler.ts
1377
1496
  var import_nanoid4 = require("nanoid");
1378
- var import_node_html_parser7 = require("node-html-parser");
1497
+ var import_node_html_parser9 = require("node-html-parser");
1379
1498
  var TAG_X_FINANCIAL_STATEMENT = "x-financial-statement";
1380
1499
  var TAG_X_HEADER = "x-header";
1381
1500
  var TAG_X_ROWS = "x-rows";
@@ -1387,7 +1506,7 @@ var TAG_X_ENTRY = "x-entry";
1387
1506
  var TAG_X_AMOUNT = "x-amount";
1388
1507
  var FinancialStatementQuestionNodeHandler2 = class extends NodeHandler2 {
1389
1508
  processNode(node) {
1390
- if (!(node instanceof import_node_html_parser7.HTMLElement) || node.tagName !== TAG_X_FINANCIAL_STATEMENT.toUpperCase()) {
1509
+ if (!(node instanceof import_node_html_parser9.HTMLElement) || node.tagName !== TAG_X_FINANCIAL_STATEMENT.toUpperCase()) {
1391
1510
  return null;
1392
1511
  }
1393
1512
  const headerElement = node.querySelector(TAG_X_HEADER);
@@ -1402,7 +1521,7 @@ var FinancialStatementQuestionNodeHandler2 = class extends NodeHandler2 {
1402
1521
  version: 1
1403
1522
  };
1404
1523
  node.childNodes.forEach((child) => {
1405
- if (!(child instanceof import_node_html_parser7.HTMLElement)) return;
1524
+ if (!(child instanceof import_node_html_parser9.HTMLElement)) return;
1406
1525
  if (child.tagName === TAG_X_DISTRACTORS.toUpperCase()) {
1407
1526
  this.processDistractorsNode(child, jsonNode);
1408
1527
  } else if (child.tagName === TAG_X_ROWS.toUpperCase()) {
@@ -1413,7 +1532,7 @@ var FinancialStatementQuestionNodeHandler2 = class extends NodeHandler2 {
1413
1532
  }
1414
1533
  processDistractorsNode(distractorsNode, jsonNode) {
1415
1534
  for (const distractorsChild of distractorsNode.childNodes) {
1416
- if (!(distractorsChild instanceof import_node_html_parser7.HTMLElement)) continue;
1535
+ if (!(distractorsChild instanceof import_node_html_parser9.HTMLElement)) continue;
1417
1536
  if (distractorsChild.tagName !== TAG_X_DISTRACTOR.toUpperCase())
1418
1537
  continue;
1419
1538
  jsonNode.distractors.push({
@@ -1434,7 +1553,7 @@ var FinancialStatementQuestionNodeHandler2 = class extends NodeHandler2 {
1434
1553
  const contentDiv = headerElement.querySelector(
1435
1554
  'div > div:not([style*="display:flex"])'
1436
1555
  );
1437
- if (contentDiv && contentDiv instanceof import_node_html_parser7.HTMLElement)
1556
+ if (contentDiv && contentDiv instanceof import_node_html_parser9.HTMLElement)
1438
1557
  return createNestedEditorFromHtml(contentDiv);
1439
1558
  }
1440
1559
  return createNestedEditorFromHtml(headerElement);
@@ -1451,7 +1570,7 @@ var FinancialStatementQuestionNodeHandler2 = class extends NodeHandler2 {
1451
1570
  }
1452
1571
  processRowsNode(rowsNode, jsonNode) {
1453
1572
  for (const rowsChild of rowsNode.childNodes) {
1454
- if (!(rowsChild instanceof import_node_html_parser7.HTMLElement)) continue;
1573
+ if (!(rowsChild instanceof import_node_html_parser9.HTMLElement)) continue;
1455
1574
  if (rowsChild.tagName === TAG_X_HEADING.toUpperCase()) {
1456
1575
  this.processHeadingRow(rowsChild, jsonNode);
1457
1576
  } else if (rowsChild.tagName === TAG_X_LINE.toUpperCase()) {
@@ -1485,7 +1604,7 @@ var FinancialStatementQuestionNodeHandler2 = class extends NodeHandler2 {
1485
1604
  };
1486
1605
 
1487
1606
  // src/importFromHtml/FormattedNodeHandler.ts
1488
- var import_node_html_parser8 = require("node-html-parser");
1607
+ var import_node_html_parser10 = require("node-html-parser");
1489
1608
  var IS_BOLD2 = 1;
1490
1609
  var IS_ITALIC2 = 1 << 1;
1491
1610
  var IS_STRIKETHROUGH2 = 1 << 2;
@@ -1525,7 +1644,7 @@ function formatToProps(format) {
1525
1644
  }
1526
1645
  var FormattedNodeHandler = class extends NodeHandler2 {
1527
1646
  processNode(node) {
1528
- if (!(node instanceof import_node_html_parser8.HTMLElement)) return null;
1647
+ if (!(node instanceof import_node_html_parser10.HTMLElement)) return null;
1529
1648
  const tagName = node.tagName;
1530
1649
  if (!tagName || !(tagName in TAG_TO_FORMAT)) return null;
1531
1650
  const formatFlag = TAG_TO_FORMAT[tagName];
@@ -1560,7 +1679,7 @@ var FormattedNodeHandler = class extends NodeHandler2 {
1560
1679
  };
1561
1680
 
1562
1681
  // src/importFromHtml/HeadingNodeHandler.ts
1563
- var import_node_html_parser9 = require("node-html-parser");
1682
+ var import_node_html_parser11 = require("node-html-parser");
1564
1683
 
1565
1684
  // src/importFromHtml/extractTextAlignment.ts
1566
1685
  var TEXT_ALIGN_TO_FORMAT = {
@@ -1588,7 +1707,7 @@ function extractTextAlignment(element) {
1588
1707
  var TAG_HEADINGS = ["h1", "h2", "h3", "h4", "h5", "h6"];
1589
1708
  var HeadingNodeHandler2 = class extends NodeHandler2 {
1590
1709
  processNode(node) {
1591
- if (!(node instanceof import_node_html_parser9.HTMLElement) || !TAG_HEADINGS.includes(node.tagName.toLowerCase())) {
1710
+ if (!(node instanceof import_node_html_parser11.HTMLElement) || !TAG_HEADINGS.includes(node.tagName.toLowerCase())) {
1592
1711
  return null;
1593
1712
  }
1594
1713
  const headingNode = {
@@ -1609,11 +1728,11 @@ var HeadingNodeHandler2 = class extends NodeHandler2 {
1609
1728
  };
1610
1729
 
1611
1730
  // src/importFromHtml/HorizontalRuleNodeHandler.ts
1612
- var import_node_html_parser10 = require("node-html-parser");
1731
+ var import_node_html_parser12 = require("node-html-parser");
1613
1732
  var TAG_HR = "hr";
1614
1733
  var HorizontalRuleNodeHandler2 = class extends NodeHandler2 {
1615
1734
  processNode(node) {
1616
- if (!(node instanceof import_node_html_parser10.HTMLElement) || node.tagName !== TAG_HR.toUpperCase()) {
1735
+ if (!(node instanceof import_node_html_parser12.HTMLElement) || node.tagName !== TAG_HR.toUpperCase()) {
1617
1736
  return null;
1618
1737
  }
1619
1738
  const horizontalRuleNode = {
@@ -1625,11 +1744,11 @@ var HorizontalRuleNodeHandler2 = class extends NodeHandler2 {
1625
1744
  };
1626
1745
 
1627
1746
  // src/importFromHtml/ImageNodeHandler.ts
1628
- var import_node_html_parser11 = require("node-html-parser");
1747
+ var import_node_html_parser13 = require("node-html-parser");
1629
1748
  var TAG_IMG = "img";
1630
1749
  var ImageNodeHandler2 = class extends NodeHandler2 {
1631
1750
  processNode(node) {
1632
- if (!(node instanceof import_node_html_parser11.HTMLElement) || node.tagName !== TAG_IMG.toUpperCase()) {
1751
+ if (!(node instanceof import_node_html_parser13.HTMLElement) || node.tagName !== TAG_IMG.toUpperCase()) {
1633
1752
  return null;
1634
1753
  }
1635
1754
  return createImageNode(
@@ -1645,11 +1764,11 @@ var ImageNodeHandler2 = class extends NodeHandler2 {
1645
1764
 
1646
1765
  // src/importFromHtml/JournalEntryQuestionNodeHandler.ts
1647
1766
  var import_nanoid6 = require("nanoid");
1648
- var import_node_html_parser13 = require("node-html-parser");
1767
+ var import_node_html_parser15 = require("node-html-parser");
1649
1768
 
1650
1769
  // src/importFromHtml/createOnePerLineDistractorNode.ts
1651
1770
  var import_nanoid5 = require("nanoid");
1652
- var import_node_html_parser12 = require("node-html-parser");
1771
+ var import_node_html_parser14 = require("node-html-parser");
1653
1772
  function extractDistractorId(id) {
1654
1773
  if (!id) return null;
1655
1774
  const parts = id.split("|");
@@ -1662,7 +1781,7 @@ var createOnePerLineDistractorNode = (node) => {
1662
1781
  distractorEditor.editorState.root.children = [];
1663
1782
  let distractorId = null;
1664
1783
  distractors.forEach((distractor) => {
1665
- if (!(distractor instanceof import_node_html_parser12.HTMLElement)) return;
1784
+ if (!(distractor instanceof import_node_html_parser14.HTMLElement)) return;
1666
1785
  distractorId = distractorId ?? extractDistractorId(distractor.getAttribute("id"));
1667
1786
  distractorEditor.editorState.root.children.push(
1668
1787
  ...createNestedNodesFromHtml(distractor)
@@ -1680,7 +1799,7 @@ var createOnePerLineDistractorNode = (node) => {
1680
1799
  // src/importFromHtml/JournalEntryQuestionNodeHandler.ts
1681
1800
  var JournalEntryQuestionNodeHandler2 = class extends NodeHandler2 {
1682
1801
  processNode(node) {
1683
- if (!(node instanceof import_node_html_parser13.HTMLElement) || node.tagName !== "x-journal-entry".toUpperCase())
1802
+ if (!(node instanceof import_node_html_parser15.HTMLElement) || node.tagName !== "x-journal-entry".toUpperCase())
1684
1803
  return null;
1685
1804
  const jsonNode = {
1686
1805
  id: node.getAttribute("id") ?? (0, import_nanoid6.nanoid)(),
@@ -1695,7 +1814,7 @@ var JournalEntryQuestionNodeHandler2 = class extends NodeHandler2 {
1695
1814
  };
1696
1815
  const lineItems = node.querySelectorAll("x-line-item");
1697
1816
  lineItems.forEach((lineItem) => {
1698
- if (!(lineItem instanceof import_node_html_parser13.HTMLElement)) return;
1817
+ if (!(lineItem instanceof import_node_html_parser15.HTMLElement)) return;
1699
1818
  const accountElement = lineItem.querySelector("x-account");
1700
1819
  const debitElement = lineItem.querySelector("x-debit");
1701
1820
  const creditElement = lineItem.querySelector("x-credit");
@@ -1724,10 +1843,10 @@ var JournalEntryQuestionNodeHandler2 = class extends NodeHandler2 {
1724
1843
  };
1725
1844
 
1726
1845
  // src/importFromHtml/LineBreakNodeHandler.ts
1727
- var import_node_html_parser14 = require("node-html-parser");
1846
+ var import_node_html_parser16 = require("node-html-parser");
1728
1847
  var LineBreakNodeHandler2 = class extends NodeHandler2 {
1729
1848
  processNode(node) {
1730
- if (!(node instanceof import_node_html_parser14.HTMLElement)) return null;
1849
+ if (!(node instanceof import_node_html_parser16.HTMLElement)) return null;
1731
1850
  if (node.tagName !== "BR") return null;
1732
1851
  return {
1733
1852
  type: "linebreak",
@@ -1737,11 +1856,11 @@ var LineBreakNodeHandler2 = class extends NodeHandler2 {
1737
1856
  };
1738
1857
 
1739
1858
  // src/importFromHtml/LinkNodeHandler.ts
1740
- var import_node_html_parser15 = require("node-html-parser");
1859
+ var import_node_html_parser17 = require("node-html-parser");
1741
1860
  var TAG_A = "a";
1742
1861
  var LinkNodeHandler2 = class extends NodeHandler2 {
1743
1862
  processNode(node) {
1744
- if (!(node instanceof import_node_html_parser15.HTMLElement) || node.tagName !== TAG_A.toUpperCase()) {
1863
+ if (!(node instanceof import_node_html_parser17.HTMLElement) || node.tagName !== TAG_A.toUpperCase()) {
1745
1864
  return null;
1746
1865
  }
1747
1866
  const url = node.getAttribute("href") || "";
@@ -1770,10 +1889,10 @@ var LinkNodeHandler2 = class extends NodeHandler2 {
1770
1889
  };
1771
1890
 
1772
1891
  // src/importFromHtml/ListItemNodeHandler.ts
1773
- var import_node_html_parser16 = require("node-html-parser");
1892
+ var import_node_html_parser18 = require("node-html-parser");
1774
1893
  var ListItemNodeHandler2 = class extends NodeHandler2 {
1775
1894
  processNode(node) {
1776
- if (!(node instanceof import_node_html_parser16.HTMLElement)) return null;
1895
+ if (!(node instanceof import_node_html_parser18.HTMLElement)) return null;
1777
1896
  if (node.tagName !== "LI") return null;
1778
1897
  const jsonNode = {
1779
1898
  type: "listitem",
@@ -1794,10 +1913,10 @@ var ListItemNodeHandler2 = class extends NodeHandler2 {
1794
1913
  };
1795
1914
 
1796
1915
  // src/importFromHtml/ListNodeHandler.ts
1797
- var import_node_html_parser17 = require("node-html-parser");
1916
+ var import_node_html_parser19 = require("node-html-parser");
1798
1917
  var ListNodeHandler2 = class extends NodeHandler2 {
1799
1918
  processNode(node) {
1800
- if (!(node instanceof import_node_html_parser17.HTMLElement)) return null;
1919
+ if (!(node instanceof import_node_html_parser19.HTMLElement)) return null;
1801
1920
  if (node.tagName !== "UL" && node.tagName !== "OL") return null;
1802
1921
  const tag = node.tagName.toLowerCase();
1803
1922
  const listType = tag === "ol" ? "number" : "bullet";
@@ -1815,7 +1934,7 @@ var ListNodeHandler2 = class extends NodeHandler2 {
1815
1934
  };
1816
1935
  let itemIndex = 1;
1817
1936
  node.childNodes.forEach((child) => {
1818
- if (child instanceof import_node_html_parser17.HTMLElement && child.tagName === "LI") {
1937
+ if (child instanceof import_node_html_parser19.HTMLElement && child.tagName === "LI") {
1819
1938
  const listItemNode = {
1820
1939
  type: "listitem",
1821
1940
  version: 1,
@@ -1840,10 +1959,10 @@ var ListNodeHandler2 = class extends NodeHandler2 {
1840
1959
 
1841
1960
  // src/importFromHtml/MatchingQuestionNodeHandler.ts
1842
1961
  var import_nanoid7 = require("nanoid");
1843
- var import_node_html_parser18 = require("node-html-parser");
1962
+ var import_node_html_parser20 = require("node-html-parser");
1844
1963
  var MatchingQuestionNodeHandler2 = class extends NodeHandler2 {
1845
1964
  processNode(node) {
1846
- if (!(node instanceof import_node_html_parser18.HTMLElement) || node.tagName !== "x-matching".toUpperCase())
1965
+ if (!(node instanceof import_node_html_parser20.HTMLElement) || node.tagName !== "x-matching".toUpperCase())
1847
1966
  return null;
1848
1967
  const jsonNode = {
1849
1968
  id: node.getAttribute("id") ?? (0, import_nanoid7.nanoid)(),
@@ -1856,7 +1975,7 @@ var MatchingQuestionNodeHandler2 = class extends NodeHandler2 {
1856
1975
  };
1857
1976
  const matches = node.querySelectorAll("x-match");
1858
1977
  matches.forEach((match) => {
1859
- if (!(match instanceof import_node_html_parser18.HTMLElement)) return;
1978
+ if (!(match instanceof import_node_html_parser20.HTMLElement)) return;
1860
1979
  const premise = match.querySelector("x-premise");
1861
1980
  const option = match.querySelector("x-option");
1862
1981
  if (!premise || !option) return;
@@ -1879,10 +1998,10 @@ var MatchingQuestionNodeHandler2 = class extends NodeHandler2 {
1879
1998
 
1880
1999
  // src/importFromHtml/MultipleOptionQuestionNodeHandler.ts
1881
2000
  var import_nanoid8 = require("nanoid");
1882
- var import_node_html_parser19 = require("node-html-parser");
2001
+ var import_node_html_parser21 = require("node-html-parser");
1883
2002
  var MultipleOptionQuestionNodeHandler2 = class extends NodeHandler2 {
1884
2003
  processNode(node) {
1885
- if (!(node instanceof import_node_html_parser19.HTMLElement)) return null;
2004
+ if (!(node instanceof import_node_html_parser21.HTMLElement)) return null;
1886
2005
  if (node.tagName === "x-multiple-choice".toUpperCase())
1887
2006
  return this.processMultipleChoiceNode(node);
1888
2007
  else if (node.tagName === "x-multiple-answers".toUpperCase())
@@ -1922,7 +2041,7 @@ var MultipleOptionQuestionNodeHandler2 = class extends NodeHandler2 {
1922
2041
  processOptions(node, jsonNode) {
1923
2042
  const childNodes = node.childNodes;
1924
2043
  childNodes.forEach((child) => {
1925
- if (!(child instanceof import_node_html_parser19.HTMLElement)) return;
2044
+ if (!(child instanceof import_node_html_parser21.HTMLElement)) return;
1926
2045
  if (child.tagName !== "x-option".toUpperCase()) return;
1927
2046
  jsonNode.options.push({
1928
2047
  id: child.getAttribute("id") ?? (0, import_nanoid8.nanoid)(),
@@ -1934,28 +2053,28 @@ var MultipleOptionQuestionNodeHandler2 = class extends NodeHandler2 {
1934
2053
  };
1935
2054
 
1936
2055
  // src/importFromHtml/ParagraphNodeHandler.ts
1937
- var import_node_html_parser20 = require("node-html-parser");
2056
+ var import_node_html_parser22 = require("node-html-parser");
1938
2057
  var ParagraphNodeHandler2 = class extends NodeHandler2 {
1939
2058
  processImageNode(node) {
1940
- if (node.childNodes.length === 1 && node.childNodes[0] instanceof import_node_html_parser20.HTMLElement && node.childNodes[0].tagName === "IMG") {
2059
+ if (node.childNodes.length === 1 && node.childNodes[0] instanceof import_node_html_parser22.HTMLElement && node.childNodes[0].tagName === "IMG") {
1941
2060
  return traverse2(node.childNodes[0]);
1942
2061
  }
1943
2062
  return null;
1944
2063
  }
1945
2064
  processSpanImageNode(node) {
1946
- if (node.childNodes.length === 1 && node.childNodes[0] instanceof import_node_html_parser20.HTMLElement && node.childNodes[0].tagName === "SPAN" && node.childNodes[0].childNodes.length === 1 && node.childNodes[0].childNodes[0] instanceof import_node_html_parser20.HTMLElement && node.childNodes[0].childNodes[0].tagName === "IMG") {
2065
+ if (node.childNodes.length === 1 && node.childNodes[0] instanceof import_node_html_parser22.HTMLElement && node.childNodes[0].tagName === "SPAN" && node.childNodes[0].childNodes.length === 1 && node.childNodes[0].childNodes[0] instanceof import_node_html_parser22.HTMLElement && node.childNodes[0].childNodes[0].tagName === "IMG") {
1947
2066
  return traverse2(node.childNodes[0].childNodes[0]);
1948
2067
  }
1949
2068
  return null;
1950
2069
  }
1951
2070
  processNode(node) {
1952
- if (!(node instanceof import_node_html_parser20.HTMLElement)) return null;
2071
+ if (!(node instanceof import_node_html_parser22.HTMLElement)) return null;
1953
2072
  if (node.tagName !== "P") return null;
1954
2073
  const imageNode = this.processImageNode(node) ?? this.processSpanImageNode(node);
1955
2074
  if (imageNode) return imageNode;
1956
2075
  const jsonNode = createEmptyParagraphNode();
1957
2076
  jsonNode.format = extractTextAlignment(node);
1958
- if (node.childNodes.length === 1 && node.childNodes[0] instanceof import_node_html_parser20.HTMLElement && node.childNodes[0].tagName === "BR")
2077
+ if (node.childNodes.length === 1 && node.childNodes[0] instanceof import_node_html_parser22.HTMLElement && node.childNodes[0].tagName === "BR")
1959
2078
  return jsonNode;
1960
2079
  node.childNodes.forEach((child) => {
1961
2080
  const processedChildren = traverse2(child);
@@ -1967,10 +2086,10 @@ var ParagraphNodeHandler2 = class extends NodeHandler2 {
1967
2086
 
1968
2087
  // src/importFromHtml/ShortAnswerQuestionNodeHandler.ts
1969
2088
  var import_nanoid9 = require("nanoid");
1970
- var import_node_html_parser21 = require("node-html-parser");
2089
+ var import_node_html_parser23 = require("node-html-parser");
1971
2090
  var ShortAnswerQuestionNodeHandler2 = class extends NodeHandler2 {
1972
2091
  processNode(node) {
1973
- if (!(node instanceof import_node_html_parser21.HTMLElement) || node.tagName !== "x-short-answer".toUpperCase())
2092
+ if (!(node instanceof import_node_html_parser23.HTMLElement) || node.tagName !== "x-short-answer".toUpperCase())
1974
2093
  return null;
1975
2094
  return {
1976
2095
  id: node.getAttribute("id") ?? (0, import_nanoid9.nanoid)(),
@@ -1986,7 +2105,7 @@ var ShortAnswerQuestionNodeHandler2 = class extends NodeHandler2 {
1986
2105
  };
1987
2106
 
1988
2107
  // src/importFromHtml/SimulationQuestionNodeHandler.ts
1989
- var import_node_html_parser22 = require("node-html-parser");
2108
+ var import_node_html_parser24 = require("node-html-parser");
1990
2109
  var TAG_X_SIMULATION = "x-simulation";
1991
2110
  var TAG_X_SYSTEM_MESSAGE2 = "x-ai-system-message";
1992
2111
  var TAG_X_COMMENT_INSTRUCTIONS = "x-comment-instructions";
@@ -1994,7 +2113,7 @@ var TAG_X_STEP2_INSTRUCTIONS = "x-step2-instructions";
1994
2113
  var findFirstNonEmptyInnerHtml = (root, elementNames) => elementNames.map((name) => root.querySelector(name)).find((el) => el?.innerHTML.trim().length)?.innerHTML.trim() ?? null;
1995
2114
  var SimulationQuestionNodeHandler2 = class extends NodeHandler2 {
1996
2115
  processNode(node) {
1997
- if (!(node instanceof import_node_html_parser22.HTMLElement) || node.tagName !== TAG_X_SIMULATION.toUpperCase()) {
2116
+ if (!(node instanceof import_node_html_parser24.HTMLElement) || node.tagName !== TAG_X_SIMULATION.toUpperCase()) {
1998
2117
  return null;
1999
2118
  }
2000
2119
  const jsonNode = {
@@ -2015,11 +2134,11 @@ var SimulationQuestionNodeHandler2 = class extends NodeHandler2 {
2015
2134
  };
2016
2135
 
2017
2136
  // src/importFromHtml/SpanNodeHandler.ts
2018
- var import_node_html_parser23 = require("node-html-parser");
2019
- var TextNode = import_node_html_parser23.parse.TextNode;
2137
+ var import_node_html_parser25 = require("node-html-parser");
2138
+ var TextNode = import_node_html_parser25.parse.TextNode;
2020
2139
  var SpanNodeHandler = class extends NodeHandler2 {
2021
2140
  processNode(node) {
2022
- if (!(node instanceof import_node_html_parser23.HTMLElement) || node.tagName !== "SPAN")
2141
+ if (!(node instanceof import_node_html_parser25.HTMLElement) || node.tagName !== "SPAN")
2023
2142
  return null;
2024
2143
  const styleAttr = node.getAttribute("style") || "";
2025
2144
  if (node.childNodes.length === 1 && node.childNodes[0] instanceof TextNode) {
@@ -2081,7 +2200,7 @@ var SpanNodeHandler = class extends NodeHandler2 {
2081
2200
  };
2082
2201
 
2083
2202
  // src/importFromHtml/TableCellNodeHandler.ts
2084
- var import_node_html_parser24 = require("node-html-parser");
2203
+ var import_node_html_parser26 = require("node-html-parser");
2085
2204
 
2086
2205
  // src/utils/styleUtils.ts
2087
2206
  var extractStyleValue = (styleAttr, property, isNumeric = false, unit = "") => {
@@ -2130,7 +2249,7 @@ function createEmptyTableCellNode(isHeader = false) {
2130
2249
 
2131
2250
  // src/importFromHtml/TableCellNodeHandler.ts
2132
2251
  var isHtmlTableCellElement = (node) => {
2133
- return node instanceof import_node_html_parser24.HTMLElement && (node.tagName === "TD" || node.tagName === "TH");
2252
+ return node instanceof import_node_html_parser26.HTMLElement && (node.tagName === "TD" || node.tagName === "TH");
2134
2253
  };
2135
2254
  var TableCellNodeHandler2 = class extends NodeHandler2 {
2136
2255
  processNode(node) {
@@ -2172,10 +2291,10 @@ var TableCellNodeHandler2 = class extends NodeHandler2 {
2172
2291
  };
2173
2292
 
2174
2293
  // src/importFromHtml/TableNodeHandler.ts
2175
- var import_node_html_parser25 = require("node-html-parser");
2294
+ var import_node_html_parser27 = require("node-html-parser");
2176
2295
  var REFERENCE_TABLE_WIDTH = 720;
2177
2296
  var MINIMUM_REFERENCE_TABLE_WIDTH = 500;
2178
- var isHtmlTableElement = (node) => node instanceof import_node_html_parser25.HTMLElement && node.tagName === "TABLE";
2297
+ var isHtmlTableElement = (node) => node instanceof import_node_html_parser27.HTMLElement && node.tagName === "TABLE";
2179
2298
  var TableNodeHandler2 = class extends NodeHandler2 {
2180
2299
  processNode(node) {
2181
2300
  if (!isHtmlTableElement(node)) return null;
@@ -2330,9 +2449,9 @@ var TableNodeHandler2 = class extends NodeHandler2 {
2330
2449
  };
2331
2450
 
2332
2451
  // src/importFromHtml/TableRowNodeHandler.ts
2333
- var import_node_html_parser26 = require("node-html-parser");
2452
+ var import_node_html_parser28 = require("node-html-parser");
2334
2453
  var isHtmlTableRowElement = (node) => {
2335
- return node instanceof import_node_html_parser26.HTMLElement && node.tagName === "TR";
2454
+ return node instanceof import_node_html_parser28.HTMLElement && node.tagName === "TR";
2336
2455
  };
2337
2456
  var TableRowNodeHandler2 = class extends NodeHandler2 {
2338
2457
  processNode(node) {
@@ -2355,8 +2474,8 @@ var TableRowNodeHandler2 = class extends NodeHandler2 {
2355
2474
  };
2356
2475
 
2357
2476
  // src/importFromHtml/TextNodeHandler.ts
2358
- var import_node_html_parser27 = require("node-html-parser");
2359
- var TextNode2 = import_node_html_parser27.parse.TextNode;
2477
+ var import_node_html_parser29 = require("node-html-parser");
2478
+ var TextNode2 = import_node_html_parser29.parse.TextNode;
2360
2479
  var TextNodeHandler2 = class extends NodeHandler2 {
2361
2480
  processNode(node) {
2362
2481
  if (!(node instanceof TextNode2)) return null;
@@ -2375,10 +2494,10 @@ var TextNodeHandler2 = class extends NodeHandler2 {
2375
2494
  };
2376
2495
 
2377
2496
  // src/importFromHtml/VariableNodeHandler.ts
2378
- var import_node_html_parser28 = require("node-html-parser");
2497
+ var import_node_html_parser30 = require("node-html-parser");
2379
2498
  var VariableNodeHandler2 = class extends NodeHandler2 {
2380
2499
  processNode(node) {
2381
- if (!(node instanceof import_node_html_parser28.HTMLElement) || !node.tagName) return null;
2500
+ if (!(node instanceof import_node_html_parser30.HTMLElement) || !node.tagName) return null;
2382
2501
  if (node.tagName !== "x-param".toUpperCase()) return null;
2383
2502
  return {
2384
2503
  variableName: node.getAttribute("data-x-name") || "undefined",
@@ -2391,7 +2510,7 @@ var VariableNodeHandler2 = class extends NodeHandler2 {
2391
2510
 
2392
2511
  // src/importFromHtml/traverse.ts
2393
2512
  var builder2 = new NodeHandlerChainBuilder();
2394
- var nodeHandlerChain2 = builder2.addHandler(CustomQuestionNodeHandler2).addHandler(DivNodeHandler).addHandler(EssayQuestionNodeHandler2).addHandler(FillInTheBlankQuestionNodeHandler2).addHandler(FillInTheBlankSpaceNodeHandler2).addHandler(FinancialStatementQuestionNodeHandler2).addHandler(FormattedNodeHandler).addHandler(ImageNodeHandler2).addHandler(HeadingNodeHandler2).addHandler(HorizontalRuleNodeHandler2).addHandler(JournalEntryQuestionNodeHandler2).addHandler(LineBreakNodeHandler2).addHandler(LinkNodeHandler2).addHandler(ListNodeHandler2).addHandler(ListItemNodeHandler2).addHandler(MatchingQuestionNodeHandler2).addHandler(MultipleOptionQuestionNodeHandler2).addHandler(ParagraphNodeHandler2).addHandler(ShortAnswerQuestionNodeHandler2).addHandler(SimulationQuestionNodeHandler2).addHandler(SpanNodeHandler).addHandler(TableCellNodeHandler2).addHandler(TableNodeHandler2).addHandler(TableRowNodeHandler2).addHandler(TextNodeHandler2).addHandler(VariableNodeHandler2).build();
2513
+ var nodeHandlerChain2 = builder2.addHandler(CustomQuestionNodeHandler2).addHandler(DivNodeHandler).addHandler(EssayQuestionNodeHandler2).addHandler(ExcelQuestionNodeHandler2).addHandler(ExcelWorksheetLinkNodeHandler).addHandler(FillInTheBlankQuestionNodeHandler2).addHandler(FillInTheBlankSpaceNodeHandler2).addHandler(FinancialStatementQuestionNodeHandler2).addHandler(FormattedNodeHandler).addHandler(HeadingNodeHandler2).addHandler(HorizontalRuleNodeHandler2).addHandler(ImageNodeHandler2).addHandler(JournalEntryQuestionNodeHandler2).addHandler(LineBreakNodeHandler2).addHandler(LinkNodeHandler2).addHandler(ListItemNodeHandler2).addHandler(ListNodeHandler2).addHandler(MatchingQuestionNodeHandler2).addHandler(MultipleOptionQuestionNodeHandler2).addHandler(ParagraphNodeHandler2).addHandler(ShortAnswerQuestionNodeHandler2).addHandler(SimulationQuestionNodeHandler2).addHandler(SpanNodeHandler).addHandler(TableCellNodeHandler2).addHandler(TableNodeHandler2).addHandler(TableRowNodeHandler2).addHandler(TextNodeHandler2).addHandler(VariableNodeHandler2).build();
2395
2514
  function traverse2(node) {
2396
2515
  const result = nodeHandlerChain2.handle(node);
2397
2516
  if (result === null) return [];
@@ -2409,7 +2528,7 @@ function processChildren(node) {
2409
2528
  return result;
2410
2529
  }
2411
2530
  function processHtml(html) {
2412
- const root = (0, import_node_html_parser29.parse)(html);
2531
+ const root = (0, import_node_html_parser31.parse)(html);
2413
2532
  return processChildren(root);
2414
2533
  }
2415
2534
  function importFromHtml(html) {
package/dist/index.mjs CHANGED
@@ -77,9 +77,9 @@ var EssayQuestionNodeHandler = class extends NodeHandler {
77
77
  }
78
78
  };
79
79
 
80
- // src/typeGuards/isSerializedFillInTheBlankQuestionNode.ts
81
- function isSerializedFillInTheBlankQuestionNode(node) {
82
- return node?.type === "fill-in-the-blank-question" && "id" in node && typeof node.id === "string" && "pointsPerSpace" in node && typeof node.pointsPerSpace === "number" && "content" in node;
80
+ // src/typeGuards/isSerializedExcelQuestionNode.ts
81
+ function isSerializedExcelQuestionNode(node) {
82
+ return node?.type === "excel-question" && "id" in node && typeof node.id === "string" && "points" in node && typeof node.points === "number" && "data" in node && typeof node.data === "object";
83
83
  }
84
84
 
85
85
  // src/typeGuards/isSerializedParagraphNode.ts
@@ -112,6 +112,35 @@ function createHtmlFromNestedEditor(editor, metadata) {
112
112
  return createHtmlFromNestedNodes(rootNode.children, metadata);
113
113
  }
114
114
 
115
+ // src/exportToHtml/ExcelQuestionNodeHandler.ts
116
+ var ExcelQuestionNodeHandler = class extends NodeHandler {
117
+ processNode(node) {
118
+ if (!isSerializedExcelQuestionNode(node)) return null;
119
+ const data = {
120
+ ...node.data,
121
+ parts: node.data.parts.map((p) => ({
122
+ ...p,
123
+ objective: createHtmlFromNestedEditor(p.objective),
124
+ instructions: createHtmlFromNestedEditor(p.instructions),
125
+ tasks: p.tasks.map((t) => ({
126
+ ...t,
127
+ instructions: createHtmlFromNestedEditor(t.instructions),
128
+ steps: t.steps.map((s) => ({
129
+ ...s,
130
+ description: createHtmlFromNestedEditor(s.description)
131
+ }))
132
+ }))
133
+ }))
134
+ };
135
+ return `<x-excel id="${node.id}" data-x-prompt data-x-points="${node.points}"><x-data>${JSON.stringify(data)}</x-data></x-excel>`;
136
+ }
137
+ };
138
+
139
+ // src/typeGuards/isSerializedFillInTheBlankQuestionNode.ts
140
+ function isSerializedFillInTheBlankQuestionNode(node) {
141
+ return node?.type === "fill-in-the-blank-question" && "id" in node && typeof node.id === "string" && "pointsPerSpace" in node && typeof node.pointsPerSpace === "number" && "content" in node;
142
+ }
143
+
115
144
  // src/exportToHtml/FillInTheBlankQuestionNodeHandler.ts
116
145
  var FillInTheBlankQuestionNodeHandler = class extends NodeHandler {
117
146
  processNode(node) {
@@ -948,7 +977,7 @@ var VariableNodeHandler = class extends NodeHandler {
948
977
 
949
978
  // src/exportToHtml/traverse.ts
950
979
  var builder = new NodeHandlerChainBuilder();
951
- var nodeHandlerChain = builder.addHandler(CustomQuestionNodeHandler).addHandler(EssayQuestionNodeHandler).addHandler(FillInTheBlankQuestionNodeHandler).addHandler(FillInTheBlankSpaceNodeHandler).addHandler(FinancialStatementQuestionNodeHandler).addHandler(HeadingNodeHandler).addHandler(HorizontalRuleNodeHandler).addHandler(ImageNodeHandler).addHandler(JournalEntryQuestionNodeHandler).addHandler(LineBreakNodeHandler).addHandler(LinkNodeHandler).addHandler(ListNodeHandler).addHandler(ListItemNodeHandler).addHandler(MatchingQuestionNodeHandler).addHandler(MultipleOptionQuestionNodeHandler).addHandler(ParagraphNodeHandler).addHandler(ShortAnswerQuestionNodeHandler).addHandler(SimulationQuestionNodeHandler).addHandler(TableCellNodeHandler).addHandler(TableNodeHandler).addHandler(TableRowNodeHandler).addHandler(TextNodeHandler).addHandler(VariableNodeHandler).build();
980
+ var nodeHandlerChain = builder.addHandler(CustomQuestionNodeHandler).addHandler(EssayQuestionNodeHandler).addHandler(ExcelQuestionNodeHandler).addHandler(FillInTheBlankQuestionNodeHandler).addHandler(FillInTheBlankSpaceNodeHandler).addHandler(FinancialStatementQuestionNodeHandler).addHandler(HeadingNodeHandler).addHandler(HorizontalRuleNodeHandler).addHandler(ImageNodeHandler).addHandler(JournalEntryQuestionNodeHandler).addHandler(LineBreakNodeHandler).addHandler(LinkNodeHandler).addHandler(ListNodeHandler).addHandler(ListItemNodeHandler).addHandler(MatchingQuestionNodeHandler).addHandler(MultipleOptionQuestionNodeHandler).addHandler(ParagraphNodeHandler).addHandler(ShortAnswerQuestionNodeHandler).addHandler(SimulationQuestionNodeHandler).addHandler(TableCellNodeHandler).addHandler(TableNodeHandler).addHandler(TableRowNodeHandler).addHandler(TextNodeHandler).addHandler(VariableNodeHandler).build();
952
981
  var traverse = (node, metadata) => {
953
982
  return nodeHandlerChain.handle(node, metadata);
954
983
  };
@@ -967,7 +996,7 @@ function exportToHtml(editorState) {
967
996
  }
968
997
 
969
998
  // src/importFromHtml/index.ts
970
- import { parse as parse3 } from "node-html-parser";
999
+ import { parse as parse4 } from "node-html-parser";
971
1000
 
972
1001
  // src/importFromHtml/createEmptyParagraphNode.ts
973
1002
  function createEmptyParagraphNode(format = "") {
@@ -1246,10 +1275,6 @@ var EssayQuestionNodeHandler2 = class extends NodeHandler2 {
1246
1275
  }
1247
1276
  };
1248
1277
 
1249
- // src/importFromHtml/FillInTheBlankQuestionNodeHandler.ts
1250
- import { nanoid as nanoid2 } from "nanoid";
1251
- import { HTMLElement as HTMLElement5 } from "node-html-parser";
1252
-
1253
1278
  // src/importFromHtml/createNestedEditorFromHtml.ts
1254
1279
  function createNestedEditorFromHtml(node) {
1255
1280
  return {
@@ -1266,10 +1291,104 @@ function createNestedEditorFromHtml(node) {
1266
1291
  };
1267
1292
  }
1268
1293
 
1294
+ // src/importFromHtml/ExcelQuestionNodeHandler.ts
1295
+ import { HTMLElement as HTMLElement5, parse } from "node-html-parser";
1296
+ var TAG_X = "x-excel";
1297
+ function parseData(xDataString) {
1298
+ const xData = JSON.parse(xDataString);
1299
+ const parts = [];
1300
+ for (const xPart of xData.parts ?? []) {
1301
+ const tasks = [];
1302
+ for (const xTask of xPart.tasks ?? []) {
1303
+ const steps = [];
1304
+ for (const xStep of xTask.steps ?? []) {
1305
+ steps.push({
1306
+ id: xStep.id,
1307
+ description: createNestedEditorFromHtml(
1308
+ parse(xStep.description ?? "")
1309
+ )
1310
+ });
1311
+ }
1312
+ tasks.push({
1313
+ id: xTask.id,
1314
+ instructions: createNestedEditorFromHtml(
1315
+ parse(xTask.instructions ?? "")
1316
+ ),
1317
+ steps
1318
+ });
1319
+ }
1320
+ parts.push({
1321
+ id: xPart.id,
1322
+ objective: createNestedEditorFromHtml(
1323
+ parse(xPart.objective ?? "")
1324
+ ),
1325
+ instructions: createNestedEditorFromHtml(
1326
+ parse(xPart.instructions ?? "")
1327
+ ),
1328
+ onLoadActions: xPart.onLoadActions,
1329
+ onNextActions: xPart.onNextActions,
1330
+ tasks
1331
+ });
1332
+ }
1333
+ return {
1334
+ sourceFileName: xData.sourceFileName || "",
1335
+ transformations: xData.transformations || [],
1336
+ parts
1337
+ };
1338
+ }
1339
+ var ExcelQuestionNodeHandler2 = class extends NodeHandler2 {
1340
+ processNode(node) {
1341
+ if (!(node instanceof HTMLElement5) || node.tagName !== TAG_X.toUpperCase()) {
1342
+ return null;
1343
+ }
1344
+ const xDataElement = node.querySelector("x-data");
1345
+ if (!xDataElement) {
1346
+ return null;
1347
+ }
1348
+ const data = parseData(
1349
+ xDataElement.innerHTML
1350
+ );
1351
+ const jsonNode = {
1352
+ id: node.getAttribute("id") || "",
1353
+ points: Number(node.getAttribute("data-x-points") || 1),
1354
+ data,
1355
+ active: data.parts.length > 0 ? data.parts[0].id : "",
1356
+ type: "excel-question",
1357
+ version: 1
1358
+ };
1359
+ return jsonNode;
1360
+ }
1361
+ };
1362
+
1363
+ // src/importFromHtml/ExcelWorksheetLinkNodeHandler.ts
1364
+ import { HTMLElement as HTMLElement6 } from "node-html-parser";
1365
+ var TAG = "x-worksheet-link";
1366
+ var ExcelWorksheetLinkNodeHandler = class extends NodeHandler2 {
1367
+ processNode(node) {
1368
+ if (!(node instanceof HTMLElement6) || node.tagName !== TAG.toUpperCase()) {
1369
+ return null;
1370
+ }
1371
+ const url = node.getAttribute("x-data-name") || "";
1372
+ const linkNode = {
1373
+ detail: 0,
1374
+ format: 0,
1375
+ mode: "normal",
1376
+ style: "",
1377
+ text: node.text || url,
1378
+ dataName: url,
1379
+ type: "excel-worksheet-link",
1380
+ version: 1
1381
+ };
1382
+ return linkNode;
1383
+ }
1384
+ };
1385
+
1269
1386
  // src/importFromHtml/FillInTheBlankQuestionNodeHandler.ts
1387
+ import { nanoid as nanoid2 } from "nanoid";
1388
+ import { HTMLElement as HTMLElement7 } from "node-html-parser";
1270
1389
  var FillInTheBlankQuestionNodeHandler2 = class extends NodeHandler2 {
1271
1390
  processNode(node) {
1272
- if (!(node instanceof HTMLElement5) || node.tagName !== "x-fill-in-the-blank".toUpperCase())
1391
+ if (!(node instanceof HTMLElement7) || node.tagName !== "x-fill-in-the-blank".toUpperCase())
1273
1392
  return null;
1274
1393
  const jsonNode = {
1275
1394
  id: node.getAttribute("id") ?? nanoid2(),
@@ -1286,7 +1405,7 @@ var FillInTheBlankQuestionNodeHandler2 = class extends NodeHandler2 {
1286
1405
 
1287
1406
  // src/importFromHtml/FillInTheBlankSpaceNodeHandler.ts
1288
1407
  import { nanoid as nanoid3 } from "nanoid";
1289
- import { HTMLElement as HTMLElement6 } from "node-html-parser";
1408
+ import { HTMLElement as HTMLElement8 } from "node-html-parser";
1290
1409
 
1291
1410
  // src/importFromHtml/parseErrorToleranceAttribute.ts
1292
1411
  function parseErrorToleranceAttribute(attr) {
@@ -1298,7 +1417,7 @@ function parseErrorToleranceAttribute(attr) {
1298
1417
  // src/importFromHtml/FillInTheBlankSpaceNodeHandler.ts
1299
1418
  var FillInTheBlankSpaceNodeHandler2 = class extends NodeHandler2 {
1300
1419
  processNode(node) {
1301
- if (!(node instanceof HTMLElement6) || node.tagName !== "x-space".toUpperCase())
1420
+ if (!(node instanceof HTMLElement8) || node.tagName !== "x-space".toUpperCase())
1302
1421
  return null;
1303
1422
  const spaceTypeAttr = node.getAttribute("data-x-type");
1304
1423
  const spaceType = spaceTypeAttr === "Text" || spaceTypeAttr === "Number" || spaceTypeAttr === "Dropdown" ? spaceTypeAttr : "Text";
@@ -1348,7 +1467,7 @@ var FillInTheBlankSpaceNodeHandler2 = class extends NodeHandler2 {
1348
1467
 
1349
1468
  // src/importFromHtml/FinancialStatementQuestionNodeHandler.ts
1350
1469
  import { nanoid as nanoid4 } from "nanoid";
1351
- import { HTMLElement as HTMLElement7 } from "node-html-parser";
1470
+ import { HTMLElement as HTMLElement9 } from "node-html-parser";
1352
1471
  var TAG_X_FINANCIAL_STATEMENT = "x-financial-statement";
1353
1472
  var TAG_X_HEADER = "x-header";
1354
1473
  var TAG_X_ROWS = "x-rows";
@@ -1360,7 +1479,7 @@ var TAG_X_ENTRY = "x-entry";
1360
1479
  var TAG_X_AMOUNT = "x-amount";
1361
1480
  var FinancialStatementQuestionNodeHandler2 = class extends NodeHandler2 {
1362
1481
  processNode(node) {
1363
- if (!(node instanceof HTMLElement7) || node.tagName !== TAG_X_FINANCIAL_STATEMENT.toUpperCase()) {
1482
+ if (!(node instanceof HTMLElement9) || node.tagName !== TAG_X_FINANCIAL_STATEMENT.toUpperCase()) {
1364
1483
  return null;
1365
1484
  }
1366
1485
  const headerElement = node.querySelector(TAG_X_HEADER);
@@ -1375,7 +1494,7 @@ var FinancialStatementQuestionNodeHandler2 = class extends NodeHandler2 {
1375
1494
  version: 1
1376
1495
  };
1377
1496
  node.childNodes.forEach((child) => {
1378
- if (!(child instanceof HTMLElement7)) return;
1497
+ if (!(child instanceof HTMLElement9)) return;
1379
1498
  if (child.tagName === TAG_X_DISTRACTORS.toUpperCase()) {
1380
1499
  this.processDistractorsNode(child, jsonNode);
1381
1500
  } else if (child.tagName === TAG_X_ROWS.toUpperCase()) {
@@ -1386,7 +1505,7 @@ var FinancialStatementQuestionNodeHandler2 = class extends NodeHandler2 {
1386
1505
  }
1387
1506
  processDistractorsNode(distractorsNode, jsonNode) {
1388
1507
  for (const distractorsChild of distractorsNode.childNodes) {
1389
- if (!(distractorsChild instanceof HTMLElement7)) continue;
1508
+ if (!(distractorsChild instanceof HTMLElement9)) continue;
1390
1509
  if (distractorsChild.tagName !== TAG_X_DISTRACTOR.toUpperCase())
1391
1510
  continue;
1392
1511
  jsonNode.distractors.push({
@@ -1407,7 +1526,7 @@ var FinancialStatementQuestionNodeHandler2 = class extends NodeHandler2 {
1407
1526
  const contentDiv = headerElement.querySelector(
1408
1527
  'div > div:not([style*="display:flex"])'
1409
1528
  );
1410
- if (contentDiv && contentDiv instanceof HTMLElement7)
1529
+ if (contentDiv && contentDiv instanceof HTMLElement9)
1411
1530
  return createNestedEditorFromHtml(contentDiv);
1412
1531
  }
1413
1532
  return createNestedEditorFromHtml(headerElement);
@@ -1424,7 +1543,7 @@ var FinancialStatementQuestionNodeHandler2 = class extends NodeHandler2 {
1424
1543
  }
1425
1544
  processRowsNode(rowsNode, jsonNode) {
1426
1545
  for (const rowsChild of rowsNode.childNodes) {
1427
- if (!(rowsChild instanceof HTMLElement7)) continue;
1546
+ if (!(rowsChild instanceof HTMLElement9)) continue;
1428
1547
  if (rowsChild.tagName === TAG_X_HEADING.toUpperCase()) {
1429
1548
  this.processHeadingRow(rowsChild, jsonNode);
1430
1549
  } else if (rowsChild.tagName === TAG_X_LINE.toUpperCase()) {
@@ -1458,7 +1577,7 @@ var FinancialStatementQuestionNodeHandler2 = class extends NodeHandler2 {
1458
1577
  };
1459
1578
 
1460
1579
  // src/importFromHtml/FormattedNodeHandler.ts
1461
- import { HTMLElement as HTMLElement8 } from "node-html-parser";
1580
+ import { HTMLElement as HTMLElement10 } from "node-html-parser";
1462
1581
  var IS_BOLD2 = 1;
1463
1582
  var IS_ITALIC2 = 1 << 1;
1464
1583
  var IS_STRIKETHROUGH2 = 1 << 2;
@@ -1498,7 +1617,7 @@ function formatToProps(format) {
1498
1617
  }
1499
1618
  var FormattedNodeHandler = class extends NodeHandler2 {
1500
1619
  processNode(node) {
1501
- if (!(node instanceof HTMLElement8)) return null;
1620
+ if (!(node instanceof HTMLElement10)) return null;
1502
1621
  const tagName = node.tagName;
1503
1622
  if (!tagName || !(tagName in TAG_TO_FORMAT)) return null;
1504
1623
  const formatFlag = TAG_TO_FORMAT[tagName];
@@ -1533,7 +1652,7 @@ var FormattedNodeHandler = class extends NodeHandler2 {
1533
1652
  };
1534
1653
 
1535
1654
  // src/importFromHtml/HeadingNodeHandler.ts
1536
- import { HTMLElement as HTMLElement9 } from "node-html-parser";
1655
+ import { HTMLElement as HTMLElement11 } from "node-html-parser";
1537
1656
 
1538
1657
  // src/importFromHtml/extractTextAlignment.ts
1539
1658
  var TEXT_ALIGN_TO_FORMAT = {
@@ -1561,7 +1680,7 @@ function extractTextAlignment(element) {
1561
1680
  var TAG_HEADINGS = ["h1", "h2", "h3", "h4", "h5", "h6"];
1562
1681
  var HeadingNodeHandler2 = class extends NodeHandler2 {
1563
1682
  processNode(node) {
1564
- if (!(node instanceof HTMLElement9) || !TAG_HEADINGS.includes(node.tagName.toLowerCase())) {
1683
+ if (!(node instanceof HTMLElement11) || !TAG_HEADINGS.includes(node.tagName.toLowerCase())) {
1565
1684
  return null;
1566
1685
  }
1567
1686
  const headingNode = {
@@ -1582,11 +1701,11 @@ var HeadingNodeHandler2 = class extends NodeHandler2 {
1582
1701
  };
1583
1702
 
1584
1703
  // src/importFromHtml/HorizontalRuleNodeHandler.ts
1585
- import { HTMLElement as HTMLElement10 } from "node-html-parser";
1704
+ import { HTMLElement as HTMLElement12 } from "node-html-parser";
1586
1705
  var TAG_HR = "hr";
1587
1706
  var HorizontalRuleNodeHandler2 = class extends NodeHandler2 {
1588
1707
  processNode(node) {
1589
- if (!(node instanceof HTMLElement10) || node.tagName !== TAG_HR.toUpperCase()) {
1708
+ if (!(node instanceof HTMLElement12) || node.tagName !== TAG_HR.toUpperCase()) {
1590
1709
  return null;
1591
1710
  }
1592
1711
  const horizontalRuleNode = {
@@ -1598,11 +1717,11 @@ var HorizontalRuleNodeHandler2 = class extends NodeHandler2 {
1598
1717
  };
1599
1718
 
1600
1719
  // src/importFromHtml/ImageNodeHandler.ts
1601
- import { HTMLElement as HTMLElement11 } from "node-html-parser";
1720
+ import { HTMLElement as HTMLElement13 } from "node-html-parser";
1602
1721
  var TAG_IMG = "img";
1603
1722
  var ImageNodeHandler2 = class extends NodeHandler2 {
1604
1723
  processNode(node) {
1605
- if (!(node instanceof HTMLElement11) || node.tagName !== TAG_IMG.toUpperCase()) {
1724
+ if (!(node instanceof HTMLElement13) || node.tagName !== TAG_IMG.toUpperCase()) {
1606
1725
  return null;
1607
1726
  }
1608
1727
  return createImageNode(
@@ -1618,11 +1737,11 @@ var ImageNodeHandler2 = class extends NodeHandler2 {
1618
1737
 
1619
1738
  // src/importFromHtml/JournalEntryQuestionNodeHandler.ts
1620
1739
  import { nanoid as nanoid6 } from "nanoid";
1621
- import { HTMLElement as HTMLElement13 } from "node-html-parser";
1740
+ import { HTMLElement as HTMLElement15 } from "node-html-parser";
1622
1741
 
1623
1742
  // src/importFromHtml/createOnePerLineDistractorNode.ts
1624
1743
  import { nanoid as nanoid5 } from "nanoid";
1625
- import { HTMLElement as HTMLElement12 } from "node-html-parser";
1744
+ import { HTMLElement as HTMLElement14 } from "node-html-parser";
1626
1745
  function extractDistractorId(id) {
1627
1746
  if (!id) return null;
1628
1747
  const parts = id.split("|");
@@ -1635,7 +1754,7 @@ var createOnePerLineDistractorNode = (node) => {
1635
1754
  distractorEditor.editorState.root.children = [];
1636
1755
  let distractorId = null;
1637
1756
  distractors.forEach((distractor) => {
1638
- if (!(distractor instanceof HTMLElement12)) return;
1757
+ if (!(distractor instanceof HTMLElement14)) return;
1639
1758
  distractorId = distractorId ?? extractDistractorId(distractor.getAttribute("id"));
1640
1759
  distractorEditor.editorState.root.children.push(
1641
1760
  ...createNestedNodesFromHtml(distractor)
@@ -1653,7 +1772,7 @@ var createOnePerLineDistractorNode = (node) => {
1653
1772
  // src/importFromHtml/JournalEntryQuestionNodeHandler.ts
1654
1773
  var JournalEntryQuestionNodeHandler2 = class extends NodeHandler2 {
1655
1774
  processNode(node) {
1656
- if (!(node instanceof HTMLElement13) || node.tagName !== "x-journal-entry".toUpperCase())
1775
+ if (!(node instanceof HTMLElement15) || node.tagName !== "x-journal-entry".toUpperCase())
1657
1776
  return null;
1658
1777
  const jsonNode = {
1659
1778
  id: node.getAttribute("id") ?? nanoid6(),
@@ -1668,7 +1787,7 @@ var JournalEntryQuestionNodeHandler2 = class extends NodeHandler2 {
1668
1787
  };
1669
1788
  const lineItems = node.querySelectorAll("x-line-item");
1670
1789
  lineItems.forEach((lineItem) => {
1671
- if (!(lineItem instanceof HTMLElement13)) return;
1790
+ if (!(lineItem instanceof HTMLElement15)) return;
1672
1791
  const accountElement = lineItem.querySelector("x-account");
1673
1792
  const debitElement = lineItem.querySelector("x-debit");
1674
1793
  const creditElement = lineItem.querySelector("x-credit");
@@ -1697,10 +1816,10 @@ var JournalEntryQuestionNodeHandler2 = class extends NodeHandler2 {
1697
1816
  };
1698
1817
 
1699
1818
  // src/importFromHtml/LineBreakNodeHandler.ts
1700
- import { HTMLElement as HTMLElement14 } from "node-html-parser";
1819
+ import { HTMLElement as HTMLElement16 } from "node-html-parser";
1701
1820
  var LineBreakNodeHandler2 = class extends NodeHandler2 {
1702
1821
  processNode(node) {
1703
- if (!(node instanceof HTMLElement14)) return null;
1822
+ if (!(node instanceof HTMLElement16)) return null;
1704
1823
  if (node.tagName !== "BR") return null;
1705
1824
  return {
1706
1825
  type: "linebreak",
@@ -1710,11 +1829,11 @@ var LineBreakNodeHandler2 = class extends NodeHandler2 {
1710
1829
  };
1711
1830
 
1712
1831
  // src/importFromHtml/LinkNodeHandler.ts
1713
- import { HTMLElement as HTMLElement15 } from "node-html-parser";
1832
+ import { HTMLElement as HTMLElement17 } from "node-html-parser";
1714
1833
  var TAG_A = "a";
1715
1834
  var LinkNodeHandler2 = class extends NodeHandler2 {
1716
1835
  processNode(node) {
1717
- if (!(node instanceof HTMLElement15) || node.tagName !== TAG_A.toUpperCase()) {
1836
+ if (!(node instanceof HTMLElement17) || node.tagName !== TAG_A.toUpperCase()) {
1718
1837
  return null;
1719
1838
  }
1720
1839
  const url = node.getAttribute("href") || "";
@@ -1743,10 +1862,10 @@ var LinkNodeHandler2 = class extends NodeHandler2 {
1743
1862
  };
1744
1863
 
1745
1864
  // src/importFromHtml/ListItemNodeHandler.ts
1746
- import { HTMLElement as HTMLElement16 } from "node-html-parser";
1865
+ import { HTMLElement as HTMLElement18 } from "node-html-parser";
1747
1866
  var ListItemNodeHandler2 = class extends NodeHandler2 {
1748
1867
  processNode(node) {
1749
- if (!(node instanceof HTMLElement16)) return null;
1868
+ if (!(node instanceof HTMLElement18)) return null;
1750
1869
  if (node.tagName !== "LI") return null;
1751
1870
  const jsonNode = {
1752
1871
  type: "listitem",
@@ -1767,10 +1886,10 @@ var ListItemNodeHandler2 = class extends NodeHandler2 {
1767
1886
  };
1768
1887
 
1769
1888
  // src/importFromHtml/ListNodeHandler.ts
1770
- import { HTMLElement as HTMLElement17 } from "node-html-parser";
1889
+ import { HTMLElement as HTMLElement19 } from "node-html-parser";
1771
1890
  var ListNodeHandler2 = class extends NodeHandler2 {
1772
1891
  processNode(node) {
1773
- if (!(node instanceof HTMLElement17)) return null;
1892
+ if (!(node instanceof HTMLElement19)) return null;
1774
1893
  if (node.tagName !== "UL" && node.tagName !== "OL") return null;
1775
1894
  const tag = node.tagName.toLowerCase();
1776
1895
  const listType = tag === "ol" ? "number" : "bullet";
@@ -1788,7 +1907,7 @@ var ListNodeHandler2 = class extends NodeHandler2 {
1788
1907
  };
1789
1908
  let itemIndex = 1;
1790
1909
  node.childNodes.forEach((child) => {
1791
- if (child instanceof HTMLElement17 && child.tagName === "LI") {
1910
+ if (child instanceof HTMLElement19 && child.tagName === "LI") {
1792
1911
  const listItemNode = {
1793
1912
  type: "listitem",
1794
1913
  version: 1,
@@ -1813,10 +1932,10 @@ var ListNodeHandler2 = class extends NodeHandler2 {
1813
1932
 
1814
1933
  // src/importFromHtml/MatchingQuestionNodeHandler.ts
1815
1934
  import { nanoid as nanoid7 } from "nanoid";
1816
- import { HTMLElement as HTMLElement18 } from "node-html-parser";
1935
+ import { HTMLElement as HTMLElement20 } from "node-html-parser";
1817
1936
  var MatchingQuestionNodeHandler2 = class extends NodeHandler2 {
1818
1937
  processNode(node) {
1819
- if (!(node instanceof HTMLElement18) || node.tagName !== "x-matching".toUpperCase())
1938
+ if (!(node instanceof HTMLElement20) || node.tagName !== "x-matching".toUpperCase())
1820
1939
  return null;
1821
1940
  const jsonNode = {
1822
1941
  id: node.getAttribute("id") ?? nanoid7(),
@@ -1829,7 +1948,7 @@ var MatchingQuestionNodeHandler2 = class extends NodeHandler2 {
1829
1948
  };
1830
1949
  const matches = node.querySelectorAll("x-match");
1831
1950
  matches.forEach((match) => {
1832
- if (!(match instanceof HTMLElement18)) return;
1951
+ if (!(match instanceof HTMLElement20)) return;
1833
1952
  const premise = match.querySelector("x-premise");
1834
1953
  const option = match.querySelector("x-option");
1835
1954
  if (!premise || !option) return;
@@ -1852,10 +1971,10 @@ var MatchingQuestionNodeHandler2 = class extends NodeHandler2 {
1852
1971
 
1853
1972
  // src/importFromHtml/MultipleOptionQuestionNodeHandler.ts
1854
1973
  import { nanoid as nanoid8 } from "nanoid";
1855
- import { HTMLElement as HTMLElement19 } from "node-html-parser";
1974
+ import { HTMLElement as HTMLElement21 } from "node-html-parser";
1856
1975
  var MultipleOptionQuestionNodeHandler2 = class extends NodeHandler2 {
1857
1976
  processNode(node) {
1858
- if (!(node instanceof HTMLElement19)) return null;
1977
+ if (!(node instanceof HTMLElement21)) return null;
1859
1978
  if (node.tagName === "x-multiple-choice".toUpperCase())
1860
1979
  return this.processMultipleChoiceNode(node);
1861
1980
  else if (node.tagName === "x-multiple-answers".toUpperCase())
@@ -1895,7 +2014,7 @@ var MultipleOptionQuestionNodeHandler2 = class extends NodeHandler2 {
1895
2014
  processOptions(node, jsonNode) {
1896
2015
  const childNodes = node.childNodes;
1897
2016
  childNodes.forEach((child) => {
1898
- if (!(child instanceof HTMLElement19)) return;
2017
+ if (!(child instanceof HTMLElement21)) return;
1899
2018
  if (child.tagName !== "x-option".toUpperCase()) return;
1900
2019
  jsonNode.options.push({
1901
2020
  id: child.getAttribute("id") ?? nanoid8(),
@@ -1907,28 +2026,28 @@ var MultipleOptionQuestionNodeHandler2 = class extends NodeHandler2 {
1907
2026
  };
1908
2027
 
1909
2028
  // src/importFromHtml/ParagraphNodeHandler.ts
1910
- import { HTMLElement as HTMLElement20 } from "node-html-parser";
2029
+ import { HTMLElement as HTMLElement22 } from "node-html-parser";
1911
2030
  var ParagraphNodeHandler2 = class extends NodeHandler2 {
1912
2031
  processImageNode(node) {
1913
- if (node.childNodes.length === 1 && node.childNodes[0] instanceof HTMLElement20 && node.childNodes[0].tagName === "IMG") {
2032
+ if (node.childNodes.length === 1 && node.childNodes[0] instanceof HTMLElement22 && node.childNodes[0].tagName === "IMG") {
1914
2033
  return traverse2(node.childNodes[0]);
1915
2034
  }
1916
2035
  return null;
1917
2036
  }
1918
2037
  processSpanImageNode(node) {
1919
- if (node.childNodes.length === 1 && node.childNodes[0] instanceof HTMLElement20 && node.childNodes[0].tagName === "SPAN" && node.childNodes[0].childNodes.length === 1 && node.childNodes[0].childNodes[0] instanceof HTMLElement20 && node.childNodes[0].childNodes[0].tagName === "IMG") {
2038
+ if (node.childNodes.length === 1 && node.childNodes[0] instanceof HTMLElement22 && node.childNodes[0].tagName === "SPAN" && node.childNodes[0].childNodes.length === 1 && node.childNodes[0].childNodes[0] instanceof HTMLElement22 && node.childNodes[0].childNodes[0].tagName === "IMG") {
1920
2039
  return traverse2(node.childNodes[0].childNodes[0]);
1921
2040
  }
1922
2041
  return null;
1923
2042
  }
1924
2043
  processNode(node) {
1925
- if (!(node instanceof HTMLElement20)) return null;
2044
+ if (!(node instanceof HTMLElement22)) return null;
1926
2045
  if (node.tagName !== "P") return null;
1927
2046
  const imageNode = this.processImageNode(node) ?? this.processSpanImageNode(node);
1928
2047
  if (imageNode) return imageNode;
1929
2048
  const jsonNode = createEmptyParagraphNode();
1930
2049
  jsonNode.format = extractTextAlignment(node);
1931
- if (node.childNodes.length === 1 && node.childNodes[0] instanceof HTMLElement20 && node.childNodes[0].tagName === "BR")
2050
+ if (node.childNodes.length === 1 && node.childNodes[0] instanceof HTMLElement22 && node.childNodes[0].tagName === "BR")
1932
2051
  return jsonNode;
1933
2052
  node.childNodes.forEach((child) => {
1934
2053
  const processedChildren = traverse2(child);
@@ -1940,10 +2059,10 @@ var ParagraphNodeHandler2 = class extends NodeHandler2 {
1940
2059
 
1941
2060
  // src/importFromHtml/ShortAnswerQuestionNodeHandler.ts
1942
2061
  import { nanoid as nanoid9 } from "nanoid";
1943
- import { HTMLElement as HTMLElement21 } from "node-html-parser";
2062
+ import { HTMLElement as HTMLElement23 } from "node-html-parser";
1944
2063
  var ShortAnswerQuestionNodeHandler2 = class extends NodeHandler2 {
1945
2064
  processNode(node) {
1946
- if (!(node instanceof HTMLElement21) || node.tagName !== "x-short-answer".toUpperCase())
2065
+ if (!(node instanceof HTMLElement23) || node.tagName !== "x-short-answer".toUpperCase())
1947
2066
  return null;
1948
2067
  return {
1949
2068
  id: node.getAttribute("id") ?? nanoid9(),
@@ -1959,7 +2078,7 @@ var ShortAnswerQuestionNodeHandler2 = class extends NodeHandler2 {
1959
2078
  };
1960
2079
 
1961
2080
  // src/importFromHtml/SimulationQuestionNodeHandler.ts
1962
- import { HTMLElement as HTMLElement22 } from "node-html-parser";
2081
+ import { HTMLElement as HTMLElement24 } from "node-html-parser";
1963
2082
  var TAG_X_SIMULATION = "x-simulation";
1964
2083
  var TAG_X_SYSTEM_MESSAGE2 = "x-ai-system-message";
1965
2084
  var TAG_X_COMMENT_INSTRUCTIONS = "x-comment-instructions";
@@ -1967,7 +2086,7 @@ var TAG_X_STEP2_INSTRUCTIONS = "x-step2-instructions";
1967
2086
  var findFirstNonEmptyInnerHtml = (root, elementNames) => elementNames.map((name) => root.querySelector(name)).find((el) => el?.innerHTML.trim().length)?.innerHTML.trim() ?? null;
1968
2087
  var SimulationQuestionNodeHandler2 = class extends NodeHandler2 {
1969
2088
  processNode(node) {
1970
- if (!(node instanceof HTMLElement22) || node.tagName !== TAG_X_SIMULATION.toUpperCase()) {
2089
+ if (!(node instanceof HTMLElement24) || node.tagName !== TAG_X_SIMULATION.toUpperCase()) {
1971
2090
  return null;
1972
2091
  }
1973
2092
  const jsonNode = {
@@ -1988,11 +2107,11 @@ var SimulationQuestionNodeHandler2 = class extends NodeHandler2 {
1988
2107
  };
1989
2108
 
1990
2109
  // src/importFromHtml/SpanNodeHandler.ts
1991
- import { HTMLElement as HTMLElement23, parse } from "node-html-parser";
1992
- var TextNode = parse.TextNode;
2110
+ import { HTMLElement as HTMLElement25, parse as parse2 } from "node-html-parser";
2111
+ var TextNode = parse2.TextNode;
1993
2112
  var SpanNodeHandler = class extends NodeHandler2 {
1994
2113
  processNode(node) {
1995
- if (!(node instanceof HTMLElement23) || node.tagName !== "SPAN")
2114
+ if (!(node instanceof HTMLElement25) || node.tagName !== "SPAN")
1996
2115
  return null;
1997
2116
  const styleAttr = node.getAttribute("style") || "";
1998
2117
  if (node.childNodes.length === 1 && node.childNodes[0] instanceof TextNode) {
@@ -2054,7 +2173,7 @@ var SpanNodeHandler = class extends NodeHandler2 {
2054
2173
  };
2055
2174
 
2056
2175
  // src/importFromHtml/TableCellNodeHandler.ts
2057
- import { HTMLElement as HTMLElement24 } from "node-html-parser";
2176
+ import { HTMLElement as HTMLElement26 } from "node-html-parser";
2058
2177
 
2059
2178
  // src/utils/styleUtils.ts
2060
2179
  var extractStyleValue = (styleAttr, property, isNumeric = false, unit = "") => {
@@ -2103,7 +2222,7 @@ function createEmptyTableCellNode(isHeader = false) {
2103
2222
 
2104
2223
  // src/importFromHtml/TableCellNodeHandler.ts
2105
2224
  var isHtmlTableCellElement = (node) => {
2106
- return node instanceof HTMLElement24 && (node.tagName === "TD" || node.tagName === "TH");
2225
+ return node instanceof HTMLElement26 && (node.tagName === "TD" || node.tagName === "TH");
2107
2226
  };
2108
2227
  var TableCellNodeHandler2 = class extends NodeHandler2 {
2109
2228
  processNode(node) {
@@ -2145,10 +2264,10 @@ var TableCellNodeHandler2 = class extends NodeHandler2 {
2145
2264
  };
2146
2265
 
2147
2266
  // src/importFromHtml/TableNodeHandler.ts
2148
- import { HTMLElement as HTMLElement25 } from "node-html-parser";
2267
+ import { HTMLElement as HTMLElement27 } from "node-html-parser";
2149
2268
  var REFERENCE_TABLE_WIDTH = 720;
2150
2269
  var MINIMUM_REFERENCE_TABLE_WIDTH = 500;
2151
- var isHtmlTableElement = (node) => node instanceof HTMLElement25 && node.tagName === "TABLE";
2270
+ var isHtmlTableElement = (node) => node instanceof HTMLElement27 && node.tagName === "TABLE";
2152
2271
  var TableNodeHandler2 = class extends NodeHandler2 {
2153
2272
  processNode(node) {
2154
2273
  if (!isHtmlTableElement(node)) return null;
@@ -2303,9 +2422,9 @@ var TableNodeHandler2 = class extends NodeHandler2 {
2303
2422
  };
2304
2423
 
2305
2424
  // src/importFromHtml/TableRowNodeHandler.ts
2306
- import { HTMLElement as HTMLElement26 } from "node-html-parser";
2425
+ import { HTMLElement as HTMLElement28 } from "node-html-parser";
2307
2426
  var isHtmlTableRowElement = (node) => {
2308
- return node instanceof HTMLElement26 && node.tagName === "TR";
2427
+ return node instanceof HTMLElement28 && node.tagName === "TR";
2309
2428
  };
2310
2429
  var TableRowNodeHandler2 = class extends NodeHandler2 {
2311
2430
  processNode(node) {
@@ -2328,8 +2447,8 @@ var TableRowNodeHandler2 = class extends NodeHandler2 {
2328
2447
  };
2329
2448
 
2330
2449
  // src/importFromHtml/TextNodeHandler.ts
2331
- import { parse as parse2 } from "node-html-parser";
2332
- var TextNode2 = parse2.TextNode;
2450
+ import { parse as parse3 } from "node-html-parser";
2451
+ var TextNode2 = parse3.TextNode;
2333
2452
  var TextNodeHandler2 = class extends NodeHandler2 {
2334
2453
  processNode(node) {
2335
2454
  if (!(node instanceof TextNode2)) return null;
@@ -2348,10 +2467,10 @@ var TextNodeHandler2 = class extends NodeHandler2 {
2348
2467
  };
2349
2468
 
2350
2469
  // src/importFromHtml/VariableNodeHandler.ts
2351
- import { HTMLElement as HTMLElement27 } from "node-html-parser";
2470
+ import { HTMLElement as HTMLElement29 } from "node-html-parser";
2352
2471
  var VariableNodeHandler2 = class extends NodeHandler2 {
2353
2472
  processNode(node) {
2354
- if (!(node instanceof HTMLElement27) || !node.tagName) return null;
2473
+ if (!(node instanceof HTMLElement29) || !node.tagName) return null;
2355
2474
  if (node.tagName !== "x-param".toUpperCase()) return null;
2356
2475
  return {
2357
2476
  variableName: node.getAttribute("data-x-name") || "undefined",
@@ -2364,7 +2483,7 @@ var VariableNodeHandler2 = class extends NodeHandler2 {
2364
2483
 
2365
2484
  // src/importFromHtml/traverse.ts
2366
2485
  var builder2 = new NodeHandlerChainBuilder();
2367
- var nodeHandlerChain2 = builder2.addHandler(CustomQuestionNodeHandler2).addHandler(DivNodeHandler).addHandler(EssayQuestionNodeHandler2).addHandler(FillInTheBlankQuestionNodeHandler2).addHandler(FillInTheBlankSpaceNodeHandler2).addHandler(FinancialStatementQuestionNodeHandler2).addHandler(FormattedNodeHandler).addHandler(ImageNodeHandler2).addHandler(HeadingNodeHandler2).addHandler(HorizontalRuleNodeHandler2).addHandler(JournalEntryQuestionNodeHandler2).addHandler(LineBreakNodeHandler2).addHandler(LinkNodeHandler2).addHandler(ListNodeHandler2).addHandler(ListItemNodeHandler2).addHandler(MatchingQuestionNodeHandler2).addHandler(MultipleOptionQuestionNodeHandler2).addHandler(ParagraphNodeHandler2).addHandler(ShortAnswerQuestionNodeHandler2).addHandler(SimulationQuestionNodeHandler2).addHandler(SpanNodeHandler).addHandler(TableCellNodeHandler2).addHandler(TableNodeHandler2).addHandler(TableRowNodeHandler2).addHandler(TextNodeHandler2).addHandler(VariableNodeHandler2).build();
2486
+ var nodeHandlerChain2 = builder2.addHandler(CustomQuestionNodeHandler2).addHandler(DivNodeHandler).addHandler(EssayQuestionNodeHandler2).addHandler(ExcelQuestionNodeHandler2).addHandler(ExcelWorksheetLinkNodeHandler).addHandler(FillInTheBlankQuestionNodeHandler2).addHandler(FillInTheBlankSpaceNodeHandler2).addHandler(FinancialStatementQuestionNodeHandler2).addHandler(FormattedNodeHandler).addHandler(HeadingNodeHandler2).addHandler(HorizontalRuleNodeHandler2).addHandler(ImageNodeHandler2).addHandler(JournalEntryQuestionNodeHandler2).addHandler(LineBreakNodeHandler2).addHandler(LinkNodeHandler2).addHandler(ListItemNodeHandler2).addHandler(ListNodeHandler2).addHandler(MatchingQuestionNodeHandler2).addHandler(MultipleOptionQuestionNodeHandler2).addHandler(ParagraphNodeHandler2).addHandler(ShortAnswerQuestionNodeHandler2).addHandler(SimulationQuestionNodeHandler2).addHandler(SpanNodeHandler).addHandler(TableCellNodeHandler2).addHandler(TableNodeHandler2).addHandler(TableRowNodeHandler2).addHandler(TextNodeHandler2).addHandler(VariableNodeHandler2).build();
2368
2487
  function traverse2(node) {
2369
2488
  const result = nodeHandlerChain2.handle(node);
2370
2489
  if (result === null) return [];
@@ -2382,7 +2501,7 @@ function processChildren(node) {
2382
2501
  return result;
2383
2502
  }
2384
2503
  function processHtml(html) {
2385
- const root = parse3(html);
2504
+ const root = parse4(html);
2386
2505
  return processChildren(root);
2387
2506
  }
2388
2507
  function importFromHtml(html) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@examind/block-sdk",
3
- "version": "0.1.41",
3
+ "version": "0.2.1",
4
4
  "@comment version": [
5
5
  "Don't specify package version here. It will be injected by publish workflow."
6
6
  ],
@@ -21,7 +21,7 @@
21
21
  "peerDependencies": {
22
22
  "nanoid": ">=3.0.0",
23
23
  "node-html-parser": ">=6.0.0",
24
- "@examind/block-types": "^0.1.41"
24
+ "@examind/block-types": "^0.2.1"
25
25
  },
26
26
  "devDependencies": {
27
27
  "@eslint/js": "^9.17.0",
@@ -36,7 +36,7 @@
36
36
  "tsup": "^8.3.5",
37
37
  "typescript": "^5.7.2",
38
38
  "typescript-eslint": "^8.18.2",
39
- "@examind/block-types": "0.1.41"
39
+ "@examind/block-types": "0.2.1"
40
40
  },
41
41
  "dependencies": {
42
42
  "lodash-es": "4.17.21"