trln-chosen-rails 1.30.0.pre.beta → 1.30.0.pre.beta3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,650 @@
1
+ /*
2
+ * decaffeinate suggestions:
3
+ * DS101: Remove unnecessary use of Array.from
4
+ * DS102: Remove unnecessary code created because of implicit returns
5
+ * DS103: Rewrite code to no longer use __guard__, or convert again using --optional-chaining
6
+ * DS205: Consider reworking code to avoid use of IIFEs
7
+ * DS206: Consider reworking classes to avoid initClass
8
+ * DS207: Consider shorter variations of null checks
9
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
10
+ */
11
+ (function() {
12
+ let triggerHtmlEvent = undefined;
13
+ const Cls = (this.Chosen = class Chosen extends AbstractChosen {
14
+ static initClass() {
15
+
16
+ triggerHtmlEvent = function(element, eventType) {
17
+ if (element.dispatchEvent) { // Modern way:
18
+ let evt;
19
+ try {
20
+ evt = new Event(eventType, {bubbles: true, cancelable: true});
21
+ } catch (error) {
22
+ evt = document.createEvent('HTMLEvents');
23
+ evt.initEvent(eventType, true, true);
24
+ }
25
+ return element.dispatchEvent(evt);
26
+ } else { // Old IE:
27
+ return element.fireEvent(`on${eventType}`, document.createEventObject());
28
+ }
29
+ };
30
+ }
31
+
32
+ setup() {
33
+ return this.current_selectedIndex = this.form_field.selectedIndex;
34
+ }
35
+
36
+ set_up_html() {
37
+ const container_classes = ["chosen-container"];
38
+ container_classes.push("chosen-container-" + (this.is_multiple ? "multi" : "single"));
39
+ if (this.inherit_select_classes && this.form_field.className) { container_classes.push(this.form_field.className); }
40
+ if (this.is_rtl) { container_classes.push("chosen-rtl"); }
41
+
42
+ const container_props = {
43
+ 'class': container_classes.join(' '),
44
+ 'title': this.form_field.title
45
+ };
46
+
47
+ if (this.form_field.id.length) { container_props.id = this.form_field.id.replace(/[^\w]/g, '_') + "_chosen"; }
48
+
49
+ this.container = new Element('div', container_props);
50
+
51
+ // CSP without 'unsafe-inline' doesn't allow setting the style attribute directly
52
+ this.container.setStyle({width: this.container_width()});
53
+
54
+ if (this.is_multiple) {
55
+ this.container.update(this.get_multi_html());
56
+ } else {
57
+ this.container.update(this.get_single_html());
58
+ }
59
+
60
+ this.form_field.hide().insert({ after: this.container });
61
+ this.dropdown = this.container.down('div.chosen-drop');
62
+
63
+ this.search_field = this.container.down('input');
64
+ this.search_results = this.container.down('ul.chosen-results');
65
+ this.search_field_scale();
66
+
67
+ this.search_no_results = this.container.down('li.no-results');
68
+
69
+ if (this.is_multiple) {
70
+ this.search_choices = this.container.down('ul.chosen-choices');
71
+ this.search_container = this.container.down('li.search-field');
72
+ } else {
73
+ this.search_container = this.container.down('div.chosen-search');
74
+ this.selected_item = this.container.down('.chosen-single');
75
+ }
76
+
77
+ this.results_build();
78
+ this.set_tab_index();
79
+ return this.set_label_behavior();
80
+ }
81
+
82
+ on_ready() {
83
+ return this.form_field.fire("chosen:ready", {chosen: this});
84
+ }
85
+
86
+ register_observers() {
87
+ this.container.observe("touchstart", evt => this.container_mousedown(evt));
88
+ this.container.observe("touchend", evt => this.container_mouseup(evt));
89
+
90
+ this.container.observe("mousedown", evt => this.container_mousedown(evt));
91
+ this.container.observe("mouseup", evt => this.container_mouseup(evt));
92
+ this.container.observe("mouseenter", evt => this.mouse_enter(evt));
93
+ this.container.observe("mouseleave", evt => this.mouse_leave(evt));
94
+
95
+ this.search_results.observe("mouseup", evt => this.search_results_mouseup(evt));
96
+ this.search_results.observe("mouseover", evt => this.search_results_mouseover(evt));
97
+ this.search_results.observe("mouseout", evt => this.search_results_mouseout(evt));
98
+ this.search_results.observe("mousewheel", evt => this.search_results_mousewheel(evt));
99
+ this.search_results.observe("DOMMouseScroll", evt => this.search_results_mousewheel(evt));
100
+
101
+ this.search_results.observe("touchstart", evt => this.search_results_touchstart(evt));
102
+ this.search_results.observe("touchmove", evt => this.search_results_touchmove(evt));
103
+ this.search_results.observe("touchend", evt => this.search_results_touchend(evt));
104
+
105
+ this.form_field.observe("chosen:updated", evt => this.results_update_field(evt));
106
+ this.form_field.observe("chosen:activate", evt => this.activate_field(evt));
107
+ this.form_field.observe("chosen:open", evt => this.container_mousedown(evt));
108
+ this.form_field.observe("chosen:close", evt => this.close_field(evt));
109
+
110
+ this.search_field.observe("blur", evt => this.input_blur(evt));
111
+ this.search_field.observe("keyup", evt => this.keyup_checker(evt));
112
+ this.search_field.observe("keydown", evt => this.keydown_checker(evt));
113
+ this.search_field.observe("focus", evt => this.input_focus(evt));
114
+ this.search_field.observe("cut", evt => this.clipboard_event_checker(evt));
115
+ this.search_field.observe("paste", evt => this.clipboard_event_checker(evt));
116
+
117
+ if (this.is_multiple) {
118
+ return this.search_choices.observe("click", evt => this.choices_click(evt));
119
+ } else {
120
+ return this.container.observe("click", evt => evt.preventDefault()); // gobble click of anchor
121
+ }
122
+ }
123
+
124
+ destroy() {
125
+ this.container.ownerDocument.stopObserving("click", this.click_test_action);
126
+
127
+ for (var event of ['chosen:updated', 'chosen:activate', 'chosen:open', 'chosen:close']) {
128
+ this.form_field.stopObserving(event);
129
+ }
130
+
131
+ this.container.stopObserving();
132
+ this.search_results.stopObserving();
133
+ this.search_field.stopObserving();
134
+ if (this.form_field_label != null) { this.form_field_label.stopObserving(); }
135
+
136
+ if (this.is_multiple) {
137
+ this.search_choices.stopObserving();
138
+ this.container.select(".search-choice-close").each(choice => choice.stopObserving());
139
+ } else {
140
+ this.selected_item.stopObserving();
141
+ }
142
+
143
+ if (this.search_field.tabIndex) {
144
+ this.form_field.tabIndex = this.search_field.tabIndex;
145
+ }
146
+
147
+ this.container.remove();
148
+ return this.form_field.show();
149
+ }
150
+
151
+ search_field_disabled() {
152
+ this.is_disabled = this.form_field.disabled || __guard__(this.form_field.up('fieldset'), x => x.disabled) || false;
153
+
154
+ if (this.is_disabled) {
155
+ this.container.addClassName('chosen-disabled');
156
+ } else {
157
+ this.container.removeClassName('chosen-disabled');
158
+ }
159
+
160
+ this.search_field.disabled = this.is_disabled;
161
+
162
+ if (!this.is_multiple) {
163
+ this.selected_item.stopObserving('focus', this.activate_field);
164
+ }
165
+
166
+ if (this.is_disabled) {
167
+ return this.close_field();
168
+ } else if (!this.is_multiple) {
169
+ return this.selected_item.observe('focus', this.activate_field);
170
+ }
171
+ }
172
+
173
+ container_mousedown(evt) {
174
+ if (this.is_disabled) { return; }
175
+
176
+ if (evt && ['mousedown', 'touchstart'].includes(evt.type) && !this.results_showing) {
177
+ evt.preventDefault();
178
+ }
179
+
180
+ if (!((evt != null) && evt.target.hasClassName("search-choice-close"))) {
181
+ if (!this.active_field) {
182
+ if (this.is_multiple) { this.search_field.clear(); }
183
+ this.container.ownerDocument.observe("click", this.click_test_action);
184
+ this.results_show();
185
+ } else if (!this.is_multiple && evt && ((evt.target === this.selected_item) || evt.target.up("a.chosen-single"))) {
186
+ this.results_toggle();
187
+ }
188
+
189
+ return this.activate_field();
190
+ }
191
+ }
192
+
193
+ container_mouseup(evt) {
194
+ if ((evt.target.nodeName === "ABBR") && !this.is_disabled) { return this.results_reset(evt); }
195
+ }
196
+
197
+ search_results_mousewheel(evt) {
198
+ let delta = evt.deltaY || -evt.wheelDelta || evt.detail;
199
+ if (delta != null) {
200
+ evt.preventDefault();
201
+ if (evt.type === 'DOMMouseScroll') { delta = delta * 40; }
202
+ return this.search_results.scrollTop = delta + this.search_results.scrollTop;
203
+ }
204
+ }
205
+
206
+ blur_test(evt) {
207
+ if (!this.active_field && this.container.hasClassName("chosen-container-active")) { return this.close_field(); }
208
+ }
209
+
210
+ close_field() {
211
+ this.container.ownerDocument.stopObserving("click", this.click_test_action);
212
+
213
+ this.active_field = false;
214
+ this.results_hide();
215
+
216
+ this.container.removeClassName("chosen-container-active");
217
+ this.clear_backstroke();
218
+
219
+ this.show_search_field_default();
220
+ this.search_field_scale();
221
+ return this.search_field.blur();
222
+ }
223
+
224
+ activate_field() {
225
+ if (this.is_disabled) { return; }
226
+
227
+ this.container.addClassName("chosen-container-active");
228
+ this.active_field = true;
229
+
230
+ this.search_field.value = this.get_search_field_value();
231
+ return this.search_field.focus();
232
+ }
233
+
234
+ test_active_click(evt) {
235
+ if (evt.target.up('.chosen-container') === this.container) {
236
+ return this.active_field = true;
237
+ } else {
238
+ return this.close_field();
239
+ }
240
+ }
241
+
242
+ results_build() {
243
+ this.parsing = true;
244
+ this.selected_option_count = null;
245
+
246
+ this.results_data = SelectParser.select_to_array(this.form_field);
247
+
248
+ if (this.is_multiple) {
249
+ this.search_choices.select("li.search-choice").invoke("remove");
250
+ } else {
251
+ this.single_set_selected_text();
252
+ if (this.disable_search || (this.form_field.options.length <= this.disable_search_threshold)) {
253
+ this.search_field.readOnly = true;
254
+ this.container.addClassName("chosen-container-single-nosearch");
255
+ } else {
256
+ this.search_field.readOnly = false;
257
+ this.container.removeClassName("chosen-container-single-nosearch");
258
+ }
259
+ }
260
+
261
+ this.update_results_content(this.results_option_build({first:true}));
262
+
263
+ this.search_field_disabled();
264
+ this.show_search_field_default();
265
+ this.search_field_scale();
266
+
267
+ return this.parsing = false;
268
+ }
269
+
270
+ result_do_highlight(el) {
271
+ this.result_clear_highlight();
272
+
273
+ this.result_highlight = el;
274
+ this.result_highlight.addClassName("highlighted");
275
+
276
+ const maxHeight = parseInt(this.search_results.getStyle('maxHeight'), 10);
277
+ const visible_top = this.search_results.scrollTop;
278
+ const visible_bottom = maxHeight + visible_top;
279
+
280
+ const high_top = this.result_highlight.positionedOffset().top;
281
+ const high_bottom = high_top + this.result_highlight.getHeight();
282
+
283
+ if (high_bottom >= visible_bottom) {
284
+ return this.search_results.scrollTop = (high_bottom - maxHeight) > 0 ? (high_bottom - maxHeight) : 0;
285
+ } else if (high_top < visible_top) {
286
+ return this.search_results.scrollTop = high_top;
287
+ }
288
+ }
289
+
290
+ result_clear_highlight() {
291
+ if (this.result_highlight) { this.result_highlight.removeClassName('highlighted'); }
292
+ return this.result_highlight = null;
293
+ }
294
+
295
+ results_show() {
296
+ if (this.is_multiple && (this.max_selected_options <= this.choices_count())) {
297
+ this.form_field.fire("chosen:maxselected", {chosen: this});
298
+ return false;
299
+ }
300
+
301
+ this.container.addClassName("chosen-with-drop");
302
+ this.results_showing = true;
303
+
304
+ this.search_field.focus();
305
+ this.search_field.value = this.get_search_field_value();
306
+
307
+ this.winnow_results();
308
+ return this.form_field.fire("chosen:showing_dropdown", {chosen: this});
309
+ }
310
+
311
+ update_results_content(content) {
312
+ return this.search_results.update(content);
313
+ }
314
+
315
+ results_hide() {
316
+ if (this.results_showing) {
317
+ this.result_clear_highlight();
318
+
319
+ this.container.removeClassName("chosen-with-drop");
320
+ this.form_field.fire("chosen:hiding_dropdown", {chosen: this});
321
+ }
322
+
323
+ return this.results_showing = false;
324
+ }
325
+
326
+
327
+ set_tab_index(el) {
328
+ if (this.form_field.tabIndex) {
329
+ const ti = this.form_field.tabIndex;
330
+ this.form_field.tabIndex = -1;
331
+ return this.search_field.tabIndex = ti;
332
+ }
333
+ }
334
+
335
+ set_label_behavior() {
336
+ this.form_field_label = this.form_field.up("label"); // first check for a parent label
337
+ if ((this.form_field_label == null)) {
338
+ this.form_field_label = $$(`label[for='${this.form_field.id}']`).first(); //next check for a for=#{id}
339
+ }
340
+
341
+ if (this.form_field_label != null) {
342
+ return this.form_field_label.observe("click", this.label_click_handler);
343
+ }
344
+ }
345
+
346
+ show_search_field_default() {
347
+ if (this.is_multiple && (this.choices_count() < 1) && !this.active_field) {
348
+ this.search_field.value = this.default_text;
349
+ return this.search_field.addClassName("default");
350
+ } else {
351
+ this.search_field.value = "";
352
+ return this.search_field.removeClassName("default");
353
+ }
354
+ }
355
+
356
+ search_results_mouseup(evt) {
357
+ const target = evt.target.hasClassName("active-result") ? evt.target : evt.target.up(".active-result");
358
+ if (target) {
359
+ this.result_highlight = target;
360
+ this.result_select(evt);
361
+ return this.search_field.focus();
362
+ }
363
+ }
364
+
365
+ search_results_mouseover(evt) {
366
+ const target = evt.target.hasClassName("active-result") ? evt.target : evt.target.up(".active-result");
367
+ if (target) { return this.result_do_highlight( target ); }
368
+ }
369
+
370
+ search_results_mouseout(evt) {
371
+ if (evt.target.hasClassName('active-result') || evt.target.up('.active-result')) { return this.result_clear_highlight(); }
372
+ }
373
+
374
+ choice_build(item) {
375
+ const choice = new Element('li', { class: "search-choice" }).update(`<span>${this.choice_label(item)}</span>`);
376
+
377
+ if (item.disabled) {
378
+ choice.addClassName('search-choice-disabled');
379
+ } else {
380
+ const close_link = new Element('a', { href: '#', class: 'search-choice-close', rel: item.array_index });
381
+ close_link.observe("click", evt => this.choice_destroy_link_click(evt));
382
+ choice.insert(close_link);
383
+ }
384
+
385
+ return this.search_container.insert({ before: choice });
386
+ }
387
+
388
+ choice_destroy_link_click(evt) {
389
+ evt.preventDefault();
390
+ evt.stopPropagation();
391
+ if (!this.is_disabled) { return this.choice_destroy(evt.target); }
392
+ }
393
+
394
+ choice_destroy(link) {
395
+ if (this.result_deselect(link.readAttribute("rel"))) {
396
+ if (this.active_field) {
397
+ this.search_field.focus();
398
+ } else {
399
+ this.show_search_field_default();
400
+ }
401
+
402
+ if (this.is_multiple && (this.choices_count() > 0) && (this.get_search_field_value().length < 1)) { this.results_hide(); }
403
+
404
+ link.up('li').remove();
405
+
406
+ return this.search_field_scale();
407
+ }
408
+ }
409
+
410
+ results_reset() {
411
+ this.reset_single_select_options();
412
+ this.form_field.options[0].selected = true;
413
+ this.single_set_selected_text();
414
+ this.show_search_field_default();
415
+ this.results_reset_cleanup();
416
+ this.trigger_form_field_change();
417
+ if (this.active_field) { return this.results_hide(); }
418
+ }
419
+
420
+ results_reset_cleanup() {
421
+ this.current_selectedIndex = this.form_field.selectedIndex;
422
+ const deselect_trigger = this.selected_item.down("abbr");
423
+ if(deselect_trigger) { return deselect_trigger.remove(); }
424
+ }
425
+
426
+ result_select(evt) {
427
+ if (this.result_highlight) {
428
+ const high = this.result_highlight;
429
+ this.result_clear_highlight();
430
+
431
+ if (this.is_multiple && (this.max_selected_options <= this.choices_count())) {
432
+ this.form_field.fire("chosen:maxselected", {chosen: this});
433
+ return false;
434
+ }
435
+
436
+ if (this.is_multiple) {
437
+ high.removeClassName("active-result");
438
+ } else {
439
+ this.reset_single_select_options();
440
+ }
441
+
442
+ high.addClassName("result-selected");
443
+
444
+ const item = this.results_data[ high.getAttribute("data-option-array-index") ];
445
+ item.selected = true;
446
+
447
+ this.form_field.options[item.options_index].selected = true;
448
+ this.selected_option_count = null;
449
+
450
+ if (this.is_multiple) {
451
+ this.choice_build(item);
452
+ } else {
453
+ this.single_set_selected_text(this.choice_label(item));
454
+ }
455
+
456
+ if (this.is_multiple && (!this.hide_results_on_select || (evt.metaKey || evt.ctrlKey))) {
457
+ if (evt.metaKey || evt.ctrlKey) {
458
+ this.winnow_results({skip_highlight: true});
459
+ } else {
460
+ this.search_field.value = "";
461
+ this.winnow_results();
462
+ }
463
+ } else {
464
+ this.results_hide();
465
+ this.show_search_field_default();
466
+ }
467
+
468
+ if (this.is_multiple || (this.form_field.selectedIndex !== this.current_selectedIndex)) { this.trigger_form_field_change(); }
469
+ this.current_selectedIndex = this.form_field.selectedIndex;
470
+
471
+ evt.preventDefault();
472
+
473
+ return this.search_field_scale();
474
+ }
475
+ }
476
+
477
+ single_set_selected_text(text) {
478
+ if (text == null) { text = this.default_text; }
479
+ if (text === this.default_text) {
480
+ this.selected_item.addClassName("chosen-default");
481
+ } else {
482
+ this.single_deselect_control_build();
483
+ this.selected_item.removeClassName("chosen-default");
484
+ }
485
+
486
+ return this.selected_item.down("span").update(text);
487
+ }
488
+
489
+ result_deselect(pos) {
490
+ const result_data = this.results_data[pos];
491
+
492
+ if (!this.form_field.options[result_data.options_index].disabled) {
493
+ result_data.selected = false;
494
+
495
+ this.form_field.options[result_data.options_index].selected = false;
496
+ this.selected_option_count = null;
497
+
498
+ this.result_clear_highlight();
499
+ if (this.results_showing) { this.winnow_results(); }
500
+
501
+ this.trigger_form_field_change();
502
+ this.search_field_scale();
503
+ return true;
504
+ } else {
505
+ return false;
506
+ }
507
+ }
508
+
509
+ single_deselect_control_build() {
510
+ if (!this.allow_single_deselect) { return; }
511
+ if (!this.selected_item.down("abbr")) { this.selected_item.down("span").insert({ after: "<abbr class=\"search-choice-close\"></abbr>" }); }
512
+ return this.selected_item.addClassName("chosen-single-with-deselect");
513
+ }
514
+
515
+ get_search_field_value() {
516
+ return this.search_field.value;
517
+ }
518
+
519
+ get_search_text() {
520
+ return this.get_search_field_value().strip();
521
+ }
522
+
523
+ escape_html(text) {
524
+ return text.escapeHTML();
525
+ }
526
+
527
+ winnow_results_set_highlight() {
528
+ let do_high;
529
+ if (!this.is_multiple) {
530
+ do_high = this.search_results.down(".result-selected.active-result");
531
+ }
532
+
533
+ if ((do_high == null)) {
534
+ do_high = this.search_results.down(".active-result");
535
+ }
536
+
537
+ if (do_high != null) { return this.result_do_highlight(do_high); }
538
+ }
539
+
540
+ no_results(terms) {
541
+ this.search_results.insert(this.get_no_results_html(terms));
542
+ return this.form_field.fire("chosen:no_results", {chosen: this});
543
+ }
544
+
545
+ no_results_clear() {
546
+ let nr = null;
547
+ return (() => {
548
+ const result = [];
549
+ while ((nr = this.search_results.down(".no-results"))) {
550
+ result.push(nr.remove());
551
+ }
552
+ return result;
553
+ })();
554
+ }
555
+
556
+
557
+ keydown_arrow() {
558
+ if (this.results_showing && this.result_highlight) {
559
+ const next_sib = this.result_highlight.next('.active-result');
560
+ if (next_sib) { return this.result_do_highlight(next_sib); }
561
+ } else {
562
+ return this.results_show();
563
+ }
564
+ }
565
+
566
+ keyup_arrow() {
567
+ if (!this.results_showing && !this.is_multiple) {
568
+ return this.results_show();
569
+ } else if (this.result_highlight) {
570
+ const sibs = this.result_highlight.previousSiblings();
571
+ const actives = this.search_results.select("li.active-result");
572
+ const prevs = sibs.intersect(actives);
573
+
574
+ if (prevs.length) {
575
+ return this.result_do_highlight(prevs.first());
576
+ } else {
577
+ if (this.choices_count() > 0) { this.results_hide(); }
578
+ return this.result_clear_highlight();
579
+ }
580
+ }
581
+ }
582
+
583
+ keydown_backstroke() {
584
+ if (this.pending_backstroke) {
585
+ this.choice_destroy(this.pending_backstroke.down("a"));
586
+ return this.clear_backstroke();
587
+ } else {
588
+ const next_available_destroy = this.search_container.siblings().last();
589
+ if (next_available_destroy && next_available_destroy.hasClassName("search-choice") && !next_available_destroy.hasClassName("search-choice-disabled")) {
590
+ this.pending_backstroke = next_available_destroy;
591
+ if (this.pending_backstroke) { this.pending_backstroke.addClassName("search-choice-focus"); }
592
+ if (this.single_backstroke_delete) {
593
+ return this.keydown_backstroke();
594
+ } else {
595
+ return this.pending_backstroke.addClassName("search-choice-focus");
596
+ }
597
+ }
598
+ }
599
+ }
600
+
601
+ clear_backstroke() {
602
+ if (this.pending_backstroke) { this.pending_backstroke.removeClassName("search-choice-focus"); }
603
+ return this.pending_backstroke = null;
604
+ }
605
+
606
+ search_field_scale() {
607
+ let container_width;
608
+ if (!this.is_multiple) { return; }
609
+
610
+ const style_block = {
611
+ position: 'absolute',
612
+ left: '-1000px',
613
+ top: '-1000px',
614
+ display: 'none',
615
+ whiteSpace: 'pre'
616
+ };
617
+
618
+ const styles = ['fontSize', 'fontStyle', 'fontWeight', 'fontFamily', 'lineHeight', 'textTransform', 'letterSpacing'];
619
+
620
+ for (var style of Array.from(styles)) {
621
+ style_block[style] = this.search_field.getStyle(style);
622
+ }
623
+
624
+ const div = new Element('div').update(this.escape_html(this.get_search_field_value()));
625
+ // CSP without 'unsafe-inline' doesn't allow setting the style attribute directly
626
+ div.setStyle(style_block);
627
+ document.body.appendChild(div);
628
+
629
+ let width = div.measure('width') + 25;
630
+ div.remove();
631
+
632
+ if (container_width = this.container.getWidth()) {
633
+ width = Math.min(container_width - 10, width);
634
+ }
635
+
636
+ return this.search_field.setStyle({width: width + 'px'});
637
+ }
638
+
639
+ trigger_form_field_change() {
640
+ triggerHtmlEvent(this.form_field, 'input');
641
+ return triggerHtmlEvent(this.form_field, 'change');
642
+ }
643
+ });
644
+ Cls.initClass();
645
+ return Cls;
646
+ })();
647
+
648
+ function __guard__(value, transform) {
649
+ return (typeof value !== 'undefined' && value !== null) ? transform(value) : undefined;
650
+ }