blockly 7.20211209.4 → 8.0.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 (262) hide show
  1. package/blockly.d.ts +18963 -18432
  2. package/blockly.min.js +852 -844
  3. package/blockly_compressed.js +669 -664
  4. package/blockly_compressed.js.map +1 -1
  5. package/blocks/blocks.js +47 -0
  6. package/blocks/colour.js +13 -3
  7. package/blocks/lists.js +22 -13
  8. package/blocks/logic.js +13 -3
  9. package/blocks/loops.js +24 -11
  10. package/blocks/math.js +12 -3
  11. package/blocks/procedures.js +41 -27
  12. package/blocks/text.js +22 -13
  13. package/blocks/variables.js +14 -3
  14. package/blocks/variables_dynamic.js +13 -3
  15. package/blocks_compressed.js +146 -141
  16. package/blocks_compressed.js.map +1 -1
  17. package/core/block.js +1869 -1814
  18. package/core/block_drag_surface.js +201 -200
  19. package/core/block_dragger.js +377 -373
  20. package/core/block_svg.js +1593 -1479
  21. package/core/blockly.js +8 -22
  22. package/core/blocks.js +9 -2
  23. package/core/browser_events.js +22 -5
  24. package/core/bubble.js +841 -797
  25. package/core/bubble_dragger.js +213 -206
  26. package/core/bump_objects.js +2 -2
  27. package/core/clipboard.js +9 -9
  28. package/core/comment.js +353 -332
  29. package/core/common.js +46 -17
  30. package/core/component_manager.js +181 -174
  31. package/core/config.js +87 -0
  32. package/core/connection.js +595 -584
  33. package/core/connection_checker.js +242 -244
  34. package/core/connection_db.js +235 -230
  35. package/core/contextmenu.js +9 -6
  36. package/core/contextmenu_items.js +1 -2
  37. package/core/contextmenu_registry.js +93 -89
  38. package/core/css.js +474 -474
  39. package/core/delete_area.js +45 -42
  40. package/core/drag_target.js +57 -56
  41. package/core/dropdowndiv.js +153 -163
  42. package/core/events/events.js +2 -2
  43. package/core/events/events_abstract.js +89 -77
  44. package/core/events/events_block_base.js +37 -36
  45. package/core/events/events_block_change.js +130 -124
  46. package/core/events/events_block_create.js +73 -71
  47. package/core/events/events_block_delete.js +84 -82
  48. package/core/events/events_block_drag.js +50 -49
  49. package/core/events/events_block_move.js +147 -140
  50. package/core/events/events_bubble_open.js +51 -50
  51. package/core/events/events_click.js +48 -44
  52. package/core/events/events_comment_base.js +72 -69
  53. package/core/events/events_comment_change.js +63 -61
  54. package/core/events/events_comment_create.js +44 -42
  55. package/core/events/events_comment_delete.js +42 -40
  56. package/core/events/events_comment_move.js +106 -104
  57. package/core/events/events_marker_move.js +65 -64
  58. package/core/events/events_selected.js +46 -45
  59. package/core/events/events_theme_change.js +36 -35
  60. package/core/events/events_toolbox_item_select.js +46 -45
  61. package/core/events/events_trashcan_open.js +37 -36
  62. package/core/events/events_ui.js +47 -46
  63. package/core/events/events_ui_base.js +30 -29
  64. package/core/events/events_var_base.js +37 -36
  65. package/core/events/events_var_create.js +50 -48
  66. package/core/events/events_var_delete.js +50 -48
  67. package/core/events/events_var_rename.js +51 -49
  68. package/core/events/events_viewport.js +66 -65
  69. package/core/events/utils.js +29 -14
  70. package/core/events/workspace_events.js +49 -55
  71. package/core/extensions.js +4 -3
  72. package/core/field.js +1061 -997
  73. package/core/field_angle.js +462 -442
  74. package/core/field_checkbox.js +194 -182
  75. package/core/field_colour.js +519 -505
  76. package/core/field_dropdown.js +617 -598
  77. package/core/field_image.js +229 -220
  78. package/core/field_label.js +102 -91
  79. package/core/field_label_serializable.js +42 -41
  80. package/core/field_multilineinput.js +372 -358
  81. package/core/field_number.js +272 -253
  82. package/core/field_textinput.js +499 -467
  83. package/core/field_variable.js +458 -420
  84. package/core/flyout_base.js +1005 -952
  85. package/core/flyout_button.js +277 -260
  86. package/core/flyout_horizontal.js +304 -302
  87. package/core/flyout_metrics_manager.js +64 -64
  88. package/core/flyout_vertical.js +306 -300
  89. package/core/generator.js +459 -446
  90. package/core/gesture.js +829 -813
  91. package/core/grid.js +166 -163
  92. package/core/icon.js +168 -159
  93. package/core/inject.js +7 -5
  94. package/core/input.js +257 -248
  95. package/core/insertion_marker_manager.js +655 -624
  96. package/core/internal_constants.js +0 -129
  97. package/core/keyboard_nav/ast_node.js +605 -596
  98. package/core/keyboard_nav/basic_cursor.js +166 -165
  99. package/core/keyboard_nav/cursor.js +99 -97
  100. package/core/keyboard_nav/marker.js +83 -79
  101. package/core/keyboard_nav/tab_navigate_cursor.js +18 -23
  102. package/core/marker_manager.js +153 -141
  103. package/core/menu.js +377 -372
  104. package/core/menuitem.js +223 -217
  105. package/core/metrics_manager.js +403 -390
  106. package/core/mutator.js +468 -437
  107. package/core/names.js +229 -188
  108. package/core/options.js +290 -284
  109. package/core/procedures.js +29 -17
  110. package/core/registry.js +19 -16
  111. package/core/rendered_connection.js +482 -463
  112. package/core/renderers/common/block_rendering.js +9 -3
  113. package/core/renderers/common/constants.js +1119 -1112
  114. package/core/renderers/common/debug.js +14 -0
  115. package/core/renderers/common/debugger.js +338 -316
  116. package/core/renderers/common/drawer.js +380 -370
  117. package/core/renderers/common/i_path_object.js +2 -2
  118. package/core/renderers/common/info.js +626 -618
  119. package/core/renderers/common/marker_svg.js +579 -541
  120. package/core/renderers/common/path_object.js +203 -200
  121. package/core/renderers/common/renderer.js +220 -218
  122. package/core/renderers/geras/constants.js +36 -36
  123. package/core/renderers/geras/drawer.js +155 -147
  124. package/core/renderers/geras/highlight_constants.js +244 -238
  125. package/core/renderers/geras/highlighter.js +231 -179
  126. package/core/renderers/geras/info.js +392 -369
  127. package/core/renderers/geras/measurables/inline_input.js +25 -19
  128. package/core/renderers/geras/measurables/statement_input.js +23 -17
  129. package/core/renderers/geras/path_object.js +106 -121
  130. package/core/renderers/geras/renderer.js +96 -98
  131. package/core/renderers/measurables/base.js +30 -18
  132. package/core/renderers/measurables/bottom_row.js +83 -80
  133. package/core/renderers/measurables/connection.js +22 -15
  134. package/core/renderers/measurables/external_value_input.js +35 -22
  135. package/core/renderers/measurables/field.js +35 -20
  136. package/core/renderers/measurables/hat.js +18 -13
  137. package/core/renderers/measurables/icon.js +24 -17
  138. package/core/renderers/measurables/in_row_spacer.js +15 -13
  139. package/core/renderers/measurables/inline_input.js +43 -33
  140. package/core/renderers/measurables/input_connection.js +41 -28
  141. package/core/renderers/measurables/input_row.js +50 -44
  142. package/core/renderers/measurables/jagged_edge.js +14 -12
  143. package/core/renderers/measurables/next_connection.js +16 -14
  144. package/core/renderers/measurables/output_connection.js +26 -20
  145. package/core/renderers/measurables/previous_connection.js +16 -15
  146. package/core/renderers/measurables/round_corner.js +20 -18
  147. package/core/renderers/measurables/row.js +184 -168
  148. package/core/renderers/measurables/spacer_row.js +38 -23
  149. package/core/renderers/measurables/square_corner.js +18 -16
  150. package/core/renderers/measurables/statement_input.js +23 -20
  151. package/core/renderers/measurables/top_row.js +88 -85
  152. package/core/renderers/minimalist/constants.js +8 -7
  153. package/core/renderers/minimalist/drawer.js +11 -10
  154. package/core/renderers/minimalist/info.js +18 -18
  155. package/core/renderers/minimalist/renderer.js +40 -39
  156. package/core/renderers/thrasos/info.js +258 -248
  157. package/core/renderers/thrasos/renderer.js +20 -20
  158. package/core/renderers/zelos/constants.js +898 -873
  159. package/core/renderers/zelos/drawer.js +186 -169
  160. package/core/renderers/zelos/info.js +502 -479
  161. package/core/renderers/zelos/marker_svg.js +129 -115
  162. package/core/renderers/zelos/measurables/bottom_row.js +31 -30
  163. package/core/renderers/zelos/measurables/inputs.js +22 -21
  164. package/core/renderers/zelos/measurables/row_elements.js +14 -13
  165. package/core/renderers/zelos/measurables/top_row.js +34 -33
  166. package/core/renderers/zelos/path_object.js +181 -180
  167. package/core/renderers/zelos/renderer.js +91 -92
  168. package/core/scrollbar.js +759 -713
  169. package/core/scrollbar_pair.js +250 -245
  170. package/core/serialization/blocks.js +19 -9
  171. package/core/serialization/workspaces.js +3 -2
  172. package/core/shortcut_registry.js +286 -277
  173. package/core/sprites.js +31 -0
  174. package/core/theme.js +135 -141
  175. package/core/theme_manager.js +147 -143
  176. package/core/toolbox/category.js +602 -576
  177. package/core/toolbox/collapsible_category.js +226 -227
  178. package/core/toolbox/separator.js +70 -61
  179. package/core/toolbox/toolbox.js +934 -927
  180. package/core/toolbox/toolbox_item.js +115 -99
  181. package/core/tooltip.js +108 -35
  182. package/core/touch.js +8 -3
  183. package/core/touch_gesture.js +254 -251
  184. package/core/trashcan.js +606 -595
  185. package/core/utils/coordinate.js +97 -95
  186. package/core/utils/dom.js +2 -2
  187. package/core/utils/global.js +2 -0
  188. package/core/utils/rect.js +41 -37
  189. package/core/utils/sentinel.js +25 -0
  190. package/core/utils/size.js +30 -27
  191. package/core/utils/svg.js +18 -16
  192. package/core/variable_map.js +325 -341
  193. package/core/variable_model.js +55 -54
  194. package/core/variables.js +9 -2
  195. package/core/variables_dynamic.js +3 -1
  196. package/core/warning.js +126 -120
  197. package/core/widgetdiv.js +4 -4
  198. package/core/workspace.js +685 -664
  199. package/core/workspace_audio.js +124 -118
  200. package/core/workspace_comment.js +308 -298
  201. package/core/workspace_comment_svg.js +1029 -951
  202. package/core/workspace_drag_surface_svg.js +147 -140
  203. package/core/workspace_dragger.js +70 -71
  204. package/core/workspace_svg.js +2322 -2297
  205. package/core/xml.js +30 -20
  206. package/core/zoom_controls.js +431 -439
  207. package/dart_compressed.js +40 -43
  208. package/dart_compressed.js.map +1 -1
  209. package/generators/dart/colour.js +56 -64
  210. package/generators/dart/lists.js +61 -50
  211. package/generators/dart/math.js +160 -148
  212. package/generators/dart/text.js +83 -61
  213. package/generators/javascript/colour.js +37 -34
  214. package/generators/javascript/lists.js +50 -43
  215. package/generators/javascript/math.js +123 -139
  216. package/generators/javascript/text.js +67 -81
  217. package/generators/lua/colour.js +25 -23
  218. package/generators/lua/lists.js +97 -69
  219. package/generators/lua/logic.js +1 -2
  220. package/generators/lua/math.js +182 -144
  221. package/generators/lua/text.js +116 -99
  222. package/generators/php/colour.js +38 -32
  223. package/generators/php/lists.js +109 -89
  224. package/generators/php/math.js +90 -81
  225. package/generators/php/text.js +63 -61
  226. package/generators/python/colour.js +18 -18
  227. package/generators/python/lists.js +38 -30
  228. package/generators/python/loops.js +12 -8
  229. package/generators/python/math.js +104 -106
  230. package/generators/python/text.js +34 -30
  231. package/javascript_compressed.js +37 -39
  232. package/javascript_compressed.js.map +1 -1
  233. package/lua_compressed.js +39 -42
  234. package/lua_compressed.js.map +1 -1
  235. package/msg/az.js +2 -2
  236. package/msg/be.js +4 -4
  237. package/msg/cs.js +15 -15
  238. package/msg/de.js +1 -1
  239. package/msg/diq.js +1 -1
  240. package/msg/eo.js +1 -1
  241. package/msg/es.js +1 -1
  242. package/msg/fa.js +1 -1
  243. package/msg/fr.js +4 -4
  244. package/msg/he.js +1 -1
  245. package/msg/hr.js +2 -2
  246. package/msg/hy.js +2 -2
  247. package/msg/id.js +12 -12
  248. package/msg/inh.js +14 -14
  249. package/msg/ja.js +7 -7
  250. package/msg/lv.js +29 -29
  251. package/msg/pa.js +3 -3
  252. package/msg/smn.js +436 -0
  253. package/msg/te.js +1 -1
  254. package/msg/yue.js +1 -1
  255. package/msg/zh-hans.js +3 -3
  256. package/msg/zh-hant.js +3 -3
  257. package/package.json +7 -6
  258. package/php_compressed.js +38 -42
  259. package/php_compressed.js.map +1 -1
  260. package/python_compressed.js +26 -25
  261. package/python_compressed.js.map +1 -1
  262. package/blocks/all.js +0 -23
@@ -42,7 +42,7 @@ Dart['math_arithmetic'] = function(block) {
42
42
  'MINUS': [' - ', Dart.ORDER_ADDITIVE],
43
43
  'MULTIPLY': [' * ', Dart.ORDER_MULTIPLICATIVE],
44
44
  'DIVIDE': [' / ', Dart.ORDER_MULTIPLICATIVE],
45
- 'POWER': [null, Dart.ORDER_NONE] // Handle power separately.
45
+ 'POWER': [null, Dart.ORDER_NONE], // Handle power separately.
46
46
  };
47
47
  const tuple = OPERATORS[block.getFieldValue('OP')];
48
48
  const operator = tuple[0];
@@ -152,7 +152,7 @@ Dart['math_constant'] = function(block) {
152
152
  'GOLDEN_RATIO': ['(1 + Math.sqrt(5)) / 2', Dart.ORDER_MULTIPLICATIVE],
153
153
  'SQRT2': ['Math.sqrt2', Dart.ORDER_UNARY_POSTFIX],
154
154
  'SQRT1_2': ['Math.sqrt1_2', Dart.ORDER_UNARY_POSTFIX],
155
- 'INFINITY': ['double.infinity', Dart.ORDER_ATOMIC]
155
+ 'INFINITY': ['double.infinity', Dart.ORDER_ATOMIC],
156
156
  };
157
157
  const constant = block.getFieldValue('CONSTANT');
158
158
  if (constant !== 'INFINITY') {
@@ -164,59 +164,56 @@ Dart['math_constant'] = function(block) {
164
164
  Dart['math_number_property'] = function(block) {
165
165
  // Check if a number is even, odd, prime, whole, positive, or negative
166
166
  // or if it is divisible by certain number. Returns true or false.
167
- const number_to_check =
168
- Dart.valueToCode(block, 'NUMBER_TO_CHECK', Dart.ORDER_MULTIPLICATIVE);
169
- if (!number_to_check) {
170
- return ['false', Dart.ORDER_ATOMIC];
171
- }
172
- const dropdown_property = block.getFieldValue('PROPERTY');
167
+ const PROPERTIES = {
168
+ 'EVEN': [' % 2 == 0', Dart.ORDER_MULTIPLICATIVE, Dart.ORDER_EQUALITY],
169
+ 'ODD': [' % 2 == 1', Dart.ORDER_MULTIPLICATIVE, Dart.ORDER_EQUALITY],
170
+ 'WHOLE': [' % 1 == 0', Dart.ORDER_MULTIPLICATIVE, Dart.ORDER_EQUALITY],
171
+ 'POSITIVE': [' > 0', Dart.ORDER_RELATIONAL, Dart.ORDER_RELATIONAL],
172
+ 'NEGATIVE': [' < 0', Dart.ORDER_RELATIONAL, Dart.ORDER_RELATIONAL],
173
+ 'DIVISIBLE_BY': [null, Dart.ORDER_MULTIPLICATIVE, Dart.ORDER_EQUALITY],
174
+ 'PRIME': [null, Dart.ORDER_NONE, Dart.ORDER_UNARY_POSTFIX],
175
+ };
176
+ const dropdownProperty = block.getFieldValue('PROPERTY');
177
+ const [suffix, inputOrder, outputOrder] = PROPERTIES[dropdownProperty];
178
+ const numberToCheck = Dart.valueToCode(block, 'NUMBER_TO_CHECK',
179
+ inputOrder) || '0';
173
180
  let code;
174
- if (dropdown_property === 'PRIME') {
181
+ if (dropdownProperty === 'PRIME') {
175
182
  // Prime is a special case as it is not a one-liner test.
176
- Dart.definitions_['import_dart_math'] = 'import \'dart:math\' as Math;';
177
- const functionName = Dart.provideFunction_('math_isPrime', [
178
- 'bool ' + Dart.FUNCTION_NAME_PLACEHOLDER_ + '(n) {',
179
- ' // https://en.wikipedia.org/wiki/Primality_test#Naive_methods',
180
- ' if (n == 2 || n == 3) {', ' return true;', ' }',
181
- ' // False if n is null, negative, is 1, or not whole.',
182
- ' // And false if n is divisible by 2 or 3.',
183
- ' if (n == null || n <= 1 || n % 1 != 0 || n % 2 == 0 ||' +
184
- ' n % 3 == 0) {',
185
- ' return false;', ' }',
186
- ' // Check all the numbers of form 6k +/- 1, up to sqrt(n).',
187
- ' for (var x = 6; x <= Math.sqrt(n) + 1; x += 6) {',
188
- ' if (n % (x - 1) == 0 || n % (x + 1) == 0) {', ' return false;',
189
- ' }', ' }', ' return true;', '}'
190
- ]);
191
- code = functionName + '(' + number_to_check + ')';
192
- return [code, Dart.ORDER_UNARY_POSTFIX];
183
+ Dart.definitions_['import_dart_math'] =
184
+ 'import \'dart:math\' as Math;';
185
+ const functionName = Dart.provideFunction_('math_isPrime', `
186
+ bool ${Dart.FUNCTION_NAME_PLACEHOLDER_}(n) {
187
+ // https://en.wikipedia.org/wiki/Primality_test#Naive_methods
188
+ if (n == 2 || n == 3) {
189
+ return true;
193
190
  }
194
- switch (dropdown_property) {
195
- case 'EVEN':
196
- code = number_to_check + ' % 2 == 0';
197
- break;
198
- case 'ODD':
199
- code = number_to_check + ' % 2 == 1';
200
- break;
201
- case 'WHOLE':
202
- code = number_to_check + ' % 1 == 0';
203
- break;
204
- case 'POSITIVE':
205
- code = number_to_check + ' > 0';
206
- break;
207
- case 'NEGATIVE':
208
- code = number_to_check + ' < 0';
209
- break;
210
- case 'DIVISIBLE_BY':
211
- const divisor =
212
- Dart.valueToCode(block, 'DIVISOR', Dart.ORDER_MULTIPLICATIVE);
213
- if (!divisor) {
214
- return ['false', Dart.ORDER_ATOMIC];
215
- }
216
- code = number_to_check + ' % ' + divisor + ' == 0';
217
- break;
191
+ // False if n is null, negative, is 1, or not whole.
192
+ // And false if n is divisible by 2 or 3.
193
+ if (n == null || n <= 1 || n % 1 != 0 || n % 2 == 0 || n % 3 == 0) {
194
+ return false;
195
+ }
196
+ // Check all the numbers of form 6k +/- 1, up to sqrt(n).
197
+ for (var x = 6; x <= Math.sqrt(n) + 1; x += 6) {
198
+ if (n % (x - 1) == 0 || n % (x + 1) == 0) {
199
+ return false;
200
+ }
218
201
  }
219
- return [code, Dart.ORDER_EQUALITY];
202
+ return true;
203
+ }
204
+ `);
205
+ code = functionName + '(' + numberToCheck + ')';
206
+ } else if (dropdownProperty === 'DIVISIBLE_BY') {
207
+ const divisor = Dart.valueToCode(block, 'DIVISOR',
208
+ Dart.ORDER_MULTIPLICATIVE) || '0';
209
+ if (divisor === '0') {
210
+ return ['false', Dart.ORDER_ATOMIC];
211
+ }
212
+ code = numberToCheck + ' % ' + divisor + ' == 0';
213
+ } else {
214
+ code = numberToCheck + suffix;
215
+ }
216
+ return [code, outputOrder];
220
217
  };
221
218
 
222
219
  Dart['math_change'] = function(block) {
@@ -241,70 +238,76 @@ Dart['math_on_list'] = function(block) {
241
238
  let code;
242
239
  switch (func) {
243
240
  case 'SUM': {
244
- const functionName = Dart.provideFunction_('math_sum', [
245
- 'num ' + Dart.FUNCTION_NAME_PLACEHOLDER_ + '(List<num> myList) {',
246
- ' num sumVal = 0;',
247
- ' myList.forEach((num entry) {sumVal += entry;});', ' return sumVal;',
248
- '}'
249
- ]);
241
+ const functionName = Dart.provideFunction_('math_sum', `
242
+ num ${Dart.FUNCTION_NAME_PLACEHOLDER_}(List<num> myList) {
243
+ num sumVal = 0;
244
+ myList.forEach((num entry) {sumVal += entry;});
245
+ return sumVal;
246
+ }
247
+ `);
250
248
  code = functionName + '(' + list + ')';
251
249
  break;
252
250
  }
253
251
  case 'MIN': {
254
252
  Dart.definitions_['import_dart_math'] = 'import \'dart:math\' as Math;';
255
- const functionName = Dart.provideFunction_('math_min', [
256
- 'num ' + Dart.FUNCTION_NAME_PLACEHOLDER_ + '(List<num> myList) {',
257
- ' if (myList.isEmpty) return null;', ' num minVal = myList[0];',
258
- ' myList.forEach((num entry) ' +
259
- '{minVal = Math.min(minVal, entry);});',
260
- ' return minVal;', '}'
261
- ]);
253
+ const functionName = Dart.provideFunction_('math_min', `
254
+ num ${Dart.FUNCTION_NAME_PLACEHOLDER_}(List<num> myList) {
255
+ if (myList.isEmpty) return null;
256
+ num minVal = myList[0];
257
+ myList.forEach((num entry) {minVal = Math.min(minVal, entry);});
258
+ return minVal;
259
+ }
260
+ `);
262
261
  code = functionName + '(' + list + ')';
263
262
  break;
264
263
  }
265
264
  case 'MAX': {
266
265
  Dart.definitions_['import_dart_math'] = 'import \'dart:math\' as Math;';
267
- const functionName = Dart.provideFunction_('math_max', [
268
- 'num ' + Dart.FUNCTION_NAME_PLACEHOLDER_ + '(List<num> myList) {',
269
- ' if (myList.isEmpty) return null;', ' num maxVal = myList[0];',
270
- ' myList.forEach((num entry) ' +
271
- '{maxVal = Math.max(maxVal, entry);});',
272
- ' return maxVal;', '}'
273
- ]);
266
+ const functionName = Dart.provideFunction_('math_max', `
267
+ num ${Dart.FUNCTION_NAME_PLACEHOLDER_}(List<num> myList) {
268
+ if (myList.isEmpty) return null;
269
+ num maxVal = myList[0];
270
+ myList.forEach((num entry) {maxVal = Math.max(maxVal, entry);});
271
+ return maxVal;
272
+ }
273
+ `);
274
274
  code = functionName + '(' + list + ')';
275
275
  break;
276
276
  }
277
277
  case 'AVERAGE': {
278
278
  // This operation exclude null and values that are not int or float:
279
279
  // math_mean([null,null,"aString",1,9]) -> 5.0
280
- const functionName = Dart.provideFunction_('math_mean', [
281
- 'num ' + Dart.FUNCTION_NAME_PLACEHOLDER_ + '(List myList) {',
282
- ' // First filter list for numbers only.',
283
- ' List localList = new List.from(myList);',
284
- ' localList.removeWhere((a) => a is! num);',
285
- ' if (localList.isEmpty) return null;', ' num sumVal = 0;',
286
- ' localList.forEach((var entry) {sumVal += entry;});',
287
- ' return sumVal / localList.length;', '}'
288
- ]);
280
+ const functionName = Dart.provideFunction_('math_mean', `
281
+ num ${Dart.FUNCTION_NAME_PLACEHOLDER_}(List myList) {
282
+ // First filter list for numbers only.
283
+ List localList = new List.from(myList);
284
+ localList.removeWhere((a) => a is! num);
285
+ if (localList.isEmpty) return null;
286
+ num sumVal = 0;
287
+ localList.forEach((var entry) {sumVal += entry;});
288
+ return sumVal / localList.length;
289
+ }
290
+ `);
289
291
  code = functionName + '(' + list + ')';
290
292
  break;
291
293
  }
292
294
  case 'MEDIAN': {
293
- const functionName = Dart.provideFunction_('math_median', [
294
- 'num ' + Dart.FUNCTION_NAME_PLACEHOLDER_ + '(List myList) {',
295
- ' // First filter list for numbers only, then sort, ' +
296
- 'then return middle value',
297
- ' // or the average of two middle values if list has an ' +
298
- 'even number of elements.',
299
- ' List localList = new List.from(myList);',
300
- ' localList.removeWhere((a) => a is! num);',
301
- ' if (localList.isEmpty) return null;',
302
- ' localList.sort((a, b) => (a - b));',
303
- ' int index = localList.length ~/ 2;',
304
- ' if (localList.length % 2 == 1) {', ' return localList[index];',
305
- ' } else {',
306
- ' return (localList[index - 1] + localList[index]) / 2;', ' }', '}'
307
- ]);
295
+ const functionName = Dart.provideFunction_('math_median', `
296
+ num ${Dart.FUNCTION_NAME_PLACEHOLDER_}(List myList) {
297
+ // First filter list for numbers only, then sort, then return middle value
298
+ // or the average of two middle values if list has an even number of elements.
299
+ List localList = new List.from(myList);
300
+ localList.removeWhere((a) => a is! num);
301
+ if (localList.isEmpty) return null;
302
+ localList.sort((a, b) => (a - b));
303
+ int index = localList.length ~/ 2;
304
+ if (localList.length % 2 == 1) {
305
+ return localList[index];
306
+ } else {
307
+ return (localList[index - 1] + localList[index]) / 2;
308
+ }
309
+ }
310
+ `);
308
311
  code = functionName + '(' + list + ')';
309
312
  break;
310
313
  }
@@ -313,63 +316,67 @@ Dart['math_on_list'] = function(block) {
313
316
  // As a list of numbers can contain more than one mode,
314
317
  // the returned result is provided as an array.
315
318
  // Mode of [3, 'x', 'x', 1, 1, 2, '3'] -> ['x', 1]
316
- const functionName = Dart.provideFunction_('math_modes', [
317
- 'List ' + Dart.FUNCTION_NAME_PLACEHOLDER_ + '(List values) {',
318
- ' List modes = [];',
319
- ' List counts = [];',
320
- ' int maxCount = 0;',
321
- ' for (int i = 0; i < values.length; i++) {',
322
- ' var value = values[i];',
323
- ' bool found = false;',
324
- ' int thisCount;',
325
- ' for (int j = 0; j < counts.length; j++) {',
326
- ' if (counts[j][0] == value) {',
327
- ' thisCount = ++counts[j][1];',
328
- ' found = true;',
329
- ' break;',
330
- ' }',
331
- ' }',
332
- ' if (!found) {',
333
- ' counts.add([value, 1]);',
334
- ' thisCount = 1;',
335
- ' }',
336
- ' maxCount = Math.max(thisCount, maxCount);',
337
- ' }',
338
- ' for (int j = 0; j < counts.length; j++) {',
339
- ' if (counts[j][1] == maxCount) {',
340
- ' modes.add(counts[j][0]);',
341
- ' }',
342
- ' }',
343
- ' return modes;',
344
- '}'
345
- ]);
319
+ const functionName = Dart.provideFunction_('math_modes', `
320
+ List ${Dart.FUNCTION_NAME_PLACEHOLDER_}(List values) {
321
+ List modes = [];
322
+ List counts = [];
323
+ int maxCount = 0;
324
+ for (int i = 0; i < values.length; i++) {
325
+ var value = values[i];
326
+ bool found = false;
327
+ int thisCount;
328
+ for (int j = 0; j < counts.length; j++) {
329
+ if (counts[j][0] == value) {
330
+ thisCount = ++counts[j][1];
331
+ found = true;
332
+ break;
333
+ }
334
+ }
335
+ if (!found) {
336
+ counts.add([value, 1]);
337
+ thisCount = 1;
338
+ }
339
+ maxCount = Math.max(thisCount, maxCount);
340
+ }
341
+ for (int j = 0; j < counts.length; j++) {
342
+ if (counts[j][1] == maxCount) {
343
+ modes.add(counts[j][0]);
344
+ }
345
+ }
346
+ return modes;
347
+ }
348
+ `);
346
349
  code = functionName + '(' + list + ')';
347
350
  break;
348
351
  }
349
352
  case 'STD_DEV': {
350
353
  Dart.definitions_['import_dart_math'] = 'import \'dart:math\' as Math;';
351
- const functionName = Dart.provideFunction_('math_standard_deviation', [
352
- 'num ' + Dart.FUNCTION_NAME_PLACEHOLDER_ + '(List myList) {',
353
- ' // First filter list for numbers only.',
354
- ' List numbers = new List.from(myList);',
355
- ' numbers.removeWhere((a) => a is! num);',
356
- ' if (numbers.isEmpty) return null;', ' num n = numbers.length;',
357
- ' num sum = 0;', ' numbers.forEach((x) => sum += x);',
358
- ' num mean = sum / n;', ' num sumSquare = 0;',
359
- ' numbers.forEach((x) => sumSquare += ' +
360
- 'Math.pow(x - mean, 2));',
361
- ' return Math.sqrt(sumSquare / n);', '}'
362
- ]);
354
+ const functionName = Dart.provideFunction_('math_standard_deviation', `
355
+ num ${Dart.FUNCTION_NAME_PLACEHOLDER_}(List myList) {
356
+ // First filter list for numbers only.
357
+ List numbers = new List.from(myList);
358
+ numbers.removeWhere((a) => a is! num);
359
+ if (numbers.isEmpty) return null;
360
+ num n = numbers.length;
361
+ num sum = 0;
362
+ numbers.forEach((x) => sum += x);
363
+ num mean = sum / n;
364
+ num sumSquare = 0;
365
+ numbers.forEach((x) => sumSquare += Math.pow(x - mean, 2));
366
+ return Math.sqrt(sumSquare / n);
367
+ }
368
+ `);
363
369
  code = functionName + '(' + list + ')';
364
370
  break;
365
371
  }
366
372
  case 'RANDOM': {
367
373
  Dart.definitions_['import_dart_math'] = 'import \'dart:math\' as Math;';
368
- const functionName = Dart.provideFunction_('math_random_item', [
369
- 'dynamic ' + Dart.FUNCTION_NAME_PLACEHOLDER_ + '(List myList) {',
370
- ' int x = new Math.Random().nextInt(myList.length);',
371
- ' return myList[x];', '}'
372
- ]);
374
+ const functionName = Dart.provideFunction_('math_random_item', `
375
+ dynamic ${Dart.FUNCTION_NAME_PLACEHOLDER_}(List myList) {
376
+ int x = new Math.Random().nextInt(myList.length);
377
+ return myList[x];
378
+ }
379
+ `);
373
380
  code = functionName + '(' + list + ')';
374
381
  break;
375
382
  }
@@ -406,12 +413,17 @@ Dart['math_random_int'] = function(block) {
406
413
  Dart.definitions_['import_dart_math'] = 'import \'dart:math\' as Math;';
407
414
  const argument0 = Dart.valueToCode(block, 'FROM', Dart.ORDER_NONE) || '0';
408
415
  const argument1 = Dart.valueToCode(block, 'TO', Dart.ORDER_NONE) || '0';
409
- const functionName = Dart.provideFunction_('math_random_int', [
410
- 'int ' + Dart.FUNCTION_NAME_PLACEHOLDER_ + '(num a, num b) {',
411
- ' if (a > b) {', ' // Swap a and b to ensure a is smaller.',
412
- ' num c = a;', ' a = b;', ' b = c;', ' }',
413
- ' return new Math.Random().nextInt(b - a + 1) + a;', '}'
414
- ]);
416
+ const functionName = Dart.provideFunction_('math_random_int', `
417
+ int ${Dart.FUNCTION_NAME_PLACEHOLDER_}(num a, num b) {
418
+ if (a > b) {
419
+ // Swap a and b to ensure a is smaller.
420
+ num c = a;
421
+ a = b;
422
+ b = c;
423
+ }
424
+ return new Math.Random().nextInt(b - a + 1) + a;
425
+ }
426
+ `);
415
427
  const code = functionName + '(' + argument0 + ', ' + argument1 + ')';
416
428
  return [code, Dart.ORDER_UNARY_POSTFIX];
417
429
  };