jspsych-tangram 0.0.8 → 0.0.10

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 (44) hide show
  1. package/dist/construct/index.browser.js +4572 -3884
  2. package/dist/construct/index.browser.js.map +1 -1
  3. package/dist/construct/index.browser.min.js +15 -12
  4. package/dist/construct/index.browser.min.js.map +1 -1
  5. package/dist/construct/index.cjs +45 -9
  6. package/dist/construct/index.cjs.map +1 -1
  7. package/dist/construct/index.js +45 -9
  8. package/dist/construct/index.js.map +1 -1
  9. package/dist/index.cjs +373 -13
  10. package/dist/index.cjs.map +1 -1
  11. package/dist/index.d.ts +180 -8
  12. package/dist/index.js +374 -15
  13. package/dist/index.js.map +1 -1
  14. package/dist/nback/index.browser.js +17703 -0
  15. package/dist/nback/index.browser.js.map +1 -0
  16. package/dist/nback/index.browser.min.js +42 -0
  17. package/dist/nback/index.browser.min.js.map +1 -0
  18. package/dist/nback/index.cjs +395 -0
  19. package/dist/nback/index.cjs.map +1 -0
  20. package/dist/nback/index.d.ts +175 -0
  21. package/dist/nback/index.js +393 -0
  22. package/dist/nback/index.js.map +1 -0
  23. package/dist/prep/index.browser.js +4578 -3892
  24. package/dist/prep/index.browser.js.map +1 -1
  25. package/dist/prep/index.browser.min.js +16 -13
  26. package/dist/prep/index.browser.min.js.map +1 -1
  27. package/dist/prep/index.cjs +46 -12
  28. package/dist/prep/index.cjs.map +1 -1
  29. package/dist/prep/index.js +46 -12
  30. package/dist/prep/index.js.map +1 -1
  31. package/package.json +9 -3
  32. package/src/assets/README.md +6 -0
  33. package/src/assets/images.d.ts +19 -0
  34. package/src/assets/locked.png +0 -0
  35. package/src/assets/unlocked.png +0 -0
  36. package/src/core/components/board/BoardView.tsx +72 -29
  37. package/src/core/io/InteractionTracker.ts +16 -8
  38. package/src/core/io/data-tracking.ts +3 -0
  39. package/src/index.ts +2 -1
  40. package/src/plugins/tangram-nback/NBackApp.tsx +316 -0
  41. package/src/plugins/tangram-nback/index.ts +141 -0
  42. package/tangram-construct.min.js +15 -12
  43. package/tangram-nback.min.js +42 -0
  44. package/tangram-prep.min.js +16 -13
@@ -12,9 +12,8 @@ const CONFIG = {
12
12
  completion: { fill: "#ccfff2", stroke: "#13da57" },
13
13
  silhouetteMask: "#374151",
14
14
  anchors: { invalid: "#7dd3fc", valid: "#475569" },
15
- piece: { draggingFill: "#8e7cc3ff", validFill: "#8e7cc3ff", invalidFill: "#ef4444", invalidStroke: "#dc2626", selectedStroke: "#674ea7", allGreenStroke: "#86efac", borderStroke: "#674ea7" },
16
- ui: { light: "#60a5fa", dark: "#1d4ed8" },
17
- blueprint: { fill: "#374151", selectedStroke: "#111827", badgeFill: "#000000", labelFill: "#ffffff" },
15
+ piece: { draggingFill: "#8e7cc3ff", validFill: "#8e7cc3ff", invalidFill: "#ef4444", allGreenStroke: "#86efac"},
16
+ blueprint: { fill: "#374151", badgeFill: "#000000", labelFill: "#ffffff" },
18
17
  tangramDecomposition: { stroke: "#fef2cc" }
19
18
  },
20
19
  opacity: {
@@ -25,7 +24,7 @@ const CONFIG = {
25
24
  piece: { invalid: 0.35, dragging: 0.75, locked: 1, normal: 1 }
26
25
  },
27
26
  size: {
28
- stroke: { bandPx: 5, pieceSelectedPx: 3, allGreenStrokePx: 10, pieceBorderPx: 2, tangramDecompositionPx: 1 },
27
+ stroke: { bandPx: 5, allGreenStrokePx: 10, tangramDecompositionPx: 1 },
29
28
  anchorRadiusPx: { valid: 1, invalid: 1 },
30
29
  badgeFontPx: 16,
31
30
  centerBadge: { fractionOfOuterR: 0.15, minPx: 20, marginPx: 4 }
@@ -45,9 +44,7 @@ const CONFIG = {
45
44
  },
46
45
  game: {
47
46
  snapRadiusPx: 15,
48
- showBorders: false,
49
- hideTouchingBorders: true
50
- }
47
+ showBorders: false}
51
48
  };
52
49
 
53
50
  function isComposite(bp) {
@@ -823,6 +820,10 @@ function shouldUseSelectiveBorders(blueprintId) {
823
820
  return CONFIG.game.showBorders;
824
821
  }
825
822
 
823
+ var lockedIcon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFoAAABaCAYAAAA4qEECAAAACXBIWXMAAAsSAAALEgHS3X78AAAFY0lEQVR4nO2d7XXrNgyGH/r0f7zB9QbXnaDqBt6gvhM0I2SE3A2UDXwnqLKBPEHdDewJ0B+kYieWZEoiQfrjPQcnjqOI0GuYAAFQMiJCLjDGLIEFsHQyB/7w/Pd397MCamAnInVgFUfDpCTaGLMACmDlfj4FHuKAJX4DVCKyC3x+b6gTbYyZA2sn31UHhy1QAqWI7FVHFhEVwVpsCUgmUgKF2vUrEVxlQGyXVBqE3zPBqoTHIHhOXlPEUCmBedZEY6OHfQZkTZU9sMqO6Buw4ujWHYLkJXaBkJqUWFIDy6REYx3eLUwVl2TPREc5heR1BgRoy1qV6DsleRLZD5KVyH6QrET2UMeX+uJyE28H6UvykvuILobKHs/Qz4fkObcdJ0+VGo9FzcV8tDGmBP7qPSg+DtgLqrFWBLYSs8C/AhMTbyKy7j3igjWvSPu1LPH4ajo9y4S6ChdyI5emjFTz8isjcgxYC98kNIxOnfuUTmEhk5e6Tvd1IiMpBxFNmlDOy6kMIDtVpNRqKK3O0BhToetk/sPOxZ0FU1cxX2CNAGxFZCc9lW3XvlARvrreh3cRKc7ezcSaOx0e1tH1hZc1PY6INA79zKrbFKuUlXrpccZDdKnomHqwzlXzmqpeotG35l0PyWMWSa3zPGkiqKKP6FJZmXUH0VVIa0pk1WUr0e5T11REaLe+dYwPEOtIk13fqSLPykp0Wd4uwLm7piTtnM1zM/aMI9boovr6hgvHvgU49zdjTNHyvnZ36bp5MYOPGFW74bDtoouA52871y7g+X3w3XH7YdGFsgJwzMKdYh55zCry+dtQwJHoVQIF7gUrSGvR94ICYOYckGYu4N7wZIxZzLDx5QNxsZxh04kPxMUS9JNINfBChB7kS4KNal4JsygaIhtNooNUTwKS/oxeoqky7kVsbB3JujuhLkCzMKBF9O+S0ebKU7il+j+xx5ldPmQyfuZKMoCIVMCv2ONoEP2qMMZUlLEHiD11HEQkdv4iCIwxUafQ2Bad7ZShjd9SK+CLkz3kTQJsQ4o93RMQNX4MFPN2NcN4t816jBE1ltZwhpPgLLmiPdZ9Aip3TNbInmjsdNG3oHhCvww3GDOOd27JFT5FidwLF+8z2ktKD4TFfkb+Idgm0DEpUV8L0Yeevx94ED0dYttyC9rJPmCzgjtFlcagnjkl+ywmOVxSasHn5M8vYJFzwsrhICK7JryrUmriA7cCPCW1vpJVYQXHODr3Oe6asYEj0VU6PW4eFTii3Ty9TajMrWLbOOrTJXiZRJXbRtm8eBAdF2Xz4oNo58HfUmhzo3g7jYq+Zu9KXV0Go+54nSPKT7+1JMArwiW86wiNL2sm3ERKKfF/VvA42zkbus9BREyoc8WC68r/N+Ap/3RtDB84S/y7A4LlqI0xueeKIWx/+PtXkoHzqeOkRpdV3TCmELbpsbWG2Td4yA2QwefUgCS/BLzO185xehSYB/6ksyObsLeX2zHmxihOkdB3Biixqc3UBC8If6eaom9Mn5tXvQJ/9x40HFtsGKmd5pxjHV/oPZU/ReS57wCvp1YYY2r0N3xeC7YicnF7im9fx4rMqzCJcMCz1cGLaDnW7R74jEI865XenUpia3M/xmp0g/ghQ+qViUOia5XBoWoO8ee1yaj1QC7B/rXIKJK94ug+JLqvXAo0jTqjc+CT2nbdwEtuu7C7xSaKphUaAi1pm62/qb/aoWXUzWiDztEdhD8e4aRB9I1YdzArjkr0CeGNo0xNnK9UBNp4pEr0CeFF5oRXXPODIzsILzMgtpFSg+BGHg/3VcLjcdVKSEr0Vzjil4x/AHvTrF5jm3d2wZUcif8BqSLxz8FiAOgAAAAASUVORK5CYII=";
824
+
825
+ var unlockedIcon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFoAAABaCAYAAAA4qEECAAAACXBIWXMAAAsSAAALEgHS3X78AAAFYklEQVR4nO1d0ZGjOBB9ct3/+iJYMlg2giODcwjeDCYEbwbeDNgMvBloIjgmAyYDHEHfh4SHsQUIaLVk7FfVNTblkZpHq1u0GqGICKlAKZUDyADkVrYA/vH891f7VwOoANREVDGrOBsqJtFKqQxAAWBn/35h7uIMQ/wJgCaimrl9b4gTrZTaAthb+SbaOfAGoARQElEj2jMRiQiMxZYAKBEpARRi5y9EsE6A2D7REoQ/MsGihIcgeIu0XMRUKQFskyYaZvbQJEDWUmkA7JIjegVWHNy6OUjOYW4QYpMSSioAeVSiYQLeGlzFmDRYGCiXkLxPgABp2YsS/aAkLyL7SbIQ2U+ShcieGvhin1xq4h0gvbJ3Nk+swZ/G9MEZZooFmKlkDB36cIYhezzv7WHJW8jOkxsAR5i7TOfNAszoOgKoBfXqk6pPz0muA3J3fDXmBBkTN2ITXi4i2lqVhKJHH6sYGXXHyGQP5kbGlJe465tsxSPWHYvoZshYYrsMNpITIbvXhfQpWwgo9eJB2AmfR1Vjjw1eoMhkF1OI1oGV0SNxofZoo8aAX7QXJAbRznOLZc1ZDzlzAtqxp60sEtEEh1XHsGanHwNwWNCm0w0h3mLEjVUnYc1M/d4k55GQVUtbQBUwJpx62q4jEV06iYaZN4fu/MafgtfqXKMlFtGEzrx6gw/sER6u5MuOsf1D94tS6gXAV8b2p2J/+dS58hKJo9tovCwIukTbNrXA+YxJ9cl1QC5ouIiONd+VkqzrOgrEQzI1zIFQALgQzeknh5AJ9ZMSdgDELTpzHDsJ9R0LRfshR4TgkNAUTMRPbyA7nL/ZxymuoQV1iIF8A2PRknDFg7W7j3wD+RnHTX9EdIJZUV4r8r8idPqvUmpLtw/rHBH+oscqV9gCskGhgblrY6+o9xWYmHSAfBWsWEenmAQ7CN9C9q5UpJMyNrEDhGsJDlTLdkC8wyTlZR+g9IR9wLRGYN+9Gf/JYhxSJRkArG7H0P1IWPTfKRMNXIo4/wvaB8IS/U5EWcD22aCUCmpwoV1HHbj9u4GEj2aBUmqnlKqUUmSlUkpJpXdZEHJao5mmYEOFNc4Cmhl9BJ9H65SJhl/NR5E40XoDcyuaMnzcwz60EgvRbJD+mp1PGjcLrcRCVPdAtM+IS31U3gXRPosCqS8cVG0gCJUy5Jp1DBX3ONchEwqGDdFHXYdmuGohUQD44zj+B3FrUnyggY8blqSHHhE1RLQD8LNz+CcR7VLPo8Byey8Wfc/QgCWazA6HbxGVWSveLLefch1lFFXWjbL98CQ6LMr2w4VoG1R+x9BmpfjdDdTXadJSVpdVo+x++UQ0EWl87MP8xHy8Wi4vcCX+DyKqzENbOnZG2nP/w/UB5w40SikN/53Ih8C+ZmgXUkHMu50zrhm+ElFx034P0Zyrwo+2Cv7dZQTONUP7w19MHd/Duh6Xjr96R9pANqut4FmavaqRUM1dz3lyZC8Hz7N3FdwO95cJV7MPXyFQCbQAJ/CUg+0HXaTHFefaq6hEQpYN3mrS0ZV4X6W4nqqtYRZS11Qf7bXw4LvBYGbJ5qy4fId8JRN3xf8ZplK2Hvuh93tYJAoB7xDOqZwL3iVhtsEfs1VaH374kgzAz0df+bg9eHzbPct+Mm8zA8ojkz2Z5NlEPzDZs0j2nnX0IfJ2x5Lw3764B4vqo23HOda9sPsGM4Vbli1kuglIYbfbELJoF2AWH91D+PMVThJEr8S62aw4KNEdwttAGZs4X9FgeFWTONEdwovECde45xdH9hBeJkBsK6UEwa08X+4rhOfrqoUQlehrWOJzzH8BewOTN69gEvI1u5Iz8T+TOcUtjzRRXwAAAABJRU5ErkJggg==";
826
+
826
827
  function pathD(poly) {
827
828
  return `M ${poly.map((pt) => `${pt.x} ${pt.y}`).join(" L ")} Z`;
828
829
  }
@@ -993,10 +994,20 @@ function BoardView(props) {
993
994
  }
994
995
  )));
995
996
  }),
997
+ /* @__PURE__ */ React.createElement("defs", null, /* @__PURE__ */ React.createElement("filter", { id: "invert-to-white" }, /* @__PURE__ */ React.createElement(
998
+ "feColorMatrix",
999
+ {
1000
+ type: "matrix",
1001
+ values: "-1 0 0 0 1\n 0 -1 0 0 1\n 0 0 -1 0 1\n 0 0 0 1 0"
1002
+ }
1003
+ ))),
996
1004
  (() => {
997
1005
  const isPrep = controller.state.cfg.mode === "prep";
998
1006
  const isSubmitEnabled = isPrep ? controller.isSubmitEnabled() : true;
999
1007
  const isClickable = !draggingId && (!isPrep || isSubmitEnabled);
1008
+ const [imageError, setImageError] = React.useState(false);
1009
+ const iconSize = badgeR * 1.6;
1010
+ const iconOffset = iconSize / 2;
1000
1011
  return /* @__PURE__ */ React.createElement(
1001
1012
  "g",
1002
1013
  {
@@ -1012,7 +1023,7 @@ function BoardView(props) {
1012
1023
  opacity: isSubmitEnabled ? 1 : 0.5
1013
1024
  }
1014
1025
  ),
1015
- /* @__PURE__ */ React.createElement(
1026
+ isPrep ? /* @__PURE__ */ React.createElement(
1016
1027
  "text",
1017
1028
  {
1018
1029
  textAnchor: "middle",
@@ -1021,7 +1032,29 @@ function BoardView(props) {
1021
1032
  fill: isSubmitEnabled ? CONFIG.color.blueprint.labelFill : "#888",
1022
1033
  pointerEvents: "none"
1023
1034
  },
1024
- isPrep ? "Submit" : controller.state.blueprintView
1035
+ "Submit"
1036
+ ) : imageError ? /* @__PURE__ */ React.createElement(
1037
+ "text",
1038
+ {
1039
+ textAnchor: "middle",
1040
+ dominantBaseline: "middle",
1041
+ fontSize: CONFIG.size.badgeFontPx,
1042
+ fill: CONFIG.color.blueprint.labelFill,
1043
+ pointerEvents: "none"
1044
+ },
1045
+ "inventory"
1046
+ ) : /* @__PURE__ */ React.createElement(
1047
+ "image",
1048
+ {
1049
+ href: controller.state.blueprintView === "quickstash" ? lockedIcon : unlockedIcon,
1050
+ x: -iconOffset,
1051
+ y: -iconOffset,
1052
+ width: iconSize,
1053
+ height: iconSize,
1054
+ pointerEvents: "none",
1055
+ onError: () => setImageError(true),
1056
+ filter: "url(#invert-to-white)"
1057
+ }
1025
1058
  )
1026
1059
  );
1027
1060
  })(),
@@ -2609,6 +2642,7 @@ class InteractionTracker {
2609
2642
  const trialEndTime = Date.now();
2610
2643
  const totalDuration = trialEndTime - this.trialStartTime;
2611
2644
  const finalSnapshot = this.buildStateSnapshot();
2645
+ const anchorToStimuliRatio = CONFIG.layout.grid.stepPx / CONFIG.layout.grid.unitPx;
2612
2646
  const mode = this.controller.state.cfg.mode;
2613
2647
  if (mode === "construction") {
2614
2648
  const finalBlueprintState = this.buildFinalBlueprintState(finalSnapshot);
@@ -2623,6 +2657,7 @@ class InteractionTracker {
2623
2657
  trialStartTime: this.trialStartTime,
2624
2658
  trialEndTime,
2625
2659
  totalDuration,
2660
+ anchorToStimuliRatio,
2626
2661
  trialParams: this.trialParams,
2627
2662
  endReason,
2628
2663
  completionTimes: this.completionTimes,
@@ -2645,6 +2680,7 @@ class InteractionTracker {
2645
2680
  trialStartTime: this.trialStartTime,
2646
2681
  trialEndTime,
2647
2682
  totalDuration,
2683
+ anchorToStimuliRatio,
2648
2684
  trialParams: this.trialParams,
2649
2685
  endReason: "submit",
2650
2686
  createdMacros: finalMacros,