engine2 1.0.5 → 1.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/app/actions.coffee +93 -58
- data/app/app.css +12 -0
- data/app/engine2.coffee +42 -24
- data/conf/message.yaml +1 -0
- data/conf/message_pl.yaml +1 -0
- data/config.coffee +2 -2
- data/engine2.gemspec +1 -1
- data/lib/engine2/action.rb +130 -126
- data/lib/engine2/action/array.rb +4 -4
- data/lib/engine2/action/decode.rb +13 -9
- data/lib/engine2/action/infra.rb +3 -3
- data/lib/engine2/action/list.rb +17 -10
- data/lib/engine2/action_node.rb +1 -2
- data/lib/engine2/core.rb +35 -7
- data/lib/engine2/model.rb +64 -15
- data/lib/engine2/post_bootstrap.rb +1 -1
- data/lib/engine2/pre_bootstrap.rb +10 -0
- data/lib/engine2/scheme.rb +2 -2
- data/lib/engine2/templates.rb +8 -0
- data/lib/engine2/type_info.rb +37 -15
- data/lib/engine2/version.rb +1 -1
- data/package.json +8 -5
- data/views/fields/blob.slim +1 -1
- data/views/fields/bs_select.slim +2 -2
- data/views/fields/bsselect_picker.slim +4 -4
- data/views/fields/bsselect_picker_opt.slim +5 -5
- data/views/fields/checkbox.slim +4 -4
- data/views/fields/checkbox_buttons.slim +3 -3
- data/views/fields/checkbox_buttons_opt.slim +3 -3
- data/views/fields/currency.slim +2 -2
- data/views/fields/date.slim +4 -4
- data/views/fields/date_range.slim +9 -9
- data/views/fields/date_time.slim +9 -9
- data/views/fields/datetime.slim +8 -8
- data/views/fields/decimal.slim +1 -1
- data/views/fields/decimal_date.slim +3 -3
- data/views/fields/decimal_time.slim +3 -3
- data/views/fields/email.slim +3 -3
- data/views/fields/file_store.slim +4 -4
- data/views/fields/input_text.slim +4 -4
- data/views/fields/integer.slim +1 -1
- data/views/fields/list_bsmselect.slim +20 -0
- data/views/fields/list_bsselect.slim +5 -5
- data/views/fields/list_bsselect_opt.slim +6 -6
- data/views/fields/list_buttons.slim +1 -1
- data/views/fields/list_buttons_opt.slim +2 -2
- data/views/fields/list_select.slim +4 -4
- data/views/fields/list_select_opt.slim +5 -5
- data/views/fields/password.slim +4 -4
- data/views/fields/radio_checkbox.slim +3 -3
- data/views/fields/scaffold.slim +1 -1
- data/views/fields/scaffold_picker.slim +5 -5
- data/views/fields/select_picker.slim +3 -3
- data/views/fields/select_picker_opt.slim +4 -4
- data/views/fields/text_area.slim +3 -3
- data/views/fields/time.slim +5 -4
- data/views/fields/typeahead_picker.slim +5 -5
- data/views/scaffold/fields.slim +4 -4
- data/views/scaffold/form.slim +1 -1
- data/views/scaffold/form_collapse.slim +4 -3
- data/views/scaffold/form_tabs.slim +3 -2
- data/views/scaffold/search.slim +2 -2
- data/views/scaffold/search_collapse.slim +6 -5
- data/views/scaffold/search_tabs.slim +4 -3
- data/views/scaffold/view.slim +2 -2
- data/views/scaffold/view_collapse.slim +5 -4
- data/views/scaffold/view_tabs.slim +4 -3
- data/views/search_fields/bsmselect_picker.slim +4 -4
- data/views/search_fields/bsselect_picker.slim +4 -4
- data/views/search_fields/checkbox.slim +3 -3
- data/views/search_fields/checkbox2.slim +5 -5
- data/views/search_fields/checkbox_buttons.slim +3 -3
- data/views/search_fields/date_range.slim +8 -8
- data/views/search_fields/decimal_date_range.slim +5 -5
- data/views/search_fields/input_text.slim +2 -2
- data/views/search_fields/integer.slim +1 -1
- data/views/search_fields/integer_range.slim +2 -2
- data/views/search_fields/list_bsmselect.slim +4 -4
- data/views/search_fields/list_bsselect.slim +4 -4
- data/views/search_fields/list_buttons.slim +2 -2
- data/views/search_fields/list_select.slim +3 -3
- data/views/search_fields/scaffold_picker.slim +2 -2
- data/views/search_fields/select_picker.slim +3 -3
- data/views/search_fields/typeahead_picker.slim +4 -4
- metadata +6 -5
data/lib/engine2/templates.rb
CHANGED
@@ -77,6 +77,14 @@ module Engine2
|
|
77
77
|
})
|
78
78
|
end
|
79
79
|
|
80
|
+
def list_bsmselect length, options = {}
|
81
|
+
options.merge({
|
82
|
+
template: "fields/list_bsmselect",
|
83
|
+
length: length,
|
84
|
+
animation: BS_ANIMATION
|
85
|
+
})
|
86
|
+
end
|
87
|
+
|
80
88
|
def list_buttons options = {}
|
81
89
|
options.merge({
|
82
90
|
template: options[:optional] ? "fields/list_buttons_opt" : "fields/list_buttons"
|
data/lib/engine2/type_info.rb
CHANGED
@@ -74,6 +74,15 @@ module Engine2
|
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
77
|
+
def boolean field, true_value = 1, false_value = 0
|
78
|
+
modify_field field do |info|
|
79
|
+
info[:type] = :boolean
|
80
|
+
info[:true_value] = true_value
|
81
|
+
info[:false_value] = false_value
|
82
|
+
info[:validations][:boolean] = true
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
77
86
|
def date_field field, format, model_format
|
78
87
|
define_field field, :date do |info|
|
79
88
|
info[:format] = format
|
@@ -84,6 +93,13 @@ module Engine2
|
|
84
93
|
|
85
94
|
def time_field field, format, model_format
|
86
95
|
define_field field, :time do |info|
|
96
|
+
end
|
97
|
+
time field, format, model_format
|
98
|
+
end
|
99
|
+
|
100
|
+
def time field, format, model_format
|
101
|
+
modify_field field do |info|
|
102
|
+
info[:type] = :time
|
87
103
|
info[:format] = format
|
88
104
|
info[:model_format] = model_format
|
89
105
|
info[:validations][:time] = true
|
@@ -245,15 +261,6 @@ module Engine2
|
|
245
261
|
end
|
246
262
|
end
|
247
263
|
|
248
|
-
def boolean field, true_value = 1, false_value = 0
|
249
|
-
modify_field field do |info|
|
250
|
-
info[:type] = :boolean
|
251
|
-
info[:true_value] = true_value
|
252
|
-
info[:false_value] = false_value
|
253
|
-
info[:validations][:boolean] = true
|
254
|
-
end
|
255
|
-
end
|
256
|
-
|
257
264
|
def currency field, symbol = LOCS[:currency_symbol]
|
258
265
|
modify_field field do |info|
|
259
266
|
info[:type] = :currency
|
@@ -307,15 +314,30 @@ module Engine2
|
|
307
314
|
end
|
308
315
|
end
|
309
316
|
|
310
|
-
def
|
317
|
+
def list_select_bits values
|
318
|
+
values.each_with_index.map{|a, i|[1 << i, a]}.to_h
|
319
|
+
end
|
320
|
+
|
321
|
+
def list_select name, options
|
311
322
|
modify_field name do |info|
|
312
323
|
info[:type] = :list_select
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
324
|
+
values = options[:values]
|
325
|
+
|
326
|
+
if options[:multiselect]
|
327
|
+
info[:multiselect] = true
|
328
|
+
case info[:otype]
|
329
|
+
when :string
|
330
|
+
info[:separator] = options[:separator] || ';'
|
331
|
+
info[:validations].delete(:string_length)
|
332
|
+
when :integer
|
333
|
+
info[:validations].delete(:integer)
|
334
|
+
end
|
335
|
+
info[:max_length] = options[:max_length] || 3
|
336
|
+
info[:max_length_html] = options[:max_length_html] || LOCS[:list_select_selected]
|
318
337
|
end
|
338
|
+
|
339
|
+
raise E2Error.new("type '#{values.class}' not supported for list_select modifier for field #{name}") unless values.is_a?(Hash)
|
340
|
+
info[:values] = values.to_a
|
319
341
|
info[:validations][:list_select] = true
|
320
342
|
end
|
321
343
|
end
|
data/lib/engine2/version.rb
CHANGED
data/package.json
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
"name": "engine2",
|
3
3
|
"description": "engine2",
|
4
4
|
"version": "1.0.0",
|
5
|
+
"license": "MIT",
|
5
6
|
"scripts": {
|
6
7
|
"postinstall": "bower install --allow-root",
|
7
8
|
"dev": "brunch w",
|
@@ -12,22 +13,24 @@
|
|
12
13
|
"angular": "^1.6.0",
|
13
14
|
"angular-animate": "^1.6.0",
|
14
15
|
"angular-cookies": "^1.6.0",
|
15
|
-
"angular-
|
16
|
-
"angular-
|
16
|
+
"angular-drag-and-drop-lists": "^2.1.0",
|
17
|
+
"angular-load": "^0.5.0",
|
18
|
+
"angular-local-storage": "^0.7.0",
|
17
19
|
"angular-motion": "^0.4.0",
|
18
20
|
"angular-sanitize": "^1.6.0",
|
19
21
|
"angular-ui-tree": "^2.22.0",
|
20
22
|
"bootstrap": "^3.3.0",
|
21
23
|
"bootstrap-additions": "0.3.1",
|
22
|
-
"
|
24
|
+
"fork-awesome": "^1.0.1",
|
23
25
|
"lodash": "~4.17.0",
|
24
26
|
"ng-file-upload": "^12.2.0",
|
25
|
-
"push.js": "^
|
27
|
+
"push.js": "^1.0.1",
|
28
|
+
"ui-select": "^0.19.8"
|
26
29
|
},
|
27
30
|
"devDependencies": {
|
28
31
|
"auto-reload-brunch": "^2.7.1",
|
29
32
|
"bower": "~1.8.0",
|
30
|
-
"brunch": "^2.
|
33
|
+
"brunch": "^2.10.0",
|
31
34
|
"clean-css-brunch": "^2.0.0",
|
32
35
|
"coffee-script-brunch": "^2.10.2",
|
33
36
|
"copycat-brunch": "^1.1.0",
|
data/views/fields/blob.slim
CHANGED
data/views/fields/bs_select.slim
CHANGED
@@ -2,9 +2,9 @@
|
|
2
2
|
select [
|
3
3
|
ng-model="action.record[f]"
|
4
4
|
bs-options="v.id as v.value for v in values"
|
5
|
-
select-resource="
|
5
|
+
select-resource="field.render.resource"
|
6
6
|
bs-select=""
|
7
|
-
ng-disabled="
|
7
|
+
ng-disabled="field.disabled"
|
8
8
|
class="form-control input-sm"
|
9
9
|
e2-field=""
|
10
10
|
]
|
@@ -1,15 +1,15 @@
|
|
1
|
-
e2-action action="[
|
1
|
+
e2-action action="[field.assoc, 'list']"
|
2
2
|
.col-lg-7.col-md-8.col-sm-12
|
3
3
|
button.btn.btn-default.btn-sm [
|
4
4
|
type="button"
|
5
5
|
ng-model="action.selected"
|
6
6
|
bs-options="v.id as v.value for v in action.values"
|
7
7
|
ng-change="action.change()"
|
8
|
-
ng-disabled="
|
9
|
-
ng-class="
|
8
|
+
ng-disabled="field.disabled"
|
9
|
+
ng-class="field.render.class"
|
10
10
|
class="form-control input-sm"
|
11
11
|
|
12
|
-
data-animation="{{::
|
12
|
+
data-animation="{{::field.render.animation}}"
|
13
13
|
data-placeholder="..."
|
14
14
|
data-html="true"
|
15
15
|
bs-select=""
|
@@ -1,4 +1,4 @@
|
|
1
|
-
e2-action action="[
|
1
|
+
e2-action action="[field.assoc, 'list']"
|
2
2
|
.col-lg-7.col-md-12.col-sm-12
|
3
3
|
.input-group.input-group-sm
|
4
4
|
button.btn.btn-default.btn-sm [
|
@@ -6,16 +6,16 @@ e2-action action="[info.assoc, 'list']"
|
|
6
6
|
ng-model="action.selected"
|
7
7
|
bs-options="v.id as v.value for v in action.values"
|
8
8
|
ng-change="action.change()"
|
9
|
-
ng-disabled="
|
10
|
-
ng-class="
|
9
|
+
ng-disabled="field.disabled"
|
10
|
+
ng-class="field.render.class"
|
11
11
|
class="form-control"
|
12
12
|
|
13
|
-
data-animation="{{::
|
13
|
+
data-animation="{{::field.render.animation}}"
|
14
14
|
data-placeholder="..."
|
15
15
|
data-html="true"
|
16
16
|
bs-select=""
|
17
17
|
e2-field=""
|
18
18
|
]
|
19
19
|
.input-group-btn
|
20
|
-
a.btn.btn-default ng-disabled="
|
20
|
+
a.btn.btn-default ng-disabled="field.disabled || !action.selected" ng-click="action.reset()"
|
21
21
|
span.glyphicon.glyphicon-remove
|
data/views/fields/checkbox.slim
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
.col-lg-1
|
2
2
|
.checkbox
|
3
3
|
input [
|
4
|
-
ng-init="action.record[f] = action.record[f] ||
|
4
|
+
ng-init="action.record[f] = action.record[f] || field.render.false_value"
|
5
5
|
type="checkbox"
|
6
6
|
ng-model="action.record[f]"
|
7
|
-
ng-true-value="{{::
|
8
|
-
ng-false-value="{{::
|
9
|
-
ng-disabled="
|
7
|
+
ng-true-value="{{::field.render.true_value}}"
|
8
|
+
ng-false-value="{{::field.render.false_value}}"
|
9
|
+
ng-disabled="field.disabled"
|
10
10
|
e2-field=""
|
11
11
|
]
|
@@ -1,6 +1,6 @@
|
|
1
1
|
.col-lg-12
|
2
|
-
.btn-group.btn-group-sm ng-init="(action.record[f] === undefined) && (action.record[f] =
|
3
|
-
a.btn.btn-default ng-class="action.record[f] ===
|
2
|
+
.btn-group.btn-group-sm ng-init="(action.record[f] === undefined) && (action.record[f] = field.render.false_value)" ng-model="action.record[f]" e2-field=""
|
3
|
+
a.btn.btn-default ng-class="action.record[f] === field.render.true_value && 'active'" ng-click="action.record[f] = field.render.true_value" ng-disabled="field.disabled"
|
4
4
|
span.glyphicon.glyphicon-check
|
5
|
-
a.btn.btn-default ng-class="action.record[f] ===
|
5
|
+
a.btn.btn-default ng-class="action.record[f] === field.render.false_value && 'active'" ng-click="action.record[f] = field.render.false_value" ng-disabled="field.disabled"
|
6
6
|
span.glyphicon.glyphicon-unchecked
|
@@ -1,8 +1,8 @@
|
|
1
1
|
.col-lg-12
|
2
2
|
.btn-group.btn-group-sm ng-model="action.record[f]" e2-field=""
|
3
|
-
a.btn.btn-default ng-class="action.record[f] ===
|
3
|
+
a.btn.btn-default ng-class="action.record[f] === field.render.true_value && 'active'" ng-click="action.record[f] = field.render.true_value" ng-disabled="field.disabled"
|
4
4
|
span.glyphicon.glyphicon-check
|
5
|
-
a.btn.btn-default ng-class="action.record[f] ===
|
5
|
+
a.btn.btn-default ng-class="action.record[f] === field.render.false_value && 'active'" ng-click="action.record[f] = field.render.false_value" ng-disabled="field.disabled"
|
6
6
|
span.glyphicon.glyphicon-unchecked
|
7
|
-
a.btn.btn-default ng-class="(action.record[f] === null || action.record[f] === undefined) && 'active'" ng-click="action.record[f] = null" ng-disabled="
|
7
|
+
a.btn.btn-default ng-class="(action.record[f] === null || action.record[f] === undefined) && 'active'" ng-click="action.record[f] = null" ng-disabled="field.disabled"
|
8
8
|
span.glyphicon.glyphicon-off
|
data/views/fields/currency.slim
CHANGED
data/views/fields/date.slim
CHANGED
@@ -4,13 +4,13 @@
|
|
4
4
|
type="text"
|
5
5
|
class="form-control"
|
6
6
|
ng-model="value"
|
7
|
-
ng-disabled="
|
7
|
+
ng-disabled="field.disabled"
|
8
8
|
|
9
|
-
data-date-format="{{::
|
10
|
-
data-animation="{{::
|
9
|
+
data-date-format="{{::field.render.format}}"
|
10
|
+
data-animation="{{::field.render.animation}}"
|
11
11
|
bs-datepicker=""
|
12
12
|
e2-datepicker=""
|
13
|
-
e2-model-format="{{::
|
13
|
+
e2-model-format="{{::field.render.model_format}}"
|
14
14
|
data-autoclose="1"
|
15
15
|
|
16
16
|
e2-force-view-value=""
|
@@ -5,14 +5,14 @@
|
|
5
5
|
type="text"
|
6
6
|
class="form-control"
|
7
7
|
ng-model="value.from"
|
8
|
-
ng-disabled="
|
8
|
+
ng-disabled="field.disabled"
|
9
9
|
|
10
|
-
data-date-format="{{::
|
10
|
+
data-date-format="{{::field.render.format}}"
|
11
11
|
data-max-date="{{value.to}}"
|
12
|
-
data-animation="{{::
|
12
|
+
data-animation="{{::field.render.animation}}"
|
13
13
|
bs-datepicker=""
|
14
14
|
e2-datepicker="from"
|
15
|
-
e2-model-format="{{::
|
15
|
+
e2-model-format="{{::field.render.model_format}}"
|
16
16
|
data-autoclose="1"
|
17
17
|
|
18
18
|
e2-field=""
|
@@ -23,18 +23,18 @@
|
|
23
23
|
.col-lg-3.col-md-3.col-sm-5
|
24
24
|
.input-group.input-group-sm
|
25
25
|
input.btn.btn-default [
|
26
|
-
ng-init="other_date = action.meta.
|
26
|
+
ng-init="other_date = action.meta.fields[f].render.other_date; field = action.meta.fields[other_date]"
|
27
27
|
type="text"
|
28
28
|
class="form-control"
|
29
29
|
ng-model="value.to"
|
30
|
-
ng-disabled="
|
30
|
+
ng-disabled="field.disabled"
|
31
31
|
|
32
|
-
data-date-format="{{::
|
32
|
+
data-date-format="{{::field.render.format}}"
|
33
33
|
data-min-date="{{value.from}}"
|
34
|
-
data-animation="{{::
|
34
|
+
data-animation="{{::field.render.animation}}"
|
35
35
|
bs-datepicker=""
|
36
36
|
e2-datepicker="to"
|
37
|
-
e2-model-format="{{::
|
37
|
+
e2-model-format="{{::field.render.model_format}}"
|
38
38
|
data-autoclose="1"
|
39
39
|
|
40
40
|
e2-field="{{other_date}}"
|
data/views/fields/date_time.slim
CHANGED
@@ -5,13 +5,13 @@
|
|
5
5
|
type="text"
|
6
6
|
class="form-control"
|
7
7
|
ng-model="value"
|
8
|
-
ng-disabled="
|
8
|
+
ng-disabled="field.disabled"
|
9
9
|
|
10
|
-
data-date-format="{{::
|
11
|
-
data-animation="{{::
|
10
|
+
data-date-format="{{::field.render.format}}"
|
11
|
+
data-animation="{{::field.render.animation}}"
|
12
12
|
bs-datepicker=""
|
13
13
|
e2-datepicker=""
|
14
|
-
e2-model-format="{{::
|
14
|
+
e2-model-format="{{::field.render.model_format}}"
|
15
15
|
data-autoclose="1"
|
16
16
|
|
17
17
|
e2-field=""
|
@@ -22,17 +22,17 @@
|
|
22
22
|
.col-lg-3.col-md-3.col-sm-5
|
23
23
|
.input-group.input-group-sm
|
24
24
|
input.btn.btn-default [
|
25
|
-
ng-init="other_time = action.meta.
|
25
|
+
ng-init="other_time = action.meta.fields[f].render.other_time; field = action.meta.fields[other_time]"
|
26
26
|
type="text"
|
27
27
|
class="form-control"
|
28
28
|
ng-model="value"
|
29
|
-
ng-disabled="
|
29
|
+
ng-disabled="field.disabled"
|
30
30
|
|
31
|
-
data-time-format="{{::
|
32
|
-
data-animation="{{::
|
31
|
+
data-time-format="{{::field.render.format}}"
|
32
|
+
data-animation="{{::field.render.animation}}"
|
33
33
|
bs-timepicker=""
|
34
34
|
e2-datepicker=""
|
35
|
-
e2-model-format="{{::
|
35
|
+
e2-model-format="{{::field.render.model_format}}"
|
36
36
|
data-autoclose="1"
|
37
37
|
|
38
38
|
e2-field="{{other_time}}"
|
data/views/fields/datetime.slim
CHANGED
@@ -5,13 +5,13 @@
|
|
5
5
|
type="text"
|
6
6
|
class="form-control"
|
7
7
|
ng-model="value.value"
|
8
|
-
ng-disabled="
|
8
|
+
ng-disabled="field.disabled"
|
9
9
|
|
10
|
-
data-date-format="{{::
|
11
|
-
data-animation="{{::
|
10
|
+
data-date-format="{{::field.render.date_format}}"
|
11
|
+
data-animation="{{::field.render.animation}}"
|
12
12
|
bs-datepicker=""
|
13
13
|
e2-datepicker="value"
|
14
|
-
e2-model-format="{{:: (
|
14
|
+
e2-model-format="{{:: (field.render.date_model_format + ' ' + field.render.time_model_format)}}"
|
15
15
|
data-autoclose="1"
|
16
16
|
|
17
17
|
e2-force-view-value=""
|
@@ -25,13 +25,13 @@
|
|
25
25
|
type="text"
|
26
26
|
class="form-control"
|
27
27
|
ng-model="value.value"
|
28
|
-
ng-disabled="
|
28
|
+
ng-disabled="field.disabled"
|
29
29
|
|
30
|
-
data-time-format="{{::
|
31
|
-
data-animation="{{::
|
30
|
+
data-time-format="{{::field.render.time_format}}"
|
31
|
+
data-animation="{{::field.render.animation}}"
|
32
32
|
bs-timepicker=""
|
33
33
|
e2-datepicker="value"
|
34
|
-
e2-model-format="{{:: (
|
34
|
+
e2-model-format="{{:: (field.render.date_model_format + ' ' + field.render.time_model_format)}}"
|
35
35
|
data-autoclose="1"
|
36
36
|
|
37
37
|
e2-force-view-value=""
|
data/views/fields/decimal.slim
CHANGED
@@ -6,11 +6,11 @@
|
|
6
6
|
class="form-control"
|
7
7
|
xng-model="value"
|
8
8
|
ng-model="action.record[f]"
|
9
|
-
ng-disabled="
|
9
|
+
ng-disabled="field.disabled"
|
10
10
|
|
11
11
|
bs-datepicker=""
|
12
|
-
data-animation="{{::
|
13
|
-
data-date-format="{{::
|
12
|
+
data-animation="{{::field.render.animation}}"
|
13
|
+
data-date-format="{{::field.render.format}}"
|
14
14
|
data-model-date-format="yyyyMMdd"
|
15
15
|
data-autoclose="1"
|
16
16
|
data-date-type="string"
|
@@ -6,11 +6,11 @@
|
|
6
6
|
class="form-control"
|
7
7
|
xng-model="value"
|
8
8
|
ng-model="action.record[f]"
|
9
|
-
ng-disabled="
|
9
|
+
ng-disabled="field.disabled"
|
10
10
|
|
11
11
|
bs-timepicker=""
|
12
|
-
data-animation="{{::
|
13
|
-
data-time-format="{{::
|
12
|
+
data-animation="{{::field.render.animation}}"
|
13
|
+
data-time-format="{{::field.render.format}}"
|
14
14
|
data-model-date-format="HHmmss"
|
15
15
|
data-show-meridian="false"
|
16
16
|
data-show-seconds="true"
|