scratch-blocks 2.0.2 → 2.0.4

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 (275) hide show
  1. package/.nvmrc +1 -1
  2. package/commitlint.config.js +2 -2
  3. package/dist/main.mjs +1 -2
  4. package/dist/types/msg/scratch_msgs.d.ts.map +1 -1
  5. package/dist/types/src/block_reporting.d.ts.map +1 -1
  6. package/dist/types/src/blocks/colour.d.ts +0 -19
  7. package/dist/types/src/blocks/colour.d.ts.map +1 -1
  8. package/dist/types/src/blocks/control.d.ts +0 -19
  9. package/dist/types/src/blocks/control.d.ts.map +1 -1
  10. package/dist/types/src/blocks/data.d.ts +0 -19
  11. package/dist/types/src/blocks/data.d.ts.map +1 -1
  12. package/dist/types/src/blocks/event.d.ts +0 -19
  13. package/dist/types/src/blocks/event.d.ts.map +1 -1
  14. package/dist/types/src/blocks/looks.d.ts +0 -19
  15. package/dist/types/src/blocks/looks.d.ts.map +1 -1
  16. package/dist/types/src/blocks/math.d.ts +0 -19
  17. package/dist/types/src/blocks/math.d.ts.map +1 -1
  18. package/dist/types/src/blocks/matrix.d.ts +0 -19
  19. package/dist/types/src/blocks/matrix.d.ts.map +1 -1
  20. package/dist/types/src/blocks/motion.d.ts +0 -19
  21. package/dist/types/src/blocks/motion.d.ts.map +1 -1
  22. package/dist/types/src/blocks/note.d.ts +0 -19
  23. package/dist/types/src/blocks/note.d.ts.map +1 -1
  24. package/dist/types/src/blocks/operators.d.ts +0 -19
  25. package/dist/types/src/blocks/operators.d.ts.map +1 -1
  26. package/dist/types/src/blocks/procedures.d.ts +7 -10
  27. package/dist/types/src/blocks/procedures.d.ts.map +1 -1
  28. package/dist/types/src/blocks/sensing.d.ts +0 -19
  29. package/dist/types/src/blocks/sensing.d.ts.map +1 -1
  30. package/dist/types/src/blocks/sound.d.ts +0 -19
  31. package/dist/types/src/blocks/sound.d.ts.map +1 -1
  32. package/dist/types/src/blocks/text.d.ts +0 -19
  33. package/dist/types/src/blocks/text.d.ts.map +1 -1
  34. package/dist/types/src/blocks/vertical_extensions.d.ts +0 -19
  35. package/dist/types/src/blocks/vertical_extensions.d.ts.map +1 -1
  36. package/dist/types/src/checkable_continuous_flyout.d.ts +2 -7
  37. package/dist/types/src/checkable_continuous_flyout.d.ts.map +1 -1
  38. package/dist/types/src/checkbox_bubble.d.ts +13 -12
  39. package/dist/types/src/checkbox_bubble.d.ts.map +1 -1
  40. package/dist/types/src/colours.d.ts.map +1 -1
  41. package/dist/types/src/constants.d.ts +0 -7
  42. package/dist/types/src/constants.d.ts.map +1 -1
  43. package/dist/types/src/context_menu_items.d.ts +0 -5
  44. package/dist/types/src/context_menu_items.d.ts.map +1 -1
  45. package/dist/types/src/data_category.d.ts +2 -4
  46. package/dist/types/src/data_category.d.ts.map +1 -1
  47. package/dist/types/src/events/events_block_comment_base.d.ts +2 -3
  48. package/dist/types/src/events/events_block_comment_base.d.ts.map +1 -1
  49. package/dist/types/src/events/events_block_comment_change.d.ts +0 -5
  50. package/dist/types/src/events/events_block_comment_change.d.ts.map +1 -1
  51. package/dist/types/src/events/events_block_comment_collapse.d.ts +0 -5
  52. package/dist/types/src/events/events_block_comment_collapse.d.ts.map +1 -1
  53. package/dist/types/src/events/events_block_comment_create.d.ts +0 -5
  54. package/dist/types/src/events/events_block_comment_create.d.ts.map +1 -1
  55. package/dist/types/src/events/events_block_comment_delete.d.ts +0 -5
  56. package/dist/types/src/events/events_block_comment_delete.d.ts.map +1 -1
  57. package/dist/types/src/events/events_block_comment_move.d.ts +0 -5
  58. package/dist/types/src/events/events_block_comment_move.d.ts.map +1 -1
  59. package/dist/types/src/events/events_block_comment_resize.d.ts +0 -5
  60. package/dist/types/src/events/events_block_comment_resize.d.ts.map +1 -1
  61. package/dist/types/src/events/events_block_drag_end.d.ts +1 -2
  62. package/dist/types/src/events/events_block_drag_end.d.ts.map +1 -1
  63. package/dist/types/src/events/events_block_drag_outside.d.ts +1 -2
  64. package/dist/types/src/events/events_block_drag_outside.d.ts.map +1 -1
  65. package/dist/types/src/events/events_scratch_variable_create.d.ts +0 -5
  66. package/dist/types/src/events/events_scratch_variable_create.d.ts.map +1 -1
  67. package/dist/types/src/fields/field_colour_slider.d.ts +7 -9
  68. package/dist/types/src/fields/field_colour_slider.d.ts.map +1 -1
  69. package/dist/types/src/fields/field_matrix.d.ts +0 -19
  70. package/dist/types/src/fields/field_matrix.d.ts.map +1 -1
  71. package/dist/types/src/fields/field_note.d.ts +8 -23
  72. package/dist/types/src/fields/field_note.d.ts.map +1 -1
  73. package/dist/types/src/fields/field_textinput_removable.d.ts +2 -4
  74. package/dist/types/src/fields/field_textinput_removable.d.ts.map +1 -1
  75. package/dist/types/src/fields/field_variable_getter.d.ts +0 -19
  76. package/dist/types/src/fields/field_variable_getter.d.ts.map +1 -1
  77. package/dist/types/src/fields/field_vertical_separator.d.ts +0 -19
  78. package/dist/types/src/fields/field_vertical_separator.d.ts.map +1 -1
  79. package/dist/types/src/fields/scratch_field_angle.d.ts +0 -19
  80. package/dist/types/src/fields/scratch_field_angle.d.ts.map +1 -1
  81. package/dist/types/src/fields/scratch_field_dropdown.d.ts +0 -5
  82. package/dist/types/src/fields/scratch_field_dropdown.d.ts.map +1 -1
  83. package/dist/types/src/fields/scratch_field_number.d.ts +0 -19
  84. package/dist/types/src/fields/scratch_field_number.d.ts.map +1 -1
  85. package/dist/types/src/fields/scratch_field_variable.d.ts +4 -7
  86. package/dist/types/src/fields/scratch_field_variable.d.ts.map +1 -1
  87. package/dist/types/src/flyout_checkbox_icon.d.ts +2 -3
  88. package/dist/types/src/flyout_checkbox_icon.d.ts.map +1 -1
  89. package/dist/types/src/glows.d.ts +1 -3
  90. package/dist/types/src/glows.d.ts.map +1 -1
  91. package/dist/types/src/index.d.ts +50 -55
  92. package/dist/types/src/index.d.ts.map +1 -1
  93. package/dist/types/src/procedures.d.ts +6 -8
  94. package/dist/types/src/procedures.d.ts.map +1 -1
  95. package/dist/types/src/recyclable_block_flyout_inflater.d.ts +3 -5
  96. package/dist/types/src/recyclable_block_flyout_inflater.d.ts.map +1 -1
  97. package/dist/types/src/renderer/bowler_hat.d.ts +2 -3
  98. package/dist/types/src/renderer/bowler_hat.d.ts.map +1 -1
  99. package/dist/types/src/renderer/cat/cat_face.d.ts +6 -5
  100. package/dist/types/src/renderer/cat/cat_face.d.ts.map +1 -1
  101. package/dist/types/src/renderer/cat/constants.d.ts +2 -2
  102. package/dist/types/src/renderer/cat/constants.d.ts.map +1 -1
  103. package/dist/types/src/renderer/cat/drawer.d.ts +3 -4
  104. package/dist/types/src/renderer/cat/drawer.d.ts.map +1 -1
  105. package/dist/types/src/renderer/cat/path_object.d.ts +2 -3
  106. package/dist/types/src/renderer/cat/path_object.d.ts.map +1 -1
  107. package/dist/types/src/renderer/cat/render_info.d.ts +3 -4
  108. package/dist/types/src/renderer/cat/render_info.d.ts.map +1 -1
  109. package/dist/types/src/renderer/cat/renderer.d.ts +6 -7
  110. package/dist/types/src/renderer/cat/renderer.d.ts.map +1 -1
  111. package/dist/types/src/renderer/constants.d.ts +4 -4
  112. package/dist/types/src/renderer/constants.d.ts.map +1 -1
  113. package/dist/types/src/renderer/drawer.d.ts +5 -4
  114. package/dist/types/src/renderer/drawer.d.ts.map +1 -1
  115. package/dist/types/src/renderer/path_object.d.ts +1 -3
  116. package/dist/types/src/renderer/path_object.d.ts.map +1 -1
  117. package/dist/types/src/renderer/render_info.d.ts +3 -4
  118. package/dist/types/src/renderer/render_info.d.ts.map +1 -1
  119. package/dist/types/src/renderer/renderer.d.ts +8 -15
  120. package/dist/types/src/renderer/renderer.d.ts.map +1 -1
  121. package/dist/types/src/scratch_block_paster.d.ts +0 -5
  122. package/dist/types/src/scratch_block_paster.d.ts.map +1 -1
  123. package/dist/types/src/scratch_blocks_utils.d.ts +0 -20
  124. package/dist/types/src/scratch_blocks_utils.d.ts.map +1 -1
  125. package/dist/types/src/scratch_comment_bubble.d.ts +1 -4
  126. package/dist/types/src/scratch_comment_bubble.d.ts.map +1 -1
  127. package/dist/types/src/scratch_comment_icon.d.ts +2 -3
  128. package/dist/types/src/scratch_comment_icon.d.ts.map +1 -1
  129. package/dist/types/src/scratch_connection_checker.d.ts +0 -5
  130. package/dist/types/src/scratch_connection_checker.d.ts.map +1 -1
  131. package/dist/types/src/scratch_continuous_category.d.ts +5 -5
  132. package/dist/types/src/scratch_continuous_category.d.ts.map +1 -1
  133. package/dist/types/src/scratch_continuous_toolbox.d.ts +3 -6
  134. package/dist/types/src/scratch_continuous_toolbox.d.ts.map +1 -1
  135. package/dist/types/src/scratch_dragger.d.ts +3 -12
  136. package/dist/types/src/scratch_dragger.d.ts.map +1 -1
  137. package/dist/types/src/scratch_insertion_marker_previewer.d.ts +0 -5
  138. package/dist/types/src/scratch_insertion_marker_previewer.d.ts.map +1 -1
  139. package/dist/types/src/scratch_variable_map.d.ts +0 -5
  140. package/dist/types/src/scratch_variable_map.d.ts.map +1 -1
  141. package/dist/types/src/scratch_variable_model.d.ts +1 -2
  142. package/dist/types/src/scratch_variable_model.d.ts.map +1 -1
  143. package/dist/types/src/scratch_zoom_controls.d.ts +4 -6
  144. package/dist/types/src/scratch_zoom_controls.d.ts.map +1 -1
  145. package/dist/types/src/shadows.d.ts +2 -2
  146. package/dist/types/src/shadows.d.ts.map +1 -1
  147. package/dist/types/src/status_indicator_label.d.ts +4 -6
  148. package/dist/types/src/status_indicator_label.d.ts.map +1 -1
  149. package/dist/types/src/status_indicator_label_flyout_inflater.d.ts +1 -6
  150. package/dist/types/src/status_indicator_label_flyout_inflater.d.ts.map +1 -1
  151. package/dist/types/src/variables.d.ts +4 -8
  152. package/dist/types/src/variables.d.ts.map +1 -1
  153. package/dist/types/src/xml.d.ts +2 -3
  154. package/dist/types/src/xml.d.ts.map +1 -1
  155. package/dist/types/tests/jsunit/block_test.d.ts.map +1 -1
  156. package/dist/types/tests/jsunit/connection_db_test.d.ts.map +1 -1
  157. package/dist/types/tests/jsunit/connection_test.d.ts.map +1 -1
  158. package/dist/types/tests/jsunit/event_test.d.ts.map +1 -1
  159. package/dist/types/tests/jsunit/extensions_test.d.ts.map +1 -1
  160. package/dist/types/tests/jsunit/field_number_test.d.ts.map +1 -1
  161. package/dist/types/tests/jsunit/field_test.d.ts.map +1 -1
  162. package/dist/types/tests/jsunit/field_variable_getter_test.d.ts.map +1 -1
  163. package/dist/types/tests/jsunit/field_variable_test.d.ts.map +1 -1
  164. package/dist/types/tests/jsunit/gesture_test.d.ts.map +1 -1
  165. package/dist/types/tests/jsunit/input_test.d.ts +1 -0
  166. package/dist/types/tests/jsunit/input_test.d.ts.map +1 -1
  167. package/dist/types/tests/jsunit/json_test.d.ts.map +1 -1
  168. package/dist/types/tests/jsunit/names_test.d.ts.map +1 -1
  169. package/dist/types/tests/jsunit/procedure_test.d.ts.map +1 -1
  170. package/dist/types/tests/jsunit/scratch_block_comment_test.d.ts.map +1 -1
  171. package/dist/types/tests/jsunit/svg_test.d.ts.map +1 -1
  172. package/dist/types/tests/jsunit/test_utilities.d.ts.map +1 -1
  173. package/dist/types/tests/jsunit/utils_test.d.ts.map +1 -1
  174. package/dist/types/tests/jsunit/variable_map_test.d.ts.map +1 -1
  175. package/dist/types/tests/jsunit/variable_model_test.d.ts.map +1 -1
  176. package/dist/types/tests/jsunit/widget_div_test.d.ts.map +1 -1
  177. package/dist/types/tests/jsunit/workspace_comment_test.d.ts.map +1 -1
  178. package/dist/types/tests/jsunit/workspace_test.d.ts.map +1 -1
  179. package/dist/types/tests/jsunit/workspace_undo_redo_test.d.ts.map +1 -1
  180. package/dist/types/tests/jsunit/xml_test.d.ts.map +1 -1
  181. package/dist/types/tests/workspace_svg/workspace_svg_test.d.ts.map +1 -1
  182. package/eslint.config.mjs +69 -0
  183. package/i18n/create_scratch_msgs.js +44 -45
  184. package/i18n/js_to_json.js +40 -32
  185. package/i18n/json_to_js.js +37 -37
  186. package/i18n/sync_tx_translations.js +64 -65
  187. package/i18n/test_scratch_msgs.js +66 -63
  188. package/msg/js/en.js +289 -287
  189. package/msg/json/en.json +284 -284
  190. package/msg/messages.js +289 -287
  191. package/msg/scratch_msgs.js +22959 -22970
  192. package/package.json +13 -10
  193. package/prettier.config.mjs +3 -0
  194. package/release.config.js +7 -7
  195. package/renovate.json5 +7 -9
  196. package/src/block_reporting.ts +15 -18
  197. package/src/blocks/colour.ts +12 -15
  198. package/src/blocks/control.ts +167 -177
  199. package/src/blocks/data.ts +225 -292
  200. package/src/blocks/event.ts +121 -123
  201. package/src/blocks/looks.ts +165 -167
  202. package/src/blocks/math.ts +44 -46
  203. package/src/blocks/matrix.ts +11 -13
  204. package/src/blocks/motion.ts +151 -153
  205. package/src/blocks/note.ts +11 -13
  206. package/src/blocks/operators.ts +158 -160
  207. package/src/blocks/procedures.ts +488 -536
  208. package/src/blocks/sensing.ts +163 -165
  209. package/src/blocks/sound.ts +58 -60
  210. package/src/blocks/text.ts +10 -12
  211. package/src/blocks/vertical_extensions.ts +86 -102
  212. package/src/checkable_continuous_flyout.ts +25 -42
  213. package/src/checkbox_bubble.ts +83 -100
  214. package/src/colours.ts +35 -37
  215. package/src/constants.ts +22 -29
  216. package/src/context_menu_items.ts +56 -81
  217. package/src/css.ts +3 -4
  218. package/src/data_category.ts +136 -250
  219. package/src/events/events_block_comment_base.ts +21 -31
  220. package/src/events/events_block_comment_change.ts +21 -42
  221. package/src/events/events_block_comment_collapse.ts +22 -43
  222. package/src/events/events_block_comment_create.ts +29 -46
  223. package/src/events/events_block_comment_delete.ts +10 -19
  224. package/src/events/events_block_comment_move.ts +27 -52
  225. package/src/events/events_block_comment_resize.ts +28 -55
  226. package/src/events/events_block_drag_end.ts +16 -26
  227. package/src/events/events_block_drag_outside.ts +12 -22
  228. package/src/events/events_scratch_variable_create.ts +33 -56
  229. package/src/fields/field_colour_slider.ts +173 -228
  230. package/src/fields/field_matrix.ts +200 -269
  231. package/src/fields/field_note.ts +272 -377
  232. package/src/fields/field_textinput_removable.ts +25 -40
  233. package/src/fields/field_variable_getter.ts +26 -31
  234. package/src/fields/field_vertical_separator.ts +19 -24
  235. package/src/fields/scratch_field_angle.ts +150 -186
  236. package/src/fields/scratch_field_dropdown.ts +15 -19
  237. package/src/fields/scratch_field_number.ts +123 -180
  238. package/src/fields/scratch_field_variable.ts +52 -73
  239. package/src/flyout_checkbox_icon.ts +18 -28
  240. package/src/glows.ts +51 -58
  241. package/src/index.ts +119 -133
  242. package/src/procedures.ts +144 -211
  243. package/src/recyclable_block_flyout_inflater.ts +14 -25
  244. package/src/renderer/bowler_hat.ts +6 -8
  245. package/src/renderer/cat/cat_face.ts +98 -99
  246. package/src/renderer/cat/constants.ts +67 -87
  247. package/src/renderer/cat/drawer.ts +21 -27
  248. package/src/renderer/cat/path_object.ts +3 -5
  249. package/src/renderer/cat/render_info.ts +5 -8
  250. package/src/renderer/cat/renderer.ts +11 -15
  251. package/src/renderer/constants.ts +34 -49
  252. package/src/renderer/drawer.ts +35 -51
  253. package/src/renderer/path_object.ts +13 -15
  254. package/src/renderer/render_info.ts +36 -56
  255. package/src/renderer/renderer.ts +16 -29
  256. package/src/scratch_block_paster.ts +12 -20
  257. package/src/scratch_blocks_utils.ts +4 -7
  258. package/src/scratch_comment_bubble.ts +70 -101
  259. package/src/scratch_comment_icon.ts +74 -123
  260. package/src/scratch_connection_checker.ts +22 -17
  261. package/src/scratch_continuous_category.ts +24 -28
  262. package/src/scratch_continuous_toolbox.ts +20 -27
  263. package/src/scratch_dragger.ts +54 -86
  264. package/src/scratch_insertion_marker_previewer.ts +6 -11
  265. package/src/scratch_variable_map.ts +5 -12
  266. package/src/scratch_variable_model.ts +4 -11
  267. package/src/scratch_zoom_controls.ts +101 -156
  268. package/src/shadows.ts +32 -37
  269. package/src/status_indicator_label.ts +54 -67
  270. package/src/status_indicator_label_flyout_inflater.ts +11 -21
  271. package/src/variables.ts +89 -138
  272. package/src/xml.ts +21 -35
  273. package/tsconfig.json +2 -6
  274. package/types/continuous-toolbox.d.ts +1 -1
  275. package/dist/main.mjs.LICENSE.txt +0 -163
package/src/procedures.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  /**
2
- * @license
3
2
  * Visual Blocks Editor
4
3
  *
5
4
  * Copyright 2012 Google Inc.
@@ -17,66 +16,64 @@
17
16
  * See the License for the specific language governing permissions and
18
17
  * limitations under the License.
19
18
  */
20
-
21
19
  /**
22
- * @fileoverview Utility functions for handling procedures.
20
+ * @file Utility functions for handling procedures.
23
21
  * @author fraser@google.com (Neil Fraser)
24
22
  */
25
-
26
- import * as Blockly from "blockly/core";
27
- import * as Constants from "./constants";
28
- import * as scratchBlocksUtils from "../src/scratch_blocks_utils";
23
+ import * as Blockly from 'blockly/core'
24
+ import * as scratchBlocksUtils from '../src/scratch_blocks_utils'
25
+ import * as Constants from './constants'
29
26
 
30
27
  /**
31
28
  * Find all user-created procedure definition mutations in a workspace.
32
29
  * @param root Root workspace.
33
- * @return Array of mutation xml elements.
30
+ * @returns Array of mutation xml elements.
34
31
  */
35
32
  function allProcedureMutations(root: Blockly.WorkspaceSvg): Element[] {
36
- const blocks = root.getAllBlocks();
33
+ const blocks = root.getAllBlocks()
37
34
  return blocks
38
35
  .filter((b) => b.type === Constants.PROCEDURES_PROTOTYPE_BLOCK_TYPE)
39
- .map((b) => b.mutationToDom!(/* opt_generateShadows */ true) as Element);
36
+ .map((b) => b.mutationToDom!(/* opt_generateShadows */ true))
40
37
  }
41
38
 
42
39
  /**
43
40
  * Sorts an array of procedure definition mutations alphabetically.
44
41
  * (Does not mutate the given array.)
45
42
  * @param mutations Array of mutation xml elements.
46
- * @return Sorted array of mutation xml elements.
43
+ * @returns Sorted array of mutation xml elements.
47
44
  */
48
45
  function sortProcedureMutations(mutations: Element[]): Element[] {
49
- return mutations.slice().sort(function (a, b) {
50
- const procCodeA = a.getAttribute("proccode")!;
51
- const procCodeB = b.getAttribute("proccode")!;
46
+ return mutations.slice().sort((a, b) => {
47
+ const procCodeA = a.getAttribute('proccode')!
48
+ const procCodeB = b.getAttribute('proccode')!
52
49
 
53
- return scratchBlocksUtils.compareStrings(procCodeA, procCodeB);
54
- });
50
+ return scratchBlocksUtils.compareStrings(procCodeA, procCodeB)
51
+ })
55
52
  }
56
53
 
57
54
  /**
58
55
  * Construct the blocks required by the flyout for the procedure category.
59
56
  * @param workspace The workspace containing procedures.
60
- * @return Array of XML block elements.
57
+ * @returns Array of XML block elements.
61
58
  */
62
59
  function getProceduresCategory(workspace: Blockly.WorkspaceSvg): Element[] {
63
- var xmlList: Element[] = [];
60
+ const xmlList: Element[] = []
64
61
 
65
- addCreateButton(workspace, xmlList);
62
+ addCreateButton(workspace, xmlList)
66
63
 
67
64
  // Create call blocks for each procedure defined in the workspace
68
- const mutations = sortProcedureMutations(allProcedureMutations(workspace));
65
+ const mutations = sortProcedureMutations(allProcedureMutations(workspace))
69
66
  for (const mutation of mutations) {
70
67
  // <block type="procedures_call">
71
68
  // <mutation ...></mutation>
72
69
  // </block>
73
- const block = document.createElement("block");
74
- block.setAttribute("type", "procedures_call");
75
- block.setAttribute("gap", "16");
76
- block.appendChild(mutation);
77
- xmlList.push(block);
70
+ const block = document.createElement('block')
71
+ block.setAttribute('type', 'procedures_call')
72
+ block.setAttribute('gap', '16')
73
+ block.appendChild(mutation)
74
+ xmlList.push(block)
78
75
  }
79
- return xmlList;
76
+ return xmlList
80
77
  }
81
78
 
82
79
  /**
@@ -85,23 +82,23 @@ function getProceduresCategory(workspace: Blockly.WorkspaceSvg): Element[] {
85
82
  * @param xmlList Array of XML block elements to add to.
86
83
  */
87
84
  function addCreateButton(workspace: Blockly.WorkspaceSvg, xmlList: Element[]) {
88
- const button = document.createElement("button");
89
- const msg = Blockly.Msg.NEW_PROCEDURE;
90
- const callbackKey = "CREATE_PROCEDURE";
85
+ const button = document.createElement('button')
86
+ const msg = Blockly.Msg.NEW_PROCEDURE
87
+ const callbackKey = 'CREATE_PROCEDURE'
91
88
  const callback = function () {
92
89
  // Run the callback after a delay to avoid it getting captured by the React
93
90
  // modal in scratch-gui and being registered as a click on the scrim that
94
91
  // dismisses the dialog.
95
92
  requestAnimationFrame(() => {
96
93
  setTimeout(() => {
97
- createProcedureDefCallback(workspace);
98
- });
99
- });
100
- };
101
- button.setAttribute("text", msg);
102
- button.setAttribute("callbackKey", callbackKey);
103
- workspace.registerButtonCallback(callbackKey, callback);
104
- xmlList.push(button);
94
+ createProcedureDefCallback(workspace)
95
+ })
96
+ })
97
+ }
98
+ button.setAttribute('text', msg)
99
+ button.setAttribute('callbackKey', callbackKey)
100
+ workspace.registerButtonCallback(callbackKey, callback)
101
+ xmlList.push(button)
105
102
  }
106
103
 
107
104
  /**
@@ -113,27 +110,28 @@ function addCreateButton(workspace: Blockly.WorkspaceSvg, xmlList: Element[]) {
113
110
  * @param allowRecursive True if the search should include recursive
114
111
  * procedure calls. False if the search should ignore the stack starting
115
112
  * with definitionRoot.
116
- * @return Array of caller blocks.
113
+ * @returns Array of caller blocks.
117
114
  */
118
115
  export function getCallers(
119
116
  name: string,
120
117
  workspace: Blockly.WorkspaceSvg,
121
118
  definitionRoot: Blockly.BlockSvg,
122
- allowRecursive: boolean
119
+ allowRecursive: boolean,
123
120
  ): Blockly.BlockSvg[] {
124
121
  return workspace.getTopBlocks().flatMap((block) => {
125
122
  if (block.id === definitionRoot.id && !allowRecursive) {
126
- return [];
123
+ return []
127
124
  }
128
125
 
129
- return block.getDescendants(false).filter((descendant) => {
130
- return (
131
- isProcedureBlock(descendant) &&
132
- descendant.type === Constants.PROCEDURES_CALL_BLOCK_TYPE &&
133
- descendant.getProcCode() === name
134
- );
135
- });
136
- });
126
+ return block
127
+ .getDescendants(false)
128
+ .filter(
129
+ (descendant) =>
130
+ isProcedureBlock(descendant) &&
131
+ descendant.type === Constants.PROCEDURES_CALL_BLOCK_TYPE &&
132
+ descendant.getProcCode() === name,
133
+ )
134
+ })
137
135
  }
138
136
 
139
137
  /**
@@ -142,108 +140,80 @@ export function getCallers(
142
140
  * @param workspace The workspace to find callers in.
143
141
  * @param mutation New mutation for the callers.
144
142
  */
145
- function mutateCallersAndPrototype(
146
- name: string,
147
- workspace: Blockly.WorkspaceSvg,
148
- mutation: Element
149
- ) {
150
- const defineBlock = getDefineBlock(name, workspace);
151
- const prototypeBlock = getPrototypeBlock(name, workspace);
143
+ function mutateCallersAndPrototype(name: string, workspace: Blockly.WorkspaceSvg, mutation: Element) {
144
+ const defineBlock = getDefineBlock(name, workspace)
145
+ const prototypeBlock = getPrototypeBlock(name, workspace)
152
146
  if (!(defineBlock && prototypeBlock)) {
153
- alert("No define block on workspace"); // TODO decide what to do about this.
154
- return;
147
+ alert('No define block on workspace') // TODO decide what to do about this.
148
+ return
155
149
  }
156
150
 
157
- const callers = getCallers(
158
- name,
159
- defineBlock.workspace,
160
- defineBlock,
161
- true /* allowRecursive */
162
- );
163
- callers.push(prototypeBlock);
164
- Blockly.Events.setGroup(true);
151
+ const callers = getCallers(name, defineBlock.workspace, defineBlock, true /* allowRecursive */)
152
+ callers.push(prototypeBlock)
153
+ Blockly.Events.setGroup(true)
165
154
  callers.forEach((caller) => {
166
- const oldMutationDom = caller.mutationToDom!();
167
- const oldMutation = oldMutationDom && Blockly.Xml.domToText(oldMutationDom);
168
- caller.domToMutation!(mutation);
169
- const newMutationDom = caller.mutationToDom!();
170
- const newMutation = newMutationDom && Blockly.Xml.domToText(newMutationDom);
155
+ const oldMutationDom = caller.mutationToDom!()
156
+ const oldMutation = oldMutationDom && Blockly.Xml.domToText(oldMutationDom)
157
+ caller.domToMutation!(mutation)
158
+ const newMutationDom = caller.mutationToDom!()
159
+ const newMutation = newMutationDom && Blockly.Xml.domToText(newMutationDom)
171
160
  if (oldMutation !== newMutation) {
172
161
  Blockly.Events.fire(
173
- new (Blockly.Events.get(Blockly.Events.BLOCK_CHANGE))(
174
- caller,
175
- "mutation",
176
- null,
177
- oldMutation,
178
- newMutation
179
- )
180
- );
162
+ new (Blockly.Events.get(Blockly.Events.BLOCK_CHANGE))(caller, 'mutation', null, oldMutation, newMutation),
163
+ )
181
164
  }
182
- });
183
- Blockly.Events.setGroup(false);
165
+ })
166
+ Blockly.Events.setGroup(false)
184
167
  }
185
168
 
186
169
  /**
187
170
  * Find the definition block for the named procedure.
188
171
  * @param procCode The identifier of the procedure.
189
172
  * @param workspace The workspace to search.
190
- * @return The procedure definition block, or undefined if not found.
173
+ * @returns The procedure definition block, or undefined if not found.
191
174
  */
192
- function getDefineBlock(
193
- procCode: string,
194
- workspace: Blockly.WorkspaceSvg
195
- ): Blockly.BlockSvg | undefined {
175
+ function getDefineBlock(procCode: string, workspace: Blockly.WorkspaceSvg): Blockly.BlockSvg | undefined {
196
176
  // Assume that a procedure definition is a top block.
197
177
  return workspace.getTopBlocks(false).find((block) => {
198
178
  if (block.type === Constants.PROCEDURES_DEFINITION_BLOCK_TYPE) {
199
- const prototypeBlock = block
200
- .getInput("custom_block")!
201
- .connection!.targetBlock() as Blockly.BlockSvg;
202
- return (
203
- isProcedureBlock(prototypeBlock) &&
204
- prototypeBlock.getProcCode() === procCode
205
- );
179
+ const prototypeBlock = block.getInput('custom_block')!.connection!.targetBlock() as Blockly.BlockSvg
180
+ return isProcedureBlock(prototypeBlock) && prototypeBlock.getProcCode() === procCode
206
181
  }
207
182
 
208
- return false;
209
- });
183
+ return false
184
+ })
210
185
  }
211
186
 
212
187
  /**
213
188
  * Find the prototype block for the named procedure.
214
189
  * @param procCode The identifier of the procedure.
215
190
  * @param workspace The workspace to search.
216
- * @return The procedure prototype block, or undefined if not found.
191
+ * @returns The procedure prototype block, or undefined if not found.
217
192
  */
218
- function getPrototypeBlock(
219
- procCode: string,
220
- workspace: Blockly.WorkspaceSvg
221
- ): Blockly.BlockSvg | undefined {
222
- const defineBlock = getDefineBlock(procCode, workspace);
193
+ function getPrototypeBlock(procCode: string, workspace: Blockly.WorkspaceSvg): Blockly.BlockSvg | undefined {
194
+ const defineBlock = getDefineBlock(procCode, workspace)
223
195
  if (defineBlock) {
224
- return defineBlock
225
- .getInput("custom_block")!
226
- .connection!.targetBlock() as Blockly.BlockSvg;
196
+ return defineBlock.getInput('custom_block')!.connection!.targetBlock() as Blockly.BlockSvg
227
197
  }
228
- return undefined;
198
+ return undefined
229
199
  }
230
200
 
231
201
  /**
232
202
  * Create a mutation for a brand new custom procedure.
233
- * @return The mutation for a new custom procedure
203
+ * @returns The mutation for a new custom procedure
234
204
  */
235
205
  function newProcedureMutation(): Element {
236
206
  const mutationText = `
237
207
  <xml>
238
208
  <mutation
239
- proccode="${Blockly.Msg["PROCEDURE_DEFAULT_NAME"]}"
209
+ proccode="${Blockly.Msg.PROCEDURE_DEFAULT_NAME}"
240
210
  argumentids="[]"
241
211
  argumentnames="[]"
242
212
  argumentdefaults="[]"
243
213
  warp="false">
244
214
  </mutation>
245
- </xml>`;
246
- return Blockly.utils.xml.textToDom(mutationText).firstElementChild!;
215
+ </xml>`
216
+ return Blockly.utils.xml.textToDom(mutationText).firstElementChild!
247
217
  }
248
218
 
249
219
  /**
@@ -251,56 +221,48 @@ function newProcedureMutation(): Element {
251
221
  * @param workspace The workspace to create the new procedure on.
252
222
  */
253
223
  function createProcedureDefCallback(workspace: Blockly.WorkspaceSvg) {
254
- ScratchProcedures.externalProcedureDefCallback!(
255
- newProcedureMutation(),
256
- createProcedureCallbackFactory(workspace)
257
- );
224
+ ScratchProcedures.externalProcedureDefCallback!(newProcedureMutation(), createProcedureCallbackFactory(workspace))
258
225
  }
259
226
 
260
227
  /**
261
228
  * Callback factory for adding a new custom procedure from a mutation.
262
229
  * @param workspace The workspace to create the new procedure on.
263
- * @return callback for creating the new custom procedure.
230
+ * @returns callback for creating the new custom procedure.
264
231
  */
265
- function createProcedureCallbackFactory(
266
- workspace: Blockly.WorkspaceSvg
267
- ): (mutation?: Element) => void {
232
+ function createProcedureCallbackFactory(workspace: Blockly.WorkspaceSvg): (mutation?: Element) => void {
268
233
  return (mutation?: Element) => {
269
- if (!mutation) return;
234
+ if (!mutation) return
270
235
 
271
236
  const blockText = `
272
237
  <xml>
273
238
  <block type="procedures_definition">
274
239
  <statement name="custom_block">
275
- <shadow type="procedures_prototype">
240
+ <block type="procedures_prototype">
276
241
  ${Blockly.Xml.domToText(mutation)}
277
- </shadow>
242
+ </block>
278
243
  </statement>
279
244
  </block>
280
- </xml>`;
281
- const blockDom = Blockly.utils.xml.textToDom(blockText).firstElementChild!;
282
- Blockly.Events.setGroup(true);
283
- const block = Blockly.Xml.domToBlock(
284
- blockDom,
285
- workspace
286
- ) as Blockly.BlockSvg;
245
+ </xml>`
246
+ const blockDom = Blockly.utils.xml.textToDom(blockText).firstElementChild!
247
+ Blockly.Events.setGroup(true)
248
+ const block = Blockly.Xml.domToBlock(blockDom, workspace) as Blockly.BlockSvg
287
249
  Blockly.renderManagement.finishQueuedRenders().then(() => {
288
250
  // To convert from pixel units to workspace units
289
- const scale = workspace.scale;
251
+ const scale = workspace.scale
290
252
  // Position the block so that it is at the top left of the visible
291
253
  // workspace, padded from the edge by 30 units. Position in the top right
292
254
  // if RTL.
293
- let posX = -workspace.scrollX;
255
+ let posX = -workspace.scrollX
294
256
  if (workspace.RTL) {
295
- posX += workspace.getMetrics().contentWidth - 30;
257
+ posX += workspace.getMetrics().contentWidth - 30
296
258
  } else {
297
- posX += 30;
259
+ posX += 30
298
260
  }
299
- block.moveBy(posX / scale, (-workspace.scrollY + 30) / scale);
300
- block.scheduleSnapAndBump();
301
- Blockly.Events.setGroup(false);
302
- });
303
- };
261
+ block.moveBy(posX / scale, (-workspace.scrollY + 30) / scale)
262
+ block.scheduleSnapAndBump()
263
+ Blockly.Events.setGroup(false)
264
+ })
265
+ }
304
266
  }
305
267
 
306
268
  /**
@@ -310,68 +272,55 @@ function createProcedureCallbackFactory(
310
272
  function editProcedureCallback(block: Blockly.BlockSvg) {
311
273
  // Edit can come from one of three block types (call, define, prototype)
312
274
  // Normalize by setting the block to the prototype block for the procedure.
313
- let prototypeBlock: Blockly.BlockSvg;
275
+ let prototypeBlock: Blockly.BlockSvg
314
276
  if (block.type === Constants.PROCEDURES_DEFINITION_BLOCK_TYPE) {
315
- const input = block.getInput("custom_block");
277
+ const input = block.getInput('custom_block')
316
278
  if (!input) {
317
- alert("Bad input"); // TODO: Decide what to do about this.
318
- return;
279
+ alert('Bad input') // TODO: Decide what to do about this.
280
+ return
319
281
  }
320
- const conn = input.connection;
282
+ const conn = input.connection
321
283
  if (!conn) {
322
- alert("Bad connection"); // TODO: Decide what to do about this.
323
- return;
284
+ alert('Bad connection') // TODO: Decide what to do about this.
285
+ return
324
286
  }
325
- const innerBlock = conn.targetBlock();
326
- if (
327
- !innerBlock ||
328
- innerBlock.type !== Constants.PROCEDURES_PROTOTYPE_BLOCK_TYPE
329
- ) {
330
- alert("Bad inner block"); // TODO: Decide what to do about this.
331
- return;
287
+ const innerBlock = conn.targetBlock()
288
+ if (innerBlock?.type !== Constants.PROCEDURES_PROTOTYPE_BLOCK_TYPE) {
289
+ alert('Bad inner block') // TODO: Decide what to do about this.
290
+ return
332
291
  }
333
- prototypeBlock = innerBlock as Blockly.BlockSvg;
334
- } else if (
335
- block.type === Constants.PROCEDURES_CALL_BLOCK_TYPE &&
336
- isProcedureBlock(block)
337
- ) {
292
+ prototypeBlock = innerBlock as Blockly.BlockSvg
293
+ } else if (block.type === Constants.PROCEDURES_CALL_BLOCK_TYPE && isProcedureBlock(block)) {
338
294
  // This is a call block, find the prototype corresponding to the procCode.
339
295
  // Make sure to search the correct workspace, call block can be in flyout.
340
- const workspaceToSearch = block.workspace.isFlyout
341
- ? block.workspace.targetWorkspace!
342
- : block.workspace;
343
- const foundBlock = getPrototypeBlock(block.getProcCode(), workspaceToSearch);
296
+ const workspaceToSearch = block.workspace.isFlyout ? block.workspace.targetWorkspace! : block.workspace
297
+ const foundBlock = getPrototypeBlock(block.getProcCode(), workspaceToSearch)
344
298
  if (!foundBlock) {
345
- console.warn(
346
- "editProcedureCallback: could not find prototype for",
347
- block.getProcCode()
348
- );
349
- return;
299
+ console.warn('editProcedureCallback: could not find prototype for', block.getProcCode())
300
+ return
350
301
  }
351
- prototypeBlock = foundBlock;
302
+ prototypeBlock = foundBlock
352
303
  } else {
353
- prototypeBlock = block;
304
+ prototypeBlock = block
354
305
  }
355
306
  // Block now refers to the procedure prototype block, it is safe to proceed.
356
307
  ScratchProcedures.externalProcedureDefCallback!(
357
308
  prototypeBlock.mutationToDom!(),
358
- editProcedureCallbackFactory(prototypeBlock)
359
- );
309
+ editProcedureCallbackFactory(prototypeBlock),
310
+ )
360
311
  }
361
312
 
362
313
  /**
363
314
  * Callback factory for editing an existing custom procedure.
364
315
  * @param block The procedure prototype block being edited.
365
- * @return Callback for editing the custom procedure.
316
+ * @returns Callback for editing the custom procedure.
366
317
  */
367
- function editProcedureCallbackFactory(
368
- block: Blockly.BlockSvg
369
- ): (mutation?: Element) => void {
318
+ function editProcedureCallbackFactory(block: Blockly.BlockSvg): (mutation?: Element) => void {
370
319
  return (mutation?: Element) => {
371
320
  if (mutation && isProcedureBlock(block)) {
372
- mutateCallersAndPrototype(block.getProcCode(), block.workspace, mutation);
321
+ mutateCallersAndPrototype(block.getProcCode(), block.workspace, mutation)
373
322
  }
374
- };
323
+ }
375
324
  }
376
325
 
377
326
  /**
@@ -379,20 +328,18 @@ function editProcedureCallbackFactory(
379
328
  * This appears in the context menu for procedure definitions and procedure
380
329
  * calls.
381
330
  * @param block The block where the right-click originated.
382
- * @return A menu option, containing text, enabled, and a callback.
331
+ * @returns A menu option, containing text, enabled, and a callback.
383
332
  */
384
- function makeEditOption(
385
- block: Blockly.BlockSvg
386
- ): Blockly.ContextMenuRegistry.ContextMenuOption {
333
+ function makeEditOption(block: Blockly.BlockSvg): Blockly.ContextMenuRegistry.ContextMenuOption {
387
334
  return {
388
335
  enabled: true,
389
336
  text: Blockly.Msg.EDIT_PROCEDURE,
390
337
  callback: () => {
391
- editProcedureCallback(block);
338
+ editProcedureCallback(block)
392
339
  },
393
340
  scope: block,
394
341
  weight: 7,
395
- };
342
+ }
396
343
  }
397
344
 
398
345
  /**
@@ -400,42 +347,31 @@ function makeEditOption(
400
347
  * @param procCode The identifier of the procedure to delete.
401
348
  * @param definitionRoot The root block of the stack that defines the custom
402
349
  * procedure.
403
- * @return True if the custom procedure was deleted, false otherwise.
350
+ * @returns True if the custom procedure was deleted, false otherwise.
404
351
  */
405
- function deleteProcedureDefCallback(
406
- procCode: string,
407
- definitionRoot: Blockly.BlockSvg
408
- ): boolean {
409
- const callers = getCallers(
410
- procCode,
411
- definitionRoot.workspace,
412
- definitionRoot,
413
- false /* allowRecursive */
414
- );
352
+ function deleteProcedureDefCallback(procCode: string, definitionRoot: Blockly.BlockSvg): boolean {
353
+ const callers = getCallers(procCode, definitionRoot.workspace, definitionRoot, false /* allowRecursive */)
415
354
  if (callers.length > 0) {
416
- return false;
355
+ return false
417
356
  }
418
357
 
419
- const workspace = definitionRoot.workspace;
358
+ const workspace = definitionRoot.workspace
420
359
  // Bypass the checkAndDelete provided by the procedure block mixin
421
- Blockly.BlockSvg.prototype.checkAndDelete.call(definitionRoot);
422
- return true;
360
+ Blockly.BlockSvg.prototype.checkAndDelete.call(definitionRoot)
361
+ return true
423
362
  }
424
363
 
425
364
  /**
426
365
  * Returns whether the given block is a procedure block and narrows its type.
427
- *
428
366
  * @param block The block to check.
429
367
  * @returns True if the block is a procedure block, otherwise false.
430
368
  */
431
- export function isProcedureBlock(
432
- block: Blockly.BlockSvg
433
- ): block is ProcedureBlock {
369
+ export function isProcedureBlock(block: Blockly.BlockSvg): block is ProcedureBlock {
434
370
  return (
435
371
  block.type === Constants.PROCEDURES_CALL_BLOCK_TYPE ||
436
372
  block.type === Constants.PROCEDURES_DECLARATION_BLOCK_TYPE ||
437
373
  block.type === Constants.PROCEDURES_PROTOTYPE_BLOCK_TYPE
438
- );
374
+ )
439
375
  }
440
376
 
441
377
  /**
@@ -443,28 +379,25 @@ export function isProcedureBlock(
443
379
  * through an extension.
444
380
  */
445
381
  interface ProcedureBlock extends Blockly.BlockSvg {
446
- getProcCode(): string;
382
+ getProcCode(): string
447
383
  }
448
384
 
449
385
  /**
450
386
  * Type for a callback function invoked after a procedure is modified.
451
387
  */
452
- type ProcedureDefCallback = (
453
- mutation: Element,
454
- postEditCallback: (mutation?: Element) => void
455
- ) => void;
388
+ type ProcedureDefCallback = (mutation: Element, postEditCallback: (mutation?: Element) => void) => void
456
389
 
457
390
  const ScratchProcedures: {
458
- externalProcedureDefCallback: ProcedureDefCallback | undefined;
459
- createProcedureDefCallback: typeof createProcedureDefCallback;
460
- deleteProcedureDefCallback: typeof deleteProcedureDefCallback;
461
- getProceduresCategory: typeof getProceduresCategory;
462
- makeEditOption: typeof makeEditOption;
391
+ externalProcedureDefCallback: ProcedureDefCallback | undefined
392
+ createProcedureDefCallback: typeof createProcedureDefCallback
393
+ deleteProcedureDefCallback: typeof deleteProcedureDefCallback
394
+ getProceduresCategory: typeof getProceduresCategory
395
+ makeEditOption: typeof makeEditOption
463
396
  } = {
464
397
  externalProcedureDefCallback: undefined,
465
398
  createProcedureDefCallback,
466
399
  deleteProcedureDefCallback,
467
400
  getProceduresCategory,
468
401
  makeEditOption,
469
- };
470
- export { ScratchProcedures };
402
+ }
403
+ export { ScratchProcedures }
@@ -1,12 +1,10 @@
1
1
  /**
2
- * @license
3
2
  * Copyright 2024 Google LLC
4
3
  * SPDX-License-Identifier: Apache-2.0
5
4
  */
6
-
7
- import * as Blockly from "blockly/core";
8
- import { CheckboxBubble } from "./checkbox_bubble";
9
- import { RecyclableBlockFlyoutInflater as BlocklyRecyclableBlockFlyoutInflater } from "@blockly/continuous-toolbox";
5
+ import { RecyclableBlockFlyoutInflater as BlocklyRecyclableBlockFlyoutInflater } from '@blockly/continuous-toolbox'
6
+ import * as Blockly from 'blockly/core'
7
+ import { CheckboxBubble } from './checkbox_bubble'
10
8
 
11
9
  /**
12
10
  * A block inflater that caches and reuses blocks to improve performance.
@@ -14,26 +12,21 @@ import { RecyclableBlockFlyoutInflater as BlocklyRecyclableBlockFlyoutInflater }
14
12
  export class RecyclableBlockFlyoutInflater extends BlocklyRecyclableBlockFlyoutInflater {
15
13
  /**
16
14
  * Creates a block on the flyout workspace from the given block definition.
17
- *
18
15
  * @param state A JSON representation of a block to load.
19
- * @param flyoutWorkspace The flyout's workspace.
16
+ * @param flyoutWorkspace The workspace on which the block will be inflated.
20
17
  * @returns The newly created block.
21
18
  */
22
- load(
23
- state: Blockly.utils.toolbox.BlockInfo,
24
- flyoutWorkspace: Blockly.WorkspaceSvg
25
- ): Blockly.FlyoutItem {
26
- const flyoutItem = super.load(state, flyoutWorkspace);
27
- const block = flyoutItem.getElement();
28
- if ("checkboxInFlyout" in block && block.checkboxInFlyout) {
19
+ load(state: Blockly.utils.toolbox.BlockInfo, flyoutWorkspace: Blockly.WorkspaceSvg): Blockly.FlyoutItem {
20
+ const flyoutItem = super.load(state, flyoutWorkspace)
21
+ const block = flyoutItem.getElement()
22
+ if ('checkboxInFlyout' in block && block.checkboxInFlyout) {
29
23
  block.moveBy(
30
- (flyoutWorkspace.RTL ? -1 : 1) *
31
- (CheckboxBubble.CHECKBOX_SIZE + CheckboxBubble.CHECKBOX_MARGIN),
32
- 0
33
- );
24
+ (flyoutWorkspace.RTL ? -1 : 1) * (CheckboxBubble.CHECKBOX_SIZE + CheckboxBubble.CHECKBOX_MARGIN),
25
+ 0,
26
+ )
34
27
  }
35
28
 
36
- return flyoutItem;
29
+ return flyoutItem
37
30
  }
38
31
  }
39
32
 
@@ -42,10 +35,6 @@ export class RecyclableBlockFlyoutInflater extends BlocklyRecyclableBlockFlyoutI
42
35
  * block flyout inflater.
43
36
  */
44
37
  export function registerRecyclableBlockFlyoutInflater() {
45
- Blockly.registry.unregister(Blockly.registry.Type.FLYOUT_INFLATER, "block");
46
- Blockly.registry.register(
47
- Blockly.registry.Type.FLYOUT_INFLATER,
48
- "block",
49
- RecyclableBlockFlyoutInflater
50
- );
38
+ Blockly.registry.unregister(Blockly.registry.Type.FLYOUT_INFLATER, 'block')
39
+ Blockly.registry.register(Blockly.registry.Type.FLYOUT_INFLATER, 'block', RecyclableBlockFlyoutInflater)
51
40
  }