@examind/block-sdk 0.1.40 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/index.js +187 -70
  2. package/dist/index.mjs +187 -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,102 @@ 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((0, import_node_html_parser5.parse)(xPart.objective)),
1350
+ instructions: createNestedEditorFromHtml(
1351
+ (0, import_node_html_parser5.parse)(xPart.instructions)
1352
+ ),
1353
+ onLoadActions: xPart.onLoadActions,
1354
+ onNextActions: xPart.onNextActions,
1355
+ tasks
1356
+ });
1357
+ }
1358
+ return {
1359
+ sourceFileName: xData.sourceFileName || "",
1360
+ transformations: xData.transformations || [],
1361
+ parts
1362
+ };
1363
+ }
1364
+ var ExcelQuestionNodeHandler2 = class extends NodeHandler2 {
1365
+ processNode(node) {
1366
+ if (!(node instanceof import_node_html_parser5.HTMLElement) || node.tagName !== TAG_X.toUpperCase()) {
1367
+ return null;
1368
+ }
1369
+ const xDataElement = node.querySelector("x-data");
1370
+ if (!xDataElement) {
1371
+ return null;
1372
+ }
1373
+ const data = parseData(
1374
+ xDataElement.innerHTML
1375
+ );
1376
+ const jsonNode = {
1377
+ id: node.getAttribute("id") || "",
1378
+ points: Number(node.getAttribute("data-x-points") || 1),
1379
+ data,
1380
+ active: data.parts.length > 0 ? data.parts[0].id : "",
1381
+ type: "excel-question",
1382
+ version: 1
1383
+ };
1384
+ return jsonNode;
1385
+ }
1386
+ };
1387
+
1388
+ // src/importFromHtml/ExcelWorksheetLinkNodeHandler.ts
1389
+ var import_node_html_parser6 = require("node-html-parser");
1390
+ var TAG = "x-worksheet-link";
1391
+ var ExcelWorksheetLinkNodeHandler = class extends NodeHandler2 {
1392
+ processNode(node) {
1393
+ if (!(node instanceof import_node_html_parser6.HTMLElement) || node.tagName !== TAG.toUpperCase()) {
1394
+ return null;
1395
+ }
1396
+ const url = node.getAttribute("x-data-name") || "";
1397
+ const linkNode = {
1398
+ detail: 0,
1399
+ format: 0,
1400
+ mode: "normal",
1401
+ style: "",
1402
+ text: node.text || url,
1403
+ dataName: url,
1404
+ type: "excel-worksheet-link",
1405
+ version: 1
1406
+ };
1407
+ return linkNode;
1408
+ }
1409
+ };
1410
+
1296
1411
  // src/importFromHtml/FillInTheBlankQuestionNodeHandler.ts
1412
+ var import_nanoid2 = require("nanoid");
1413
+ var import_node_html_parser7 = require("node-html-parser");
1297
1414
  var FillInTheBlankQuestionNodeHandler2 = class extends NodeHandler2 {
1298
1415
  processNode(node) {
1299
- if (!(node instanceof import_node_html_parser5.HTMLElement) || node.tagName !== "x-fill-in-the-blank".toUpperCase())
1416
+ if (!(node instanceof import_node_html_parser7.HTMLElement) || node.tagName !== "x-fill-in-the-blank".toUpperCase())
1300
1417
  return null;
1301
1418
  const jsonNode = {
1302
1419
  id: node.getAttribute("id") ?? (0, import_nanoid2.nanoid)(),
@@ -1313,7 +1430,7 @@ var FillInTheBlankQuestionNodeHandler2 = class extends NodeHandler2 {
1313
1430
 
1314
1431
  // src/importFromHtml/FillInTheBlankSpaceNodeHandler.ts
1315
1432
  var import_nanoid3 = require("nanoid");
1316
- var import_node_html_parser6 = require("node-html-parser");
1433
+ var import_node_html_parser8 = require("node-html-parser");
1317
1434
 
1318
1435
  // src/importFromHtml/parseErrorToleranceAttribute.ts
1319
1436
  function parseErrorToleranceAttribute(attr) {
@@ -1325,7 +1442,7 @@ function parseErrorToleranceAttribute(attr) {
1325
1442
  // src/importFromHtml/FillInTheBlankSpaceNodeHandler.ts
1326
1443
  var FillInTheBlankSpaceNodeHandler2 = class extends NodeHandler2 {
1327
1444
  processNode(node) {
1328
- if (!(node instanceof import_node_html_parser6.HTMLElement) || node.tagName !== "x-space".toUpperCase())
1445
+ if (!(node instanceof import_node_html_parser8.HTMLElement) || node.tagName !== "x-space".toUpperCase())
1329
1446
  return null;
1330
1447
  const spaceTypeAttr = node.getAttribute("data-x-type");
1331
1448
  const spaceType = spaceTypeAttr === "Text" || spaceTypeAttr === "Number" || spaceTypeAttr === "Dropdown" ? spaceTypeAttr : "Text";
@@ -1375,7 +1492,7 @@ var FillInTheBlankSpaceNodeHandler2 = class extends NodeHandler2 {
1375
1492
 
1376
1493
  // src/importFromHtml/FinancialStatementQuestionNodeHandler.ts
1377
1494
  var import_nanoid4 = require("nanoid");
1378
- var import_node_html_parser7 = require("node-html-parser");
1495
+ var import_node_html_parser9 = require("node-html-parser");
1379
1496
  var TAG_X_FINANCIAL_STATEMENT = "x-financial-statement";
1380
1497
  var TAG_X_HEADER = "x-header";
1381
1498
  var TAG_X_ROWS = "x-rows";
@@ -1387,7 +1504,7 @@ var TAG_X_ENTRY = "x-entry";
1387
1504
  var TAG_X_AMOUNT = "x-amount";
1388
1505
  var FinancialStatementQuestionNodeHandler2 = class extends NodeHandler2 {
1389
1506
  processNode(node) {
1390
- if (!(node instanceof import_node_html_parser7.HTMLElement) || node.tagName !== TAG_X_FINANCIAL_STATEMENT.toUpperCase()) {
1507
+ if (!(node instanceof import_node_html_parser9.HTMLElement) || node.tagName !== TAG_X_FINANCIAL_STATEMENT.toUpperCase()) {
1391
1508
  return null;
1392
1509
  }
1393
1510
  const headerElement = node.querySelector(TAG_X_HEADER);
@@ -1402,7 +1519,7 @@ var FinancialStatementQuestionNodeHandler2 = class extends NodeHandler2 {
1402
1519
  version: 1
1403
1520
  };
1404
1521
  node.childNodes.forEach((child) => {
1405
- if (!(child instanceof import_node_html_parser7.HTMLElement)) return;
1522
+ if (!(child instanceof import_node_html_parser9.HTMLElement)) return;
1406
1523
  if (child.tagName === TAG_X_DISTRACTORS.toUpperCase()) {
1407
1524
  this.processDistractorsNode(child, jsonNode);
1408
1525
  } else if (child.tagName === TAG_X_ROWS.toUpperCase()) {
@@ -1413,7 +1530,7 @@ var FinancialStatementQuestionNodeHandler2 = class extends NodeHandler2 {
1413
1530
  }
1414
1531
  processDistractorsNode(distractorsNode, jsonNode) {
1415
1532
  for (const distractorsChild of distractorsNode.childNodes) {
1416
- if (!(distractorsChild instanceof import_node_html_parser7.HTMLElement)) continue;
1533
+ if (!(distractorsChild instanceof import_node_html_parser9.HTMLElement)) continue;
1417
1534
  if (distractorsChild.tagName !== TAG_X_DISTRACTOR.toUpperCase())
1418
1535
  continue;
1419
1536
  jsonNode.distractors.push({
@@ -1434,7 +1551,7 @@ var FinancialStatementQuestionNodeHandler2 = class extends NodeHandler2 {
1434
1551
  const contentDiv = headerElement.querySelector(
1435
1552
  'div > div:not([style*="display:flex"])'
1436
1553
  );
1437
- if (contentDiv && contentDiv instanceof import_node_html_parser7.HTMLElement)
1554
+ if (contentDiv && contentDiv instanceof import_node_html_parser9.HTMLElement)
1438
1555
  return createNestedEditorFromHtml(contentDiv);
1439
1556
  }
1440
1557
  return createNestedEditorFromHtml(headerElement);
@@ -1451,7 +1568,7 @@ var FinancialStatementQuestionNodeHandler2 = class extends NodeHandler2 {
1451
1568
  }
1452
1569
  processRowsNode(rowsNode, jsonNode) {
1453
1570
  for (const rowsChild of rowsNode.childNodes) {
1454
- if (!(rowsChild instanceof import_node_html_parser7.HTMLElement)) continue;
1571
+ if (!(rowsChild instanceof import_node_html_parser9.HTMLElement)) continue;
1455
1572
  if (rowsChild.tagName === TAG_X_HEADING.toUpperCase()) {
1456
1573
  this.processHeadingRow(rowsChild, jsonNode);
1457
1574
  } else if (rowsChild.tagName === TAG_X_LINE.toUpperCase()) {
@@ -1485,7 +1602,7 @@ var FinancialStatementQuestionNodeHandler2 = class extends NodeHandler2 {
1485
1602
  };
1486
1603
 
1487
1604
  // src/importFromHtml/FormattedNodeHandler.ts
1488
- var import_node_html_parser8 = require("node-html-parser");
1605
+ var import_node_html_parser10 = require("node-html-parser");
1489
1606
  var IS_BOLD2 = 1;
1490
1607
  var IS_ITALIC2 = 1 << 1;
1491
1608
  var IS_STRIKETHROUGH2 = 1 << 2;
@@ -1525,7 +1642,7 @@ function formatToProps(format) {
1525
1642
  }
1526
1643
  var FormattedNodeHandler = class extends NodeHandler2 {
1527
1644
  processNode(node) {
1528
- if (!(node instanceof import_node_html_parser8.HTMLElement)) return null;
1645
+ if (!(node instanceof import_node_html_parser10.HTMLElement)) return null;
1529
1646
  const tagName = node.tagName;
1530
1647
  if (!tagName || !(tagName in TAG_TO_FORMAT)) return null;
1531
1648
  const formatFlag = TAG_TO_FORMAT[tagName];
@@ -1560,7 +1677,7 @@ var FormattedNodeHandler = class extends NodeHandler2 {
1560
1677
  };
1561
1678
 
1562
1679
  // src/importFromHtml/HeadingNodeHandler.ts
1563
- var import_node_html_parser9 = require("node-html-parser");
1680
+ var import_node_html_parser11 = require("node-html-parser");
1564
1681
 
1565
1682
  // src/importFromHtml/extractTextAlignment.ts
1566
1683
  var TEXT_ALIGN_TO_FORMAT = {
@@ -1588,7 +1705,7 @@ function extractTextAlignment(element) {
1588
1705
  var TAG_HEADINGS = ["h1", "h2", "h3", "h4", "h5", "h6"];
1589
1706
  var HeadingNodeHandler2 = class extends NodeHandler2 {
1590
1707
  processNode(node) {
1591
- if (!(node instanceof import_node_html_parser9.HTMLElement) || !TAG_HEADINGS.includes(node.tagName.toLowerCase())) {
1708
+ if (!(node instanceof import_node_html_parser11.HTMLElement) || !TAG_HEADINGS.includes(node.tagName.toLowerCase())) {
1592
1709
  return null;
1593
1710
  }
1594
1711
  const headingNode = {
@@ -1609,11 +1726,11 @@ var HeadingNodeHandler2 = class extends NodeHandler2 {
1609
1726
  };
1610
1727
 
1611
1728
  // src/importFromHtml/HorizontalRuleNodeHandler.ts
1612
- var import_node_html_parser10 = require("node-html-parser");
1729
+ var import_node_html_parser12 = require("node-html-parser");
1613
1730
  var TAG_HR = "hr";
1614
1731
  var HorizontalRuleNodeHandler2 = class extends NodeHandler2 {
1615
1732
  processNode(node) {
1616
- if (!(node instanceof import_node_html_parser10.HTMLElement) || node.tagName !== TAG_HR.toUpperCase()) {
1733
+ if (!(node instanceof import_node_html_parser12.HTMLElement) || node.tagName !== TAG_HR.toUpperCase()) {
1617
1734
  return null;
1618
1735
  }
1619
1736
  const horizontalRuleNode = {
@@ -1625,11 +1742,11 @@ var HorizontalRuleNodeHandler2 = class extends NodeHandler2 {
1625
1742
  };
1626
1743
 
1627
1744
  // src/importFromHtml/ImageNodeHandler.ts
1628
- var import_node_html_parser11 = require("node-html-parser");
1745
+ var import_node_html_parser13 = require("node-html-parser");
1629
1746
  var TAG_IMG = "img";
1630
1747
  var ImageNodeHandler2 = class extends NodeHandler2 {
1631
1748
  processNode(node) {
1632
- if (!(node instanceof import_node_html_parser11.HTMLElement) || node.tagName !== TAG_IMG.toUpperCase()) {
1749
+ if (!(node instanceof import_node_html_parser13.HTMLElement) || node.tagName !== TAG_IMG.toUpperCase()) {
1633
1750
  return null;
1634
1751
  }
1635
1752
  return createImageNode(
@@ -1645,11 +1762,11 @@ var ImageNodeHandler2 = class extends NodeHandler2 {
1645
1762
 
1646
1763
  // src/importFromHtml/JournalEntryQuestionNodeHandler.ts
1647
1764
  var import_nanoid6 = require("nanoid");
1648
- var import_node_html_parser13 = require("node-html-parser");
1765
+ var import_node_html_parser15 = require("node-html-parser");
1649
1766
 
1650
1767
  // src/importFromHtml/createOnePerLineDistractorNode.ts
1651
1768
  var import_nanoid5 = require("nanoid");
1652
- var import_node_html_parser12 = require("node-html-parser");
1769
+ var import_node_html_parser14 = require("node-html-parser");
1653
1770
  function extractDistractorId(id) {
1654
1771
  if (!id) return null;
1655
1772
  const parts = id.split("|");
@@ -1662,7 +1779,7 @@ var createOnePerLineDistractorNode = (node) => {
1662
1779
  distractorEditor.editorState.root.children = [];
1663
1780
  let distractorId = null;
1664
1781
  distractors.forEach((distractor) => {
1665
- if (!(distractor instanceof import_node_html_parser12.HTMLElement)) return;
1782
+ if (!(distractor instanceof import_node_html_parser14.HTMLElement)) return;
1666
1783
  distractorId = distractorId ?? extractDistractorId(distractor.getAttribute("id"));
1667
1784
  distractorEditor.editorState.root.children.push(
1668
1785
  ...createNestedNodesFromHtml(distractor)
@@ -1680,7 +1797,7 @@ var createOnePerLineDistractorNode = (node) => {
1680
1797
  // src/importFromHtml/JournalEntryQuestionNodeHandler.ts
1681
1798
  var JournalEntryQuestionNodeHandler2 = class extends NodeHandler2 {
1682
1799
  processNode(node) {
1683
- if (!(node instanceof import_node_html_parser13.HTMLElement) || node.tagName !== "x-journal-entry".toUpperCase())
1800
+ if (!(node instanceof import_node_html_parser15.HTMLElement) || node.tagName !== "x-journal-entry".toUpperCase())
1684
1801
  return null;
1685
1802
  const jsonNode = {
1686
1803
  id: node.getAttribute("id") ?? (0, import_nanoid6.nanoid)(),
@@ -1695,7 +1812,7 @@ var JournalEntryQuestionNodeHandler2 = class extends NodeHandler2 {
1695
1812
  };
1696
1813
  const lineItems = node.querySelectorAll("x-line-item");
1697
1814
  lineItems.forEach((lineItem) => {
1698
- if (!(lineItem instanceof import_node_html_parser13.HTMLElement)) return;
1815
+ if (!(lineItem instanceof import_node_html_parser15.HTMLElement)) return;
1699
1816
  const accountElement = lineItem.querySelector("x-account");
1700
1817
  const debitElement = lineItem.querySelector("x-debit");
1701
1818
  const creditElement = lineItem.querySelector("x-credit");
@@ -1724,10 +1841,10 @@ var JournalEntryQuestionNodeHandler2 = class extends NodeHandler2 {
1724
1841
  };
1725
1842
 
1726
1843
  // src/importFromHtml/LineBreakNodeHandler.ts
1727
- var import_node_html_parser14 = require("node-html-parser");
1844
+ var import_node_html_parser16 = require("node-html-parser");
1728
1845
  var LineBreakNodeHandler2 = class extends NodeHandler2 {
1729
1846
  processNode(node) {
1730
- if (!(node instanceof import_node_html_parser14.HTMLElement)) return null;
1847
+ if (!(node instanceof import_node_html_parser16.HTMLElement)) return null;
1731
1848
  if (node.tagName !== "BR") return null;
1732
1849
  return {
1733
1850
  type: "linebreak",
@@ -1737,11 +1854,11 @@ var LineBreakNodeHandler2 = class extends NodeHandler2 {
1737
1854
  };
1738
1855
 
1739
1856
  // src/importFromHtml/LinkNodeHandler.ts
1740
- var import_node_html_parser15 = require("node-html-parser");
1857
+ var import_node_html_parser17 = require("node-html-parser");
1741
1858
  var TAG_A = "a";
1742
1859
  var LinkNodeHandler2 = class extends NodeHandler2 {
1743
1860
  processNode(node) {
1744
- if (!(node instanceof import_node_html_parser15.HTMLElement) || node.tagName !== TAG_A.toUpperCase()) {
1861
+ if (!(node instanceof import_node_html_parser17.HTMLElement) || node.tagName !== TAG_A.toUpperCase()) {
1745
1862
  return null;
1746
1863
  }
1747
1864
  const url = node.getAttribute("href") || "";
@@ -1770,10 +1887,10 @@ var LinkNodeHandler2 = class extends NodeHandler2 {
1770
1887
  };
1771
1888
 
1772
1889
  // src/importFromHtml/ListItemNodeHandler.ts
1773
- var import_node_html_parser16 = require("node-html-parser");
1890
+ var import_node_html_parser18 = require("node-html-parser");
1774
1891
  var ListItemNodeHandler2 = class extends NodeHandler2 {
1775
1892
  processNode(node) {
1776
- if (!(node instanceof import_node_html_parser16.HTMLElement)) return null;
1893
+ if (!(node instanceof import_node_html_parser18.HTMLElement)) return null;
1777
1894
  if (node.tagName !== "LI") return null;
1778
1895
  const jsonNode = {
1779
1896
  type: "listitem",
@@ -1794,10 +1911,10 @@ var ListItemNodeHandler2 = class extends NodeHandler2 {
1794
1911
  };
1795
1912
 
1796
1913
  // src/importFromHtml/ListNodeHandler.ts
1797
- var import_node_html_parser17 = require("node-html-parser");
1914
+ var import_node_html_parser19 = require("node-html-parser");
1798
1915
  var ListNodeHandler2 = class extends NodeHandler2 {
1799
1916
  processNode(node) {
1800
- if (!(node instanceof import_node_html_parser17.HTMLElement)) return null;
1917
+ if (!(node instanceof import_node_html_parser19.HTMLElement)) return null;
1801
1918
  if (node.tagName !== "UL" && node.tagName !== "OL") return null;
1802
1919
  const tag = node.tagName.toLowerCase();
1803
1920
  const listType = tag === "ol" ? "number" : "bullet";
@@ -1815,7 +1932,7 @@ var ListNodeHandler2 = class extends NodeHandler2 {
1815
1932
  };
1816
1933
  let itemIndex = 1;
1817
1934
  node.childNodes.forEach((child) => {
1818
- if (child instanceof import_node_html_parser17.HTMLElement && child.tagName === "LI") {
1935
+ if (child instanceof import_node_html_parser19.HTMLElement && child.tagName === "LI") {
1819
1936
  const listItemNode = {
1820
1937
  type: "listitem",
1821
1938
  version: 1,
@@ -1840,10 +1957,10 @@ var ListNodeHandler2 = class extends NodeHandler2 {
1840
1957
 
1841
1958
  // src/importFromHtml/MatchingQuestionNodeHandler.ts
1842
1959
  var import_nanoid7 = require("nanoid");
1843
- var import_node_html_parser18 = require("node-html-parser");
1960
+ var import_node_html_parser20 = require("node-html-parser");
1844
1961
  var MatchingQuestionNodeHandler2 = class extends NodeHandler2 {
1845
1962
  processNode(node) {
1846
- if (!(node instanceof import_node_html_parser18.HTMLElement) || node.tagName !== "x-matching".toUpperCase())
1963
+ if (!(node instanceof import_node_html_parser20.HTMLElement) || node.tagName !== "x-matching".toUpperCase())
1847
1964
  return null;
1848
1965
  const jsonNode = {
1849
1966
  id: node.getAttribute("id") ?? (0, import_nanoid7.nanoid)(),
@@ -1856,7 +1973,7 @@ var MatchingQuestionNodeHandler2 = class extends NodeHandler2 {
1856
1973
  };
1857
1974
  const matches = node.querySelectorAll("x-match");
1858
1975
  matches.forEach((match) => {
1859
- if (!(match instanceof import_node_html_parser18.HTMLElement)) return;
1976
+ if (!(match instanceof import_node_html_parser20.HTMLElement)) return;
1860
1977
  const premise = match.querySelector("x-premise");
1861
1978
  const option = match.querySelector("x-option");
1862
1979
  if (!premise || !option) return;
@@ -1879,10 +1996,10 @@ var MatchingQuestionNodeHandler2 = class extends NodeHandler2 {
1879
1996
 
1880
1997
  // src/importFromHtml/MultipleOptionQuestionNodeHandler.ts
1881
1998
  var import_nanoid8 = require("nanoid");
1882
- var import_node_html_parser19 = require("node-html-parser");
1999
+ var import_node_html_parser21 = require("node-html-parser");
1883
2000
  var MultipleOptionQuestionNodeHandler2 = class extends NodeHandler2 {
1884
2001
  processNode(node) {
1885
- if (!(node instanceof import_node_html_parser19.HTMLElement)) return null;
2002
+ if (!(node instanceof import_node_html_parser21.HTMLElement)) return null;
1886
2003
  if (node.tagName === "x-multiple-choice".toUpperCase())
1887
2004
  return this.processMultipleChoiceNode(node);
1888
2005
  else if (node.tagName === "x-multiple-answers".toUpperCase())
@@ -1922,7 +2039,7 @@ var MultipleOptionQuestionNodeHandler2 = class extends NodeHandler2 {
1922
2039
  processOptions(node, jsonNode) {
1923
2040
  const childNodes = node.childNodes;
1924
2041
  childNodes.forEach((child) => {
1925
- if (!(child instanceof import_node_html_parser19.HTMLElement)) return;
2042
+ if (!(child instanceof import_node_html_parser21.HTMLElement)) return;
1926
2043
  if (child.tagName !== "x-option".toUpperCase()) return;
1927
2044
  jsonNode.options.push({
1928
2045
  id: child.getAttribute("id") ?? (0, import_nanoid8.nanoid)(),
@@ -1934,28 +2051,28 @@ var MultipleOptionQuestionNodeHandler2 = class extends NodeHandler2 {
1934
2051
  };
1935
2052
 
1936
2053
  // src/importFromHtml/ParagraphNodeHandler.ts
1937
- var import_node_html_parser20 = require("node-html-parser");
2054
+ var import_node_html_parser22 = require("node-html-parser");
1938
2055
  var ParagraphNodeHandler2 = class extends NodeHandler2 {
1939
2056
  processImageNode(node) {
1940
- if (node.childNodes.length === 1 && node.childNodes[0] instanceof import_node_html_parser20.HTMLElement && node.childNodes[0].tagName === "IMG") {
2057
+ if (node.childNodes.length === 1 && node.childNodes[0] instanceof import_node_html_parser22.HTMLElement && node.childNodes[0].tagName === "IMG") {
1941
2058
  return traverse2(node.childNodes[0]);
1942
2059
  }
1943
2060
  return null;
1944
2061
  }
1945
2062
  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") {
2063
+ 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
2064
  return traverse2(node.childNodes[0].childNodes[0]);
1948
2065
  }
1949
2066
  return null;
1950
2067
  }
1951
2068
  processNode(node) {
1952
- if (!(node instanceof import_node_html_parser20.HTMLElement)) return null;
2069
+ if (!(node instanceof import_node_html_parser22.HTMLElement)) return null;
1953
2070
  if (node.tagName !== "P") return null;
1954
2071
  const imageNode = this.processImageNode(node) ?? this.processSpanImageNode(node);
1955
2072
  if (imageNode) return imageNode;
1956
2073
  const jsonNode = createEmptyParagraphNode();
1957
2074
  jsonNode.format = extractTextAlignment(node);
1958
- if (node.childNodes.length === 1 && node.childNodes[0] instanceof import_node_html_parser20.HTMLElement && node.childNodes[0].tagName === "BR")
2075
+ if (node.childNodes.length === 1 && node.childNodes[0] instanceof import_node_html_parser22.HTMLElement && node.childNodes[0].tagName === "BR")
1959
2076
  return jsonNode;
1960
2077
  node.childNodes.forEach((child) => {
1961
2078
  const processedChildren = traverse2(child);
@@ -1967,10 +2084,10 @@ var ParagraphNodeHandler2 = class extends NodeHandler2 {
1967
2084
 
1968
2085
  // src/importFromHtml/ShortAnswerQuestionNodeHandler.ts
1969
2086
  var import_nanoid9 = require("nanoid");
1970
- var import_node_html_parser21 = require("node-html-parser");
2087
+ var import_node_html_parser23 = require("node-html-parser");
1971
2088
  var ShortAnswerQuestionNodeHandler2 = class extends NodeHandler2 {
1972
2089
  processNode(node) {
1973
- if (!(node instanceof import_node_html_parser21.HTMLElement) || node.tagName !== "x-short-answer".toUpperCase())
2090
+ if (!(node instanceof import_node_html_parser23.HTMLElement) || node.tagName !== "x-short-answer".toUpperCase())
1974
2091
  return null;
1975
2092
  return {
1976
2093
  id: node.getAttribute("id") ?? (0, import_nanoid9.nanoid)(),
@@ -1986,7 +2103,7 @@ var ShortAnswerQuestionNodeHandler2 = class extends NodeHandler2 {
1986
2103
  };
1987
2104
 
1988
2105
  // src/importFromHtml/SimulationQuestionNodeHandler.ts
1989
- var import_node_html_parser22 = require("node-html-parser");
2106
+ var import_node_html_parser24 = require("node-html-parser");
1990
2107
  var TAG_X_SIMULATION = "x-simulation";
1991
2108
  var TAG_X_SYSTEM_MESSAGE2 = "x-ai-system-message";
1992
2109
  var TAG_X_COMMENT_INSTRUCTIONS = "x-comment-instructions";
@@ -1994,7 +2111,7 @@ var TAG_X_STEP2_INSTRUCTIONS = "x-step2-instructions";
1994
2111
  var findFirstNonEmptyInnerHtml = (root, elementNames) => elementNames.map((name) => root.querySelector(name)).find((el) => el?.innerHTML.trim().length)?.innerHTML.trim() ?? null;
1995
2112
  var SimulationQuestionNodeHandler2 = class extends NodeHandler2 {
1996
2113
  processNode(node) {
1997
- if (!(node instanceof import_node_html_parser22.HTMLElement) || node.tagName !== TAG_X_SIMULATION.toUpperCase()) {
2114
+ if (!(node instanceof import_node_html_parser24.HTMLElement) || node.tagName !== TAG_X_SIMULATION.toUpperCase()) {
1998
2115
  return null;
1999
2116
  }
2000
2117
  const jsonNode = {
@@ -2015,11 +2132,11 @@ var SimulationQuestionNodeHandler2 = class extends NodeHandler2 {
2015
2132
  };
2016
2133
 
2017
2134
  // src/importFromHtml/SpanNodeHandler.ts
2018
- var import_node_html_parser23 = require("node-html-parser");
2019
- var TextNode = import_node_html_parser23.parse.TextNode;
2135
+ var import_node_html_parser25 = require("node-html-parser");
2136
+ var TextNode = import_node_html_parser25.parse.TextNode;
2020
2137
  var SpanNodeHandler = class extends NodeHandler2 {
2021
2138
  processNode(node) {
2022
- if (!(node instanceof import_node_html_parser23.HTMLElement) || node.tagName !== "SPAN")
2139
+ if (!(node instanceof import_node_html_parser25.HTMLElement) || node.tagName !== "SPAN")
2023
2140
  return null;
2024
2141
  const styleAttr = node.getAttribute("style") || "";
2025
2142
  if (node.childNodes.length === 1 && node.childNodes[0] instanceof TextNode) {
@@ -2081,7 +2198,7 @@ var SpanNodeHandler = class extends NodeHandler2 {
2081
2198
  };
2082
2199
 
2083
2200
  // src/importFromHtml/TableCellNodeHandler.ts
2084
- var import_node_html_parser24 = require("node-html-parser");
2201
+ var import_node_html_parser26 = require("node-html-parser");
2085
2202
 
2086
2203
  // src/utils/styleUtils.ts
2087
2204
  var extractStyleValue = (styleAttr, property, isNumeric = false, unit = "") => {
@@ -2130,7 +2247,7 @@ function createEmptyTableCellNode(isHeader = false) {
2130
2247
 
2131
2248
  // src/importFromHtml/TableCellNodeHandler.ts
2132
2249
  var isHtmlTableCellElement = (node) => {
2133
- return node instanceof import_node_html_parser24.HTMLElement && (node.tagName === "TD" || node.tagName === "TH");
2250
+ return node instanceof import_node_html_parser26.HTMLElement && (node.tagName === "TD" || node.tagName === "TH");
2134
2251
  };
2135
2252
  var TableCellNodeHandler2 = class extends NodeHandler2 {
2136
2253
  processNode(node) {
@@ -2172,10 +2289,10 @@ var TableCellNodeHandler2 = class extends NodeHandler2 {
2172
2289
  };
2173
2290
 
2174
2291
  // src/importFromHtml/TableNodeHandler.ts
2175
- var import_node_html_parser25 = require("node-html-parser");
2292
+ var import_node_html_parser27 = require("node-html-parser");
2176
2293
  var REFERENCE_TABLE_WIDTH = 720;
2177
2294
  var MINIMUM_REFERENCE_TABLE_WIDTH = 500;
2178
- var isHtmlTableElement = (node) => node instanceof import_node_html_parser25.HTMLElement && node.tagName === "TABLE";
2295
+ var isHtmlTableElement = (node) => node instanceof import_node_html_parser27.HTMLElement && node.tagName === "TABLE";
2179
2296
  var TableNodeHandler2 = class extends NodeHandler2 {
2180
2297
  processNode(node) {
2181
2298
  if (!isHtmlTableElement(node)) return null;
@@ -2330,9 +2447,9 @@ var TableNodeHandler2 = class extends NodeHandler2 {
2330
2447
  };
2331
2448
 
2332
2449
  // src/importFromHtml/TableRowNodeHandler.ts
2333
- var import_node_html_parser26 = require("node-html-parser");
2450
+ var import_node_html_parser28 = require("node-html-parser");
2334
2451
  var isHtmlTableRowElement = (node) => {
2335
- return node instanceof import_node_html_parser26.HTMLElement && node.tagName === "TR";
2452
+ return node instanceof import_node_html_parser28.HTMLElement && node.tagName === "TR";
2336
2453
  };
2337
2454
  var TableRowNodeHandler2 = class extends NodeHandler2 {
2338
2455
  processNode(node) {
@@ -2355,8 +2472,8 @@ var TableRowNodeHandler2 = class extends NodeHandler2 {
2355
2472
  };
2356
2473
 
2357
2474
  // src/importFromHtml/TextNodeHandler.ts
2358
- var import_node_html_parser27 = require("node-html-parser");
2359
- var TextNode2 = import_node_html_parser27.parse.TextNode;
2475
+ var import_node_html_parser29 = require("node-html-parser");
2476
+ var TextNode2 = import_node_html_parser29.parse.TextNode;
2360
2477
  var TextNodeHandler2 = class extends NodeHandler2 {
2361
2478
  processNode(node) {
2362
2479
  if (!(node instanceof TextNode2)) return null;
@@ -2375,10 +2492,10 @@ var TextNodeHandler2 = class extends NodeHandler2 {
2375
2492
  };
2376
2493
 
2377
2494
  // src/importFromHtml/VariableNodeHandler.ts
2378
- var import_node_html_parser28 = require("node-html-parser");
2495
+ var import_node_html_parser30 = require("node-html-parser");
2379
2496
  var VariableNodeHandler2 = class extends NodeHandler2 {
2380
2497
  processNode(node) {
2381
- if (!(node instanceof import_node_html_parser28.HTMLElement) || !node.tagName) return null;
2498
+ if (!(node instanceof import_node_html_parser30.HTMLElement) || !node.tagName) return null;
2382
2499
  if (node.tagName !== "x-param".toUpperCase()) return null;
2383
2500
  return {
2384
2501
  variableName: node.getAttribute("data-x-name") || "undefined",
@@ -2391,7 +2508,7 @@ var VariableNodeHandler2 = class extends NodeHandler2 {
2391
2508
 
2392
2509
  // src/importFromHtml/traverse.ts
2393
2510
  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();
2511
+ 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
2512
  function traverse2(node) {
2396
2513
  const result = nodeHandlerChain2.handle(node);
2397
2514
  if (result === null) return [];
@@ -2409,7 +2526,7 @@ function processChildren(node) {
2409
2526
  return result;
2410
2527
  }
2411
2528
  function processHtml(html) {
2412
- const root = (0, import_node_html_parser29.parse)(html);
2529
+ const root = (0, import_node_html_parser31.parse)(html);
2413
2530
  return processChildren(root);
2414
2531
  }
2415
2532
  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,102 @@ 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(parse(xPart.objective)),
1323
+ instructions: createNestedEditorFromHtml(
1324
+ parse(xPart.instructions)
1325
+ ),
1326
+ onLoadActions: xPart.onLoadActions,
1327
+ onNextActions: xPart.onNextActions,
1328
+ tasks
1329
+ });
1330
+ }
1331
+ return {
1332
+ sourceFileName: xData.sourceFileName || "",
1333
+ transformations: xData.transformations || [],
1334
+ parts
1335
+ };
1336
+ }
1337
+ var ExcelQuestionNodeHandler2 = class extends NodeHandler2 {
1338
+ processNode(node) {
1339
+ if (!(node instanceof HTMLElement5) || node.tagName !== TAG_X.toUpperCase()) {
1340
+ return null;
1341
+ }
1342
+ const xDataElement = node.querySelector("x-data");
1343
+ if (!xDataElement) {
1344
+ return null;
1345
+ }
1346
+ const data = parseData(
1347
+ xDataElement.innerHTML
1348
+ );
1349
+ const jsonNode = {
1350
+ id: node.getAttribute("id") || "",
1351
+ points: Number(node.getAttribute("data-x-points") || 1),
1352
+ data,
1353
+ active: data.parts.length > 0 ? data.parts[0].id : "",
1354
+ type: "excel-question",
1355
+ version: 1
1356
+ };
1357
+ return jsonNode;
1358
+ }
1359
+ };
1360
+
1361
+ // src/importFromHtml/ExcelWorksheetLinkNodeHandler.ts
1362
+ import { HTMLElement as HTMLElement6 } from "node-html-parser";
1363
+ var TAG = "x-worksheet-link";
1364
+ var ExcelWorksheetLinkNodeHandler = class extends NodeHandler2 {
1365
+ processNode(node) {
1366
+ if (!(node instanceof HTMLElement6) || node.tagName !== TAG.toUpperCase()) {
1367
+ return null;
1368
+ }
1369
+ const url = node.getAttribute("x-data-name") || "";
1370
+ const linkNode = {
1371
+ detail: 0,
1372
+ format: 0,
1373
+ mode: "normal",
1374
+ style: "",
1375
+ text: node.text || url,
1376
+ dataName: url,
1377
+ type: "excel-worksheet-link",
1378
+ version: 1
1379
+ };
1380
+ return linkNode;
1381
+ }
1382
+ };
1383
+
1269
1384
  // src/importFromHtml/FillInTheBlankQuestionNodeHandler.ts
1385
+ import { nanoid as nanoid2 } from "nanoid";
1386
+ import { HTMLElement as HTMLElement7 } from "node-html-parser";
1270
1387
  var FillInTheBlankQuestionNodeHandler2 = class extends NodeHandler2 {
1271
1388
  processNode(node) {
1272
- if (!(node instanceof HTMLElement5) || node.tagName !== "x-fill-in-the-blank".toUpperCase())
1389
+ if (!(node instanceof HTMLElement7) || node.tagName !== "x-fill-in-the-blank".toUpperCase())
1273
1390
  return null;
1274
1391
  const jsonNode = {
1275
1392
  id: node.getAttribute("id") ?? nanoid2(),
@@ -1286,7 +1403,7 @@ var FillInTheBlankQuestionNodeHandler2 = class extends NodeHandler2 {
1286
1403
 
1287
1404
  // src/importFromHtml/FillInTheBlankSpaceNodeHandler.ts
1288
1405
  import { nanoid as nanoid3 } from "nanoid";
1289
- import { HTMLElement as HTMLElement6 } from "node-html-parser";
1406
+ import { HTMLElement as HTMLElement8 } from "node-html-parser";
1290
1407
 
1291
1408
  // src/importFromHtml/parseErrorToleranceAttribute.ts
1292
1409
  function parseErrorToleranceAttribute(attr) {
@@ -1298,7 +1415,7 @@ function parseErrorToleranceAttribute(attr) {
1298
1415
  // src/importFromHtml/FillInTheBlankSpaceNodeHandler.ts
1299
1416
  var FillInTheBlankSpaceNodeHandler2 = class extends NodeHandler2 {
1300
1417
  processNode(node) {
1301
- if (!(node instanceof HTMLElement6) || node.tagName !== "x-space".toUpperCase())
1418
+ if (!(node instanceof HTMLElement8) || node.tagName !== "x-space".toUpperCase())
1302
1419
  return null;
1303
1420
  const spaceTypeAttr = node.getAttribute("data-x-type");
1304
1421
  const spaceType = spaceTypeAttr === "Text" || spaceTypeAttr === "Number" || spaceTypeAttr === "Dropdown" ? spaceTypeAttr : "Text";
@@ -1348,7 +1465,7 @@ var FillInTheBlankSpaceNodeHandler2 = class extends NodeHandler2 {
1348
1465
 
1349
1466
  // src/importFromHtml/FinancialStatementQuestionNodeHandler.ts
1350
1467
  import { nanoid as nanoid4 } from "nanoid";
1351
- import { HTMLElement as HTMLElement7 } from "node-html-parser";
1468
+ import { HTMLElement as HTMLElement9 } from "node-html-parser";
1352
1469
  var TAG_X_FINANCIAL_STATEMENT = "x-financial-statement";
1353
1470
  var TAG_X_HEADER = "x-header";
1354
1471
  var TAG_X_ROWS = "x-rows";
@@ -1360,7 +1477,7 @@ var TAG_X_ENTRY = "x-entry";
1360
1477
  var TAG_X_AMOUNT = "x-amount";
1361
1478
  var FinancialStatementQuestionNodeHandler2 = class extends NodeHandler2 {
1362
1479
  processNode(node) {
1363
- if (!(node instanceof HTMLElement7) || node.tagName !== TAG_X_FINANCIAL_STATEMENT.toUpperCase()) {
1480
+ if (!(node instanceof HTMLElement9) || node.tagName !== TAG_X_FINANCIAL_STATEMENT.toUpperCase()) {
1364
1481
  return null;
1365
1482
  }
1366
1483
  const headerElement = node.querySelector(TAG_X_HEADER);
@@ -1375,7 +1492,7 @@ var FinancialStatementQuestionNodeHandler2 = class extends NodeHandler2 {
1375
1492
  version: 1
1376
1493
  };
1377
1494
  node.childNodes.forEach((child) => {
1378
- if (!(child instanceof HTMLElement7)) return;
1495
+ if (!(child instanceof HTMLElement9)) return;
1379
1496
  if (child.tagName === TAG_X_DISTRACTORS.toUpperCase()) {
1380
1497
  this.processDistractorsNode(child, jsonNode);
1381
1498
  } else if (child.tagName === TAG_X_ROWS.toUpperCase()) {
@@ -1386,7 +1503,7 @@ var FinancialStatementQuestionNodeHandler2 = class extends NodeHandler2 {
1386
1503
  }
1387
1504
  processDistractorsNode(distractorsNode, jsonNode) {
1388
1505
  for (const distractorsChild of distractorsNode.childNodes) {
1389
- if (!(distractorsChild instanceof HTMLElement7)) continue;
1506
+ if (!(distractorsChild instanceof HTMLElement9)) continue;
1390
1507
  if (distractorsChild.tagName !== TAG_X_DISTRACTOR.toUpperCase())
1391
1508
  continue;
1392
1509
  jsonNode.distractors.push({
@@ -1407,7 +1524,7 @@ var FinancialStatementQuestionNodeHandler2 = class extends NodeHandler2 {
1407
1524
  const contentDiv = headerElement.querySelector(
1408
1525
  'div > div:not([style*="display:flex"])'
1409
1526
  );
1410
- if (contentDiv && contentDiv instanceof HTMLElement7)
1527
+ if (contentDiv && contentDiv instanceof HTMLElement9)
1411
1528
  return createNestedEditorFromHtml(contentDiv);
1412
1529
  }
1413
1530
  return createNestedEditorFromHtml(headerElement);
@@ -1424,7 +1541,7 @@ var FinancialStatementQuestionNodeHandler2 = class extends NodeHandler2 {
1424
1541
  }
1425
1542
  processRowsNode(rowsNode, jsonNode) {
1426
1543
  for (const rowsChild of rowsNode.childNodes) {
1427
- if (!(rowsChild instanceof HTMLElement7)) continue;
1544
+ if (!(rowsChild instanceof HTMLElement9)) continue;
1428
1545
  if (rowsChild.tagName === TAG_X_HEADING.toUpperCase()) {
1429
1546
  this.processHeadingRow(rowsChild, jsonNode);
1430
1547
  } else if (rowsChild.tagName === TAG_X_LINE.toUpperCase()) {
@@ -1458,7 +1575,7 @@ var FinancialStatementQuestionNodeHandler2 = class extends NodeHandler2 {
1458
1575
  };
1459
1576
 
1460
1577
  // src/importFromHtml/FormattedNodeHandler.ts
1461
- import { HTMLElement as HTMLElement8 } from "node-html-parser";
1578
+ import { HTMLElement as HTMLElement10 } from "node-html-parser";
1462
1579
  var IS_BOLD2 = 1;
1463
1580
  var IS_ITALIC2 = 1 << 1;
1464
1581
  var IS_STRIKETHROUGH2 = 1 << 2;
@@ -1498,7 +1615,7 @@ function formatToProps(format) {
1498
1615
  }
1499
1616
  var FormattedNodeHandler = class extends NodeHandler2 {
1500
1617
  processNode(node) {
1501
- if (!(node instanceof HTMLElement8)) return null;
1618
+ if (!(node instanceof HTMLElement10)) return null;
1502
1619
  const tagName = node.tagName;
1503
1620
  if (!tagName || !(tagName in TAG_TO_FORMAT)) return null;
1504
1621
  const formatFlag = TAG_TO_FORMAT[tagName];
@@ -1533,7 +1650,7 @@ var FormattedNodeHandler = class extends NodeHandler2 {
1533
1650
  };
1534
1651
 
1535
1652
  // src/importFromHtml/HeadingNodeHandler.ts
1536
- import { HTMLElement as HTMLElement9 } from "node-html-parser";
1653
+ import { HTMLElement as HTMLElement11 } from "node-html-parser";
1537
1654
 
1538
1655
  // src/importFromHtml/extractTextAlignment.ts
1539
1656
  var TEXT_ALIGN_TO_FORMAT = {
@@ -1561,7 +1678,7 @@ function extractTextAlignment(element) {
1561
1678
  var TAG_HEADINGS = ["h1", "h2", "h3", "h4", "h5", "h6"];
1562
1679
  var HeadingNodeHandler2 = class extends NodeHandler2 {
1563
1680
  processNode(node) {
1564
- if (!(node instanceof HTMLElement9) || !TAG_HEADINGS.includes(node.tagName.toLowerCase())) {
1681
+ if (!(node instanceof HTMLElement11) || !TAG_HEADINGS.includes(node.tagName.toLowerCase())) {
1565
1682
  return null;
1566
1683
  }
1567
1684
  const headingNode = {
@@ -1582,11 +1699,11 @@ var HeadingNodeHandler2 = class extends NodeHandler2 {
1582
1699
  };
1583
1700
 
1584
1701
  // src/importFromHtml/HorizontalRuleNodeHandler.ts
1585
- import { HTMLElement as HTMLElement10 } from "node-html-parser";
1702
+ import { HTMLElement as HTMLElement12 } from "node-html-parser";
1586
1703
  var TAG_HR = "hr";
1587
1704
  var HorizontalRuleNodeHandler2 = class extends NodeHandler2 {
1588
1705
  processNode(node) {
1589
- if (!(node instanceof HTMLElement10) || node.tagName !== TAG_HR.toUpperCase()) {
1706
+ if (!(node instanceof HTMLElement12) || node.tagName !== TAG_HR.toUpperCase()) {
1590
1707
  return null;
1591
1708
  }
1592
1709
  const horizontalRuleNode = {
@@ -1598,11 +1715,11 @@ var HorizontalRuleNodeHandler2 = class extends NodeHandler2 {
1598
1715
  };
1599
1716
 
1600
1717
  // src/importFromHtml/ImageNodeHandler.ts
1601
- import { HTMLElement as HTMLElement11 } from "node-html-parser";
1718
+ import { HTMLElement as HTMLElement13 } from "node-html-parser";
1602
1719
  var TAG_IMG = "img";
1603
1720
  var ImageNodeHandler2 = class extends NodeHandler2 {
1604
1721
  processNode(node) {
1605
- if (!(node instanceof HTMLElement11) || node.tagName !== TAG_IMG.toUpperCase()) {
1722
+ if (!(node instanceof HTMLElement13) || node.tagName !== TAG_IMG.toUpperCase()) {
1606
1723
  return null;
1607
1724
  }
1608
1725
  return createImageNode(
@@ -1618,11 +1735,11 @@ var ImageNodeHandler2 = class extends NodeHandler2 {
1618
1735
 
1619
1736
  // src/importFromHtml/JournalEntryQuestionNodeHandler.ts
1620
1737
  import { nanoid as nanoid6 } from "nanoid";
1621
- import { HTMLElement as HTMLElement13 } from "node-html-parser";
1738
+ import { HTMLElement as HTMLElement15 } from "node-html-parser";
1622
1739
 
1623
1740
  // src/importFromHtml/createOnePerLineDistractorNode.ts
1624
1741
  import { nanoid as nanoid5 } from "nanoid";
1625
- import { HTMLElement as HTMLElement12 } from "node-html-parser";
1742
+ import { HTMLElement as HTMLElement14 } from "node-html-parser";
1626
1743
  function extractDistractorId(id) {
1627
1744
  if (!id) return null;
1628
1745
  const parts = id.split("|");
@@ -1635,7 +1752,7 @@ var createOnePerLineDistractorNode = (node) => {
1635
1752
  distractorEditor.editorState.root.children = [];
1636
1753
  let distractorId = null;
1637
1754
  distractors.forEach((distractor) => {
1638
- if (!(distractor instanceof HTMLElement12)) return;
1755
+ if (!(distractor instanceof HTMLElement14)) return;
1639
1756
  distractorId = distractorId ?? extractDistractorId(distractor.getAttribute("id"));
1640
1757
  distractorEditor.editorState.root.children.push(
1641
1758
  ...createNestedNodesFromHtml(distractor)
@@ -1653,7 +1770,7 @@ var createOnePerLineDistractorNode = (node) => {
1653
1770
  // src/importFromHtml/JournalEntryQuestionNodeHandler.ts
1654
1771
  var JournalEntryQuestionNodeHandler2 = class extends NodeHandler2 {
1655
1772
  processNode(node) {
1656
- if (!(node instanceof HTMLElement13) || node.tagName !== "x-journal-entry".toUpperCase())
1773
+ if (!(node instanceof HTMLElement15) || node.tagName !== "x-journal-entry".toUpperCase())
1657
1774
  return null;
1658
1775
  const jsonNode = {
1659
1776
  id: node.getAttribute("id") ?? nanoid6(),
@@ -1668,7 +1785,7 @@ var JournalEntryQuestionNodeHandler2 = class extends NodeHandler2 {
1668
1785
  };
1669
1786
  const lineItems = node.querySelectorAll("x-line-item");
1670
1787
  lineItems.forEach((lineItem) => {
1671
- if (!(lineItem instanceof HTMLElement13)) return;
1788
+ if (!(lineItem instanceof HTMLElement15)) return;
1672
1789
  const accountElement = lineItem.querySelector("x-account");
1673
1790
  const debitElement = lineItem.querySelector("x-debit");
1674
1791
  const creditElement = lineItem.querySelector("x-credit");
@@ -1697,10 +1814,10 @@ var JournalEntryQuestionNodeHandler2 = class extends NodeHandler2 {
1697
1814
  };
1698
1815
 
1699
1816
  // src/importFromHtml/LineBreakNodeHandler.ts
1700
- import { HTMLElement as HTMLElement14 } from "node-html-parser";
1817
+ import { HTMLElement as HTMLElement16 } from "node-html-parser";
1701
1818
  var LineBreakNodeHandler2 = class extends NodeHandler2 {
1702
1819
  processNode(node) {
1703
- if (!(node instanceof HTMLElement14)) return null;
1820
+ if (!(node instanceof HTMLElement16)) return null;
1704
1821
  if (node.tagName !== "BR") return null;
1705
1822
  return {
1706
1823
  type: "linebreak",
@@ -1710,11 +1827,11 @@ var LineBreakNodeHandler2 = class extends NodeHandler2 {
1710
1827
  };
1711
1828
 
1712
1829
  // src/importFromHtml/LinkNodeHandler.ts
1713
- import { HTMLElement as HTMLElement15 } from "node-html-parser";
1830
+ import { HTMLElement as HTMLElement17 } from "node-html-parser";
1714
1831
  var TAG_A = "a";
1715
1832
  var LinkNodeHandler2 = class extends NodeHandler2 {
1716
1833
  processNode(node) {
1717
- if (!(node instanceof HTMLElement15) || node.tagName !== TAG_A.toUpperCase()) {
1834
+ if (!(node instanceof HTMLElement17) || node.tagName !== TAG_A.toUpperCase()) {
1718
1835
  return null;
1719
1836
  }
1720
1837
  const url = node.getAttribute("href") || "";
@@ -1743,10 +1860,10 @@ var LinkNodeHandler2 = class extends NodeHandler2 {
1743
1860
  };
1744
1861
 
1745
1862
  // src/importFromHtml/ListItemNodeHandler.ts
1746
- import { HTMLElement as HTMLElement16 } from "node-html-parser";
1863
+ import { HTMLElement as HTMLElement18 } from "node-html-parser";
1747
1864
  var ListItemNodeHandler2 = class extends NodeHandler2 {
1748
1865
  processNode(node) {
1749
- if (!(node instanceof HTMLElement16)) return null;
1866
+ if (!(node instanceof HTMLElement18)) return null;
1750
1867
  if (node.tagName !== "LI") return null;
1751
1868
  const jsonNode = {
1752
1869
  type: "listitem",
@@ -1767,10 +1884,10 @@ var ListItemNodeHandler2 = class extends NodeHandler2 {
1767
1884
  };
1768
1885
 
1769
1886
  // src/importFromHtml/ListNodeHandler.ts
1770
- import { HTMLElement as HTMLElement17 } from "node-html-parser";
1887
+ import { HTMLElement as HTMLElement19 } from "node-html-parser";
1771
1888
  var ListNodeHandler2 = class extends NodeHandler2 {
1772
1889
  processNode(node) {
1773
- if (!(node instanceof HTMLElement17)) return null;
1890
+ if (!(node instanceof HTMLElement19)) return null;
1774
1891
  if (node.tagName !== "UL" && node.tagName !== "OL") return null;
1775
1892
  const tag = node.tagName.toLowerCase();
1776
1893
  const listType = tag === "ol" ? "number" : "bullet";
@@ -1788,7 +1905,7 @@ var ListNodeHandler2 = class extends NodeHandler2 {
1788
1905
  };
1789
1906
  let itemIndex = 1;
1790
1907
  node.childNodes.forEach((child) => {
1791
- if (child instanceof HTMLElement17 && child.tagName === "LI") {
1908
+ if (child instanceof HTMLElement19 && child.tagName === "LI") {
1792
1909
  const listItemNode = {
1793
1910
  type: "listitem",
1794
1911
  version: 1,
@@ -1813,10 +1930,10 @@ var ListNodeHandler2 = class extends NodeHandler2 {
1813
1930
 
1814
1931
  // src/importFromHtml/MatchingQuestionNodeHandler.ts
1815
1932
  import { nanoid as nanoid7 } from "nanoid";
1816
- import { HTMLElement as HTMLElement18 } from "node-html-parser";
1933
+ import { HTMLElement as HTMLElement20 } from "node-html-parser";
1817
1934
  var MatchingQuestionNodeHandler2 = class extends NodeHandler2 {
1818
1935
  processNode(node) {
1819
- if (!(node instanceof HTMLElement18) || node.tagName !== "x-matching".toUpperCase())
1936
+ if (!(node instanceof HTMLElement20) || node.tagName !== "x-matching".toUpperCase())
1820
1937
  return null;
1821
1938
  const jsonNode = {
1822
1939
  id: node.getAttribute("id") ?? nanoid7(),
@@ -1829,7 +1946,7 @@ var MatchingQuestionNodeHandler2 = class extends NodeHandler2 {
1829
1946
  };
1830
1947
  const matches = node.querySelectorAll("x-match");
1831
1948
  matches.forEach((match) => {
1832
- if (!(match instanceof HTMLElement18)) return;
1949
+ if (!(match instanceof HTMLElement20)) return;
1833
1950
  const premise = match.querySelector("x-premise");
1834
1951
  const option = match.querySelector("x-option");
1835
1952
  if (!premise || !option) return;
@@ -1852,10 +1969,10 @@ var MatchingQuestionNodeHandler2 = class extends NodeHandler2 {
1852
1969
 
1853
1970
  // src/importFromHtml/MultipleOptionQuestionNodeHandler.ts
1854
1971
  import { nanoid as nanoid8 } from "nanoid";
1855
- import { HTMLElement as HTMLElement19 } from "node-html-parser";
1972
+ import { HTMLElement as HTMLElement21 } from "node-html-parser";
1856
1973
  var MultipleOptionQuestionNodeHandler2 = class extends NodeHandler2 {
1857
1974
  processNode(node) {
1858
- if (!(node instanceof HTMLElement19)) return null;
1975
+ if (!(node instanceof HTMLElement21)) return null;
1859
1976
  if (node.tagName === "x-multiple-choice".toUpperCase())
1860
1977
  return this.processMultipleChoiceNode(node);
1861
1978
  else if (node.tagName === "x-multiple-answers".toUpperCase())
@@ -1895,7 +2012,7 @@ var MultipleOptionQuestionNodeHandler2 = class extends NodeHandler2 {
1895
2012
  processOptions(node, jsonNode) {
1896
2013
  const childNodes = node.childNodes;
1897
2014
  childNodes.forEach((child) => {
1898
- if (!(child instanceof HTMLElement19)) return;
2015
+ if (!(child instanceof HTMLElement21)) return;
1899
2016
  if (child.tagName !== "x-option".toUpperCase()) return;
1900
2017
  jsonNode.options.push({
1901
2018
  id: child.getAttribute("id") ?? nanoid8(),
@@ -1907,28 +2024,28 @@ var MultipleOptionQuestionNodeHandler2 = class extends NodeHandler2 {
1907
2024
  };
1908
2025
 
1909
2026
  // src/importFromHtml/ParagraphNodeHandler.ts
1910
- import { HTMLElement as HTMLElement20 } from "node-html-parser";
2027
+ import { HTMLElement as HTMLElement22 } from "node-html-parser";
1911
2028
  var ParagraphNodeHandler2 = class extends NodeHandler2 {
1912
2029
  processImageNode(node) {
1913
- if (node.childNodes.length === 1 && node.childNodes[0] instanceof HTMLElement20 && node.childNodes[0].tagName === "IMG") {
2030
+ if (node.childNodes.length === 1 && node.childNodes[0] instanceof HTMLElement22 && node.childNodes[0].tagName === "IMG") {
1914
2031
  return traverse2(node.childNodes[0]);
1915
2032
  }
1916
2033
  return null;
1917
2034
  }
1918
2035
  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") {
2036
+ 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
2037
  return traverse2(node.childNodes[0].childNodes[0]);
1921
2038
  }
1922
2039
  return null;
1923
2040
  }
1924
2041
  processNode(node) {
1925
- if (!(node instanceof HTMLElement20)) return null;
2042
+ if (!(node instanceof HTMLElement22)) return null;
1926
2043
  if (node.tagName !== "P") return null;
1927
2044
  const imageNode = this.processImageNode(node) ?? this.processSpanImageNode(node);
1928
2045
  if (imageNode) return imageNode;
1929
2046
  const jsonNode = createEmptyParagraphNode();
1930
2047
  jsonNode.format = extractTextAlignment(node);
1931
- if (node.childNodes.length === 1 && node.childNodes[0] instanceof HTMLElement20 && node.childNodes[0].tagName === "BR")
2048
+ if (node.childNodes.length === 1 && node.childNodes[0] instanceof HTMLElement22 && node.childNodes[0].tagName === "BR")
1932
2049
  return jsonNode;
1933
2050
  node.childNodes.forEach((child) => {
1934
2051
  const processedChildren = traverse2(child);
@@ -1940,10 +2057,10 @@ var ParagraphNodeHandler2 = class extends NodeHandler2 {
1940
2057
 
1941
2058
  // src/importFromHtml/ShortAnswerQuestionNodeHandler.ts
1942
2059
  import { nanoid as nanoid9 } from "nanoid";
1943
- import { HTMLElement as HTMLElement21 } from "node-html-parser";
2060
+ import { HTMLElement as HTMLElement23 } from "node-html-parser";
1944
2061
  var ShortAnswerQuestionNodeHandler2 = class extends NodeHandler2 {
1945
2062
  processNode(node) {
1946
- if (!(node instanceof HTMLElement21) || node.tagName !== "x-short-answer".toUpperCase())
2063
+ if (!(node instanceof HTMLElement23) || node.tagName !== "x-short-answer".toUpperCase())
1947
2064
  return null;
1948
2065
  return {
1949
2066
  id: node.getAttribute("id") ?? nanoid9(),
@@ -1959,7 +2076,7 @@ var ShortAnswerQuestionNodeHandler2 = class extends NodeHandler2 {
1959
2076
  };
1960
2077
 
1961
2078
  // src/importFromHtml/SimulationQuestionNodeHandler.ts
1962
- import { HTMLElement as HTMLElement22 } from "node-html-parser";
2079
+ import { HTMLElement as HTMLElement24 } from "node-html-parser";
1963
2080
  var TAG_X_SIMULATION = "x-simulation";
1964
2081
  var TAG_X_SYSTEM_MESSAGE2 = "x-ai-system-message";
1965
2082
  var TAG_X_COMMENT_INSTRUCTIONS = "x-comment-instructions";
@@ -1967,7 +2084,7 @@ var TAG_X_STEP2_INSTRUCTIONS = "x-step2-instructions";
1967
2084
  var findFirstNonEmptyInnerHtml = (root, elementNames) => elementNames.map((name) => root.querySelector(name)).find((el) => el?.innerHTML.trim().length)?.innerHTML.trim() ?? null;
1968
2085
  var SimulationQuestionNodeHandler2 = class extends NodeHandler2 {
1969
2086
  processNode(node) {
1970
- if (!(node instanceof HTMLElement22) || node.tagName !== TAG_X_SIMULATION.toUpperCase()) {
2087
+ if (!(node instanceof HTMLElement24) || node.tagName !== TAG_X_SIMULATION.toUpperCase()) {
1971
2088
  return null;
1972
2089
  }
1973
2090
  const jsonNode = {
@@ -1988,11 +2105,11 @@ var SimulationQuestionNodeHandler2 = class extends NodeHandler2 {
1988
2105
  };
1989
2106
 
1990
2107
  // src/importFromHtml/SpanNodeHandler.ts
1991
- import { HTMLElement as HTMLElement23, parse } from "node-html-parser";
1992
- var TextNode = parse.TextNode;
2108
+ import { HTMLElement as HTMLElement25, parse as parse2 } from "node-html-parser";
2109
+ var TextNode = parse2.TextNode;
1993
2110
  var SpanNodeHandler = class extends NodeHandler2 {
1994
2111
  processNode(node) {
1995
- if (!(node instanceof HTMLElement23) || node.tagName !== "SPAN")
2112
+ if (!(node instanceof HTMLElement25) || node.tagName !== "SPAN")
1996
2113
  return null;
1997
2114
  const styleAttr = node.getAttribute("style") || "";
1998
2115
  if (node.childNodes.length === 1 && node.childNodes[0] instanceof TextNode) {
@@ -2054,7 +2171,7 @@ var SpanNodeHandler = class extends NodeHandler2 {
2054
2171
  };
2055
2172
 
2056
2173
  // src/importFromHtml/TableCellNodeHandler.ts
2057
- import { HTMLElement as HTMLElement24 } from "node-html-parser";
2174
+ import { HTMLElement as HTMLElement26 } from "node-html-parser";
2058
2175
 
2059
2176
  // src/utils/styleUtils.ts
2060
2177
  var extractStyleValue = (styleAttr, property, isNumeric = false, unit = "") => {
@@ -2103,7 +2220,7 @@ function createEmptyTableCellNode(isHeader = false) {
2103
2220
 
2104
2221
  // src/importFromHtml/TableCellNodeHandler.ts
2105
2222
  var isHtmlTableCellElement = (node) => {
2106
- return node instanceof HTMLElement24 && (node.tagName === "TD" || node.tagName === "TH");
2223
+ return node instanceof HTMLElement26 && (node.tagName === "TD" || node.tagName === "TH");
2107
2224
  };
2108
2225
  var TableCellNodeHandler2 = class extends NodeHandler2 {
2109
2226
  processNode(node) {
@@ -2145,10 +2262,10 @@ var TableCellNodeHandler2 = class extends NodeHandler2 {
2145
2262
  };
2146
2263
 
2147
2264
  // src/importFromHtml/TableNodeHandler.ts
2148
- import { HTMLElement as HTMLElement25 } from "node-html-parser";
2265
+ import { HTMLElement as HTMLElement27 } from "node-html-parser";
2149
2266
  var REFERENCE_TABLE_WIDTH = 720;
2150
2267
  var MINIMUM_REFERENCE_TABLE_WIDTH = 500;
2151
- var isHtmlTableElement = (node) => node instanceof HTMLElement25 && node.tagName === "TABLE";
2268
+ var isHtmlTableElement = (node) => node instanceof HTMLElement27 && node.tagName === "TABLE";
2152
2269
  var TableNodeHandler2 = class extends NodeHandler2 {
2153
2270
  processNode(node) {
2154
2271
  if (!isHtmlTableElement(node)) return null;
@@ -2303,9 +2420,9 @@ var TableNodeHandler2 = class extends NodeHandler2 {
2303
2420
  };
2304
2421
 
2305
2422
  // src/importFromHtml/TableRowNodeHandler.ts
2306
- import { HTMLElement as HTMLElement26 } from "node-html-parser";
2423
+ import { HTMLElement as HTMLElement28 } from "node-html-parser";
2307
2424
  var isHtmlTableRowElement = (node) => {
2308
- return node instanceof HTMLElement26 && node.tagName === "TR";
2425
+ return node instanceof HTMLElement28 && node.tagName === "TR";
2309
2426
  };
2310
2427
  var TableRowNodeHandler2 = class extends NodeHandler2 {
2311
2428
  processNode(node) {
@@ -2328,8 +2445,8 @@ var TableRowNodeHandler2 = class extends NodeHandler2 {
2328
2445
  };
2329
2446
 
2330
2447
  // src/importFromHtml/TextNodeHandler.ts
2331
- import { parse as parse2 } from "node-html-parser";
2332
- var TextNode2 = parse2.TextNode;
2448
+ import { parse as parse3 } from "node-html-parser";
2449
+ var TextNode2 = parse3.TextNode;
2333
2450
  var TextNodeHandler2 = class extends NodeHandler2 {
2334
2451
  processNode(node) {
2335
2452
  if (!(node instanceof TextNode2)) return null;
@@ -2348,10 +2465,10 @@ var TextNodeHandler2 = class extends NodeHandler2 {
2348
2465
  };
2349
2466
 
2350
2467
  // src/importFromHtml/VariableNodeHandler.ts
2351
- import { HTMLElement as HTMLElement27 } from "node-html-parser";
2468
+ import { HTMLElement as HTMLElement29 } from "node-html-parser";
2352
2469
  var VariableNodeHandler2 = class extends NodeHandler2 {
2353
2470
  processNode(node) {
2354
- if (!(node instanceof HTMLElement27) || !node.tagName) return null;
2471
+ if (!(node instanceof HTMLElement29) || !node.tagName) return null;
2355
2472
  if (node.tagName !== "x-param".toUpperCase()) return null;
2356
2473
  return {
2357
2474
  variableName: node.getAttribute("data-x-name") || "undefined",
@@ -2364,7 +2481,7 @@ var VariableNodeHandler2 = class extends NodeHandler2 {
2364
2481
 
2365
2482
  // src/importFromHtml/traverse.ts
2366
2483
  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();
2484
+ 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
2485
  function traverse2(node) {
2369
2486
  const result = nodeHandlerChain2.handle(node);
2370
2487
  if (result === null) return [];
@@ -2382,7 +2499,7 @@ function processChildren(node) {
2382
2499
  return result;
2383
2500
  }
2384
2501
  function processHtml(html) {
2385
- const root = parse3(html);
2502
+ const root = parse4(html);
2386
2503
  return processChildren(root);
2387
2504
  }
2388
2505
  function importFromHtml(html) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@examind/block-sdk",
3
- "version": "0.1.40",
3
+ "version": "0.2.0",
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.40"
24
+ "@examind/block-types": "^0.2.0"
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.40"
39
+ "@examind/block-types": "0.2.0"
40
40
  },
41
41
  "dependencies": {
42
42
  "lodash-es": "4.17.21"