@owlmeans/client-auth 0.1.18-rc.12 → 0.1.18-rc.13

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.
Files changed (118) hide show
  1. package/agent-meta/manifest.json +2 -2
  2. package/agent-meta/skills/client-auth/SKILL.md +1 -1
  3. package/build/login/adopt.d.ts +9 -0
  4. package/build/login/adopt.d.ts.map +1 -1
  5. package/build/login/adopt.js +11 -0
  6. package/build/login/adopt.js.map +1 -1
  7. package/build/login/consts.d.ts +25 -4
  8. package/build/login/consts.d.ts.map +1 -1
  9. package/build/login/consts.js +25 -4
  10. package/build/login/consts.js.map +1 -1
  11. package/build/login/credit.d.ts +19 -0
  12. package/build/login/credit.d.ts.map +1 -0
  13. package/build/login/credit.js +24 -0
  14. package/build/login/credit.js.map +1 -0
  15. package/build/login/hook.d.ts +14 -3
  16. package/build/login/hook.d.ts.map +1 -1
  17. package/build/login/hook.js +27 -9
  18. package/build/login/hook.js.map +1 -1
  19. package/build/login/i18n/be.json +37 -0
  20. package/build/login/i18n/de.json +37 -0
  21. package/build/login/i18n/en.json +37 -0
  22. package/build/login/i18n/es.json +37 -0
  23. package/build/login/i18n/pl.json +37 -0
  24. package/build/login/i18n/ru.json +37 -0
  25. package/build/login/i18n/uk.json +37 -0
  26. package/build/login/i18n.d.ts +2 -0
  27. package/build/login/i18n.d.ts.map +1 -0
  28. package/build/login/i18n.js +25 -0
  29. package/build/login/i18n.js.map +1 -0
  30. package/build/login/index.d.ts +7 -0
  31. package/build/login/index.d.ts.map +1 -1
  32. package/build/login/index.js +7 -0
  33. package/build/login/index.js.map +1 -1
  34. package/build/login/methods.d.ts +25 -0
  35. package/build/login/methods.d.ts.map +1 -0
  36. package/build/login/methods.js +97 -0
  37. package/build/login/methods.js.map +1 -0
  38. package/build/login/resume.d.ts +20 -0
  39. package/build/login/resume.d.ts.map +1 -0
  40. package/build/login/resume.js +33 -0
  41. package/build/login/resume.js.map +1 -0
  42. package/build/login/screen.d.ts +4 -0
  43. package/build/login/screen.d.ts.map +1 -0
  44. package/build/login/screen.js +63 -0
  45. package/build/login/screen.js.map +1 -0
  46. package/build/login/service.d.ts +4 -3
  47. package/build/login/service.d.ts.map +1 -1
  48. package/build/login/service.js +57 -4
  49. package/build/login/service.js.map +1 -1
  50. package/build/login/surrogate.d.ts +20 -0
  51. package/build/login/surrogate.d.ts.map +1 -0
  52. package/build/login/surrogate.js +33 -0
  53. package/build/login/surrogate.js.map +1 -0
  54. package/build/login/terms.d.ts +20 -0
  55. package/build/login/terms.d.ts.map +1 -0
  56. package/build/login/terms.js +0 -0
  57. package/build/login/terms.js.map +1 -0
  58. package/build/login/types.d.ts +123 -1
  59. package/build/login/types.d.ts.map +1 -1
  60. package/build/login/types.js +7 -1
  61. package/build/login/types.js.map +1 -1
  62. package/build/manager/plugins/basic-ed25519.d.ts.map +1 -1
  63. package/build/manager/plugins/basic-ed25519.js +1 -0
  64. package/build/manager/plugins/basic-ed25519.js.map +1 -1
  65. package/build/manager/plugins/exports.d.ts +2 -0
  66. package/build/manager/plugins/exports.d.ts.map +1 -1
  67. package/build/manager/plugins/exports.js +2 -0
  68. package/build/manager/plugins/exports.js.map +1 -1
  69. package/build/manager/plugins/index.d.ts +1 -5
  70. package/build/manager/plugins/index.d.ts.map +1 -1
  71. package/build/manager/plugins/index.js +9 -1
  72. package/build/manager/plugins/index.js.map +1 -1
  73. package/build/manager/plugins/methods.d.ts +10 -0
  74. package/build/manager/plugins/methods.d.ts.map +1 -0
  75. package/build/manager/plugins/methods.js +46 -0
  76. package/build/manager/plugins/methods.js.map +1 -0
  77. package/build/manager/plugins/re-captcha.d.ts.map +1 -1
  78. package/build/manager/plugins/re-captcha.js +2 -0
  79. package/build/manager/plugins/re-captcha.js.map +1 -1
  80. package/build/manager/plugins/registry.d.ts +20 -0
  81. package/build/manager/plugins/registry.d.ts.map +1 -0
  82. package/build/manager/plugins/registry.js +19 -0
  83. package/build/manager/plugins/registry.js.map +1 -0
  84. package/build/manager/plugins/tunnel-consumer.d.ts.map +1 -1
  85. package/build/manager/plugins/tunnel-consumer.js +1 -0
  86. package/build/manager/plugins/tunnel-consumer.js.map +1 -1
  87. package/build/manager/plugins/types.d.ts +31 -0
  88. package/build/manager/plugins/types.d.ts.map +1 -1
  89. package/package.json +20 -18
  90. package/src/login/adopt.ts +12 -0
  91. package/src/login/consts.ts +31 -4
  92. package/src/login/credit.ts +37 -0
  93. package/src/login/hook.ts +28 -11
  94. package/src/login/i18n/be.json +37 -0
  95. package/src/login/i18n/de.json +37 -0
  96. package/src/login/i18n/en.json +37 -0
  97. package/src/login/i18n/es.json +37 -0
  98. package/src/login/i18n/pl.json +37 -0
  99. package/src/login/i18n/ru.json +37 -0
  100. package/src/login/i18n/uk.json +37 -0
  101. package/src/login/i18n.ts +26 -0
  102. package/src/login/index.ts +8 -0
  103. package/src/login/methods.ts +113 -0
  104. package/src/login/resume.ts +33 -0
  105. package/src/login/screen.tsx +122 -0
  106. package/src/login/service.ts +78 -5
  107. package/src/login/surrogate.ts +45 -0
  108. package/src/login/terms.ts +0 -0
  109. package/src/login/types.ts +132 -1
  110. package/src/manager/plugins/basic-ed25519.tsx +2 -0
  111. package/src/manager/plugins/exports.ts +2 -0
  112. package/src/manager/plugins/index.ts +10 -4
  113. package/src/manager/plugins/methods.ts +52 -0
  114. package/src/manager/plugins/re-captcha.tsx +3 -0
  115. package/src/manager/plugins/registry.ts +26 -0
  116. package/src/manager/plugins/tunnel-consumer.tsx +2 -0
  117. package/src/manager/plugins/types.ts +32 -0
  118. package/tests/login.spec.ts +202 -0
@@ -1,7 +1,14 @@
1
+ import './i18n.js';
1
2
  export * from './consts.js';
2
3
  export * from './types.js';
3
4
  export * from './env.js';
4
5
  export * from './adopt.js';
6
+ export * from './methods.js';
7
+ export * from './resume.js';
8
+ export * from './terms.js';
9
+ export * from './credit.js';
10
+ export * from './surrogate.js';
11
+ export * from './screen.js';
5
12
  export * from './service.js';
6
13
  export * from './hook.js';
7
14
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/login/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,UAAU,CAAA;AACxB,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,WAAW,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/login/index.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,CAAA;AAElB,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,UAAU,CAAA;AACxB,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,WAAW,CAAA"}
@@ -1,7 +1,14 @@
1
+ import './i18n.js';
1
2
  export * from './consts.js';
2
3
  export * from './types.js';
3
4
  export * from './env.js';
4
5
  export * from './adopt.js';
6
+ export * from './methods.js';
7
+ export * from './resume.js';
8
+ export * from './terms.js';
9
+ export * from './credit.js';
10
+ export * from './surrogate.js';
11
+ export * from './screen.js';
5
12
  export * from './service.js';
6
13
  export * from './hook.js';
7
14
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/login/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,UAAU,CAAA;AACxB,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,WAAW,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/login/index.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,CAAA;AAElB,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,UAAU,CAAA;AACxB,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,WAAW,CAAA"}
@@ -0,0 +1,25 @@
1
+ import type { LoginScreenConfig } from '@owlmeans/config';
2
+ import type { LoginMethod, LoginMethodContext, LoginMethodSource } from './types.js';
3
+ export declare const registerMethodSource: (source: LoginMethodSource) => void;
4
+ export declare const listMethodSources: () => LoginMethodSource[];
5
+ /**
6
+ * Everything the current environment may be offered, in the order it should be offered in.
7
+ *
8
+ * Resolution order matters and is not arbitrary:
9
+ *
10
+ * 1. Sources produce candidates. A source that throws is skipped rather than taking the screen
11
+ * down — a misconfigured provider list must not remove the sign-in method that does work.
12
+ * 2. `restricted` candidates are dropped unless the configuration named them, which is what makes
13
+ * an operator login opt-in rather than merely unadvertised.
14
+ * 3. An explicit `methods` list is both a filter AND the order, because an app that bothered to
15
+ * list them means that list.
16
+ */
17
+ export declare const resolveLoginMethods: (ctx: LoginMethodContext, cfg?: LoginScreenConfig, extra?: LoginMethodSource[]) => LoginMethod[];
18
+ /**
19
+ * The method a screen highlights and focuses.
20
+ *
21
+ * The first `primary` one, else the first offered. It is highlighted, never started: requirement
22
+ * one of this whole feature is that nothing leaves the document without a click.
23
+ */
24
+ export declare const primaryLoginMethod: (methods: LoginMethod[]) => LoginMethod | null;
25
+ //# sourceMappingURL=methods.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"methods.d.ts","sourceRoot":"","sources":["../../src/login/methods.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAqB,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAE5E,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAgBpF,eAAO,MAAM,oBAAoB,WAAY,iBAAiB,KAAG,IAMhE,CAAA;AAED,eAAO,MAAM,iBAAiB,QAAO,iBAAiB,EAAkB,CAAA;AAiBxE;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,QACzB,kBAAkB,QAAQ,iBAAiB,UAAS,iBAAiB,EAAE,KAC3E,WAAW,EA8Cb,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,YAAa,WAAW,EAAE,KAAG,WAAW,GAAG,IACG,CAAA"}
@@ -0,0 +1,97 @@
1
+ import { DEFAULT_METHOD_ORDER } from './consts.js';
2
+ /**
3
+ * The module-global registry of method SOURCES.
4
+ *
5
+ * A source, rather than a method, because the two things that offer sign-in methods answer
6
+ * different questions at different times: the plugin registry knows what code is loaded, and the
7
+ * OIDC configuration knows what an entity is federated with. Both are answered per render — a
8
+ * provider list can arrive from the api-config middleware after the first paint.
9
+ *
10
+ * Global, like the `AuthenticationPlugin` map it mirrors, because a package registers its source
11
+ * from a side-effect import that has no context to hang it on. A context-scoped registry exists
12
+ * alongside it on the login service, and both are merged by {@link resolveLoginMethods}.
13
+ */
14
+ const sources = [];
15
+ export const registerMethodSource = (source) => {
16
+ const existing = sources.findIndex(candidate => candidate.alias === source.alias);
17
+ if (existing >= 0) {
18
+ sources.splice(existing, 1);
19
+ }
20
+ sources.push(source);
21
+ };
22
+ export const listMethodSources = () => [...sources];
23
+ /** Normalize a config entry, which may be a bare id or a full override object. */
24
+ const asConfig = (entry) => typeof entry === 'string' ? { id: entry } : entry;
25
+ const merge = (method, override) => override == null ? method : {
26
+ ...method,
27
+ ...(override.label != null ? { label: override.label } : {}),
28
+ ...(override.i18nKey != null ? { i18nKey: override.i18nKey } : {}),
29
+ ...(override.icon != null ? { icon: override.icon } : {}),
30
+ ...(override.order != null ? { order: override.order } : {}),
31
+ ...(override.emphasis != null ? { emphasis: override.emphasis } : {}),
32
+ ...(override.params != null ? { params: { ...method.params, ...override.params } } : {}),
33
+ };
34
+ /**
35
+ * Everything the current environment may be offered, in the order it should be offered in.
36
+ *
37
+ * Resolution order matters and is not arbitrary:
38
+ *
39
+ * 1. Sources produce candidates. A source that throws is skipped rather than taking the screen
40
+ * down — a misconfigured provider list must not remove the sign-in method that does work.
41
+ * 2. `restricted` candidates are dropped unless the configuration named them, which is what makes
42
+ * an operator login opt-in rather than merely unadvertised.
43
+ * 3. An explicit `methods` list is both a filter AND the order, because an app that bothered to
44
+ * list them means that list.
45
+ */
46
+ export const resolveLoginMethods = (ctx, cfg, extra = []) => {
47
+ const candidates = [];
48
+ for (const source of [...sources, ...extra]) {
49
+ try {
50
+ candidates.push(...source.list(ctx));
51
+ }
52
+ catch (e) {
53
+ console.error(`login: method source "${source.alias}" failed`, e);
54
+ }
55
+ }
56
+ const overrides = cfg?.overrides ?? {};
57
+ const listed = cfg?.methods?.map(asConfig);
58
+ const listedIds = listed?.map(entry => entry.id).filter((id) => id != null);
59
+ const offered = candidates
60
+ .filter(method => {
61
+ const override = overrides[method.id] ?? listed?.find(entry => entry.id === method.id);
62
+ if (override?.enabled === false || override?.hidden === true) {
63
+ return false;
64
+ }
65
+ // A restricted method is offered only where the configuration asked for it — by naming it in
66
+ // `methods`, or by enabling it in `overrides`. Registering the plugin is deliberately not
67
+ // enough: an operator login that appears wherever its code happens to be bundled is an
68
+ // operator login in production.
69
+ if (method.restricted === true
70
+ && listedIds?.includes(method.id) !== true
71
+ && override?.enabled !== true) {
72
+ return false;
73
+ }
74
+ return true;
75
+ })
76
+ .map(method => merge(method, overrides[method.id]));
77
+ if (listedIds != null) {
78
+ return listedIds
79
+ .map(id => {
80
+ const method = offered.find(candidate => candidate.id === id);
81
+ return method != null ? merge(method, listed?.find(entry => entry.id === id)) : null;
82
+ })
83
+ .filter((method) => method != null);
84
+ }
85
+ return offered.sort((a, b) => {
86
+ const order = (a.order ?? DEFAULT_METHOD_ORDER) - (b.order ?? DEFAULT_METHOD_ORDER);
87
+ return order !== 0 ? order : a.id.localeCompare(b.id);
88
+ });
89
+ };
90
+ /**
91
+ * The method a screen highlights and focuses.
92
+ *
93
+ * The first `primary` one, else the first offered. It is highlighted, never started: requirement
94
+ * one of this whole feature is that nothing leaves the document without a click.
95
+ */
96
+ export const primaryLoginMethod = (methods) => methods.find(method => method.emphasis === 'primary') ?? methods[0] ?? null;
97
+ //# sourceMappingURL=methods.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"methods.js","sourceRoot":"","sources":["../../src/login/methods.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { LoginOutcome } from './types.js';
2
+ /** What a dispatcher does once `login().resume(...)` has answered. */
3
+ export declare enum ResumeAction {
4
+ /** The plugin took it over — the browser is leaving, or the window is closing. */
5
+ Stop = "stop",
6
+ /** Render the outcome to the user; there is nothing further to do automatically. */
7
+ Render = "render",
8
+ /** Ordinary tab: keep the session and carry on to the application. */
9
+ Navigate = "navigate"
10
+ }
11
+ /**
12
+ * The one reading of a `resume` outcome, shared by every dispatcher.
13
+ *
14
+ * Exported as a pure function because three dispatchers — `web-client`, `web-oidc-rp` and
15
+ * `mui-oidc-rp` — have to agree on it, and the last time they each held their own copy of a
16
+ * decision they drifted, which is how a popup came to render the application inside itself in two
17
+ * packages at once. It is also the whole rule, so it is testable without a DOM.
18
+ */
19
+ export declare const resumeAction: (outcome: LoginOutcome) => ResumeAction;
20
+ //# sourceMappingURL=resume.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resume.d.ts","sourceRoot":"","sources":["../../src/login/resume.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAEzC,sEAAsE;AACtE,oBAAY,YAAY;IACtB,kFAAkF;IAClF,IAAI,SAAS;IACb,oFAAoF;IACpF,MAAM,WAAW;IACjB,sEAAsE;IACtE,QAAQ,aAAa;CACtB;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,YAAa,YAAY,KAAG,YAYpD,CAAA"}
@@ -0,0 +1,33 @@
1
+ import { LoginOutcome } from './types.js';
2
+ /** What a dispatcher does once `login().resume(...)` has answered. */
3
+ export var ResumeAction;
4
+ (function (ResumeAction) {
5
+ /** The plugin took it over — the browser is leaving, or the window is closing. */
6
+ ResumeAction["Stop"] = "stop";
7
+ /** Render the outcome to the user; there is nothing further to do automatically. */
8
+ ResumeAction["Render"] = "render";
9
+ /** Ordinary tab: keep the session and carry on to the application. */
10
+ ResumeAction["Navigate"] = "navigate";
11
+ })(ResumeAction || (ResumeAction = {}));
12
+ /**
13
+ * The one reading of a `resume` outcome, shared by every dispatcher.
14
+ *
15
+ * Exported as a pure function because three dispatchers — `web-client`, `web-oidc-rp` and
16
+ * `mui-oidc-rp` — have to agree on it, and the last time they each held their own copy of a
17
+ * decision they drifted, which is how a popup came to render the application inside itself in two
18
+ * packages at once. It is also the whole rule, so it is testable without a DOM.
19
+ */
20
+ export const resumeAction = (outcome) => {
21
+ switch (outcome) {
22
+ case LoginOutcome.Handled:
23
+ case LoginOutcome.Redirected:
24
+ return ResumeAction.Stop;
25
+ case LoginOutcome.Orphaned:
26
+ case LoginOutcome.Failed:
27
+ case LoginOutcome.Gesture:
28
+ return ResumeAction.Render;
29
+ default:
30
+ return ResumeAction.Navigate;
31
+ }
32
+ };
33
+ //# sourceMappingURL=resume.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resume.js","sourceRoot":"","sources":["../../src/login/resume.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAEzC,sEAAsE;AACtE,MAAM,CAAN,IAAY,YAOX;AAPD,WAAY,YAAY;IACtB,kFAAkF;IAClF,6BAAa,CAAA;IACb,oFAAoF;IACpF,iCAAiB,CAAA;IACjB,sEAAsE;IACtE,qCAAqB,CAAA;AACvB,CAAC,EAPW,YAAY,KAAZ,YAAY,QAOvB;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,OAAqB,EAAgB,EAAE;IAClE,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,YAAY,CAAC,OAAO,CAAC;QAC1B,KAAK,YAAY,CAAC,UAAU;YAC1B,OAAO,YAAY,CAAC,IAAI,CAAA;QAC1B,KAAK,YAAY,CAAC,QAAQ,CAAC;QAC3B,KAAK,YAAY,CAAC,MAAM,CAAC;QACzB,KAAK,YAAY,CAAC,OAAO;YACvB,OAAO,YAAY,CAAC,MAAM,CAAA;QAC5B;YACE,OAAO,YAAY,CAAC,QAAQ,CAAA;IAChC,CAAC;AACH,CAAC,CAAA"}
@@ -0,0 +1,4 @@
1
+ import type { FC } from 'react';
2
+ import type { LoginScreenProps } from './types.js';
3
+ export declare const FallbackLoginScreen: FC<LoginScreenProps>;
4
+ //# sourceMappingURL=screen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screen.d.ts","sourceRoot":"","sources":["../../src/login/screen.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAiB,EAAE,EAAE,MAAM,OAAO,CAAA;AAG9C,OAAO,KAAK,EAA6B,gBAAgB,EAAgB,MAAM,YAAY,CAAA;AA8B3F,eAAO,MAAM,mBAAmB,EAAE,EAAE,CAAC,gBAAgB,CAuFpD,CAAA"}
@@ -0,0 +1,63 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useCallback, useState } from 'react';
3
+ import { useContext } from '@owlmeans/client';
4
+ import { LOGIN_SERVICE } from './consts.js';
5
+ import { primaryLoginMethod } from './methods.js';
6
+ import { acceptTerms, resolveTerms, termsAccepted } from './terms.js';
7
+ import { resolveCredit } from './credit.js';
8
+ /**
9
+ * The sign-in screen every application gets, whether or not it registered a styled one.
10
+ *
11
+ * It exists because a relying party must render SOMETHING rather than start a flow on its own, and
12
+ * a relying party may not depend on a UI family. So this is deliberately plain: raw elements and
13
+ * inline styles, no Tailwind class that a consumer's stylesheet would have to scan for, no shadcn
14
+ * primitive a consumer would have to vendor. An application that registers a real screen through
15
+ * `login().registerScreen(...)` never sees it.
16
+ *
17
+ * Because it is the floor rather than the design, it still has to be correct: it offers the same
18
+ * methods, enforces the same terms confirmation, and renders the same credit line.
19
+ */
20
+ const box = {
21
+ maxWidth: '24rem', margin: '10vh auto', padding: '1.5rem',
22
+ fontFamily: 'system-ui, sans-serif', lineHeight: 1.5,
23
+ };
24
+ const button = (emphasis) => ({
25
+ display: 'block', width: '100%', marginTop: '.5rem', padding: '.625rem 1rem',
26
+ fontSize: '1rem', cursor: 'pointer', borderRadius: '.375rem',
27
+ border: '1px solid currentColor',
28
+ ...(emphasis === 'primary' ? { fontWeight: 600 } : {}),
29
+ });
30
+ export const FallbackLoginScreen = props => {
31
+ const context = useContext();
32
+ const t = props.translate ?? ((_key, defaultValue) => defaultValue);
33
+ const cfg = props.config ?? context.cfg.security?.auth?.login;
34
+ const brand = context.cfg.brand;
35
+ const login = context.service(LOGIN_SERVICE);
36
+ const env = login.env();
37
+ const resolved = resolveTerms(props.terms ?? cfg?.terms);
38
+ const credit = resolveCredit(cfg?.credit, brand, context.cfg.service);
39
+ const [accepted, setAccepted] = useState(() => termsAccepted(resolved));
40
+ const [attempted, setAttempted] = useState(false);
41
+ const all = login.methods({ context, env });
42
+ const methods = typeof props.methods === 'function'
43
+ ? props.methods(all)
44
+ : props.methods ?? all;
45
+ const primary = primaryLoginMethod(methods);
46
+ const blocked = resolved != null && resolved.required && !accepted;
47
+ const select = useCallback((method) => {
48
+ if (blocked) {
49
+ setAttempted(true);
50
+ return;
51
+ }
52
+ void method.start({ context, env });
53
+ }, [blocked, context, env]);
54
+ const onAccept = useCallback((value) => {
55
+ setAccepted(value);
56
+ setAttempted(false);
57
+ acceptTerms(resolved, value);
58
+ }, [resolved]);
59
+ return _jsxs("div", { style: box, children: [_jsx("h1", { style: { fontSize: '1.25rem', marginBottom: '.25rem' }, children: props.title ?? t('login.title', 'Sign in') }), _jsx("p", { style: { opacity: .75, marginTop: 0 }, children: props.subtitle ?? t('login.subtitle', 'Choose how you would like to continue.') }), methods.length < 1
60
+ ? _jsx("p", { role: "status", children: t('login.empty', 'No sign-in method is configured for this application.') })
61
+ : methods.map(method => _jsx("button", { type: "button", "data-login-method": method.id, "aria-disabled": blocked, "data-blocked": blocked ? 'true' : undefined, style: { ...button(method.emphasis), opacity: blocked ? .6 : 1 }, autoFocus: method.id === primary?.id, onClick: () => select(method), children: method.label ?? t(`login.method.${method.i18nKey ?? method.id}`, method.id) }, method.id)), resolved != null && _jsxs("p", { style: { marginTop: '1rem', fontSize: '.875rem' }, children: [_jsxs("label", { children: [_jsx("input", { type: "checkbox", checked: accepted, "data-login-terms": true, onChange: event => onAccept(event.target.checked) }), ' ', t('login.terms.agreement', 'I have read and agree to the Terms & Conditions and the Privacy Policy.')] }), ' ', _jsx("a", { href: resolved.terms, target: "_blank", rel: "noreferrer noopener", children: t('login.terms.terms', 'Terms & Conditions') }), ' · ', _jsx("a", { href: resolved.privacy, target: "_blank", rel: "noreferrer noopener", children: t('login.terms.privacy', 'Privacy Policy') })] }), attempted && blocked && _jsx("p", { role: "alert", style: { color: '#b00', fontSize: '.875rem' }, children: t('login.terms.required', 'Please confirm the Terms & Conditions and the Privacy Policy to continue.') }), props.footer ?? _jsxs("p", { style: { marginTop: '2rem', fontSize: '.75rem', opacity: .7 }, children: [credit.poweredBy && _jsx("span", { children: t('login.credit.powered', 'Powered by OwlMeans') }), credit.poweredBy && credit.line != null && ' · ', credit.line] })] });
62
+ };
63
+ //# sourceMappingURL=screen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screen.js","sourceRoot":"","sources":["../../src/login/screen.tsx"],"names":[],"mappings":"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"}
@@ -14,9 +14,10 @@ import type { LoginService, LoginServiceAppend } from './types.js';
14
14
  * stage. `context.service()` throws for an uninitialized non-lazy service, which would make
15
15
  * `ensureLoginService` fail exactly where apps are told to call it.
16
16
  *
17
- * `begin` is deliberately NOT `async`. An async facade method defers the plugin's body past a
18
- * microtask boundary, and a `window.open` that lands after the user gesture has finished being
19
- * handled is eaten by the popup blocker. The same rule binds every plugin's own `begin`.
17
+ * `begin` and `logout` are deliberately NOT `async`. An async facade method defers the plugin's
18
+ * body past a microtask boundary, and a `window.open` that lands after the user gesture has
19
+ * finished being handled is eaten by the popup blocker. The same rule binds every plugin's own
20
+ * `begin` and `logout`, and it is why a precondition must be synchronous too.
20
21
  */
21
22
  export declare const makeLoginService: (alias?: string) => LoginService;
22
23
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/login/service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAIlE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACzC,OAAO,KAAK,EAA6B,YAAY,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAE7F;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,gBAAgB,WAAW,MAAM,KAAmB,YAuDhE,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,kBAAkB,QAAS,YAAY,CAAC,GAAG,CAAC,KAAG,YAQ3D,CAAA;AAED,4DAA4D;AAC5D,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,WAAW,EAAE,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,OACrE,CAAC,KACL,CAAC,GAAG,kBAMN,CAAA;AAED,OAAO,EAAE,YAAY,EAAE,CAAA"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/login/service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAMlE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACzC,OAAO,KAAK,EAEV,YAAY,EAAE,kBAAkB,EACjC,MAAM,YAAY,CAAA;AAEnB;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,gBAAgB,WAAW,MAAM,KAAmB,YA0HhE,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,kBAAkB,QAAS,YAAY,CAAC,GAAG,CAAC,KAAG,YAQ3D,CAAA;AAED,4DAA4D;AAC5D,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,WAAW,EAAE,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,OACrE,CAAC,KACL,CAAC,GAAG,kBAMN,CAAA;AAED,OAAO,EAAE,YAAY,EAAE,CAAA"}
@@ -1,7 +1,8 @@
1
1
  import { createLazyService } from '@owlmeans/context';
2
2
  import { DEFAULT_ALIAS } from './consts.js';
3
3
  import { defaultLoginEnv } from './env.js';
4
- import { adoptToken } from './adopt.js';
4
+ import { adoptToken, revokeToken } from './adopt.js';
5
+ import { resolveLoginMethods } from './methods.js';
5
6
  import { LoginOutcome } from './types.js';
6
7
  /**
7
8
  * Login service = plugin host. It holds a registry of login plugins and, on every facade call,
@@ -16,12 +17,16 @@ import { LoginOutcome } from './types.js';
16
17
  * stage. `context.service()` throws for an uninitialized non-lazy service, which would make
17
18
  * `ensureLoginService` fail exactly where apps are told to call it.
18
19
  *
19
- * `begin` is deliberately NOT `async`. An async facade method defers the plugin's body past a
20
- * microtask boundary, and a `window.open` that lands after the user gesture has finished being
21
- * handled is eaten by the popup blocker. The same rule binds every plugin's own `begin`.
20
+ * `begin` and `logout` are deliberately NOT `async`. An async facade method defers the plugin's
21
+ * body past a microtask boundary, and a `window.open` that lands after the user gesture has
22
+ * finished being handled is eaten by the popup blocker. The same rule binds every plugin's own
23
+ * `begin` and `logout`, and it is why a precondition must be synchronous too.
22
24
  */
23
25
  export const makeLoginService = (alias = DEFAULT_ALIAS) => {
24
26
  const plugins = [];
27
+ const preconditions = [];
28
+ const methodSources = [];
29
+ let screen = null;
25
30
  const ctx = () => service.ctx;
26
31
  const service = createLazyService(alias, {
27
32
  registerPlugin: (plugin) => {
@@ -32,6 +37,24 @@ export const makeLoginService = (alias = DEFAULT_ALIAS) => {
32
37
  plugins.push(plugin);
33
38
  plugins.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
34
39
  },
40
+ registerPrecondition: (precondition) => {
41
+ const existing = preconditions.findIndex(candidate => candidate.alias === precondition.alias);
42
+ if (existing >= 0) {
43
+ preconditions.splice(existing, 1);
44
+ }
45
+ preconditions.push(precondition);
46
+ preconditions.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
47
+ },
48
+ registerMethodSource: (source) => {
49
+ const existing = methodSources.findIndex(candidate => candidate.alias === source.alias);
50
+ if (existing >= 0) {
51
+ methodSources.splice(existing, 1);
52
+ }
53
+ methodSources.push(source);
54
+ },
55
+ methods: methodCtx => resolveLoginMethods(methodCtx, methodCtx.context.cfg.security?.auth?.login, methodSources),
56
+ registerScreen: value => { screen = value; },
57
+ screen: () => screen,
35
58
  plugin: env => {
36
59
  const environment = env ?? defaultLoginEnv();
37
60
  const plugin = plugins.find(candidate => candidate.match?.(environment, service.ctx) ?? true);
@@ -47,6 +70,13 @@ export const makeLoginService = (alias = DEFAULT_ALIAS) => {
47
70
  },
48
71
  begin: request => {
49
72
  const env = defaultLoginEnv();
73
+ // Synchronously, before anything can open a window: a precondition that refuses leaves the
74
+ // user exactly where `Gesture` describes — unable to proceed until they act again.
75
+ for (const precondition of preconditions) {
76
+ if (!precondition.check(ctx(), request, env)) {
77
+ return Promise.resolve(LoginOutcome.Gesture);
78
+ }
79
+ }
50
80
  return service.plugin(env).begin(ctx(), request, env);
51
81
  },
52
82
  authorize: async (url) => {
@@ -57,7 +87,30 @@ export const makeLoginService = (alias = DEFAULT_ALIAS) => {
57
87
  const env = defaultLoginEnv();
58
88
  return await service.plugin(env).complete(ctx(), token, env);
59
89
  },
90
+ resume: async (token) => {
91
+ const env = defaultLoginEnv();
92
+ // Absent means "keep it and carry on" — which is what an ordinary tab has always done, and
93
+ // is why the redirect plugin implements nothing here.
94
+ return await service.plugin(env).resume?.(ctx(), token, env) ?? LoginOutcome.Passed;
95
+ },
96
+ logout: request => {
97
+ const env = defaultLoginEnv();
98
+ const plugin = service.plugin(env);
99
+ if (plugin.logout == null) {
100
+ // A plugin with no logout mechanic still has to end the session it started.
101
+ return revokeToken(ctx()).then(async () => {
102
+ await request.navigate?.();
103
+ return LoginOutcome.Passed;
104
+ });
105
+ }
106
+ return plugin.logout(ctx(), request, env);
107
+ },
108
+ logoutComplete: async () => {
109
+ const env = defaultLoginEnv();
110
+ return await service.plugin(env).logoutComplete?.(ctx(), env) ?? LoginOutcome.Passed;
111
+ },
60
112
  adopt: async (token) => { await adoptToken(ctx(), token); },
113
+ revoke: async () => { await revokeToken(ctx()); },
61
114
  });
62
115
  return service;
63
116
  };
@@ -1 +1 @@
1
- {"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/login/service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/login/service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { LoginIntent } from './types.js';
2
+ import type { LoginContext } from './types.js';
3
+ export interface SurrogateTarget {
4
+ intent: LoginIntent;
5
+ /** The address the surrogate should actually run, once it is one window up. */
6
+ next?: string;
7
+ /** The method the user already chose in the opener. */
8
+ method?: string;
9
+ }
10
+ /**
11
+ * Where a surrogate window opens.
12
+ *
13
+ * Returns `null` when the application's entrypoint list predates the surrogate route — an app
14
+ * built against an older `@owlmeans/auth-common` has no such entrypoint, and the caller then falls
15
+ * back to opening the dispatcher directly, which is exactly what it used to do. That fallback is
16
+ * the whole compatibility story for already-deployed applications, so it must never be removed in
17
+ * favour of throwing.
18
+ */
19
+ export declare const surrogatePath: (ctx: LoginContext, target: SurrogateTarget) => string | null;
20
+ //# sourceMappingURL=surrogate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"surrogate.d.ts","sourceRoot":"","sources":["../../src/login/surrogate.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AACxC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAE9C,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,WAAW,CAAA;IACnB,+EAA+E;IAC/E,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,uDAAuD;IACvD,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa,QAAS,YAAY,UAAU,eAAe,KAAG,MAAM,GAAG,IAqBnF,CAAA"}
@@ -0,0 +1,33 @@
1
+ import { DISPATCHER_SURROGATE } from '@owlmeans/auth';
2
+ import { LOGIN_INTENT_QUERY, LOGIN_METHOD_QUERY, LOGIN_NEXT_QUERY } from './consts.js';
3
+ /**
4
+ * Where a surrogate window opens.
5
+ *
6
+ * Returns `null` when the application's entrypoint list predates the surrogate route — an app
7
+ * built against an older `@owlmeans/auth-common` has no such entrypoint, and the caller then falls
8
+ * back to opening the dispatcher directly, which is exactly what it used to do. That fallback is
9
+ * the whole compatibility story for already-deployed applications, so it must never be removed in
10
+ * favour of throwing.
11
+ */
12
+ export const surrogatePath = (ctx, target) => {
13
+ if (!ctx.hasEntrypoint(DISPATCHER_SURROGATE)) {
14
+ return null;
15
+ }
16
+ let path;
17
+ try {
18
+ path = ctx.entrypoint(DISPATCHER_SURROGATE).getPath();
19
+ }
20
+ catch {
21
+ return null;
22
+ }
23
+ const query = new URLSearchParams();
24
+ query.set(LOGIN_INTENT_QUERY, target.intent);
25
+ if (target.next != null && target.next !== '') {
26
+ query.set(LOGIN_NEXT_QUERY, target.next);
27
+ }
28
+ if (target.method != null && target.method !== '') {
29
+ query.set(LOGIN_METHOD_QUERY, target.method);
30
+ }
31
+ return `${path}?${query.toString()}`;
32
+ };
33
+ //# sourceMappingURL=surrogate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"surrogate.js","sourceRoot":"","sources":["../../src/login/surrogate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAErD,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAYtF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,GAAiB,EAAE,MAAuB,EAAiB,EAAE;IACzF,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,oBAAoB,CAAC,EAAE,CAAC;QAC7C,OAAO,IAAI,CAAA;IACb,CAAC;IACD,IAAI,IAAY,CAAA;IAChB,IAAI,CAAC;QACH,IAAI,GAAG,GAAG,CAAC,UAAU,CAAmB,oBAAoB,CAAC,CAAC,OAAO,EAAE,CAAA;IACzE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,eAAe,EAAE,CAAA;IACnC,KAAK,CAAC,GAAG,CAAC,kBAAkB,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;IAC5C,IAAI,MAAM,CAAC,IAAI,IAAI,IAAI,IAAI,MAAM,CAAC,IAAI,KAAK,EAAE,EAAE,CAAC;QAC9C,KAAK,CAAC,GAAG,CAAC,gBAAgB,EAAE,MAAM,CAAC,IAAI,CAAC,CAAA;IAC1C,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QAClD,KAAK,CAAC,GAAG,CAAC,kBAAkB,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;IAC9C,CAAC;IAED,OAAO,GAAG,IAAI,IAAI,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAA;AACtC,CAAC,CAAA"}
@@ -0,0 +1,20 @@
1
+ import type { LoginTermsConfig } from '@owlmeans/config';
2
+ export interface ResolvedTerms {
3
+ required: boolean;
4
+ terms: string;
5
+ privacy: string;
6
+ cookies?: string;
7
+ version: string;
8
+ }
9
+ export declare const resolveTerms: (cfg?: LoginTermsConfig | false) => ResolvedTerms | null;
10
+ /**
11
+ * Whether this browser has already agreed to exactly these documents.
12
+ *
13
+ * `localStorage` and not a cookie: the record is a UI convenience, it never travels to a server,
14
+ * and it must be readable by the surrogate login window — which is same-origin, so it sees the
15
+ * opener's acceptance and does not ask twice. A preview iframe on a different origin gets its own
16
+ * partition and therefore its own acceptance, which is correct rather than unfortunate.
17
+ */
18
+ export declare const termsAccepted: (resolved: ResolvedTerms | null) => boolean;
19
+ export declare const acceptTerms: (resolved: ResolvedTerms | null, accepted: boolean) => void;
20
+ //# sourceMappingURL=terms.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terms.d.ts","sourceRoot":"","sources":["../../src/login/terms.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAGxD,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,OAAO,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;CAChB;AAkBD,eAAO,MAAM,YAAY,SAAU,gBAAgB,GAAG,KAAK,KAAG,aAAa,GAAG,IAa7E,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,aAAc,aAAa,GAAG,IAAI,KAAG,OAW9D,CAAA;AAED,eAAO,MAAM,WAAW,aAAc,aAAa,GAAG,IAAI,YAAY,OAAO,KAAG,IAW/E,CAAA"}
Binary file
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terms.js","sourceRoot":"","sources":["../../src/login/terms.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AAEjG,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAUjD;;;;;;GAMG;AACH,MAAM,MAAM,GAAG,CAAC,KAAe,EAAU,EAAE;IACzC,IAAI,IAAI,GAAG,CAAC,CAAA;IACZ,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACnC,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;IACtD,CAAC;IAED,OAAO,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;AAClC,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,GAA8B,EAAwB,EAAE;IACnF,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;QAClB,OAAO,IAAI,CAAA;IACb,CAAC;IACD,MAAM,KAAK,GAAG,GAAG,EAAE,KAAK,IAAI,kBAAkB,CAAA;IAC9C,MAAM,OAAO,GAAG,GAAG,EAAE,OAAO,IAAI,oBAAoB,CAAA;IACpD,MAAM,OAAO,GAAG,GAAG,EAAE,OAAO,IAAI,oBAAoB,CAAA;IAEpD,OAAO;QACL,QAAQ,EAAE,GAAG,EAAE,QAAQ,IAAI,IAAI;QAC/B,KAAK,EAAE,OAAO,EAAE,OAAO;QACvB,OAAO,EAAE,GAAG,EAAE,OAAO,IAAI,MAAM,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;KAC3D,CAAA;AACH,CAAC,CAAA;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,QAA8B,EAAW,EAAE;IACvE,IAAI,QAAQ,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;QAC3C,OAAO,IAAI,CAAA;IACb,CAAC;IACD,IAAI,CAAC;QACH,OAAO,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,mBAAmB,CAAC,KAAK,QAAQ,CAAC,OAAO,CAAA;IAC9E,CAAC;IAAC,MAAM,CAAC;QACP,2FAA2F;QAC3F,yFAAyF;QACzF,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,QAA8B,EAAE,QAAiB,EAAQ,EAAE;IACrF,IAAI,QAAQ,IAAI,IAAI,EAAE,CAAC;QACrB,OAAM;IACR,CAAC;IACD,IAAI,CAAC;QACH,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,mBAAmB,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAA;QACpE,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAA;QACrD,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAC,wDAAwD,CAAC,CAAC;AACtE,CAAC,CAAA"}