@maiyunnet/kebab 9.6.0 → 9.7.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.
package/doc/kebab-rag.md CHANGED
@@ -1360,7 +1360,7 @@ index/variables/VER.md
1360
1360
 
1361
1361
  # Variable: VER
1362
1362
 
1363
- > `const` **VER**: `"9.6.0"` = `'9.6.0'`
1363
+ > `const` **VER**: `"9.7.0"` = `'9.7.0'`
1364
1364
 
1365
1365
  Defined in: [index.ts:10](https://github.com/maiyunnet/kebab/blob/master/index.ts#L10)
1366
1366
 
@@ -13675,7 +13675,7 @@ Defined in: [lib/sql.ts:69](https://github.com/maiyunnet/kebab/blob/master/lib/s
13675
13675
 
13676
13676
  > **append**(`sql`): `this`
13677
13677
 
13678
- Defined in: [lib/sql.ts:980](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L980)
13678
+ Defined in: [lib/sql.ts:1003](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L1003)
13679
13679
 
13680
13680
  在 sql 最后追加字符串
13681
13681
 
@@ -13695,7 +13695,7 @@ Defined in: [lib/sql.ts:980](https://github.com/maiyunnet/kebab/blob/master/lib/
13695
13695
 
13696
13696
  > **by**(`c`, `d?`): `this`
13697
13697
 
13698
- Defined in: [lib/sql.ts:736](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L736)
13698
+ Defined in: [lib/sql.ts:759](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L759)
13699
13699
 
13700
13700
  ORDER BY
13701
13701
 
@@ -13723,7 +13723,7 @@ ORDER BY
13723
13723
 
13724
13724
  > **copy**(`f?`, `opt?`): `Sql`
13725
13725
 
13726
- Defined in: [lib/sql.ts:804](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L804)
13726
+ Defined in: [lib/sql.ts:827](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L827)
13727
13727
 
13728
13728
  创建一个本对象的一个新的 sql 对象拷贝
13729
13729
 
@@ -13751,7 +13751,7 @@ Defined in: [lib/sql.ts:804](https://github.com/maiyunnet/kebab/blob/master/lib/
13751
13751
 
13752
13752
  > **crossJoin**(`f`, `s?`, `suf?`, `pre?`): `this`
13753
13753
 
13754
- Defined in: [lib/sql.ts:485](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L485)
13754
+ Defined in: [lib/sql.ts:488](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L488)
13755
13755
 
13756
13756
  cross join 方法
13757
13757
 
@@ -13791,7 +13791,7 @@ MySQL 时为表前缀,PostgreSQL 时为 Schema 名,仅在 join 非默认前
13791
13791
 
13792
13792
  > **delete**(`f`): `this`
13793
13793
 
13794
- Defined in: [lib/sql.ts:373](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L373)
13794
+ Defined in: [lib/sql.ts:376](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L376)
13795
13795
 
13796
13796
  'xx'
13797
13797
 
@@ -13813,7 +13813,7 @@ Defined in: [lib/sql.ts:373](https://github.com/maiyunnet/kebab/blob/master/lib/
13813
13813
 
13814
13814
  > **field**(`str`, `pre?`, `suf?`): `string`
13815
13815
 
13816
- Defined in: [lib/sql.ts:991](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L991)
13816
+ Defined in: [lib/sql.ts:1014](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L1014)
13817
13817
 
13818
13818
  对字段进行包裹
13819
13819
 
@@ -13845,7 +13845,7 @@ MySQL 时为表前缀,PostgreSQL 时为 Schema 名,仅请在 field 表名时
13845
13845
 
13846
13846
  > **format**(`sql?`, `data?`): `string`
13847
13847
 
13848
- Defined in: [lib/sql.ts:970](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L970)
13848
+ Defined in: [lib/sql.ts:993](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L993)
13849
13849
 
13850
13850
  获取带 data 的 sql 语句
13851
13851
 
@@ -13869,7 +13869,7 @@ Defined in: [lib/sql.ts:970](https://github.com/maiyunnet/kebab/blob/master/lib/
13869
13869
 
13870
13870
  > **fullJoin**(`f`, `s?`, `suf?`, `pre?`): `this`
13871
13871
 
13872
- Defined in: [lib/sql.ts:474](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L474)
13872
+ Defined in: [lib/sql.ts:477](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L477)
13873
13873
 
13874
13874
  full join 方法
13875
13875
 
@@ -13909,7 +13909,7 @@ MySQL 时为表前缀,PostgreSQL 时为 Schema 名,仅在 join 非默认前
13909
13909
 
13910
13910
  > **getData**(): [`DbValue`](../../../index/type-aliases/DbValue.md)[]
13911
13911
 
13912
- Defined in: [lib/sql.ts:954](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L954)
13912
+ Defined in: [lib/sql.ts:977](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L977)
13913
13913
 
13914
13914
  获取全部 data
13915
13915
 
@@ -13923,7 +13923,7 @@ Defined in: [lib/sql.ts:954](https://github.com/maiyunnet/kebab/blob/master/lib/
13923
13923
 
13924
13924
  > **getPre**(): `string`
13925
13925
 
13926
- Defined in: [lib/sql.ts:961](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L961)
13926
+ Defined in: [lib/sql.ts:984](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L984)
13927
13927
 
13928
13928
  获取定义的 pre
13929
13929
 
@@ -13937,7 +13937,7 @@ Defined in: [lib/sql.ts:961](https://github.com/maiyunnet/kebab/blob/master/lib/
13937
13937
 
13938
13938
  > **getSql**(): `string`
13939
13939
 
13940
- Defined in: [lib/sql.ts:938](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L938)
13940
+ Defined in: [lib/sql.ts:961](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L961)
13941
13941
 
13942
13942
  获取 sql 语句
13943
13943
 
@@ -13951,7 +13951,7 @@ Defined in: [lib/sql.ts:938](https://github.com/maiyunnet/kebab/blob/master/lib/
13951
13951
 
13952
13952
  > **group**(`c`): `this`
13953
13953
 
13954
- Defined in: [lib/sql.ts:760](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L760)
13954
+ Defined in: [lib/sql.ts:783](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L783)
13955
13955
 
13956
13956
  GROUP BY
13957
13957
 
@@ -13973,7 +13973,7 @@ GROUP BY
13973
13973
 
13974
13974
  > **having**(`s?`): `this`
13975
13975
 
13976
- Defined in: [lib/sql.ts:492](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L492)
13976
+ Defined in: [lib/sql.ts:495](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L495)
13977
13977
 
13978
13978
  having 后置筛选器,用法类似 where
13979
13979
 
@@ -13993,7 +13993,7 @@ having 后置筛选器,用法类似 where
13993
13993
 
13994
13994
  > **innerJoin**(`f`, `s?`, `suf?`, `pre?`): `this`
13995
13995
 
13996
- Defined in: [lib/sql.ts:463](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L463)
13996
+ Defined in: [lib/sql.ts:466](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L466)
13997
13997
 
13998
13998
  inner join 方法
13999
13999
 
@@ -14061,7 +14061,7 @@ Defined in: [lib/sql.ts:99](https://github.com/maiyunnet/kebab/blob/master/lib/s
14061
14061
 
14062
14062
  > **join**(`f`, `s?`, `type?`, `suf?`, `pre?`): `this`
14063
14063
 
14064
- Defined in: [lib/sql.ts:415](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L415)
14064
+ Defined in: [lib/sql.ts:418](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L418)
14065
14065
 
14066
14066
  join 方法
14067
14067
 
@@ -14107,7 +14107,7 @@ MySQL 时为表前缀,PostgreSQL 时为 Schema 名,仅在 join 非默认前
14107
14107
 
14108
14108
  > **leftJoin**(`f`, `s?`, `suf?`, `pre?`): `this`
14109
14109
 
14110
- Defined in: [lib/sql.ts:441](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L441)
14110
+ Defined in: [lib/sql.ts:444](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L444)
14111
14111
 
14112
14112
  left join 方法
14113
14113
 
@@ -14147,7 +14147,7 @@ MySQL 时为表前缀,PostgreSQL 时为 Schema 名,仅在 join 非默认前
14147
14147
 
14148
14148
  > **limit**(`a`, `b?`): `this`
14149
14149
 
14150
- Defined in: [lib/sql.ts:780](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L780)
14150
+ Defined in: [lib/sql.ts:803](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L803)
14151
14151
 
14152
14152
  LIMIT(limit、offset, limit)
14153
14153
 
@@ -14175,7 +14175,7 @@ LIMIT(limit、offset, limit)
14175
14175
 
14176
14176
  > **lock**(): `this`
14177
14177
 
14178
- Defined in: [lib/sql.ts:795](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L795)
14178
+ Defined in: [lib/sql.ts:818](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L818)
14179
14179
 
14180
14180
  追加消极锁,通常不建议使用
14181
14181
 
@@ -14189,7 +14189,7 @@ Defined in: [lib/sql.ts:795](https://github.com/maiyunnet/kebab/blob/master/lib/
14189
14189
 
14190
14190
  > **rightJoin**(`f`, `s?`, `suf?`, `pre?`): `this`
14191
14191
 
14192
- Defined in: [lib/sql.ts:452](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L452)
14192
+ Defined in: [lib/sql.ts:455](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L455)
14193
14193
 
14194
14194
  right join 方法
14195
14195
 
@@ -14229,7 +14229,7 @@ MySQL 时为表前缀,PostgreSQL 时为 Schema 名,仅在 join 非默认前
14229
14229
 
14230
14230
  > **select**(`c`, `f`): `this`
14231
14231
 
14232
- Defined in: [lib/sql.ts:264](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L264)
14232
+ Defined in: [lib/sql.ts:267](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L267)
14233
14233
 
14234
14234
  '*', 'xx'
14235
14235
 
@@ -14257,7 +14257,7 @@ Defined in: [lib/sql.ts:264](https://github.com/maiyunnet/kebab/blob/master/lib/
14257
14257
 
14258
14258
  > **union**(`lsql`, `type?`): `this`
14259
14259
 
14260
- Defined in: [lib/sql.ts:385](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L385)
14260
+ Defined in: [lib/sql.ts:388](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L388)
14261
14261
 
14262
14262
  联查另一个 sql 对象
14263
14263
 
@@ -14285,7 +14285,7 @@ sql 对象
14285
14285
 
14286
14286
  > **unionAll**(`lsql`): `this`
14287
14287
 
14288
- Defined in: [lib/sql.ts:403](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L403)
14288
+ Defined in: [lib/sql.ts:406](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L406)
14289
14289
 
14290
14290
  所有联查另一个 sql 对象
14291
14291
 
@@ -14307,7 +14307,7 @@ sql 对象
14307
14307
 
14308
14308
  > **update**(`f`, `s`): `this`
14309
14309
 
14310
- Defined in: [lib/sql.ts:305](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L305)
14310
+ Defined in: [lib/sql.ts:308](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L308)
14311
14311
 
14312
14312
  UPDATE SQL 方法
14313
14313
 
@@ -14433,7 +14433,7 @@ Defined in: [lib/sql.ts:118](https://github.com/maiyunnet/kebab/blob/master/lib/
14433
14433
 
14434
14434
  > **where**(`s`): `this`
14435
14435
 
14436
- Defined in: [lib/sql.ts:526](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L526)
14436
+ Defined in: [lib/sql.ts:529](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L529)
14437
14437
 
14438
14438
  筛选器
14439
14439
  1. 'city': 'bj', 'type': '2'
@@ -14576,7 +14576,7 @@ lib/sql/functions/aoMix.md
14576
14576
 
14577
14577
  > **aoMix**(`arr`): `Record`\<`string`, `string` \| `number` \| [`Json`](../../../index/type-aliases/Json.md)\>
14578
14578
 
14579
- Defined in: [lib/sql.ts:1376](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L1376)
14579
+ Defined in: [lib/sql.ts:1399](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L1399)
14580
14580
 
14581
14581
  将数组兑换为组合的对象(Array/Object mix)
14582
14582
 
@@ -14605,7 +14605,7 @@ lib/sql/functions/column.md
14605
14605
 
14606
14606
  > **column**(`field`): `object`
14607
14607
 
14608
- Defined in: [lib/sql.ts:1397](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L1397)
14608
+ Defined in: [lib/sql.ts:1420](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L1420)
14609
14609
 
14610
14610
  创建字段对象
14611
14611
 
@@ -14644,7 +14644,7 @@ lib/sql/functions/format.md
14644
14644
 
14645
14645
  > **format**(`sql`, `data`, `service?`): `string`
14646
14646
 
14647
- Defined in: [lib/sql.ts:1338](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L1338)
14647
+ Defined in: [lib/sql.ts:1361](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L1361)
14648
14648
 
14649
14649
  返回代入后的完整 SQL 字符串,这并不安全不能直接执行,只是用来调试打印 sql 语句
14650
14650
 
@@ -14685,7 +14685,7 @@ lib/sql/functions/get.md
14685
14685
 
14686
14686
  > **get**(`opt`): [`Sql`](../classes/Sql.md)
14687
14687
 
14688
- Defined in: [lib/sql.ts:1310](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L1310)
14688
+ Defined in: [lib/sql.ts:1333](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L1333)
14689
14689
 
14690
14690
  创建 sql 对象
14691
14691
 
@@ -14738,7 +14738,7 @@ lib/sql/functions/json.md
14738
14738
 
14739
14739
  > **json**(`obj`): `any`
14740
14740
 
14741
- Defined in: [lib/sql.ts:1435](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L1435)
14741
+ Defined in: [lib/sql.ts:1458](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L1458)
14742
14742
 
14743
14743
  将对象转换为 JSON 字符串并避开类型检查,用于适配 PostgreSQL 的 jsonb 字段
14744
14744
 
@@ -14767,7 +14767,7 @@ lib/sql/functions/value.md
14767
14767
 
14768
14768
  > **value**(`val`): `object`
14769
14769
 
14770
- Defined in: [lib/sql.ts:1416](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L1416)
14770
+ Defined in: [lib/sql.ts:1439](https://github.com/maiyunnet/kebab/blob/master/lib/sql.ts#L1439)
14771
14771
 
14772
14772
  创建字面量值对象,用于 where 条件中 v[0] 需要是值而非字段名的场景
14773
14773
  例:[value('hello'), 'IN', column('tags')]
package/index.d.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  * --- 本文件用来定义每个目录实体地址的常量 ---
6
6
  */
7
7
  /** --- 当前系统版本号 --- */
8
- export declare const VER = "9.6.0";
8
+ export declare const VER = "9.7.0";
9
9
  /** --- 框架根目录,以 / 结尾 --- */
10
10
  export declare const ROOT_PATH: string;
11
11
  /** --- 框架的 LIB,以 / 结尾 --- */
package/index.js CHANGED
@@ -6,7 +6,7 @@
6
6
  * --- 本文件用来定义每个目录实体地址的常量 ---
7
7
  */
8
8
  /** --- 当前系统版本号 --- */
9
- export const VER = '9.6.0';
9
+ export const VER = '9.7.0';
10
10
  // --- 服务端用的路径 ---
11
11
  const imu = decodeURIComponent(import.meta.url).replace('file://', '').replace(/^\/(\w:)/, '$1');
12
12
  /** --- /xxx/xxx --- */
package/lib/sql.js CHANGED
@@ -182,21 +182,24 @@ export class Sql {
182
182
  const quotedTable = this.field(table, this._pre);
183
183
  const quotedKey = this.field(key);
184
184
  if (this._service === ESERVICE.MYSQL) {
185
- // --- MySQL 8.0.19+ VALUES ROW() 派生表语法 ---
186
- const valueParts = [];
187
- for (const row of rows) {
188
- const parts = row.map(v => {
185
+ // --- MySQL 使用 UNION ALL SELECT 子查询,比 VALUES ROW() 更稳定 ---
186
+ // --- MySQL 8.0 优化器在行数较多时对 VALUES ROW() 派生表会走不同执行路径,
187
+ // 导致列名别名解析失败,JOIN 静默匹配 0 行;UNION ALL 无此问题 ---
188
+ const selectParts = [];
189
+ for (let ri = 0; ri < rows.length; ri++) {
190
+ const row = rows[ri];
191
+ const parts = row.map((v, ci) => {
189
192
  const result = this._processValue(v);
190
193
  if (result.data.length > 0) {
191
194
  this._data.push(...result.data);
192
195
  }
193
- return result.sql;
196
+ // --- 第一行加列名别名,后续行省略 ---
197
+ return ri === 0 ? `${result.sql} AS ${this.field(allCols[ci])}` : result.sql;
194
198
  });
195
- valueParts.push(`ROW(${parts.join(', ')})`);
199
+ selectParts.push(`SELECT ${parts.join(', ')}`);
196
200
  }
197
- const tmpCols = allCols.map(c => this.field(c)).join(', ');
198
201
  const setClauses = cols.map(c => `t.${this.field(c)} = tmp.${this.field(c)}`).join(', ');
199
- this._sql = [`UPDATE ${quotedTable} t INNER JOIN (VALUES ${valueParts.join(', ')}) AS tmp(${tmpCols}) ON t.${quotedKey} = tmp.${quotedKey} SET ${setClauses}`];
202
+ this._sql = [`UPDATE ${quotedTable} t INNER JOIN (${selectParts.join(' UNION ALL ')}) AS tmp ON t.${quotedKey} = tmp.${quotedKey} SET ${setClauses}`];
200
203
  }
201
204
  else {
202
205
  // --- PostgreSQL 使用 UPDATE FROM (VALUES ...) ---
@@ -596,8 +599,18 @@ export class Sql {
596
599
  // --- 3 ---
597
600
  sql += this.field(v[0]) + ' ' + v[1].toUpperCase() + ' (';
598
601
  for (const v1 of v[2]) {
599
- sql += this._placeholder() + ', ';
600
- data.push(v1);
602
+ if (Array.isArray(v1)) {
603
+ sql += '(';
604
+ for (const v2 of v1) {
605
+ sql += this._placeholder() + ', ';
606
+ data.push(v2);
607
+ }
608
+ sql = sql.slice(0, -2) + '), ';
609
+ }
610
+ else {
611
+ sql += this._placeholder() + ', ';
612
+ data.push(v1);
613
+ }
601
614
  }
602
615
  sql = sql.slice(0, -2) + ') AND ';
603
616
  }
@@ -658,8 +671,18 @@ export class Sql {
658
671
  if (v.length > 0) {
659
672
  sql += this.field(k) + ' IN (';
660
673
  for (const v1 of v) {
661
- sql += this._placeholder() + ', ';
662
- data.push(v1);
674
+ if (Array.isArray(v1)) {
675
+ sql += '(';
676
+ for (const v2 of v1) {
677
+ sql += this._placeholder() + ', ';
678
+ data.push(v2);
679
+ }
680
+ sql = sql.slice(0, -2) + '), ';
681
+ }
682
+ else {
683
+ sql += this._placeholder() + ', ';
684
+ data.push(v1);
685
+ }
663
686
  }
664
687
  sql = sql.slice(0, -2) + ') AND ';
665
688
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maiyunnet/kebab",
3
- "version": "9.6.0",
3
+ "version": "9.7.0",
4
4
  "description": "Simple, easy-to-use, and fully-featured Node.js framework that is ready-to-use out of the box.",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -3405,12 +3405,14 @@ Result:<pre id="result">Nothing.</pre>`);
3405
3405
  s = sql.update('order', { 'state': '1' }).where({
3406
3406
  'user_id': '2',
3407
3407
  'state': ['1', '2', '3'],
3408
+ '(a, b, c)': [['1', '2', '3'], ['4', '5', '6']],
3408
3409
  '$or': [{ 'type': '1', 'find': '0' }, { 'type': '2', 'find': '1' }, [['type', '<', '-1']]]
3409
3410
  }).getSql();
3410
3411
  sd = sql.getData();
3411
3412
  echo.push(`<pre>sql.update('order', { 'state': '1' }).where({
3412
3413
  'user_id': '2',
3413
3414
  'state': ['1', '2', '3'],
3415
+ '(a, b, c)': [['1', '2', '3'], ['4', '5', '6']],
3414
3416
  '$or': [{ 'type': '1', 'find': '0' }, { 'type': '2', 'find': '1' }, [['type', '<', '-1']]]
3415
3417
  });</pre>
3416
3418
  <b>getSql() :</b> ${s}<br>