@justeattakeaway/pie-button 0.37.1 → 0.38.1-next.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/README.md +3 -1
- package/dist/index.d.ts +12 -0
- package/dist/index.js +278 -266
- package/dist/react.d.ts +13 -1
- package/dist/react.js +39 -60
- package/package.json +4 -4
- package/src/button.scss +74 -33
- package/src/defs.ts +11 -0
- package/src/index.ts +11 -0
package/dist/react.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { CSSResult } from 'lit';
|
|
2
2
|
import type { LitElement } from 'lit';
|
|
3
3
|
import type { PropertyValues } from 'lit';
|
|
4
|
-
import type { ReactWebComponent } from '@lit
|
|
4
|
+
import type { ReactWebComponent } from '@lit/react';
|
|
5
5
|
import type { TemplateResult } from 'lit';
|
|
6
6
|
|
|
7
7
|
export declare interface ButtonProps {
|
|
@@ -33,6 +33,10 @@ export declare interface ButtonProps {
|
|
|
33
33
|
* When true, displays a loading indicator inside the button.
|
|
34
34
|
*/
|
|
35
35
|
isLoading: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* When true, enables the responsive size feature.
|
|
38
|
+
*/
|
|
39
|
+
isResponsive: boolean;
|
|
36
40
|
/**
|
|
37
41
|
* The name of the button, submitted as a pair with the button's value as part of the form data, when that button is used to submit the form.
|
|
38
42
|
* [MDN reference](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attributes)
|
|
@@ -71,6 +75,10 @@ export declare interface ButtonProps {
|
|
|
71
75
|
* [MDN reference](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attributes)
|
|
72
76
|
*/
|
|
73
77
|
formtarget?: typeof formTargetTypes[number];
|
|
78
|
+
/**
|
|
79
|
+
* What size should be attributed to the button when isResponsive is true and the screen is wide.
|
|
80
|
+
*/
|
|
81
|
+
responsiveSize?: typeof responsiveSizes[number];
|
|
74
82
|
}
|
|
75
83
|
|
|
76
84
|
export declare const formEncodingtypes: readonly ["application/x-www-form-urlencoded", "multipart/form-data", "text/plain"];
|
|
@@ -103,6 +111,7 @@ declare class PieButton_2 extends LitElement implements ButtonProps {
|
|
|
103
111
|
disabled: boolean;
|
|
104
112
|
isLoading: boolean;
|
|
105
113
|
isFullWidth: boolean;
|
|
114
|
+
isResponsive: boolean;
|
|
106
115
|
name?: string;
|
|
107
116
|
value?: string;
|
|
108
117
|
formaction: ButtonProps['formaction'];
|
|
@@ -110,6 +119,7 @@ declare class PieButton_2 extends LitElement implements ButtonProps {
|
|
|
110
119
|
formmethod: ButtonProps['formmethod'];
|
|
111
120
|
formnovalidate: ButtonProps['formnovalidate'];
|
|
112
121
|
formtarget: ButtonProps['formtarget'];
|
|
122
|
+
responsiveSize?: ButtonProps['responsiveSize'];
|
|
113
123
|
/**
|
|
114
124
|
* This method creates an invisible button of the same type as pie-button. It is then clicked, and immediately removed from the DOM.
|
|
115
125
|
* This is done so that we trigger native form actions, such as submit and reset in the browser. The performance impact of adding and removing a single button to the DOM
|
|
@@ -132,6 +142,8 @@ declare class PieButton_2 extends LitElement implements ButtonProps {
|
|
|
132
142
|
static styles: CSSResult;
|
|
133
143
|
}
|
|
134
144
|
|
|
145
|
+
export declare const responsiveSizes: readonly ["productive", "expressive"];
|
|
146
|
+
|
|
135
147
|
export declare const sizes: readonly ["xsmall", "small-productive", "small-expressive", "medium", "large"];
|
|
136
148
|
|
|
137
149
|
export declare const types: readonly ["submit", "button", "reset"];
|
package/dist/react.js
CHANGED
|
@@ -1,78 +1,57 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as y from "react";
|
|
2
2
|
import { PieButton as E } from "./index.js";
|
|
3
|
-
import { formEncodingtypes as k, formMethodTypes as
|
|
3
|
+
import { formEncodingtypes as k, formMethodTypes as C, formTargetTypes as S, iconPlacements as j, responsiveSizes as x, sizes as z, types as A, variants as H } from "./index.js";
|
|
4
4
|
import "lit";
|
|
5
5
|
import "lit/decorators.js";
|
|
6
|
+
import "lit/directives/if-defined.js";
|
|
6
7
|
import "@justeattakeaway/pie-spinner";
|
|
7
8
|
/**
|
|
8
9
|
* @license
|
|
9
10
|
* Copyright 2018 Google LLC
|
|
10
11
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
11
12
|
*/
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
let
|
|
16
|
-
|
|
17
|
-
let
|
|
18
|
-
|
|
19
|
-
})(t,
|
|
20
|
-
},
|
|
21
|
-
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
constructor() {
|
|
33
|
-
super(...arguments), this.o = null;
|
|
34
|
-
}
|
|
35
|
-
t(e) {
|
|
36
|
-
if (this.o !== null)
|
|
37
|
-
for (const h in this.i)
|
|
38
|
-
M(this.o, h, this.props[h], e ? e[h] : void 0, p);
|
|
39
|
-
}
|
|
40
|
-
componentDidMount() {
|
|
13
|
+
const N = /* @__PURE__ */ new Set(["children", "localName", "ref", "style", "className"]), v = /* @__PURE__ */ new WeakMap(), g = (t, c, a, l, u) => {
|
|
14
|
+
const m = u == null ? void 0 : u[c];
|
|
15
|
+
m === void 0 || a === l ? (t[c] = a, a == null && c in HTMLElement.prototype && t.removeAttribute(c)) : ((i, n, o) => {
|
|
16
|
+
let s = v.get(i);
|
|
17
|
+
s === void 0 && v.set(i, s = /* @__PURE__ */ new Map());
|
|
18
|
+
let r = s.get(n);
|
|
19
|
+
o !== void 0 ? r === void 0 ? (s.set(n, r = { handleEvent: o }), i.addEventListener(n, r)) : r.handleEvent = o : r !== void 0 && (s.delete(n), i.removeEventListener(n, r));
|
|
20
|
+
})(t, m, a);
|
|
21
|
+
}, h = ({ react: t, tagName: c, elementClass: a, events: l, displayName: u }) => {
|
|
22
|
+
const m = new Set(Object.keys(l ?? {})), i = t.forwardRef((n, o) => {
|
|
23
|
+
const s = t.useRef(null), r = t.useRef(null), p = {}, d = {};
|
|
24
|
+
for (const [e, f] of Object.entries(n))
|
|
25
|
+
N.has(e) ? p[e === "className" ? "class" : e] = f : m.has(e) || e in a.prototype ? d[e] = f : p[e] = f;
|
|
26
|
+
return t.useLayoutEffect(() => {
|
|
27
|
+
if (r.current !== null) {
|
|
28
|
+
for (const e in d)
|
|
29
|
+
g(r.current, e, n[e], s.current ? s.current[e] : void 0, l);
|
|
30
|
+
s.current = n;
|
|
31
|
+
}
|
|
32
|
+
}), t.useLayoutEffect(() => {
|
|
41
33
|
var e;
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
this.h !== e && (this.u = (s) => {
|
|
50
|
-
e !== null && P(e, s), this.o = s, this.h = e;
|
|
51
|
-
}), this.i = {};
|
|
52
|
-
const v = { ref: this.u };
|
|
53
|
-
for (const [s, y] of Object.entries(h))
|
|
54
|
-
b.has(s) ? v[s === "className" ? "class" : s] = y : l.has(s) || s in n.prototype ? this.i[s] = y : v[s] = y;
|
|
55
|
-
return v.suppressHydrationWarning = !0, a(r, v);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
f.displayName = d ?? n.name;
|
|
59
|
-
const N = i.forwardRef((c, e) => a(f, { ...c, _$Gl: e }, c == null ? void 0 : c.children));
|
|
60
|
-
return N.displayName = f.displayName, N;
|
|
61
|
-
}
|
|
62
|
-
const R = B({
|
|
34
|
+
(e = r.current) == null || e.removeAttribute("defer-hydration");
|
|
35
|
+
}, []), p.suppressHydrationWarning = !0, t.createElement(c, { ...p, ref: t.useCallback((e) => {
|
|
36
|
+
r.current = e, typeof o == "function" ? o(e) : o !== null && (o.current = e);
|
|
37
|
+
}, [o]) });
|
|
38
|
+
});
|
|
39
|
+
return i.displayName = u ?? a.name, i;
|
|
40
|
+
}, M = h({
|
|
63
41
|
displayName: "PieButton",
|
|
64
42
|
elementClass: E,
|
|
65
|
-
react:
|
|
43
|
+
react: y,
|
|
66
44
|
tagName: "pie-button",
|
|
67
45
|
events: {}
|
|
68
46
|
});
|
|
69
47
|
export {
|
|
70
|
-
|
|
48
|
+
M as PieButton,
|
|
71
49
|
k as formEncodingtypes,
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
50
|
+
C as formMethodTypes,
|
|
51
|
+
S as formTargetTypes,
|
|
52
|
+
j as iconPlacements,
|
|
53
|
+
x as responsiveSizes,
|
|
54
|
+
z as sizes,
|
|
55
|
+
A as types,
|
|
56
|
+
H as variants
|
|
78
57
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@justeattakeaway/pie-button",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.38.1-next.0",
|
|
4
4
|
"description": "PIE design system button built using web components",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"author": "Just Eat Takeaway.com - Design System Team",
|
|
29
29
|
"license": "Apache-2.0",
|
|
30
30
|
"devDependencies": {
|
|
31
|
-
"@justeattakeaway/pie-components-config": "0.
|
|
31
|
+
"@justeattakeaway/pie-components-config": "0.6.0"
|
|
32
32
|
},
|
|
33
33
|
"volta": {
|
|
34
34
|
"extends": "../../../package.json"
|
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
"dist/*.js"
|
|
38
38
|
],
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@justeattakeaway/pie-spinner": "0.2.
|
|
41
|
-
"@justeattakeaway/pie-webc-core": "0.
|
|
40
|
+
"@justeattakeaway/pie-spinner": "0.2.2-next.0",
|
|
41
|
+
"@justeattakeaway/pie-webc-core": "0.12.0-next.0",
|
|
42
42
|
"element-internals-polyfill": "1.3.8"
|
|
43
43
|
}
|
|
44
44
|
}
|
package/src/button.scss
CHANGED
|
@@ -6,6 +6,20 @@
|
|
|
6
6
|
box-sizing: border-box;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
$breakpoint-wide: 768px;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Mixin for adding the responsive behaviour.
|
|
13
|
+
* Takes in the the particular settings for the wide breakpoint.
|
|
14
|
+
*/
|
|
15
|
+
@mixin responsive-wide {
|
|
16
|
+
&[isResponsive] {
|
|
17
|
+
@media (min-width: $breakpoint-wide) {
|
|
18
|
+
@content;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
9
23
|
// Base button styles
|
|
10
24
|
.o-btn {
|
|
11
25
|
// Custom Property Declarations
|
|
@@ -14,11 +28,6 @@
|
|
|
14
28
|
--btn-font-family: var(--dt-font-interactive-m-family);
|
|
15
29
|
--btn-font-weight: var(--dt-font-interactive-m-weight);
|
|
16
30
|
|
|
17
|
-
// The base values are set to the size default, which is for the medium button size
|
|
18
|
-
--btn-padding: 10px var(--dt-spacing-e);
|
|
19
|
-
--btn-font-size: #{p.font-size(--dt-font-size-20)};
|
|
20
|
-
--btn-line-height: calc(var(--dt-font-size-20-line-height) * 1px);
|
|
21
|
-
|
|
22
31
|
// The following values set to default background and color
|
|
23
32
|
// currently this sets the primary button styles
|
|
24
33
|
--btn-bg-color: var(--dt-color-interactive-brand);
|
|
@@ -30,11 +39,43 @@
|
|
|
30
39
|
--btn-height--medium: 48px;
|
|
31
40
|
--btn-height--large: 56px;
|
|
32
41
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
42
|
+
/**
|
|
43
|
+
* Mixin for updating the button styles based on the size passed in.
|
|
44
|
+
* Takes in the name of the size to be used.
|
|
45
|
+
*/
|
|
46
|
+
@mixin button-size($size) {
|
|
47
|
+
@if $size == 'xsmall' {
|
|
48
|
+
--btn-height: var(--btn-height--xsmall);
|
|
49
|
+
--btn-padding: 6px var(--dt-spacing-b);
|
|
50
|
+
--btn-font-size: #{p.font-size(--dt-font-size-14)};
|
|
51
|
+
--btn-line-height: calc(var(--dt-font-size-14-line-height) * 1px);
|
|
52
|
+
--btn-icon-size: 16px;
|
|
53
|
+
} @else if $size == 'small-expressive' {
|
|
54
|
+
--btn-height: var(--btn-height--small);
|
|
55
|
+
--btn-padding: 6px var(--dt-spacing-d);
|
|
56
|
+
--btn-font-size: #{p.font-size(--dt-font-size-20)};
|
|
57
|
+
--btn-line-height: calc(var(--dt-font-size-20-line-height) * 1px);
|
|
58
|
+
--btn-icon-size: 20px;
|
|
59
|
+
} @else if $size == 'small-productive' {
|
|
60
|
+
--btn-height: var(--btn-height--small);
|
|
61
|
+
--btn-padding: 8px var(--dt-spacing-d);
|
|
62
|
+
--btn-font-size: #{p.font-size(--dt-font-size-16)};
|
|
63
|
+
--btn-line-height: calc(var(--dt-font-size-16-line-height) * 1px);
|
|
64
|
+
--btn-icon-size: 20px;
|
|
65
|
+
} @else if $size == 'medium' {
|
|
66
|
+
--btn-height: var(--btn-height--medium);
|
|
67
|
+
--btn-padding: 10px var(--dt-spacing-e);
|
|
68
|
+
--btn-font-size: #{p.font-size(--dt-font-size-20)};
|
|
69
|
+
--btn-line-height: calc(var(--dt-font-size-20-line-height) * 1px);
|
|
70
|
+
--btn-icon-size: 24px;
|
|
71
|
+
} @else if $size == 'large' {
|
|
72
|
+
--btn-height: var(--btn-height--large);
|
|
73
|
+
--btn-padding: 14px var(--dt-spacing-e);
|
|
74
|
+
--btn-font-size: #{p.font-size(--dt-font-size-20)};
|
|
75
|
+
--btn-line-height: calc(var(--dt-font-size-20-line-height) * 1px);
|
|
76
|
+
--btn-icon-size: 24px;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
38
79
|
|
|
39
80
|
position: relative;
|
|
40
81
|
display: flex;
|
|
@@ -71,7 +112,7 @@
|
|
|
71
112
|
**/
|
|
72
113
|
--btn-bg-color: var(--dt-color-interactive-primary);
|
|
73
114
|
|
|
74
|
-
@include p.button-interactive-states('--dt-color-interactive-primary', '
|
|
115
|
+
@include p.button-interactive-states('--dt-color-interactive-primary', 'inverse');
|
|
75
116
|
}
|
|
76
117
|
}
|
|
77
118
|
|
|
@@ -160,40 +201,40 @@
|
|
|
160
201
|
}
|
|
161
202
|
|
|
162
203
|
&[size='xsmall'] {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
--btn-height: var(--btn-height--small);
|
|
173
|
-
--btn-icon-size: 20px;
|
|
204
|
+
@include button-size(xsmall);
|
|
205
|
+
@include responsive-wide {
|
|
206
|
+
// productive is the default size when responsive is enabled
|
|
207
|
+
@include button-size(small-productive);
|
|
208
|
+
|
|
209
|
+
&[responsiveSize='expressive'] {
|
|
210
|
+
@include button-size(small-expressive);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
174
213
|
}
|
|
175
214
|
|
|
176
215
|
&[size='small-expressive'] {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
216
|
+
@include button-size(small-expressive);
|
|
217
|
+
@include responsive-wide {
|
|
218
|
+
@include button-size(medium);
|
|
219
|
+
}
|
|
180
220
|
}
|
|
181
221
|
|
|
182
222
|
&[size='small-productive'] {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
223
|
+
@include button-size(small-productive);
|
|
224
|
+
@include responsive-wide {
|
|
225
|
+
@include button-size(medium);
|
|
226
|
+
}
|
|
186
227
|
}
|
|
187
228
|
|
|
188
229
|
&[size='medium'] {
|
|
189
|
-
|
|
230
|
+
@include button-size(medium);
|
|
231
|
+
@include responsive-wide {
|
|
232
|
+
@include button-size(large);
|
|
233
|
+
}
|
|
190
234
|
}
|
|
191
235
|
|
|
192
236
|
&[size='large'] {
|
|
193
|
-
|
|
194
|
-
--btn-padding: 14px var(--dt-spacing-e);
|
|
195
|
-
--btn-font-size: #{p.font-size(--dt-font-size-20)};
|
|
196
|
-
--btn-line-height: calc(var(--dt-font-size-20-line-height) * 1px);
|
|
237
|
+
@include button-size(large);
|
|
197
238
|
}
|
|
198
239
|
|
|
199
240
|
&[isLoading] {
|
package/src/defs.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export const sizes = ['xsmall', 'small-productive', 'small-expressive', 'medium', 'large'] as const;
|
|
2
|
+
export const responsiveSizes = ['productive', 'expressive'] as const;
|
|
2
3
|
export const types = ['submit', 'button', 'reset'] as const;
|
|
3
4
|
export const variants = [
|
|
4
5
|
'primary', 'secondary', 'outline', 'outline-inverse', 'ghost',
|
|
@@ -42,6 +43,11 @@ export interface ButtonProps {
|
|
|
42
43
|
*/
|
|
43
44
|
isLoading: boolean;
|
|
44
45
|
|
|
46
|
+
/**
|
|
47
|
+
* When true, enables the responsive size feature.
|
|
48
|
+
*/
|
|
49
|
+
isResponsive: boolean;
|
|
50
|
+
|
|
45
51
|
/**
|
|
46
52
|
* The name of the button, submitted as a pair with the button's value as part of the form data, when that button is used to submit the form.
|
|
47
53
|
* [MDN reference](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attributes)
|
|
@@ -86,4 +92,9 @@ export interface ButtonProps {
|
|
|
86
92
|
* [MDN reference](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attributes)
|
|
87
93
|
*/
|
|
88
94
|
formtarget?: typeof formTargetTypes[number]
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* What size should be attributed to the button when isResponsive is true and the screen is wide.
|
|
98
|
+
*/
|
|
99
|
+
responsiveSize?: typeof responsiveSizes[number];
|
|
89
100
|
}
|
package/src/index.ts
CHANGED
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
LitElement, html, unsafeCSS, nothing, PropertyValues, TemplateResult,
|
|
3
3
|
} from 'lit';
|
|
4
4
|
import { property } from 'lit/decorators.js';
|
|
5
|
+
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
5
6
|
import { validPropertyValues, defineCustomElement } from '@justeattakeaway/pie-webc-core';
|
|
6
7
|
import {
|
|
7
8
|
ButtonProps, sizes, types, variants, iconPlacements,
|
|
@@ -89,6 +90,9 @@ export class PieButton extends LitElement implements ButtonProps {
|
|
|
89
90
|
@property({ type: Boolean })
|
|
90
91
|
public isFullWidth = false;
|
|
91
92
|
|
|
93
|
+
@property({ type: Boolean })
|
|
94
|
+
public isResponsive = false;
|
|
95
|
+
|
|
92
96
|
@property({ type: String })
|
|
93
97
|
public name?: string;
|
|
94
98
|
|
|
@@ -110,6 +114,9 @@ export class PieButton extends LitElement implements ButtonProps {
|
|
|
110
114
|
@property()
|
|
111
115
|
public formtarget: ButtonProps['formtarget'];
|
|
112
116
|
|
|
117
|
+
@property({ type: String })
|
|
118
|
+
public responsiveSize?: ButtonProps['responsiveSize'];
|
|
119
|
+
|
|
113
120
|
/**
|
|
114
121
|
* This method creates an invisible button of the same type as pie-button. It is then clicked, and immediately removed from the DOM.
|
|
115
122
|
* This is done so that we trigger native form actions, such as submit and reset in the browser. The performance impact of adding and removing a single button to the DOM
|
|
@@ -222,7 +229,9 @@ export class PieButton extends LitElement implements ButtonProps {
|
|
|
222
229
|
variant,
|
|
223
230
|
size,
|
|
224
231
|
isLoading,
|
|
232
|
+
isResponsive,
|
|
225
233
|
iconPlacement,
|
|
234
|
+
responsiveSize,
|
|
226
235
|
} = this;
|
|
227
236
|
|
|
228
237
|
return html`
|
|
@@ -232,8 +241,10 @@ export class PieButton extends LitElement implements ButtonProps {
|
|
|
232
241
|
type=${type}
|
|
233
242
|
variant=${variant}
|
|
234
243
|
size=${size}
|
|
244
|
+
responsiveSize=${ifDefined(responsiveSize)}
|
|
235
245
|
?disabled=${disabled}
|
|
236
246
|
?isFullWidth=${isFullWidth}
|
|
247
|
+
?isResponsive=${isResponsive}
|
|
237
248
|
?isLoading=${isLoading}>
|
|
238
249
|
${isLoading ? this.renderSpinner() : nothing}
|
|
239
250
|
${iconPlacement === 'leading' ? html`<slot name="icon"></slot>` : nothing}
|