diff --git a/forms/account/address/ui.xml b/forms/account/address/ui.xml index 9b9eab0f..1e596cf6 100644 --- a/forms/account/address/ui.xml +++ b/forms/account/address/ui.xml @@ -59,13 +59,9 @@
- + placeholder="_Country" + id="country" + one-way="true"> SELECT id, country FROM vn.country ORDER BY country @@ -77,9 +73,9 @@ placeholder="_Province" column="provinceFk" form="iter"> - + SELECT id, name FROM vn.province - WHERE countryFk = #countryFk + WHERE countryFk = #id ORDER BY name diff --git a/js/hedera/gui.js b/js/hedera/gui.js index a2fa2c63..8311a915 100644 --- a/js/hedera/gui.js +++ b/js/hedera/gui.js @@ -5,7 +5,7 @@ var Tpl = require('./gui.xml').default; require('./gui.scss'); module.exports = new Class({ - Extends: Htk.Component, + Extends: Vn.Component, Properties: { conn: { type: Db.Connection @@ -30,7 +30,7 @@ module.exports = new Class({ ,_navbarVisible: true ,initialize: function(props) { - this.builderInitString(Tpl); + this.loadTemplateFromString(Tpl); this.loadingCount = 0; this.$.background.onclick = function() {}; diff --git a/js/hedera/login.js b/js/hedera/login.js index e6d9829c..e042cb7f 100644 --- a/js/hedera/login.js +++ b/js/hedera/login.js @@ -3,7 +3,7 @@ require('./login.scss'); var Tpl = require('./login.xml').default; module.exports = new Class({ - Extends: Htk.Component, + Extends: Vn.Component, Properties: { conn: @@ -20,7 +20,7 @@ module.exports = new Class({ ,initialize: function(props) { this.parent(props); - this.builderInitString(Tpl); + this.loadTemplateFromString(Tpl); //this.$.socialBar.conn = this._conn; diff --git a/js/hedera/social-bar.js b/js/hedera/social-bar.js index 0930812f..7920b0fa 100644 --- a/js/hedera/social-bar.js +++ b/js/hedera/social-bar.js @@ -1,6 +1,6 @@ module.exports = new Class({ - Extends: Htk.Widget + Extends: Vn.Component ,Tag: 'htk-social-bar' ,Properties: { conn: { diff --git a/js/htk/assistant-bar/index.js b/js/htk/assistant-bar/index.js index 7035e56b..eb9859fe 100644 --- a/js/htk/assistant-bar/index.js +++ b/js/htk/assistant-bar/index.js @@ -1,9 +1,9 @@ require('./style.scss'); -var Widget = require('../widget'); +var Component = require('vn/component'); var Assistant = require('../assistant'); module.exports = new Class({ - Extends: Widget, + Extends: Component, Tag: 'htk-assistant-bar', Properties: { assistant: { diff --git a/js/htk/assistant/index.js b/js/htk/assistant/index.js index c03eb8d8..cd26e6cb 100644 --- a/js/htk/assistant/index.js +++ b/js/htk/assistant/index.js @@ -1,5 +1,5 @@ require('./style.scss'); -var Widget = require('../widget'); +var Component = require('vn/component'); var Step = require('../step'); var Toast = require('../toast'); @@ -7,7 +7,7 @@ var Toast = require('../toast'); * A simple assistant with steps. */ module.exports = new Class({ - Extends: Widget, + Extends: Component, Tag: 'htk-assistant', Properties: { /** diff --git a/js/htk/fields/bar-button/index.js b/js/htk/bar-button/index.js similarity index 100% rename from js/htk/fields/bar-button/index.js rename to js/htk/bar-button/index.js diff --git a/js/htk/fields/button/index.js b/js/htk/button/index.js similarity index 100% rename from js/htk/fields/button/index.js rename to js/htk/button/index.js diff --git a/js/htk/fields/button/style.scss b/js/htk/button/style.scss similarity index 100% rename from js/htk/fields/button/style.scss rename to js/htk/button/style.scss diff --git a/js/htk/fields/calendar/index.js b/js/htk/calendar/index.js similarity index 98% rename from js/htk/fields/calendar/index.js rename to js/htk/calendar/index.js index 0a1b7017..15c28a17 100644 --- a/js/htk/fields/calendar/index.js +++ b/js/htk/calendar/index.js @@ -3,15 +3,13 @@ require('./style.scss'); module.exports = new Class({ Extends: Htk.Field ,Tag: 'htk-calendar' - ,Properties: - { - restrictFunc: - { + ,Properties: { + restrictFunc: { type: Function ,set: function(x) { this._restrictFunc = x; } - ,get: function(x) { + ,get: function() { return this._restrictFunc; } } diff --git a/js/htk/fields/calendar/style.scss b/js/htk/calendar/style.scss similarity index 95% rename from js/htk/fields/calendar/style.scss rename to js/htk/calendar/style.scss index cb1c5e37..56761078 100644 --- a/js/htk/fields/calendar/style.scss +++ b/js/htk/calendar/style.scss @@ -1,5 +1,5 @@ -@import "../../style/variables"; -@import "../../style/classes"; +@import "../style/variables"; +@import "../style/classes"; .htk-calendar { @extend %box; diff --git a/js/htk/fields/check/index.js b/js/htk/check/index.js similarity index 100% rename from js/htk/fields/check/index.js rename to js/htk/check/index.js diff --git a/js/htk/component/index.js b/js/htk/component/index.js deleted file mode 100644 index b3ae0755..00000000 --- a/js/htk/component/index.js +++ /dev/null @@ -1,36 +0,0 @@ - -const Widget = require('../widget'); - -module.exports = new Class({ - Extends: Widget - - ,scope: null - - ,builderInit: function(path) { - const builder = new Vn.Builder(); - builder.compileFile(path); - this.builderResultInit(builder); - } - - ,builderInitString: function(xmlString) { - const builder = new Vn.Builder(); - builder.compileString(xmlString); - this.builderResultInit(builder); - } - - ,builderResultInit: function(builder) { - const scope = this.scope = builder.load(this.doc, this); - scope.link(); - - this.$ = scope.$; - this._node = scope.$.main; - } - - ,_destroy: function() { - if (this.scope) - this.scope.unref(); - - this.parent(); - } -}); - diff --git a/js/htk/fields/date-chooser/index.js b/js/htk/date-chooser/index.js similarity index 100% rename from js/htk/fields/date-chooser/index.js rename to js/htk/date-chooser/index.js diff --git a/js/htk/fields/date-chooser/style.scss b/js/htk/date-chooser/style.scss similarity index 100% rename from js/htk/fields/date-chooser/style.scss rename to js/htk/date-chooser/style.scss diff --git a/js/htk/fields/entry/index.js b/js/htk/entry/index.js similarity index 100% rename from js/htk/fields/entry/index.js rename to js/htk/entry/index.js diff --git a/js/htk/field/index.js b/js/htk/field/index.js index ac4f2842..81b66f90 100644 --- a/js/htk/field/index.js +++ b/js/htk/field/index.js @@ -1,8 +1,8 @@ -var Widget = require('../widget'); +var Component = require('vn/component'); module.exports = new Class({ - Extends: Widget + Extends: Component ,Implements: Vn.ParamIface ,Tag: 'htk-field' ,Child: 'param' diff --git a/js/htk/grid/index.js b/js/htk/grid/index.js index 4a9e6c72..5cdc88f9 100644 --- a/js/htk/grid/index.js +++ b/js/htk/grid/index.js @@ -1,8 +1,8 @@ require('./style.scss'); -var Widget = require('../widget'); +var Component = require('vn/component'); module.exports = new Class({ - Extends: Widget + Extends: Component ,Tag: 'htk-grid' ,Child: 'model' ,Properties: diff --git a/js/htk/htk.js b/js/htk/htk.js index b7f196f6..5cc21c26 100644 --- a/js/htk/htk.js +++ b/js/htk/htk.js @@ -3,9 +3,7 @@ require('db/db'); require('./style/index.scss'); Htk = module.exports = { - Widget : require('./widget') - ,Component : require('./component') - ,Popup : require('./popup') + Popup : require('./popup') ,Dialog : require('./dialog') ,Toast : require('./toast') ,Repeater : require('./repeater') @@ -24,23 +22,23 @@ Htk = module.exports = { }; var Fields = { - Text : require('./fields/text') - ,Html : require('./fields/html') - ,Entry : require('./fields/entry') - ,RadioGroup : require('./fields/radio/radio-group') - ,Radio : require('./fields/radio') - ,Label : require('./fields/label') - ,TextArea : require('./fields/text-area') - ,Spin : require('./fields/spin') - ,Check : require('./fields/check') - ,Select : require('./fields/select') - ,Calendar : require('./fields/calendar') - ,DateChooser : require('./fields/date-chooser') - ,Image : require('./fields/image') - ,Button : require('./fields/button') - ,BarButton : require('./fields/bar-button') - ,Table : require('./fields/table') - ,SearchEntry : require('./fields/search-entry') + Text : require('./text') + ,Html : require('./html') + ,Entry : require('./entry') + ,RadioGroup : require('./radio/radio-group') + ,Radio : require('./radio') + ,Label : require('./label') + ,TextArea : require('./text-area') + ,Spin : require('./spin') + ,Check : require('./check') + ,Select : require('./select') + ,Calendar : require('./calendar') + ,DateChooser : require('./date-chooser') + ,Image : require('./image') + ,Button : require('./button') + ,BarButton : require('./bar-button') + ,Table : require('./table') + ,SearchEntry : require('./search-entry') ,ColumnButton : require('./columns/button') ,ColumnLink : require('./columns/link') ,ColumnDate : require('./columns/date') diff --git a/js/htk/fields/html/index.js b/js/htk/html/index.js similarity index 100% rename from js/htk/fields/html/index.js rename to js/htk/html/index.js diff --git a/js/htk/icon/index.js b/js/htk/icon/index.js index e127a07a..ad12013a 100644 --- a/js/htk/icon/index.js +++ b/js/htk/icon/index.js @@ -1,8 +1,8 @@ -var Widget = require('../widget'); +var Component = require('vn/component'); module.exports = new Class({ - Extends: Widget + Extends: Component ,Tag: 'htk-icon' ,Properties: { diff --git a/js/htk/image-editor/index.js b/js/htk/image-editor/index.js index 24ee2466..f18797e0 100644 --- a/js/htk/image-editor/index.js +++ b/js/htk/image-editor/index.js @@ -1,5 +1,5 @@ require('./style.scss'); -var Component = require('../component'); +var Component = require('vn/component'); var Toast = require('../toast'); var Tpl = require('./ui.xml').default; @@ -19,7 +19,7 @@ module.exports = new Class({ }, initialize: function(props) { - this.builderInitString(Tpl); + this.loadTemplateFromString(Tpl); var self = this; this.$.form.onsubmit = function() { diff --git a/js/htk/fields/image/index.js b/js/htk/image/index.js similarity index 99% rename from js/htk/fields/image/index.js rename to js/htk/image/index.js index 07441da1..76b084ca 100644 --- a/js/htk/fields/image/index.js +++ b/js/htk/image/index.js @@ -1,3 +1,5 @@ +require('./style.scss'); + /** * Class to display or edit an image. Also it allows to show it's full version. */ diff --git a/js/htk/fields/image/style.scss b/js/htk/image/style.scss similarity index 100% rename from js/htk/fields/image/style.scss rename to js/htk/image/style.scss diff --git a/js/htk/fields/label/index.js b/js/htk/label/index.js similarity index 100% rename from js/htk/fields/label/index.js rename to js/htk/label/index.js diff --git a/js/htk/list/style.scss b/js/htk/list/style.scss index 5bc03763..70669d0c 100644 --- a/js/htk/list/style.scss +++ b/js/htk/list/style.scss @@ -46,11 +46,11 @@ margin: .6em; } } - } - .item:hover > .actions { - display: flex; - } - .item:last-child { - border-bottom: none; + &:hover > .actions { + display: flex; + } + &:last-child { + border-bottom: none; + } } } diff --git a/js/htk/loader/index.js b/js/htk/loader/index.js index 9b56cc62..d0034c9e 100644 --- a/js/htk/loader/index.js +++ b/js/htk/loader/index.js @@ -1,9 +1,9 @@ require('./style.scss'); -var Widget = require('../widget'); +var Component = require('vn/component'); module.exports = new Class({ Tag: 'htk-loader' - ,Extends: Widget + ,Extends: Component ,Properties: { form: { type: Db.Form diff --git a/js/htk/popup/index.js b/js/htk/popup/index.js index d62f2f01..a0f82f27 100644 --- a/js/htk/popup/index.js +++ b/js/htk/popup/index.js @@ -1,18 +1,18 @@ require('./style.scss'); -var Widget = require('../widget'); +var Component = require('vn/component'); /** * Class to handle popups. */ module.exports = new Class({ - Extends: Widget + Extends: Component ,Tag: 'htk-popup' ,Properties: { /** * The popup child. */ child: { - type: Widget + type: Component ,set: function(x) { this._child = x; this._setChildNode(x.node); diff --git a/js/htk/fields/radio/index.js b/js/htk/radio/index.js similarity index 100% rename from js/htk/fields/radio/index.js rename to js/htk/radio/index.js diff --git a/js/htk/fields/radio/radio-group.js b/js/htk/radio/radio-group.js similarity index 100% rename from js/htk/fields/radio/radio-group.js rename to js/htk/radio/radio-group.js diff --git a/js/htk/repeater/index.js b/js/htk/repeater/index.js index b7947d53..77b45ea7 100644 --- a/js/htk/repeater/index.js +++ b/js/htk/repeater/index.js @@ -1,8 +1,8 @@ require('./style.scss'); -var Widget = require('../widget'); +var Component = require('vn/component'); module.exports = new Class({ - Extends: Widget + Extends: Component ,Tag: 'htk-repeater' ,Child: 'model' ,Properties: diff --git a/js/htk/fields/search-entry/index.js b/js/htk/search-entry/index.js similarity index 100% rename from js/htk/fields/search-entry/index.js rename to js/htk/search-entry/index.js diff --git a/js/htk/fields/search-entry/style.scss b/js/htk/search-entry/style.scss similarity index 100% rename from js/htk/fields/search-entry/style.scss rename to js/htk/search-entry/style.scss diff --git a/js/htk/fields/select/index.js b/js/htk/select/index.js similarity index 95% rename from js/htk/fields/select/index.js rename to js/htk/select/index.js index a247cca8..1899cb82 100644 --- a/js/htk/fields/select/index.js +++ b/js/htk/select/index.js @@ -1,5 +1,5 @@ require('./style.scss'); -var ColumnText = require('../../columns/text'); +var ColumnText = require('../columns/text'); module.exports = new Class({ Extends: Htk.Field @@ -40,8 +40,7 @@ module.exports = new Class({ /** * The number of rows in the form. */ - numRows: - { + numRows:{ type: Number ,get: function() { if (this._model) @@ -53,8 +52,7 @@ module.exports = new Class({ /** * Checks if the form data is ready. */ - ready: - { + ready:{ type: Boolean ,get: function() { return this._model && this._model.ready; @@ -63,8 +61,7 @@ module.exports = new Class({ /** * Checks if the form data is ready. */ - placeholder: - { + placeholder:{ type: String ,set: function(x) { this._placeholder = x; @@ -77,8 +74,7 @@ module.exports = new Class({ /** * Wether to allow null values. */ - notNull: - { + notNull:{ type: Boolean ,set: function(x) { this._notNull = x; @@ -93,7 +89,13 @@ module.exports = new Class({ $: { type: Object ,get: function() { - return this._model.getObject(this._row); + return this._model.getObject(this._row) || {}; + } + }, + params: { + type: Object + ,get: function() { + return this.$; } } } diff --git a/js/htk/fields/select/style.scss b/js/htk/select/style.scss similarity index 95% rename from js/htk/fields/select/style.scss rename to js/htk/select/style.scss index 9a678ebc..58b1e7f7 100644 --- a/js/htk/fields/select/style.scss +++ b/js/htk/select/style.scss @@ -1,4 +1,4 @@ -@import "../../style/variables"; +@import "../style/variables"; .htk-select { display: flex; diff --git a/js/htk/fields/spin/index.js b/js/htk/spin/index.js similarity index 100% rename from js/htk/fields/spin/index.js rename to js/htk/spin/index.js diff --git a/js/htk/spinner/index.js b/js/htk/spinner/index.js index d2139b45..326a68d9 100644 --- a/js/htk/spinner/index.js +++ b/js/htk/spinner/index.js @@ -1,8 +1,8 @@ require('./style.scss'); -var Widget = require('../widget'); +var Component = require('vn/component'); module.exports = new Class({ - Extends: Widget + Extends: Component ,Tag: 'htk-spinner' ,_started: false diff --git a/js/htk/step/index.js b/js/htk/step/index.js index b3d4a72e..7634d657 100644 --- a/js/htk/step/index.js +++ b/js/htk/step/index.js @@ -1,8 +1,8 @@ -var Widget = require('../widget'); +var Component = require('vn/component'); module.exports = new Class({ - Extends: Widget, + Extends: Component, Tag: 'htk-step', Properties: { name: { @@ -42,7 +42,7 @@ module.exports = new Class({ }, appendChild: function(child) { - if (child instanceof Widget) + if (child instanceof Component) child = child.node; this.node.appendChild(child); } diff --git a/js/htk/fields/table/index.js b/js/htk/table/index.js similarity index 95% rename from js/htk/fields/table/index.js rename to js/htk/table/index.js index 2f43ff03..26ed5fad 100644 --- a/js/htk/fields/table/index.js +++ b/js/htk/table/index.js @@ -1,6 +1,6 @@ var Entry = require('../entry'); -var ColumnRadio = require('../../columns/radio'); +var ColumnRadio = require('../columns/radio'); module.exports = new Class({ Extends: Entry diff --git a/js/htk/fields/text-area/index.js b/js/htk/text-area/index.js similarity index 100% rename from js/htk/fields/text-area/index.js rename to js/htk/text-area/index.js diff --git a/js/htk/fields/text/index.js b/js/htk/text/index.js similarity index 100% rename from js/htk/fields/text/index.js rename to js/htk/text/index.js diff --git a/js/vn/builder.js b/js/vn/builder.js index c6039494..437340e4 100644 --- a/js/vn/builder.js +++ b/js/vn/builder.js @@ -1,5 +1,5 @@ const VnObject = require('./object'); -const Widget = require('../htk/widget'); +const Component = require('./component'); const VnNode = require('./node'); const Scope = require('./scope'); const Type = require('./type'); @@ -515,7 +515,7 @@ module.exports = new Class({ const object = new context.klass(); object.setProperties(context.props); - if (context.nodeId && object instanceof Widget) { + if (context.nodeId && object instanceof Component) { var id = context.nodeId; object.htmlId = scope.getHtmlId(id); object.className = '_'+ id +' '+ object.className; @@ -646,7 +646,7 @@ module.exports = new Class({ for (var i = 0; i < childs.length; i++) { let child = objects[childs[i]]; - if (child instanceof Widget) + if (child instanceof Component) child = child.node; if (child instanceof Node) object.appendChild(child); diff --git a/js/htk/widget/index.js b/js/vn/component.js similarity index 56% rename from js/htk/widget/index.js rename to js/vn/component.js index 103d9daa..b52e4444 100644 --- a/js/htk/widget/index.js +++ b/js/vn/component.js @@ -1,11 +1,16 @@ -const NodeBuilder = require('../../vn/node-builder'); +const NodeBuilder = require('./node-builder'); -const WidgetClass = { +const Klass = new Class(); +module.exports = Klass; + +Klass.extend({Classes: ''}); + +const ComponentClass = { Extends: NodeBuilder ,Properties: { /** - * Main HTML node that represents the widget + * Main HTML node that represents the component */ node: { type: Object @@ -32,11 +37,24 @@ const WidgetClass = { class: { type: String ,set: function(x) { - this._cssClass = x; + this._className = x; this._refreshClass(); } ,get: function() { - return this._node.className; + return this._className; + } + }, + /** + * CSS classes to be appendend to the node classes. + */ + className: { + type: String + ,set: function(x) { + this._className = x; + this._refreshClass(); + } + ,get: function() { + return this._className; } }, /** @@ -78,6 +96,7 @@ const WidgetClass = { } ,_node: null + ,scope: null ,initialize: function(props) { this.doc = document; @@ -87,10 +106,20 @@ const WidgetClass = { ,createRoot: function(tagName) { const node = this._node = this.createElement(tagName); - if (this._htmlId) node.id = this._htmlId; + if (this._htmlId) + node.id = this._htmlId; + if (this.$constructor.Classes) + node.className = this.$constructor.Classes; return node; } + ,appendChild: function(child) { + if (child instanceof Klass) + this._node.appendChild(child.node); + else if (child instanceof Element) + this._node.appendChild(child); + } + ,renderBase: function() { if (this._node) return; @@ -100,8 +129,8 @@ const WidgetClass = { } ,_refreshClass: function() { - if (this._node && this._cssClass) - this._node.className = this._cssClass +' '+ this._node.className; + if (this._node && this._className) + this._node.className = this._className +' '+ this._node.className; } ,remove: function() { @@ -110,11 +139,38 @@ const WidgetClass = { ,on: function(id, callback, instance) { if (htmlEventMap[id]) { - this.node.addEventListener(id, + this.addEventListener(id, callback.bind(instance, this)); } else this.parent(id, callback, instance); } + + ,loadTemplateFromFile: function(path) { + const builder = new Vn.Builder(); + builder.compileFile(path); + this.loadScope(builder); + } + + ,loadTemplateFromString: function(xmlString) { + const builder = new Vn.Builder(); + builder.compileString(xmlString); + this.loadScope(builder); + } + + ,loadScope: function(builder) { + const scope = this.scope = builder.load(this.doc, this); + scope.link(); + + this.$ = scope.$; + this._node = scope.$.main; + } + + ,_destroy: function() { + if (this.scope) + this.scope.unref(); + + this.parent(); + } }; htmlEventMap = {}; @@ -141,9 +197,9 @@ htmlMethods = [ 'addEventListener' ]; htmlMethods.forEach(method => { - WidgetClass[method] = function() { + ComponentClass[method] = function() { this.node[method].apply(this.node, arguments); }; }); -module.exports = new Class(WidgetClass); +Klass.implement(ComponentClass); diff --git a/js/vn/lot.js b/js/vn/lot.js index 8d9cd5a4..68a4353d 100644 --- a/js/vn/lot.js +++ b/js/vn/lot.js @@ -8,7 +8,7 @@ module.exports = new Class({ ,Implements: LotIface ,Tag: 'vn-lot' ,Properties: { - params: { + $: { type: Object ,set: function(x) { this.setAll(x); @@ -17,13 +17,13 @@ module.exports = new Class({ return this._params; } } - ,$: { + ,params: { type: Object ,set: function(x) { - this.setAll(x); + this.$ = x; } ,get: function() { - return this._params; + return this.$; } } } diff --git a/js/vn/mutators.js b/js/vn/mutators.js index 11951890..0c681e0c 100644 --- a/js/vn/mutators.js +++ b/js/vn/mutators.js @@ -1,9 +1,8 @@ vnCustomTags = {}; -var Mutators = Class.Mutators; - -var _Extends = Mutators.Extends; +const Mutators = Class.Mutators; +const _Extends = Mutators.Extends; Mutators.Extends = function() { _Extends.apply(this, arguments); @@ -13,13 +12,22 @@ Mutators.Extends = function() { Mutators.Tag = function(tagName) { vnCustomTags[tagName] = this; this.extend({Tag: tagName}); + + const parent = this.parent; + if (parent && parent.Classes !== undefined) { + let Classes = tagName + + if (parent.Classes !== '') + Classes += ' '+ parent.Classes; + this.extend({Classes}); + } }; Mutators.Properties = function(props) { - var parentProps; + let parentProps; - for (var propName in props) { - var prop = props[propName]; + for (const propName in props) { + const prop = props[propName]; prop.configurable = true; if (!prop.get && !prop.set && prop.writable === undefined) @@ -27,19 +35,10 @@ Mutators.Properties = function(props) { } if (this.parent && (parentProps = this.parent.Properties)) - for (var propName in parentProps) + for (const propName in parentProps) if (!props[propName]) props[propName] = parentProps[propName]; this.extend({Properties: props}); Object.defineProperties(this.prototype, props); }; - -Mutators.Parent = function(propName) { - this.extend({Parent: propName}); -}; - -Mutators.Child = function(propName) { - this.extend({Child: propName}); -}; - diff --git a/js/vn/vn.js b/js/vn/vn.js index feb249d5..5e272e9d 100644 --- a/js/vn/vn.js +++ b/js/vn/vn.js @@ -27,6 +27,7 @@ Vn = module.exports = { ,Form : require('./form') ,Node : require('./node') ,NodeBuilder : require('./node-builder') + ,Component : require('./component') ,Builder : require('./builder') ,JsonException : require('./json-exception') ,JsonConnection : require('./json-connection')