@prosopo/procaptcha-react 2.9.95 → 2.9.97

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.
@@ -1,164 +1,146 @@
1
- "use strict";
2
- const jsxRuntime = require("@emotion/react/jsx-runtime");
3
- const locale = require("@prosopo/locale");
4
- const procaptcha = require("@prosopo/procaptcha");
5
- const procaptchaCommon = require("@prosopo/procaptcha-common");
6
- const types = require("@prosopo/types");
7
- const widgetSkeleton = require("@prosopo/widget-skeleton");
8
- const React = require("react");
9
- const CaptchaComponent = require("./CaptchaComponent.cjs");
10
- const Modal = require("./Modal.cjs");
11
- const PROCAPTCHA_EXECUTE_EVENT = "procaptcha:execute";
12
- const ProcaptchaWidget = (props) => {
13
- const { t, ready: isTranslationReady } = locale.useTranslation();
14
- const config = types.ProcaptchaConfigSchema.parse(props.config);
15
- const frictionlessState = props.frictionlessState;
16
- const i18n = props.i18n;
17
- const callbacks = props.callbacks || {};
18
- const [state, updateState] = procaptchaCommon.useProcaptcha(React.useState, React.useRef);
19
- const [loading, setLoading] = React.useState(false);
20
- const hpRef = React.useRef(null);
21
- const manager = React.useRef(
22
- procaptcha.Manager(
23
- config,
24
- state,
25
- updateState,
26
- callbacks,
27
- frictionlessState,
28
- () => hpRef.current?.value || void 0
29
- )
30
- );
31
- const lastCoordsRef = React.useRef(null);
32
- const sessionInvalidatedFiredRef = React.useRef(false);
33
- const theme = "light" === props.config.theme ? widgetSkeleton.lightTheme : widgetSkeleton.darkTheme;
34
- React.useEffect(() => {
35
- if (!config.language) return;
36
- if (i18n) {
37
- if (i18n.language !== config.language) {
38
- void i18n.changeLanguage(config.language);
39
- }
40
- return;
41
- }
42
- void locale.loadI18next(false, config.language);
43
- }, [i18n, config.language]);
44
- React.useEffect(() => {
45
- if (!props.autoStart) return;
46
- setLoading(true);
47
- const coords = props.startCoords;
48
- lastCoordsRef.current = coords ?? null;
49
- manager.current.start(coords?.x ?? 0, coords?.y ?? 0).then(
50
- () => setLoading(false),
51
- () => setLoading(false)
52
- );
53
- }, [props.autoStart, props.startCoords]);
54
- React.useEffect(() => {
55
- if (!state.error) return;
56
- setLoading(false);
57
- if (state.error.key !== "CAPTCHA.NO_SESSION_FOUND") return;
58
- if (props.onSessionInvalidated && !sessionInvalidatedFiredRef.current) {
59
- sessionInvalidatedFiredRef.current = true;
60
- const coords = lastCoordsRef.current;
61
- props.onSessionInvalidated(coords?.x, coords?.y);
62
- return;
63
- }
64
- if (frictionlessState) {
65
- setTimeout(() => {
66
- frictionlessState.restart();
67
- }, 100);
68
- }
69
- }, [state.error, frictionlessState, props.onSessionInvalidated]);
70
- React.useEffect(() => {
71
- const handleExecuteEvent = (event) => {
72
- updateState({
73
- showModal: true
74
- });
75
- if (!state.challenge && manager.current.start) {
76
- console.log("No challenge set, attempting to start verification");
77
- try {
78
- manager.current.start();
79
- } catch (error) {
80
- console.error("Error starting verification:", error);
81
- }
82
- }
83
- };
84
- document.addEventListener(PROCAPTCHA_EXECUTE_EVENT, handleExecuteEvent);
85
- return () => {
86
- document.removeEventListener(
87
- PROCAPTCHA_EXECUTE_EVENT,
88
- handleExecuteEvent
89
- );
90
- };
91
- }, [state.challenge, updateState]);
92
- const honeypot = frictionlessState?.hp ? /* @__PURE__ */ jsxRuntime.jsx(procaptchaCommon.Honeypot, { ref: hpRef, encodedQuestion: frictionlessState.hp }) : null;
93
- if (config.mode === "invisible") {
94
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
95
- honeypot,
96
- /* @__PURE__ */ jsxRuntime.jsx(Modal, { show: state.showModal, children: state.challenge ? /* @__PURE__ */ jsxRuntime.jsx(
97
- CaptchaComponent,
98
- {
99
- challenge: state.challenge,
100
- index: state.index,
101
- solutions: state.solutions,
102
- onSubmit: manager.current.submit,
103
- onCancel: manager.current.cancel,
104
- onClick: manager.current.select,
105
- onNext: manager.current.nextRound,
106
- onReload: manager.current.reload,
107
- themeColor: config.theme ?? "light"
108
- }
109
- ) : null })
110
- ] });
111
- }
112
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "image-captcha", children: [
113
- honeypot,
114
- /* @__PURE__ */ jsxRuntime.jsx(Modal, { show: state.showModal, children: state.challenge ? /* @__PURE__ */ jsxRuntime.jsx(
115
- CaptchaComponent,
116
- {
117
- challenge: state.challenge,
118
- index: state.index,
119
- solutions: state.solutions,
120
- onSubmit: manager.current.submit,
121
- onCancel: manager.current.cancel,
122
- onClick: manager.current.select,
123
- onNext: manager.current.nextRound,
124
- onReload: manager.current.reload,
125
- themeColor: config.theme ?? "light"
126
- }
127
- ) : /* @__PURE__ */ jsxRuntime.jsx("div", { children: "No challenge set." }) }),
128
- /* @__PURE__ */ jsxRuntime.jsx(procaptchaCommon.TestModeBanner, { siteKey: config.account.address ?? "" }),
129
- /* @__PURE__ */ jsxRuntime.jsx(
130
- procaptchaCommon.Checkbox,
131
- {
132
- theme,
133
- onChange: async (event) => {
134
- if (!event.isTrusted) {
135
- return;
136
- }
137
- if (loading) {
138
- return;
139
- }
140
- setLoading(true);
141
- let x = 0;
142
- let y = 0;
143
- const nativeEvent = event.nativeEvent;
144
- if ("touches" in nativeEvent && nativeEvent.touches.length > 0 && nativeEvent.touches[0]) {
145
- x = nativeEvent.touches[0].clientX;
146
- y = nativeEvent.touches[0].clientY;
147
- } else if ("clientX" in nativeEvent && "clientY" in nativeEvent) {
148
- x = nativeEvent.clientX;
149
- y = nativeEvent.clientY;
150
- }
151
- lastCoordsRef.current = { x, y };
152
- await manager.current.start(x, y);
153
- setLoading(false);
154
- },
155
- checked: state.isHuman,
156
- labelText: isTranslationReady ? t("WIDGET.I_AM_HUMAN") : "",
157
- error: state.error?.message,
158
- "aria-label": "human checkbox",
159
- loading
160
- }
161
- )
162
- ] });
1
+ const require_CaptchaComponent = require("./CaptchaComponent.cjs");
2
+ const require_Modal = require("./Modal.cjs");
3
+ let _prosopo_widget_skeleton = require("@prosopo/widget-skeleton");
4
+ let react = require("react");
5
+ let _emotion_react_jsx_runtime = require("@emotion/react/jsx-runtime");
6
+ let _prosopo_locale = require("@prosopo/locale");
7
+ let _prosopo_procaptcha_common = require("@prosopo/procaptcha-common");
8
+ let _prosopo_procaptcha = require("@prosopo/procaptcha");
9
+ let _prosopo_types = require("@prosopo/types");
10
+ //#region src/components/ProcaptchaWidget.tsx
11
+ /** @jsxImportSource @emotion/react */
12
+ var PROCAPTCHA_EXECUTE_EVENT = "procaptcha:execute";
13
+ var ProcaptchaWidget = (props) => {
14
+ const { t, ready: isTranslationReady } = (0, _prosopo_locale.useTranslation)();
15
+ const config = _prosopo_types.ProcaptchaConfigSchema.parse(props.config);
16
+ const frictionlessState = props.frictionlessState;
17
+ const i18n = props.i18n;
18
+ const callbacks = props.callbacks || {};
19
+ const [state, updateState] = (0, _prosopo_procaptcha_common.useProcaptcha)(react.useState, react.useRef);
20
+ const [loading, setLoading] = (0, react.useState)(false);
21
+ const hpRef = (0, react.useRef)(null);
22
+ const manager = (0, react.useRef)((0, _prosopo_procaptcha.Manager)(config, state, updateState, callbacks, frictionlessState, () => hpRef.current?.value || void 0));
23
+ const lastCoordsRef = (0, react.useRef)(null);
24
+ const sessionInvalidatedFiredRef = (0, react.useRef)(false);
25
+ const theme = "light" === props.config.theme ? _prosopo_widget_skeleton.lightTheme : _prosopo_widget_skeleton.darkTheme;
26
+ (0, react.useEffect)(() => {
27
+ if (!config.language) return;
28
+ if (i18n) {
29
+ if (i18n.language !== config.language) i18n.changeLanguage(config.language);
30
+ return;
31
+ }
32
+ (0, _prosopo_locale.loadI18next)(false, config.language);
33
+ }, [i18n, config.language]);
34
+ (0, react.useEffect)(() => {
35
+ if (!props.autoStart) return;
36
+ setLoading(true);
37
+ const coords = props.startCoords;
38
+ lastCoordsRef.current = coords ?? null;
39
+ manager.current.start(coords?.x ?? 0, coords?.y ?? 0).then(() => setLoading(false), () => setLoading(false));
40
+ }, [props.autoStart, props.startCoords]);
41
+ (0, react.useEffect)(() => {
42
+ if (!state.error) return;
43
+ setLoading(false);
44
+ if (state.error.key !== "CAPTCHA.NO_SESSION_FOUND") return;
45
+ if (props.onSessionInvalidated && !sessionInvalidatedFiredRef.current) {
46
+ sessionInvalidatedFiredRef.current = true;
47
+ const coords = lastCoordsRef.current;
48
+ props.onSessionInvalidated(coords?.x, coords?.y);
49
+ return;
50
+ }
51
+ if (frictionlessState) setTimeout(() => {
52
+ frictionlessState.restart();
53
+ }, 100);
54
+ }, [
55
+ state.error,
56
+ frictionlessState,
57
+ props.onSessionInvalidated
58
+ ]);
59
+ (0, react.useEffect)(() => {
60
+ const handleExecuteEvent = (event) => {
61
+ updateState({ showModal: true });
62
+ if (!state.challenge && manager.current.start) {
63
+ console.log("No challenge set, attempting to start verification");
64
+ try {
65
+ manager.current.start();
66
+ } catch (error) {
67
+ console.error("Error starting verification:", error);
68
+ }
69
+ }
70
+ };
71
+ document.addEventListener(PROCAPTCHA_EXECUTE_EVENT, handleExecuteEvent);
72
+ return () => {
73
+ document.removeEventListener(PROCAPTCHA_EXECUTE_EVENT, handleExecuteEvent);
74
+ };
75
+ }, [state.challenge, updateState]);
76
+ const honeypot = frictionlessState?.hp ? /* @__PURE__ */ (0, _emotion_react_jsx_runtime.jsx)(_prosopo_procaptcha_common.Honeypot, {
77
+ ref: hpRef,
78
+ encodedQuestion: frictionlessState.hp
79
+ }) : null;
80
+ if (config.mode === "invisible") return /* @__PURE__ */ (0, _emotion_react_jsx_runtime.jsxs)(_emotion_react_jsx_runtime.Fragment, { children: [honeypot, /* @__PURE__ */ (0, _emotion_react_jsx_runtime.jsx)(require_Modal.default, {
81
+ show: state.showModal,
82
+ children: state.challenge ? /* @__PURE__ */ (0, _emotion_react_jsx_runtime.jsx)(require_CaptchaComponent.default, {
83
+ challenge: state.challenge,
84
+ index: state.index,
85
+ solutions: state.solutions,
86
+ onSubmit: manager.current.submit,
87
+ onCancel: manager.current.cancel,
88
+ onClick: manager.current.select,
89
+ onNext: manager.current.nextRound,
90
+ onReload: manager.current.reload,
91
+ themeColor: config.theme ?? "light"
92
+ }) : null
93
+ })] });
94
+ return /* @__PURE__ */ (0, _emotion_react_jsx_runtime.jsxs)("div", {
95
+ className: "image-captcha",
96
+ children: [
97
+ honeypot,
98
+ /* @__PURE__ */ (0, _emotion_react_jsx_runtime.jsx)(require_Modal.default, {
99
+ show: state.showModal,
100
+ children: state.challenge ? /* @__PURE__ */ (0, _emotion_react_jsx_runtime.jsx)(require_CaptchaComponent.default, {
101
+ challenge: state.challenge,
102
+ index: state.index,
103
+ solutions: state.solutions,
104
+ onSubmit: manager.current.submit,
105
+ onCancel: manager.current.cancel,
106
+ onClick: manager.current.select,
107
+ onNext: manager.current.nextRound,
108
+ onReload: manager.current.reload,
109
+ themeColor: config.theme ?? "light"
110
+ }) : /* @__PURE__ */ (0, _emotion_react_jsx_runtime.jsx)("div", { children: "No challenge set." })
111
+ }),
112
+ /* @__PURE__ */ (0, _emotion_react_jsx_runtime.jsx)(_prosopo_procaptcha_common.TestModeBanner, { siteKey: config.account.address ?? "" }),
113
+ /* @__PURE__ */ (0, _emotion_react_jsx_runtime.jsx)(_prosopo_procaptcha_common.Checkbox, {
114
+ theme,
115
+ onChange: async (event) => {
116
+ if (!event.isTrusted) return;
117
+ if (loading) return;
118
+ setLoading(true);
119
+ let x = 0;
120
+ let y = 0;
121
+ const nativeEvent = event.nativeEvent;
122
+ if ("touches" in nativeEvent && nativeEvent.touches.length > 0 && nativeEvent.touches[0]) {
123
+ x = nativeEvent.touches[0].clientX;
124
+ y = nativeEvent.touches[0].clientY;
125
+ } else if ("clientX" in nativeEvent && "clientY" in nativeEvent) {
126
+ x = nativeEvent.clientX;
127
+ y = nativeEvent.clientY;
128
+ }
129
+ lastCoordsRef.current = {
130
+ x,
131
+ y
132
+ };
133
+ await manager.current.start(x, y);
134
+ setLoading(false);
135
+ },
136
+ checked: state.isHuman,
137
+ labelText: isTranslationReady ? t("WIDGET.I_AM_HUMAN") : "",
138
+ error: state.error?.message,
139
+ "aria-label": "human checkbox",
140
+ loading
141
+ })
142
+ ]
143
+ });
163
144
  };
164
- module.exports = ProcaptchaWidget;
145
+ //#endregion
146
+ exports.default = ProcaptchaWidget;
@@ -1,9 +1,6 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const CaptchaWidget = require("./CaptchaWidget.cjs");
4
- require("./CaptchaComponent.cjs");
5
- const ProcaptchaWidget = require("./ProcaptchaWidget.cjs");
6
- const Procaptcha = require("./Procaptcha.cjs");
7
- exports.CaptchaWidget = CaptchaWidget.CaptchaWidget;
8
- exports.ProcaptchaWidget = ProcaptchaWidget;
9
- exports.Procaptcha = Procaptcha;
1
+ const require_CaptchaWidget = require("./CaptchaWidget.cjs");
2
+ const require_ProcaptchaWidget = require("./ProcaptchaWidget.cjs");
3
+ const require_Procaptcha = require("./Procaptcha.cjs");
4
+ exports.CaptchaWidget = require_CaptchaWidget.CaptchaWidget;
5
+ exports.Procaptcha = require_Procaptcha.default;
6
+ exports.ProcaptchaWidget = require_ProcaptchaWidget.default;
@@ -1,10 +1,7 @@
1
- "use strict";
2
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- require("./components/index.cjs");
4
- require("./util/index.cjs");
5
- const ProcaptchaWidget = require("./components/ProcaptchaWidget.cjs");
6
- const Procaptcha = require("./components/Procaptcha.cjs");
7
- const CaptchaWidget = require("./components/CaptchaWidget.cjs");
8
- exports.ProcaptchaWidget = ProcaptchaWidget;
9
- exports.Procaptcha = Procaptcha;
10
- exports.CaptchaWidget = CaptchaWidget.CaptchaWidget;
2
+ const require_CaptchaWidget = require("./components/CaptchaWidget.cjs");
3
+ const require_ProcaptchaWidget = require("./components/ProcaptchaWidget.cjs");
4
+ const require_Procaptcha = require("./components/Procaptcha.cjs");
5
+ exports.CaptchaWidget = require_CaptchaWidget.CaptchaWidget;
6
+ exports.Procaptcha = require_Procaptcha.default;
7
+ exports.ProcaptchaWidget = require_ProcaptchaWidget.default;
@@ -1,18 +1,20 @@
1
- "use strict";
1
+ //#region src/util/index.ts
2
2
  function renameKeysForDataAttr(data = {}) {
3
- return Object.keys(data).reduce(
4
- // biome-ignore lint/performance/noAccumulatingSpread: TODO fix
5
- (prev, curr) => ({ ...prev, [`data-${curr}`]: data[curr] }),
6
- {}
7
- );
3
+ return Object.keys(data).reduce((prev, curr) => ({
4
+ ...prev,
5
+ [`data-${curr}`]: data[curr]
6
+ }), {});
8
7
  }
9
- function addDataAttr({
10
- general,
11
- dev
12
- }) {
13
- return {
14
- ...renameKeysForDataAttr(general),
15
- ...process.env.NODE_ENV !== "production" ? renameKeysForDataAttr(dev) : {}
16
- };
8
+ /**
9
+ * maps any data to data attributes (mapped to { data-[key]: value })
10
+ *
11
+ * dev - only in development mode
12
+ */
13
+ function addDataAttr({ general, dev }) {
14
+ return {
15
+ ...renameKeysForDataAttr(general),
16
+ ...process.env.NODE_ENV !== "production" ? renameKeysForDataAttr(dev) : {}
17
+ };
17
18
  }
18
- module.exports = addDataAttr;
19
+ //#endregion
20
+ exports.default = addDataAttr;
@@ -1,81 +1,70 @@
1
- import { jsx } from "@emotion/react/jsx-runtime";
2
- import { lightTheme, darkTheme } from "@prosopo/widget-skeleton";
3
- import { useMemo, useState } from "react";
4
1
  import addDataAttr from "../util/index.js";
5
- const buttonStyleBase = {
6
- display: "inline-flex",
7
- alignItems: "center",
8
- justifyContent: "center",
9
- position: "relative",
10
- boxSizing: "border-box",
11
- outline: "0px",
12
- margin: "0px",
13
- cursor: "pointer",
14
- userSelect: "none",
15
- verticalAlign: "middle",
16
- appearance: void 0,
17
- textDecoration: "none",
18
- fontWeight: "500",
19
- fontSize: "0.875rem",
20
- lineHeight: "1.75",
21
- letterSpacing: "0.02857em",
22
- textTransform: "uppercase",
23
- minWidth: "64px",
24
- padding: "6px 16px",
25
- borderRadius: "4px",
26
- transition: "background-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, border-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms",
27
- backgroundColor: "#ffffff"
28
- };
29
- const Button = ({
30
- themeColor,
31
- buttonType,
32
- text,
33
- onClick
34
- }) => {
35
- const theme = useMemo(
36
- () => themeColor === "light" ? lightTheme : darkTheme,
37
- [themeColor]
38
- );
39
- const [hover, setHover] = useState(false);
40
- const buttonStyle = useMemo(() => {
41
- const baseStyle = {
42
- ...buttonStyleBase,
43
- border: `1px solid ${theme.palette.grey[500]}`,
44
- boxShadow: `0px 1px 3px 0px ${theme.palette.grey[500]}`,
45
- fontFamily: theme.font.fontFamily,
46
- width: "100%",
47
- color: hover ? theme.palette.primary.contrastText : theme.palette.background.contrastText
48
- };
49
- if (buttonType === "cancel") {
50
- return {
51
- ...baseStyle,
52
- backgroundColor: hover ? theme.palette.grey[600] : "transparent"
53
- };
54
- }
55
- return {
56
- ...baseStyle,
57
- backgroundColor: hover ? theme.palette.primary.main : theme.palette.background.default
58
- };
59
- }, [buttonType, hover, theme]);
60
- return /* @__PURE__ */ jsx(
61
- "button",
62
- {
63
- ...addDataAttr({ dev: { cy: `button-${buttonType}` } }),
64
- onMouseEnter: () => setHover(true),
65
- onMouseLeave: () => setHover(false),
66
- style: buttonStyle,
67
- onClick: (e) => {
68
- if (!e.isTrusted) {
69
- return;
70
- }
71
- e.preventDefault();
72
- onClick();
73
- },
74
- "aria-label": text,
75
- children: text
76
- }
77
- );
2
+ import { darkTheme, lightTheme } from "@prosopo/widget-skeleton";
3
+ import { useMemo, useState } from "react";
4
+ import { jsx } from "@emotion/react/jsx-runtime";
5
+ //#region src/components/Button.tsx
6
+ var buttonStyleBase = {
7
+ display: "inline-flex",
8
+ alignItems: "center",
9
+ justifyContent: "center",
10
+ position: "relative",
11
+ boxSizing: "border-box",
12
+ outline: "0px",
13
+ margin: "0px",
14
+ cursor: "pointer",
15
+ userSelect: "none",
16
+ verticalAlign: "middle",
17
+ appearance: void 0,
18
+ textDecoration: "none",
19
+ fontWeight: "500",
20
+ fontSize: "0.875rem",
21
+ lineHeight: "1.75",
22
+ letterSpacing: "0.02857em",
23
+ textTransform: "uppercase",
24
+ minWidth: "64px",
25
+ padding: "6px 16px",
26
+ borderRadius: "4px",
27
+ transition: "background-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, border-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms",
28
+ backgroundColor: "#ffffff"
78
29
  };
79
- export {
80
- Button as default
30
+ var Button = ({ themeColor, buttonType, text, onClick }) => {
31
+ const theme = useMemo(() => themeColor === "light" ? lightTheme : darkTheme, [themeColor]);
32
+ const [hover, setHover] = useState(false);
33
+ const buttonStyle = useMemo(() => {
34
+ const baseStyle = {
35
+ ...buttonStyleBase,
36
+ border: `1px solid ${theme.palette.grey[500]}`,
37
+ boxShadow: `0px 1px 3px 0px ${theme.palette.grey[500]}`,
38
+ fontFamily: theme.font.fontFamily,
39
+ width: "100%",
40
+ color: hover ? theme.palette.primary.contrastText : theme.palette.background.contrastText
41
+ };
42
+ if (buttonType === "cancel") return {
43
+ ...baseStyle,
44
+ backgroundColor: hover ? theme.palette.grey[600] : "transparent"
45
+ };
46
+ return {
47
+ ...baseStyle,
48
+ backgroundColor: hover ? theme.palette.primary.main : theme.palette.background.default
49
+ };
50
+ }, [
51
+ buttonType,
52
+ hover,
53
+ theme
54
+ ]);
55
+ return /* @__PURE__ */ jsx("button", {
56
+ ...addDataAttr({ dev: { cy: `button-${buttonType}` } }),
57
+ onMouseEnter: () => setHover(true),
58
+ onMouseLeave: () => setHover(false),
59
+ style: buttonStyle,
60
+ onClick: (e) => {
61
+ if (!e.isTrusted) return;
62
+ e.preventDefault();
63
+ onClick();
64
+ },
65
+ "aria-label": text,
66
+ children: text
67
+ });
81
68
  };
69
+ //#endregion
70
+ export { Button as default };