@viceme-ai/sdk 0.7.0 → 0.8.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 +52 -16
- package/dist/chunks/client-DbPCnwf-.js +1471 -0
- package/dist/chunks/client-DbPCnwf-.js.map +1 -0
- package/dist/chunks/version-DXLLix7K.js +6 -0
- package/dist/chunks/{version-CAPPYmfK.js.map → version-DXLLix7K.js.map} +1 -1
- package/dist/core/access-bridge.d.ts +17 -0
- package/dist/core/access-bridge.d.ts.map +1 -0
- package/dist/core/capabilities.d.ts +12 -2
- package/dist/core/capabilities.d.ts.map +1 -1
- package/dist/core/client.d.ts.map +1 -1
- package/dist/core/presentation.d.ts +5 -1
- package/dist/core/presentation.d.ts.map +1 -1
- package/dist/danmaku.js +1 -1
- package/dist/generated/public-contract.d.ts +248 -14
- package/dist/generated/public-contract.d.ts.map +1 -1
- package/dist/index.js +28 -27
- package/dist/index.js.map +1 -1
- package/dist/manifest.json +23 -23
- package/dist/session/session.d.ts +24 -3
- package/dist/session/session.d.ts.map +1 -1
- package/dist/testing.js +1 -1
- package/dist/transport/transport.d.ts +2 -0
- package/dist/transport/transport.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/viceme.min.js +7 -6
- package/dist/viceme.min.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunks/client-C1Sw400H.js +0 -1113
- package/dist/chunks/client-C1Sw400H.js.map +0 -1
- package/dist/chunks/version-CAPPYmfK.js +0 -6
package/dist/manifest.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.
|
|
2
|
+
"version": "0.8.0",
|
|
3
3
|
"apiMajor": 1,
|
|
4
4
|
"loader": "viceme.min.js",
|
|
5
5
|
"features": {
|
|
@@ -16,11 +16,11 @@
|
|
|
16
16
|
"bytes": 230,
|
|
17
17
|
"gzipBytes": 159
|
|
18
18
|
},
|
|
19
|
-
"chunks/client-
|
|
20
|
-
"sha256": "
|
|
21
|
-
"sri": "sha384-
|
|
22
|
-
"bytes":
|
|
23
|
-
"gzipBytes":
|
|
19
|
+
"chunks/client-DbPCnwf-.js": {
|
|
20
|
+
"sha256": "b2daf93827955bd3ebc5a38c17340241b34051c7bfba5e88ace42639a4769a5b",
|
|
21
|
+
"sri": "sha384-ImQuS8+9XB1rQB+/DDvlBzMgOlUcW8rzyKMgMXOBsyiOdVguPDtqnqSIJg8GjjoX",
|
|
22
|
+
"bytes": 51574,
|
|
23
|
+
"gzipBytes": 13639
|
|
24
24
|
},
|
|
25
25
|
"chunks/errors-C7DfLKcF.js": {
|
|
26
26
|
"sha256": "6ed053a2ab0ff6d4969ed644fb4e4ae89e850526f32c7841294a964447d2d1f3",
|
|
@@ -40,29 +40,29 @@
|
|
|
40
40
|
"bytes": 1379,
|
|
41
41
|
"gzipBytes": 657
|
|
42
42
|
},
|
|
43
|
-
"chunks/version-
|
|
44
|
-
"sha256": "
|
|
45
|
-
"sri": "sha384-
|
|
43
|
+
"chunks/version-DXLLix7K.js": {
|
|
44
|
+
"sha256": "33c9eee6a9dcdce237156d7264294decc9fb61a7357b211a89d7b97eaec8b995",
|
|
45
|
+
"sri": "sha384-dXQElJ4mAxVxkKZpeyZfHkApMw0zuO0pozRx4280ghYq0IidGxoZh3ViaGzQbyTG",
|
|
46
46
|
"bytes": 102,
|
|
47
47
|
"gzipBytes": 119
|
|
48
48
|
},
|
|
49
49
|
"danmaku.js": {
|
|
50
|
-
"sha256": "
|
|
51
|
-
"sri": "sha384-
|
|
50
|
+
"sha256": "6d573db86571b458f9a495d3ec5f581da95508e2229dd7edc2d449899997b5e6",
|
|
51
|
+
"sri": "sha384-mzSUGBDCrnyMMMuUwuluO14XNAzv7mCCb64dpwXnB65W3yxQr98hMcL4Izkj6sbM",
|
|
52
52
|
"bytes": 10426,
|
|
53
|
-
"gzipBytes":
|
|
53
|
+
"gzipBytes": 3661
|
|
54
54
|
},
|
|
55
55
|
"index.js": {
|
|
56
|
-
"sha256": "
|
|
57
|
-
"sri": "sha384-
|
|
58
|
-
"bytes":
|
|
59
|
-
"gzipBytes":
|
|
56
|
+
"sha256": "11293c496aed27e1fd072dd382d9ecd99294b16c6386421b98edb3c4d3e97f7b",
|
|
57
|
+
"sri": "sha384-qthoVMC0TQ1joxnSx8CqoW9d5OE6ixQY7km5ms2LiXh/kN04vn1U6oq4cCbaMmdn",
|
|
58
|
+
"bytes": 4625,
|
|
59
|
+
"gzipBytes": 1871
|
|
60
60
|
},
|
|
61
61
|
"testing.js": {
|
|
62
|
-
"sha256": "
|
|
63
|
-
"sri": "sha384
|
|
62
|
+
"sha256": "03043c6e9d448ad5eef25f6c3fadd51396abfcd499954cc13ece10cfd77e10a3",
|
|
63
|
+
"sri": "sha384-93LMtVPztw67XUkg4+2tWLR88jhtsQIsZ1Ikcql/5ZBlcikj6udKWSSilE/gyzCI",
|
|
64
64
|
"bytes": 2300,
|
|
65
|
-
"gzipBytes":
|
|
65
|
+
"gzipBytes": 1024
|
|
66
66
|
},
|
|
67
67
|
"tip.js": {
|
|
68
68
|
"sha256": "fd3df8a0b2f9541cb39c7c55eaeeb7a8cd150615150b8fb7980b99d3575847e6",
|
|
@@ -77,10 +77,10 @@
|
|
|
77
77
|
"gzipBytes": 540
|
|
78
78
|
},
|
|
79
79
|
"viceme.min.js": {
|
|
80
|
-
"sha256": "
|
|
81
|
-
"sri": "sha384-
|
|
82
|
-
"bytes":
|
|
83
|
-
"gzipBytes":
|
|
80
|
+
"sha256": "1a7ef823ac63a536d0dc27b6047159fd91bac88df0b8764eb6334a0cc3a77418",
|
|
81
|
+
"sri": "sha384-UzkQ/ZrgAbdDnYcI5Qqkbb1UTjaZ3VKXW70my1Byq07OPK5H9wlAFb8yYL/5ActT",
|
|
82
|
+
"bytes": 52355,
|
|
83
|
+
"gzipBytes": 15611
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
}
|
|
@@ -2,18 +2,26 @@
|
|
|
2
2
|
* Public visitor session.
|
|
3
3
|
*
|
|
4
4
|
* ```text
|
|
5
|
-
* SDK + workKey +
|
|
5
|
+
* SDK + workKey + supported protocols -> POST /v1/public/work-sdk/sessions
|
|
6
6
|
* -> short-lived capability token -> public capability calls
|
|
7
7
|
* ```
|
|
8
8
|
*
|
|
9
9
|
* The token lives in memory only (never localStorage/cookies), is bound to the
|
|
10
|
-
* Work,
|
|
10
|
+
* Work, market, capability set, and expiry by the server, and is dropped on
|
|
11
11
|
* `destroy()`. `workKey` locates the Work — it is never an authorization
|
|
12
12
|
* credential.
|
|
13
13
|
*/
|
|
14
14
|
import type { Transport, TransportRequest, TransportResponse } from '../transport/transport.ts';
|
|
15
15
|
export interface CreateWorkSessionRequestDto {
|
|
16
16
|
workKey: string;
|
|
17
|
+
supportedAccessProtocolVersions: [3];
|
|
18
|
+
}
|
|
19
|
+
export interface AccessMarketCapabilities {
|
|
20
|
+
market: 'CN' | 'GLOBAL';
|
|
21
|
+
loginMethods: string[];
|
|
22
|
+
supportedPriceCurrencies: Array<'CNY' | 'USD'>;
|
|
23
|
+
checkoutAvailability: 'AVAILABLE' | 'PENDING_CHANNEL' | 'DISABLED';
|
|
24
|
+
anonymousPurchase: boolean;
|
|
17
25
|
}
|
|
18
26
|
export interface WorkDescriptor {
|
|
19
27
|
key: string;
|
|
@@ -40,6 +48,11 @@ export interface WorkSessionSnapshot {
|
|
|
40
48
|
expiresAt?: number;
|
|
41
49
|
user?: WorkUser;
|
|
42
50
|
userToken?: string;
|
|
51
|
+
userExpiresAt?: number;
|
|
52
|
+
accessProtocolVersion?: 3;
|
|
53
|
+
marketCapabilities?: AccessMarketCapabilities;
|
|
54
|
+
buyerToken?: string;
|
|
55
|
+
buyerExpiresAt?: number;
|
|
43
56
|
}
|
|
44
57
|
export interface WorkUser {
|
|
45
58
|
subject: string;
|
|
@@ -48,6 +61,7 @@ export interface WorkUser {
|
|
|
48
61
|
}
|
|
49
62
|
export interface SessionManagerOptions {
|
|
50
63
|
workKey: string;
|
|
64
|
+
region?: 'cn' | 'global';
|
|
51
65
|
transport: Transport;
|
|
52
66
|
signal?: AbortSignal;
|
|
53
67
|
timeoutMs?: number;
|
|
@@ -58,6 +72,8 @@ export declare class SessionManager {
|
|
|
58
72
|
#private;
|
|
59
73
|
constructor(options: SessionManagerOptions);
|
|
60
74
|
get snapshot(): WorkSessionSnapshot | undefined;
|
|
75
|
+
/** Identity generation prevents a late bridge from undoing logout or account changes. */
|
|
76
|
+
get identityGeneration(): number;
|
|
61
77
|
/**
|
|
62
78
|
* Establish (or return the established) public session.
|
|
63
79
|
*
|
|
@@ -66,11 +82,16 @@ export declare class SessionManager {
|
|
|
66
82
|
* in-flight request (single flight).
|
|
67
83
|
*/
|
|
68
84
|
establish(): Promise<WorkSessionSnapshot>;
|
|
69
|
-
request(request: Omit<TransportRequest, 'authorization' | 'userAuthorization' | '
|
|
85
|
+
request(request: Omit<TransportRequest, 'authorization' | 'userAuthorization' | 'buyerAuthorization'>): Promise<TransportResponse>;
|
|
70
86
|
authenticate(input: {
|
|
71
87
|
userToken: string;
|
|
72
88
|
user: WorkUser;
|
|
89
|
+
expiresAt?: number;
|
|
73
90
|
}): void;
|
|
91
|
+
identifyBuyer(input: {
|
|
92
|
+
buyerToken: string;
|
|
93
|
+
expiresAt: number;
|
|
94
|
+
}, generation: number): void;
|
|
74
95
|
signOut(): Promise<void>;
|
|
75
96
|
/** Drop the token; next `establish()` re-authenticates. */
|
|
76
97
|
invalidate(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/session/session.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAChG,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/session/session.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAChG,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,+BAA+B,EAAE,CAAC,CAAC,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,IAAI,GAAG,QAAQ,CAAC;IACxB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,wBAAwB,EAAE,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC;IAC/C,oBAAoB,EAAE,WAAW,GAAG,iBAAiB,GAAG,UAAU,CAAC;IACnE,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,8CAA8C;IAC9C,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,CAAC,EAAE,qBAAqB,CAAC;IAChC,OAAO,CAAC,EAAE,0BAA0B,CAAC;CACtC;AAED,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,cAAc,CAAC;IACrB,wDAAwD;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8EAA8E;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qBAAqB,CAAC,EAAE,CAAC,CAAC;IAC1B,kBAAkB,CAAC,EAAE,wBAAwB,CAAC;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,IAAI,GAAG,QAAQ,CAAC;IACzB,SAAS,EAAE,SAAS,CAAC;IACrB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AA0HD,qBAAa,cAAc;;gBASb,OAAO,EAAE,qBAAqB;IAK1C,IAAI,QAAQ,IAAI,mBAAmB,GAAG,SAAS,CAE9C;IAED,yFAAyF;IACzF,IAAI,kBAAkB,IAAI,MAAM,CAE/B;IAQD;;;;;;OAMG;IACH,SAAS,IAAI,OAAO,CAAC,mBAAmB,CAAC;IA6DnC,OAAO,CACX,OAAO,EAAE,IAAI,CAAC,gBAAgB,EAAE,eAAe,GAAG,mBAAmB,GAAG,oBAAoB,CAAC,GAC5F,OAAO,CAAC,iBAAiB,CAAC;IAgB7B,YAAY,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,QAAQ,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAgBpF,aAAa,CAAC,KAAK,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IAgBnF,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAO9B,2DAA2D;IAC3D,UAAU,IAAI,IAAI;IAMlB,uDAAuD;IACvD,OAAO,IAAI,IAAI;CAkDhB"}
|
package/dist/testing.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { a as i } from "./chunks/errors-C7DfLKcF.js";
|
|
2
|
-
import { i as l, a as u, V as k } from "./chunks/client-
|
|
2
|
+
import { i as l, a as u, V as k } from "./chunks/client-DbPCnwf-.js";
|
|
3
3
|
function g(e) {
|
|
4
4
|
const s = [], o = [...e.sessionFailures ?? []], a = e.latencyMs ?? 0;
|
|
5
5
|
return {
|
|
@@ -16,6 +16,8 @@ export interface TransportRequest {
|
|
|
16
16
|
authorization?: string;
|
|
17
17
|
/** Optional memory-only signed-in widget token. */
|
|
18
18
|
userAuthorization?: string;
|
|
19
|
+
/** Optional memory-only, Work-scoped anonymous purchase authorization. */
|
|
20
|
+
buyerAuthorization?: string;
|
|
19
21
|
signal?: AbortSignal;
|
|
20
22
|
/** Per-request timeout; defaults to the transport default. */
|
|
21
23
|
timeoutMs?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/transport/transport.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC;IAC1C,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,sCAAsC;IACtC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,kEAAkE;IAClE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mDAAmD;IACnD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;CAChE;AAED,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,wDAAwD;IACxD,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,8DAA8D;IAC9D,iBAAiB,CAAC,EAAE,MAAM,MAAM,CAAC;CAClC;AAqED,qBAAa,cAAe,YAAW,SAAS;;gBAMlC,OAAO,EAAE,qBAAqB;IAOpC,OAAO,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/transport/transport.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC;IAC1C,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,sCAAsC;IACtC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,kEAAkE;IAClE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mDAAmD;IACnD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,0EAA0E;IAC1E,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;CAChE;AAED,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,wDAAwD;IACxD,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,8DAA8D;IAC9D,iBAAiB,CAAC,EAAE,MAAM,MAAM,CAAC;CAClC;AAqED,qBAAa,cAAe,YAAW,SAAS;;gBAMlC,OAAO,EAAE,qBAAqB;IAOpC,OAAO,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAkHrE;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,qBAAqB,GAAG,SAAS,CAE9E"}
|
package/dist/version.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Kept in sync with `packages/sdk/package.json#version`; a unit test enforces
|
|
5
5
|
* the match so the loader, release manifest, and npm metadata can never drift.
|
|
6
6
|
*/
|
|
7
|
-
export declare const SDK_VERSION = "0.
|
|
7
|
+
export declare const SDK_VERSION = "0.8.0";
|
|
8
8
|
/** Public API major carried by this build (loader namespace `v1`). */
|
|
9
9
|
export declare const API_MAJOR = 1;
|
|
10
10
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/viceme.min.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(){"use strict";const le=new Set(["RATE_LIMITED","NETWORK_TIMEOUT","CHECKOUT_UNAVAILABLE","INTERNAL_ERROR"]);class w extends Error{code;retryable;requestId;capability;constructor(e){super(e.message),this.name="ViceMeError",this.code=e.code,this.retryable=e.retryable??le.has(e.code),this.requestId=e.requestId,this.capability=e.capability}toJSON(){const e={code:this.code,retryable:this.retryable};return this.requestId!==void 0&&(e.requestId=this.requestId),this.capability!==void 0&&(e.capability=this.capability),e}}function de(t){return t instanceof w}function p(t){return new w({code:"CONFIG_INVALID",message:t,retryable:!1})}function T(){return new w({code:"CLIENT_DESTROYED",message:"ViceMe client has been destroyed.",retryable:!1})}const H={cn:"https://api.viceme.cn",global:"https://api.viceme.ai"},ue={cn:"https://viceme.cn",global:"https://viceme.ai"},fe=new Set(["cn","global"]),me={cn:H.cn,global:H.global};function he(t){return me[t]}function z(t){return typeof t=="string"&&/^wrk_(?:test|live)_[A-Za-z0-9_-]{4,119}$/.test(t)}function Y(t){return typeof t=="string"&&fe.has(t)}function ye(t){if(typeof t!="object"||t===null)throw p("createViceMe expects a configuration object.");const e=t,r=new Set(["workKey","region","signal"]);for(const i of Object.keys(e))if(!r.has(i))throw p(`Unknown configuration field "${i}".`);if(!z(e.workKey))throw p('Configuration field "workKey" must start with "wrk_test_" or "wrk_live_".');if(!Y(e.region))throw p('Configuration field "region" must be "cn" or "global".');if(e.signal!==void 0&&!(e.signal instanceof AbortSignal))throw p('Configuration field "signal" must be an AbortSignal.');return{workKey:e.workKey,region:e.region,signal:e.signal}}const pe=new Set(["data-viceme-work","data-viceme-region","data-viceme-features","data-viceme-target","data-viceme-theme","data-viceme-loader"]),we=new Set(["light","dark","auto"]),X=["danmaku","tip"];function ge(t){for(const g of t.getAttributeNames())if(g.startsWith("data-viceme-")&&!pe.has(g))throw p(`Unknown loader attribute "${g}".`);const e=t.getAttribute("data-viceme-work");if(!z(e))throw p('Loader attribute "data-viceme-work" must be a public Work key.');const r=t.getAttribute("data-viceme-region");if(!Y(r))throw p('Loader attribute "data-viceme-region" must be "cn" or "global".');const i=t.getAttribute("data-viceme-features"),a=i?.split(",")??[],d=new Set(a);if(!i||/\s/.test(i)||a.length!==d.size||a.some(g=>!X.includes(g)))throw p('Loader attribute "data-viceme-features" must contain each of "danmaku" and "tip" at most once.');const n=X.filter(g=>d.has(g)),l=t.getAttribute("data-viceme-target");if(l==="")throw p('Loader attribute "data-viceme-target" must be a CSS selector.');if(l===null)throw p('Loader attribute "data-viceme-target" is required when features are declared.');try{t.matches(l)}catch{throw p('Loader attribute "data-viceme-target" is not a valid CSS selector.')}const f=t.getAttribute("data-viceme-theme");if(f!==null&&!we.has(f))throw p('Loader attribute "data-viceme-theme" must be "light", "dark", or "auto".');return{workKey:e,region:r,features:n,target:l,theme:f??"auto"}}function $(t,e,r){return`v${t}+${e}+${r}`}class be{#e=new Map;#t=new Map;#r=new Map;#i=0;getClient(e){return this.#e.get(e)}registerClient(e){this.#e.set(e.clientKey,e)}unregisterClient(e){this.#e.delete(e)}getInstance(e){return this.#t.get(e)}findInstance(e,r,i){return this.#r.get(`${e}::${r}`)?.get(i)}registerInstance(e,r,i,a){const d=`${e}::${r}`;let n=this.#r.get(d);n===void 0&&(n=new WeakMap,this.#r.set(d,n));const l=n.get(i);if(l)return l;this.#i+=1;const f={instanceKey:`${e}::${r}::el${this.#i}`,clientKey:e,capability:r,host:i,raw:a,destroyed:!1};return this.#t.set(f.instanceKey,f),n.set(i,f),f}removeInstance(e){const r=this.#t.get(e);if(r)return this.#t.delete(e),this.#r.get(`${r.clientKey}::${r.capability}`)?.delete(r.host),r}instancesForClient(e){return[...this.#t.values()].filter(r=>r.clientKey===e)}}const ve=new Map([["viceme:ready",new Set(["clientKey","workKey","capabilities","version"])],["viceme:capability-ready",new Set(["clientKey","instanceKey","capability","version"])],["viceme:error",new Set(["clientKey","instanceKey","capability","code","retryable","requestId"])],["viceme:destroyed",new Set(["clientKey","instanceKey","capability"])],["viceme:widget-close",new Set(["workId"])],["viceme:tip-paid",new Set(["status","work","amountCents","currency"])]]);function Ee(t,e){if(t==="viceme:tip-paid"){const a=e;return{status:a.status,work:{id:a.work.id,title:a.work.title},amountCents:a.amountCents,currency:a.currency}}const r=ve.get(t),i={};for(const[a,d]of Object.entries(e))r.has(a)&&d!==void 0&&(i[a]=d);return i}function F(t,e,r){const i=new CustomEvent(e,{detail:Ee(e,r),bubbles:!0,composed:!0,cancelable:!1});t.dispatchEvent(i)}const ke={CREATED:["READY","DESTROYED"],READY:["DEGRADED","DESTROYED"],DEGRADED:["DESTROYED"],DESTROYED:[]};class Ie{#e="CREATED";#t=new Set;get state(){return this.#e}get destroyed(){return this.#e==="DESTROYED"}transition(e){if(e!==this.#e){if(!ke[this.#e].includes(e))throw new w({code:"INTERNAL_ERROR",message:`Illegal lifecycle transition ${this.#e} -> ${e}.`,retryable:!1});this.#e=e;for(const r of this.#t)r(e)}}assertAlive(){if(this.destroyed)throw T()}subscribe(e){return this.#t.add(e),()=>{this.#t.delete(e)}}clearListeners(){this.#t.clear()}}function Ae(t,e){if(typeof t!="object"||t===null)throw M();const r=t;if(typeof r.workKey!="string"||!Array.isArray(r.capabilities)||!r.capabilities.every(a=>typeof a=="string"))throw M();if(r.workKey!==e)throw new w({code:"WORK_NOT_FOUND",message:"Work-session response did not match the requested work key.",retryable:!1});const i={work:{key:r.workKey,capabilities:r.capabilities}};if(r.creator!==void 0||r.work!==void 0){const a=Q(r.creator),d=Q(r.work);if(typeof a.displayName!="string"||a.displayName.length===0||!J(a.avatarUrl)||!Number.isInteger(a.publishedWorkCount)||a.publishedWorkCount<0||typeof d.title!="string"||d.title.length===0||typeof d.summary!="string"||!J(d.coverUrl))throw M();i.work.creator={displayName:a.displayName,avatarUrl:a.avatarUrl,publishedWorkCount:a.publishedWorkCount},i.work.details={title:d.title,summary:d.summary,coverUrl:d.coverUrl}}if(typeof r.token=="string"&&(i.token=r.token),typeof r.expiresAt=="string"){const a=new Date(r.expiresAt).getTime();Number.isNaN(a)||(i.expiresAt=a)}return i}function Q(t){if(typeof t!="object"||t===null)throw M();return t}function J(t){if(t===null)return!0;if(typeof t!="string")return!1;try{return new URL(t),!0}catch{return!1}}function M(){return new w({code:"INTERNAL_ERROR",message:"Malformed work-session response.",retryable:!0})}function Te(){return new w({code:"SESSION_EXPIRED",message:"The work session was invalidated before it completed.",retryable:!0})}class Se{#e;#t;#r;#i;#a=0;#n=!1;constructor(e){this.#e=e,this.#t=e.now??(()=>Date.now())}get snapshot(){return this.#r}#s(){const e=this.#r?.expiresAt;return e!==void 0&&e<=this.#t()}establish(){if(this.#n)return Promise.reject(T());if(this.#r){if(!this.#s())return Promise.resolve(this.#r);this.#r=void 0}if(this.#i)return this.#i;const e=this.#a,r=this.#e.transport.request({method:"POST",path:"/v1/public/work-sdk/sessions",body:{workKey:this.#e.workKey},signal:this.#e.signal,timeoutMs:this.#e.timeoutMs}).then(i=>{this.#c(e);const a=Ae(i.body,this.#e.workKey);return this.#c(e),this.#r=a,a}).finally(()=>{this.#i===r&&(this.#i=void 0)});return this.#i=r,r}async request(e){const r=await this.establish();if(!r.token)throw M();try{return await this.#l(e,r)}catch(i){if(this.#n)throw T();if(!(i instanceof w)||i.code!=="SESSION_EXPIRED")throw i;this.#r===r&&this.invalidate();const a=await this.establish();if(!a.token)throw M();return this.#l(e,a)}}authenticate(e){if(this.#o(),!this.#r)throw M();this.#r={...this.#r,userToken:e.userToken,user:e.user}}async signOut(){this.#o(),this.invalidate(),await this.establish()}invalidate(){this.#a+=1,this.#r=void 0,this.#i=void 0}destroy(){this.#n||(this.#n=!0,this.#a+=1,this.#r=void 0,this.#i=void 0)}#o(){if(this.#n)throw T()}#c(e){if(this.#o(),e!==this.#a)throw Te()}async#l(e,r){this.#o();try{const i=await this.#e.transport.request({...e,authorization:r.token,userAuthorization:r.userToken,signal:this.#e.signal});return this.#o(),i}catch(i){throw this.#n?T():i}}}const Z="0.7.0",P=1,W="viceme-access-layer",B=50;function Ne(t){switch(t){case"SIGN_IN":return{description:"",label:"授权"};case"FOLLOW":return{description:"",label:"关注"};case"CHECKOUT":return{description:"",label:"打开支付"}}}function Re(t){if(!de(t))return"操作未完成,请重试。";switch(t.code){case"CONFIG_INVALID":return"微信授权配置无效,请稍后重试。";case"AUTH_CANCELLED":return"微信授权已取消,请重试。";case"SESSION_EXPIRED":return"授权会话已过期,请重试。";case"NETWORK_TIMEOUT":return"网络连接超时,请重试。";default:return t.requestId?`操作未完成,请重试。请求 ID:${t.requestId}`:"操作未完成,请重试。"}}function Oe(){if(customElements.get(W))return;class t extends HTMLElement{interaction;connectedCallback(){const r=Ne(this.interaction.action),i=this.attachShadow({mode:"open"});i.innerHTML=`
|
|
1
|
+
(function(){"use strict";const ve=new Set(["RATE_LIMITED","NETWORK_TIMEOUT","CHECKOUT_UNAVAILABLE","INTERNAL_ERROR"]);class w extends Error{code;retryable;requestId;capability;constructor(e){super(e.message),this.name="ViceMeError",this.code=e.code,this.retryable=e.retryable??ve.has(e.code),this.requestId=e.requestId,this.capability=e.capability}toJSON(){const e={code:this.code,retryable:this.retryable};return this.requestId!==void 0&&(e.requestId=this.requestId),this.capability!==void 0&&(e.capability=this.capability),e}}function Ee(t){return t instanceof w}function E(t){return new w({code:"CONFIG_INVALID",message:t,retryable:!1})}function T(){return new w({code:"CLIENT_DESTROYED",message:"ViceMe client has been destroyed.",retryable:!1})}const ie={cn:"https://api.viceme.cn",global:"https://api.viceme.ai"},Ie={cn:"https://viceme.cn",global:"https://viceme.ai"},Ae=new Set(["cn","global"]),ke={cn:ie.cn,global:ie.global};function Ne(t){return ke[t]}function ne(t){return typeof t=="string"&&/^wrk_(?:test|live)_[A-Za-z0-9_-]{4,119}$/.test(t)}function ae(t){return typeof t=="string"&&Ae.has(t)}function Te(t){if(typeof t!="object"||t===null)throw E("createViceMe expects a configuration object.");const e=t,r=new Set(["workKey","region","signal"]);for(const i of Object.keys(e))if(!r.has(i))throw E(`Unknown configuration field "${i}".`);if(!ne(e.workKey))throw E('Configuration field "workKey" must start with "wrk_test_" or "wrk_live_".');if(!ae(e.region))throw E('Configuration field "region" must be "cn" or "global".');if(e.signal!==void 0&&!(e.signal instanceof AbortSignal))throw E('Configuration field "signal" must be an AbortSignal.');return{workKey:e.workKey,region:e.region,signal:e.signal}}const Se=new Set(["data-viceme-work","data-viceme-region","data-viceme-features","data-viceme-target","data-viceme-theme","data-viceme-loader"]),Re=new Set(["light","dark","auto"]),oe=["danmaku","tip"];function Le(t){for(const v of t.getAttributeNames())if(v.startsWith("data-viceme-")&&!Se.has(v))throw E(`Unknown loader attribute "${v}".`);const e=t.getAttribute("data-viceme-work");if(!ne(e))throw E('Loader attribute "data-viceme-work" must be a public Work key.');const r=t.getAttribute("data-viceme-region");if(!ae(r))throw E('Loader attribute "data-viceme-region" must be "cn" or "global".');const i=t.getAttribute("data-viceme-features"),n=i?.split(",")??[],s=new Set(n);if(!i||/\s/.test(i)||n.length!==s.size||n.some(v=>!oe.includes(v)))throw E('Loader attribute "data-viceme-features" must contain each of "danmaku" and "tip" at most once.');const a=oe.filter(v=>s.has(v)),d=t.getAttribute("data-viceme-target");if(d==="")throw E('Loader attribute "data-viceme-target" must be a CSS selector.');if(d===null)throw E('Loader attribute "data-viceme-target" is required when features are declared.');try{t.matches(d)}catch{throw E('Loader attribute "data-viceme-target" is not a valid CSS selector.')}const f=t.getAttribute("data-viceme-theme");if(f!==null&&!Re.has(f))throw E('Loader attribute "data-viceme-theme" must be "light", "dark", or "auto".');return{workKey:e,region:r,features:a,target:d,theme:f??"auto"}}function H(t,e,r){return`v${t}+${e}+${r}`}class Ce{#e=new Map;#r=new Map;#t=new Map;#i=0;getClient(e){return this.#e.get(e)}registerClient(e){this.#e.set(e.clientKey,e)}unregisterClient(e){this.#e.delete(e)}getInstance(e){return this.#r.get(e)}findInstance(e,r,i){return this.#t.get(`${e}::${r}`)?.get(i)}registerInstance(e,r,i,n){const s=`${e}::${r}`;let a=this.#t.get(s);a===void 0&&(a=new WeakMap,this.#t.set(s,a));const d=a.get(i);if(d)return d;this.#i+=1;const f={instanceKey:`${e}::${r}::el${this.#i}`,clientKey:e,capability:r,host:i,raw:n,destroyed:!1};return this.#r.set(f.instanceKey,f),a.set(i,f),f}removeInstance(e){const r=this.#r.get(e);if(r)return this.#r.delete(e),this.#t.get(`${r.clientKey}::${r.capability}`)?.delete(r.host),r}instancesForClient(e){return[...this.#r.values()].filter(r=>r.clientKey===e)}}const Oe=new Map([["viceme:ready",new Set(["clientKey","workKey","capabilities","version"])],["viceme:capability-ready",new Set(["clientKey","instanceKey","capability","version"])],["viceme:error",new Set(["clientKey","instanceKey","capability","code","retryable","requestId"])],["viceme:destroyed",new Set(["clientKey","instanceKey","capability"])],["viceme:widget-close",new Set(["workId"])],["viceme:tip-paid",new Set(["status","work","amountCents","currency"])]]);function _e(t,e){if(t==="viceme:tip-paid"){const n=e;return{status:n.status,work:{id:n.work.id,title:n.work.title},amountCents:n.amountCents,currency:n.currency}}const r=Oe.get(t),i={};for(const[n,s]of Object.entries(e))r.has(n)&&s!==void 0&&(i[n]=s);return i}function j(t,e,r){const i=new CustomEvent(e,{detail:_e(e,r),bubbles:!0,composed:!0,cancelable:!1});t.dispatchEvent(i)}const Ue={CREATED:["READY","DESTROYED"],READY:["DEGRADED","DESTROYED"],DEGRADED:["DESTROYED"],DESTROYED:[]};class De{#e="CREATED";#r=new Set;get state(){return this.#e}get destroyed(){return this.#e==="DESTROYED"}transition(e){if(e!==this.#e){if(!Ue[this.#e].includes(e))throw new w({code:"INTERNAL_ERROR",message:`Illegal lifecycle transition ${this.#e} -> ${e}.`,retryable:!1});this.#e=e;for(const r of this.#r)r(e)}}assertAlive(){if(this.destroyed)throw T()}subscribe(e){return this.#r.add(e),()=>{this.#r.delete(e)}}clearListeners(){this.#r.clear()}}function xe(t,e,r){if(typeof t!="object"||t===null)throw K();const i=t;if(typeof i.workKey!="string"||!Array.isArray(i.capabilities)||!i.capabilities.every(s=>typeof s=="string"))throw K();if(i.workKey!==e)throw new w({code:"WORK_NOT_FOUND",message:"Work-session response did not match the requested work key.",retryable:!1});const n={work:{key:i.workKey,capabilities:i.capabilities}};if(i.accessProtocolVersion!==void 0){if(i.accessProtocolVersion!==3)throw K();const s=z(i.marketCapabilities);if(r!==void 0&&s.market!==(r==="cn"?"CN":"GLOBAL")||!["CN","GLOBAL"].includes(s.market)||!Array.isArray(s.loginMethods)||!s.loginMethods.every(a=>typeof a=="string")||!Array.isArray(s.supportedPriceCurrencies)||!s.supportedPriceCurrencies.every(a=>a==="CNY"||a==="USD")||!["AVAILABLE","PENDING_CHANNEL","DISABLED"].includes(s.checkoutAvailability)||typeof s.anonymousPurchase!="boolean")throw K();n.accessProtocolVersion=3,n.marketCapabilities=s}if(i.creator!==void 0||i.work!==void 0){const s=z(i.creator),a=z(i.work);if(typeof s.displayName!="string"||s.displayName.length===0||!se(s.avatarUrl)||!Number.isInteger(s.publishedWorkCount)||s.publishedWorkCount<0||typeof a.title!="string"||a.title.length===0||typeof a.summary!="string"||!se(a.coverUrl))throw K();n.work.creator={displayName:s.displayName,avatarUrl:s.avatarUrl,publishedWorkCount:s.publishedWorkCount},n.work.details={title:a.title,summary:a.summary,coverUrl:a.coverUrl}}if(typeof i.token=="string"&&(n.token=i.token),typeof i.expiresAt=="string"){const s=new Date(i.expiresAt).getTime();Number.isNaN(s)||(n.expiresAt=s)}return n}function z(t){if(typeof t!="object"||t===null)throw K();return t}function se(t){if(t===null)return!0;if(typeof t!="string")return!1;try{return new URL(t),!0}catch{return!1}}function K(){return new w({code:"INTERNAL_ERROR",message:"Malformed work-session response.",retryable:!0})}function Y(){return new w({code:"SESSION_EXPIRED",message:"The work session was invalidated before it completed.",retryable:!0})}class Pe{#e;#r;#t;#i;#n=0;#a=0;#o=!1;constructor(e){this.#e=e,this.#r=e.now??(()=>Date.now())}get snapshot(){return this.#t}get identityGeneration(){return this.#a}#d(){const e=this.#t?.expiresAt;return e!==void 0&&e<=this.#r()}establish(){if(this.#o)return Promise.reject(T());if(this.#t){if(!this.#d())return this.#t.userExpiresAt!==void 0&&this.#t.userExpiresAt<=this.#r()&&(this.#n+=1,this.#a+=1,this.#t={...this.#t,user:void 0,userToken:void 0,userExpiresAt:void 0}),this.#t.buyerExpiresAt!==void 0&&this.#t.buyerExpiresAt<=this.#r()&&(this.#n+=1,this.#a+=1,this.#t={...this.#t,buyerToken:void 0,buyerExpiresAt:void 0}),Promise.resolve(this.#t);this.#n+=1,this.#t=void 0}if(this.#i)return this.#i;const e=this.#n,r=this.#e.transport.request({method:"POST",path:"/v1/public/work-sdk/sessions",body:{workKey:this.#e.workKey,supportedAccessProtocolVersions:[3]},signal:this.#e.signal,timeoutMs:this.#e.timeoutMs}).then(i=>{this.#c(e);const n=xe(i.body,this.#e.workKey,this.#e.region);return this.#c(e),this.#t=n,n}).finally(()=>{this.#i===r&&(this.#i=void 0)});return this.#i=r,r}async request(e){const r=await this.establish();if(!r.token)throw K();try{return await this.#l(e,r)}catch(i){if(this.#o)throw T();if(e.signal?.aborted||this.#e.signal?.aborted||!(i instanceof w)||i.code!=="SESSION_EXPIRED")throw i;this.#t===r&&this.invalidate();const n=await this.establish();if(!n.token)throw K();return this.#l(e,n)}}authenticate(e){if(this.#s(),!this.#t)throw K();if(e.expiresAt!==void 0&&e.expiresAt<=this.#r())throw Y();this.#n+=1,this.#a+=1,this.#t={...this.#t,userToken:e.userToken,user:e.user,userExpiresAt:e.expiresAt,buyerToken:void 0,buyerExpiresAt:void 0}}identifyBuyer(e,r){if(this.#s(),r!==this.#a||!this.#t||e.expiresAt<=this.#r())throw Y();this.#n+=1,this.#a+=1,this.#t={...this.#t,user:void 0,userToken:void 0,userExpiresAt:void 0,buyerToken:e.buyerToken,buyerExpiresAt:e.expiresAt}}async signOut(){this.#s(),this.#a+=1,this.invalidate(),await this.establish()}invalidate(){this.#n+=1,this.#t=void 0,this.#i=void 0}destroy(){this.#o||(this.#o=!0,this.#n+=1,this.#a+=1,this.#t=void 0,this.#i=void 0)}#s(){if(this.#o)throw T()}#c(e){if(this.#s(),e!==this.#n)throw Y()}async#l(e,r){this.#s();const i=this.#n;try{const n=await this.#e.transport.request({...e,authorization:r.token,userAuthorization:r.userToken,buyerAuthorization:r.buyerExpiresAt!==void 0&&r.buyerExpiresAt>this.#r()?r.buyerToken:void 0,signal:e.signal&&this.#e.signal?AbortSignal.any([e.signal,this.#e.signal]):e.signal??this.#e.signal});return this.#s(),(e.method==="GET"||e.path==="/v1/public/work-sdk/access/check")&&this.#c(i),n}catch(n){throw this.#o?T():n}}}const ce="0.8.0",G=1,X="viceme-access-layer",Q=50;function N(){return typeof document<"u"&&document.documentElement.lang.toLowerCase().startsWith("en")}function Me(t){switch(t){case"SIGN_IN":return{description:"",label:N()?"Sign in":"授权"};case"FOLLOW":return{description:"",label:N()?"Follow":"关注"};case"CHECKOUT":return{description:"",label:N()?"Open checkout":"打开支付"};case"RESOLVE_BUYER":return{description:"",label:N()?"Continue or restore purchase":"继续购买或恢复权益"}}}function le(t){const e=N()?"Unable to complete this action. Please try again.":"操作未完成,请重试。";if(!Ee(t))return e;switch(t.code){case"CONFIG_INVALID":return N()?"This action is not configured correctly. Please try again later.":"操作配置无效,请稍后重试。";case"AUTH_CANCELLED":return N()?"This action was cancelled. Please try again.":"操作已取消,请重试。";case"SESSION_EXPIRED":return N()?"Your session expired. Please try again.":"授权会话已过期,请重试。";case"NETWORK_TIMEOUT":return N()?"The connection timed out. Please try again.":"网络连接超时,请重试。";default:return t.requestId?`${e} ${N()?"Request ID:":"请求 ID:"} ${t.requestId}`:e}}function Ke(){if(customElements.get(X))return;class t extends HTMLElement{interaction;connectedCallback(){const r=Me(this.interaction.action),i=this.attachShadow({mode:"open"});i.innerHTML=`
|
|
2
2
|
<style>
|
|
3
3
|
:host {
|
|
4
4
|
position: fixed;
|
|
@@ -223,12 +223,12 @@
|
|
|
223
223
|
@keyframes viceme-enter { from { opacity: 0; transform: translateY(1rem); } }
|
|
224
224
|
}
|
|
225
225
|
</style>
|
|
226
|
-
<button data-viceme="backdrop" type="button" tabindex="-1" aria-label="关闭"></button>
|
|
227
|
-
<section data-viceme="panel" role="dialog" aria-modal="true" aria-label="ViceMe 授权">
|
|
228
|
-
<button data-viceme="close" type="button" aria-label="关闭">×</button>
|
|
226
|
+
<button data-viceme="backdrop" type="button" tabindex="-1" aria-label="${N()?"Close":"关闭"}"></button>
|
|
227
|
+
<section data-viceme="panel" role="dialog" aria-modal="true" aria-label="${N()?"ViceMe access":"ViceMe 授权"}">
|
|
228
|
+
<button data-viceme="close" type="button" aria-label="${N()?"Close":"关闭"}">×</button>
|
|
229
229
|
<div data-viceme="content">
|
|
230
230
|
<p data-viceme="description"></p>
|
|
231
|
-
<section data-viceme="profile" aria-label="创作者">
|
|
231
|
+
<section data-viceme="profile" aria-label="${N()?"Creator":"创作者"}">
|
|
232
232
|
<div data-viceme="profile-header">
|
|
233
233
|
<img data-viceme="avatar" hidden />
|
|
234
234
|
<span data-viceme="avatar-fallback" aria-hidden="true"></span>
|
|
@@ -253,6 +253,7 @@
|
|
|
253
253
|
</div>
|
|
254
254
|
</div>
|
|
255
255
|
<iframe data-viceme="frame" title="" referrerpolicy="no-referrer" allow="payment"></iframe>
|
|
256
|
+
<button data-viceme="continue" type="button" hidden>${N()?"Continue in this page":"在当前页面继续"}</button>
|
|
256
257
|
</section>
|
|
257
|
-
`;const a=i.querySelector("[data-viceme='panel']");a.dataset.action=this.interaction.action,a.dataset.frame="false";const d=i.querySelector("[data-viceme='description']");d.textContent=r.description;const n=i.querySelector("[data-viceme='action']"),l=n.parentElement,f=i.querySelector("[data-viceme='close']"),g=i.querySelector("[data-viceme='backdrop']"),N=i.querySelector("[data-viceme='error']"),c=i.querySelector("[data-viceme='frame']"),O=i.querySelector("[data-viceme='profile']"),U=i.querySelector("[data-viceme='avatar']"),K=i.querySelector("[data-viceme='avatar-fallback']"),o=i.querySelector("[data-viceme='profile-name']"),u=i.querySelector("[data-viceme='profile-description']"),y=i.querySelector("[data-viceme='profile-stats']"),s=i.querySelector("[data-viceme='work']"),h=i.querySelector("[data-viceme='work-cover']"),I=i.querySelector("[data-viceme='work-title']"),_=i.querySelector("[data-viceme='work-summary']");n.textContent=r.label,n.hidden=!1,l.dataset.single="true";const x=r.label;c.title=this.interaction.action==="SIGN_IN"?"登录授权":"支付";const E=this.interaction.followTarget;if(E){a.setAttribute("aria-label",this.interaction.action==="SIGN_IN"?`授权 ${E.displayName}`:`关注 ${E.displayName}`),O.dataset.visible="true",o.textContent=E.displayName;const m=[...E.description??""];u.textContent=m.length>B?`${m.slice(0,B).join("")}…`:m.join(""),m.length>B&&(u.title=E.description),y.textContent=`${E.workCount} 个作品`,K.textContent=E.displayName.trim().slice(0,1)||"V",E.avatarUrl&&(U.src=E.avatarUrl,U.alt=`${E.displayName}的头像`,U.hidden=!1,K.hidden=!0)}const A=this.interaction.work;A&&(s.dataset.visible="true",I.textContent=A.title,_.textContent=A.summary,A.coverUrl&&(h.src=A.coverUrl,h.alt=A.title,h.hidden=!1));let R=null,C=!1;const S=m=>{C||(C=!0,this.interaction.signal?.removeEventListener("abort",v),this.dispatchEvent(new CustomEvent("viceme:access-layer-close",{detail:m})))},v=()=>{R?.cancel(),S("dismissed")};this.interaction.signal?.addEventListener("abort",v,{once:!0}),this.interaction.signal?.aborted&&queueMicrotask(v),g.addEventListener("click",v),f.addEventListener("click",v),this.addEventListener("keydown",m=>{if(m.key==="Escape"&&v(),m.key==="Tab"){if(m.preventDefault(),R?.type==="frame"){c.focus();return}const q=[f,...n.hidden?[]:[n]].filter(ce=>!ce.disabled&&!ce.hidden);if(q.length===0)return;const ot=q.indexOf(i.activeElement),st=m.shiftKey?-1:1;q[(ot+st+q.length)%q.length]?.focus()}});const j=async()=>{n.disabled=!0,n.setAttribute("aria-busy","true"),n.textContent="正在打开…",N.textContent="";try{const m=await this.interaction.perform();if(C||this.interaction.signal?.aborted){m.type!=="completed"&&m.cancel();return}m.type==="frame"?(R=m,a.dataset.frame="true",c.src=m.url,c.focus(),await m.completion):m.type==="external"&&(R=m,await m.completion),S("acted")}catch(m){if(C)return;R?.cancel(),R=null,a.dataset.frame="false",c.removeAttribute("src"),N.textContent=Re(m),n.hidden=!1,n.disabled=!1,n.removeAttribute("aria-busy"),n.textContent=x,n.focus()}};n.addEventListener("click",j),queueMicrotask(()=>n.focus())}}customElements.define(W,t)}const Ce=async t=>{if(typeof document>"u"||typeof customElements>"u"||t.signal?.aborted)return"dismissed";Oe();const e=document.createElement(W);e.interaction=t;const r=document.documentElement.style.overflow,i=document.activeElement instanceof HTMLElement?document.activeElement:null;document.documentElement.style.overflow="hidden",document.body.append(e);try{return await new Promise(a=>{e.addEventListener("viceme:access-layer-close",d=>a(d.detail),{once:!0})})}finally{e.remove(),document.documentElement.style.overflow=r,i?.focus()}};function L(t){if(typeof t!="object"||t===null)throw k();return t}function k(){return new w({code:"INTERNAL_ERROR",message:"Malformed public API response.",retryable:!0})}function Le(t){const e=L(t);if(typeof e.id!="string"||!(typeof e.displayName=="string"||e.displayName===null)||!(typeof e.avatarUrl=="string"||e.avatarUrl===null))throw k();return{subject:e.id,nickname:e.displayName,avatarUrl:e.avatarUrl}}function ee(t){const e=L(t);if(typeof e.following!="boolean"||!(typeof e.followedAt=="string"||e.followedAt===null))throw k();const r=L(e.creator);if(typeof r.displayName!="string"||!(typeof r.avatarUrl=="string"||r.avatarUrl===null)||!(typeof r.description=="string"||r.description===null)||!Number.isInteger(r.publishedWorkCount)||r.publishedWorkCount<0)throw k();return{following:e.following,followedAt:e.followedAt,target:{kind:"CREATOR",displayName:r.displayName,avatarUrl:r.avatarUrl,description:r.description,workCount:r.publishedWorkCount}}}function _e(t){const e=L(t),r=new Set(["PUBLIC","OWNER","FOLLOWING","ENTITLED","AUTH_REQUIRED","FOLLOW_REQUIRED","PURCHASE_REQUIRED","FEATURE_NOT_FOUND","FEATURE_DISABLED"]),i=new Set([null,"SIGN_IN","FOLLOW","CHECKOUT"]);if(typeof e.allowed!="boolean"||typeof e.reason!="string"||!r.has(e.reason)||!i.has(e.nextAction))throw k();return{allowed:e.allowed,reason:e.reason,nextAction:e.nextAction}}function De(t){const e=L(t);if(typeof e.featureKey!="string"||!/^[a-z][a-z0-9_-]{1,63}$/.test(e.featureKey)||typeof e.title!="string"||e.title.trim().length===0||e.title.length>120||!(e.policyType==="PUBLIC"||e.policyType==="FOLLOW_OWNER"||e.policyType==="WORK_ENTITLEMENT"))throw k();const r=e.price===null?null:L(e.price);if(r!==null&&(!Number.isInteger(r.amountCents)||r.amountCents<=0||r.currency!=="CNY")||e.policyType==="WORK_ENTITLEMENT"!=(r!==null))throw k();return{featureKey:e.featureKey,title:e.title,policy:{type:e.policyType},price:r===null?null:{amountCents:r.amountCents,currency:"CNY"}}}function Ue(){const t=crypto.getRandomValues(new Uint8Array(32));return xe(t)}function xe(t){let e="";for(const r of t)e+=String.fromCharCode(r);return btoa(e).replaceAll("+","-").replaceAll("/","_").replace(/=+$/,"")}function Me(){return typeof document<"u"&&document.documentElement.lang.toLowerCase()==="en-us"?"en-US":"zh-CN"}function Ke(t){const e=()=>new w({code:"AUTH_CANCELLED",message:"The interactive action was cancelled.",retryable:!1}),r=o=>{if(t.signal.aborted)return Promise.reject(T());let u;const y=new Promise((h,I)=>{u=()=>I(T()),t.signal.addEventListener("abort",u,{once:!0}),t.signal.aborted&&u()});let s;try{s=(t.presenter??Ce)({...o,signal:t.signal})}catch(h){s=Promise.reject(h)}return Promise.race([s,y]).then(h=>{if(t.signal.aborted)throw T();return h}).finally(()=>{u&&t.signal.removeEventListener("abort",u)})},i=(o,u,y,s,h,I)=>{if(typeof window>"u")throw new w({code:"CONFIG_INVALID",message:"Interactive access requires a browser window.",retryable:!1});let _=!0,x,E;const A=()=>{_&&(_=!1,window.removeEventListener("message",C))},R=new Promise((S,v)=>{x=S,E=v}),C=S=>{if(!_||S.origin!==u||typeof S.data!="object"||S.data===null)return;const v=S.data;if(!(v.workKey!==t.workKey||v.channel!==y)){if(v.type===`viceme:${s}:ready`){S.source&&"postMessage"in S.source&&S.source.postMessage({type:`viceme:${s}:init`,workKey:t.workKey,channel:y,...h},u);return}if(v.type===`viceme:${s}:cancelled`){A(),E(e());return}v.type===`viceme:${s}:complete`&&(A(),I(v).then(x,E))}};return window.addEventListener("message",C),{type:"frame",url:o,completion:R,cancel(){A(),x()}}},a=async()=>{if(await t.ready(),typeof window>"u")throw new w({code:"CONFIG_INVALID",message:"Interactive access requires a browser window.",retryable:!1});const o=Ue(),u=new URL("/sdk/login",t.widgetOrigin);u.search=new URLSearchParams({workKey:t.workKey,channel:o,parentOrigin:window.location.origin,locale:Me()}).toString();const y=t.session.snapshot?.token;if(!y)throw k();return i(u.toString(),t.widgetOrigin,o,"auth",{workSessionToken:y},async s=>{if(typeof s.userToken!="string")throw k();t.session.authenticate({userToken:s.userToken,user:Le(s.user)})})},d=async()=>(await t.ready(),ee((await t.session.request({method:"GET",path:"/v1/public/work-sdk/follow"})).body)),n=async()=>(await t.ready(),ee((await t.session.request({method:"PUT",path:"/v1/public/work-sdk/follow"})).body)),l=()=>{const o=t.session.snapshot?.work;return{...o?.creator?{followTarget:{kind:"CREATOR",displayName:o.creator.displayName,avatarUrl:o.creator.avatarUrl,description:null,workCount:o.creator.publishedWorkCount}}:{},...o?.details?{work:o.details}:{}}},f={async getState(){await t.ready();const o=t.session.snapshot?.user??null;return{authenticated:o!==null,user:o}},async signIn(){if(await t.ready(),await r({featureKey:"auth",reason:"AUTH_REQUIRED",action:"SIGN_IN",...l(),perform:a})==="dismissed")throw e();return this.getState()},async signOut(){await t.ready(),await t.session.signOut()}},g={getState:d,follow:n,unfollow:async()=>{throw new w({code:"CAPABILITY_DISABLED",message:"Unfollow is not exposed by website access.",retryable:!1})}},N=async o=>{await t.ready();const u=L((await t.session.request({method:"POST",path:"/v1/public/work-sdk/access/check",body:{featureKeys:o}})).body),y=L(u.decisions);return Object.fromEntries(Object.entries(y).map(([s,h])=>[s,_e(h)]))},c=async(o,u={})=>{await t.ready();const y={featureKey:o,locale:u.locale??"zh-CN"},s=L((await t.session.request({method:"POST",path:"/v1/public/work-sdk/checkout",body:y})).body);if(typeof s.checkoutUrl!="string"||typeof s.alreadyOwned!="boolean"||!(s.expiresAt===null||typeof s.expiresAt=="string"&&!Number.isNaN(Date.parse(s.expiresAt)))||s.alreadyOwned!==(s.expiresAt===null))throw k();let h;try{h=new URL(s.checkoutUrl)}catch{throw k()}if(!s.alreadyOwned&&(h.protocol!=="https:"||h.origin!==t.widgetOrigin))throw k();return{checkoutUrl:s.checkoutUrl,alreadyOwned:s.alreadyOwned,expiresAt:s.expiresAt}},O=(o,u)=>{if(o.alreadyOwned)return{type:"completed"};const y=Date.parse(o.expiresAt);if(typeof window>"u")throw new w({code:"CONFIG_INVALID",message:"Hosted checkout requires a browser window.",retryable:!1});let s=!0,h,I,_,x;const E=new Promise((m,se)=>{_=m,x=se}),A=()=>{h&&clearTimeout(h),I&&clearTimeout(I),document.removeEventListener("visibilitychange",v)},R=()=>{s&&(s=!1,A(),x(new w({code:"SESSION_EXPIRED",message:"Hosted checkout session expired.",retryable:!0})))},C=()=>{if(!s||document.visibilityState==="hidden")return;const m=y-t.now();if(m<=0){R();return}h=setTimeout(()=>{S()},Math.min(1500,m))},S=async()=>{if(s)try{const m=(await N([u]))[u];if(!m)throw k();if(m.allowed){s=!1,A(),_();return}C()}catch(m){s=!1,A(),x(m)}};function v(){if(s){if(document.visibilityState==="hidden"){h&&clearTimeout(h),h=void 0;return}C()}}document.addEventListener("visibilitychange",v);const j=y-t.now();return j<=0?R():(I=setTimeout(R,j),C()),{type:"frame",url:o.checkoutUrl,completion:E,cancel(){s&&(s=!1,A(),_())}}};return{auth:f,follow:g,access:{async getFeatures(){await t.ready();const o=L((await t.session.request({method:"GET",path:"/v1/public/work-sdk/access/features"})).body);if(!Array.isArray(o.features)||o.features.length>100)throw k();return o.features.map(De)},async check(o){const y=(await N([o]))[o];if(!y)throw k();return y},checkMany:N,async require(o){let u=await this.check(o);for(let y=0;!u.allowed&&u.nextAction&&y<3;y+=1){const s=u.nextAction,h=s==="FOLLOW"?(await g.getState()).target:void 0,I=s==="CHECKOUT"?await c(o):void 0;if(I?.alreadyOwned){u=await this.check(o);continue}if(await r({featureKey:o,reason:u.reason,action:s,...s==="SIGN_IN"?l():h?{followTarget:h}:{},perform:async()=>s==="SIGN_IN"?a():s==="FOLLOW"?(await g.follow(),{type:"completed"}):O(I,o)})==="dismissed")return u;u=await this.check(o)}return u},async refresh(){await t.ready()}},checkout:{async open(o){const u=await c(o.featureKey,o);if(u.alreadyOwned)return u;if(await r({featureKey:o.featureKey,reason:"PURCHASE_REQUIRED",action:"CHECKOUT",perform:async()=>O(u,o.featureKey)})==="dismissed")throw e();return u}}}}function te(t){t instanceof re&&t.markDegraded()}class Pe extends DOMException{constructor(){super("ViceMe client destroyed.","AbortError")}}class re{#e=new Ie;#t;#r;#i=new AbortController;#a;auth;access;checkout;#n;constructor(e){this.#r=e.config,this.#t=new Se({workKey:e.config.workKey,transport:e.transport,signal:this.#i.signal,...e.now!==void 0?{now:e.now}:{}});const r=Ke({session:this.#t,workKey:e.config.workKey,widgetOrigin:ue[e.config.region],now:e.now??(()=>Date.now()),presenter:e.presenter,signal:this.#i.signal,ready:()=>this.#s()});this.auth=r.auth,this.access=r.access,this.checkout=r.checkout;const i=e.config.signal;if(i){const a=()=>{this.#i.abort(i.reason instanceof Error?i.reason:new DOMException("Caller signal aborted.","AbortError"))};i.aborted?a():(i.addEventListener("abort",a,{once:!0}),this.#n=()=>{i.removeEventListener("abort",a)})}}get version(){return Z}get workKey(){return this.#r.workKey}get region(){return this.#r.region}get state(){return this.#e.state}get apiMajor(){return P}ready(){return this.#e.destroyed?Promise.reject(T()):(this.#a||(this.#e.transition("READY"),this.#a=Promise.resolve()),this.#a)}async#s(){if(this.#e.destroyed)throw T();await this.ready();try{if(await this.#t.establish(),this.#e.destroyed)throw T()}catch(e){throw this.#e.destroyed?T():(this.#t.invalidate(),e)}}hasCapability(e){if(this.#e.destroyed)return!1;const r=this.#t.snapshot?.work.capabilities;return e==="danmaku"||e==="tip"||r?.includes(e)===!0}get capabilities(){return this.#t.snapshot?.work.capabilities??[]}markDegraded(){this.#e.state==="READY"&&this.#e.transition("DEGRADED")}get sessionSnapshot(){return this.#t.snapshot}destroy(){this.#e.destroyed||(this.#e.transition("DESTROYED"),this.#i.abort(new Pe),this.#t.destroy(),this.#e.clearListeners(),this.#a=void 0,this.#n?.(),this.#n=void 0)}}const qe=1e4,Fe=new Map([[400,"CONFIG_INVALID"],[401,"SESSION_EXPIRED"],[403,"CAPABILITY_DISABLED"],[404,"WORK_NOT_FOUND"],[409,"CONFIG_INVALID"],[422,"CONFIG_INVALID"],[429,"RATE_LIMITED"]]),je=new Set(["CONFIG_INVALID","WORK_NOT_FOUND","CAPABILITY_DISABLED","SESSION_EXPIRED","AUTH_REQUIRED","AUTH_CANCELLED","RETURN_URL_NOT_ALLOWED","RATE_LIMITED","NETWORK_TIMEOUT","CHECKOUT_UNAVAILABLE","INTERNAL_ERROR"]);function $e(t){if(typeof t!="object"||t===null)return{};const e=t,r=typeof e.error=="object"&&e.error!==null?e.error:e,i={};return typeof r.code=="string"&&je.has(r.code)&&(i.code=r.code),typeof r.message=="string"&&(i.message=r.message.slice(0,200)),typeof r.retryable=="boolean"&&(i.retryable=r.retryable),typeof r.requestId=="string"&&(i.requestId=r.requestId),i}function We(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`req-${Math.random().toString(36).slice(2)}`}class Be{#e;#t;#r;#i;constructor(e){this.#e=e.apiBaseUrl.replace(/\/+$/,""),this.#t=e.fetchImpl??globalThis.fetch.bind(globalThis),this.#r=e.defaultTimeoutMs??qe,this.#i=e.generateRequestId??We}async request(e){if(e.signal?.aborted)throw this.#a(e.signal);const r=e.timeoutMs??this.#r,i=new AbortController;let a=!1;const d=setTimeout(()=>{a=!0,i.abort(new ie)},r),n=()=>i.abort(new ie(!1));e.signal?.addEventListener("abort",n,{once:!0});const l=this.#i();try{const f=await this.#t(`${this.#e}${e.path}`,{method:e.method,credentials:"omit",mode:"cors",headers:{"content-type":"application/json","x-client-request-id":l,...e.authorization!==void 0?{authorization:`Bearer ${e.authorization}`}:{},...e.userAuthorization!==void 0?{"x-viceme-user-token":e.userAuthorization}:{}},body:e.body!==void 0?JSON.stringify(e.body):void 0,signal:i.signal});let g;try{g=await f.json()}catch(c){if(e.signal?.aborted||a)throw c;g=void 0}if(i.signal.aborted)throw i.signal.reason;const N=f.headers.get("x-request-id")??void 0;if(!f.ok){const c=$e(g),O=c.code??Fe.get(f.status)??"INTERNAL_ERROR";throw new w({code:O,message:c.message??"Public API request failed.",retryable:c.retryable,requestId:c.requestId??N})}return{status:f.status,body:g,requestId:N}}catch(f){throw e.signal?.aborted?this.#a(e.signal):a?new w({code:"NETWORK_TIMEOUT",message:"Public API request timed out.",retryable:!0,requestId:l}):f instanceof w?f:f instanceof DOMException&&f.name==="AbortError"?new DOMException("ViceMe request aborted by caller.","AbortError"):new w({code:"INTERNAL_ERROR",message:"Public API request failed.",retryable:!0,requestId:l})}finally{clearTimeout(d),e.signal?.removeEventListener("abort",n)}}#a(e){return e.reason instanceof Error?e.reason:new DOMException("ViceMe request aborted by caller.","AbortError")}}function Ve(t){return new Be(t)}class ie extends DOMException{constructor(e=!0){super(e?"ViceMe request timed out.":"ViceMe request aborted.","AbortError")}}function Ge(t){const e=ye(t),r=he(e.region),i=Ve({apiBaseUrl:r});return new re({config:e,transport:i})}const He=8e3,ze=8e3,ae={danmaku:"danmaku.js",tip:"tip.js"},Ye={danmaku:"mountDanmaku",tip:"mountTip"},ne=Symbol.for("viceme.loader.state.v1");function b(){const e=globalThis[ne];if(e)return e;const r={registry:new be,queue:{current:Promise.resolve()}};return Object.defineProperty(globalThis,ne,{value:r,writable:!0,configurable:!0,enumerable:!1}),r}function V(t){if(!t.destroyed){t.destroyed=!0,b().registry.removeInstance(t.instanceKey);try{t.raw.destroy()}finally{F(t.host,"viceme:destroyed",{clientKey:t.clientKey,instanceKey:t.instanceKey,capability:t.capability})}}}function Xe(t){return{instanceKey:t.instanceKey,capability:t.capability,destroy:()=>V(t)}}function G(t,e,r){Object.defineProperty(t,e,{value:r,writable:!0,configurable:!0,enumerable:!1})}function Qe(t){let r=globalThis.ViceMe;r||(r={},G(globalThis,"ViceMe",r));let i=r.versions;i||(i={},G(r,"versions",i));const a=i[`v${P}`];if(a)return a;const d={version:t,whenReady(n){const l=b().registry.getClient(n);return l?l.ready.then(()=>l.client):Promise.reject(p(`Unknown clientKey "${n}".`))},getInstance(n){const l=b().registry.getInstance(n);return l?Xe(l):void 0},destroyInstance(n){const l=b().registry.getInstance(n);l&&V(l)},destroyClient(n){for(const f of b().registry.instancesForClient(n))V(f);const l=b().registry.getClient(n);for(const f of l?.pendingMounts??[])f.abort();b().registry.unregisterClient(n),l?.client.destroy()}};return G(i,`v${P}`,d),d}function Je(){return document.readyState!=="loading"?Promise.resolve():new Promise(t=>{document.addEventListener("DOMContentLoaded",()=>t(),{once:!0})})}async function Ze(t){const e=new AbortController,r=globalThis.setTimeout(()=>e.abort(),He);try{let i;try{i=await fetch(t,{credentials:"omit",signal:e.signal})}catch{if(e.signal.aborted)throw new w({code:"INTERNAL_ERROR",message:"Release manifest request timed out.",retryable:!0});i={ok:!1,status:0}}return{manifest:await et(i),baseUrl:t}}finally{globalThis.clearTimeout(r)}}async function et(t){if(!t.ok)throw p(`Release manifest is not available (HTTP ${t.status}).`);const e=await t.json();if(typeof e!="object"||e===null||typeof e.version!="string"||typeof e.apiMajor!="number"||typeof e.features!="object"||e.features===null)throw p("Release manifest is malformed.");const r=e;if(r.version!==Z)throw p("Release manifest version does not match this loader.");if(r.apiMajor!==P)throw p("Release manifest major version does not match this loader.");const i=Object.keys(r.features).sort();if(i.length!==2||i[0]!=="danmaku"||i[1]!=="tip"||r.features.danmaku!==ae.danmaku||r.features.tip!==ae.tip)throw p("Release manifest features must be exactly danmaku.js and tip.js.");return r}const tt=new Set(["CONFIG_INVALID","CAPABILITY_DISABLED","CLIENT_DESTROYED","INTERNAL_ERROR"]);function rt(t){if(typeof t=="object"&&t!==null){const e=t;if(typeof e.code=="string"&&tt.has(e.code)&&typeof e.retryable=="boolean"){const r={code:e.code,retryable:e.retryable};return typeof e.requestId=="string"&&(r.requestId=e.requestId),typeof e.capability=="string"&&(r.capability=e.capability),r}}return{code:"INTERNAL_ERROR",retryable:!0}}function D(t,e,r={}){F(t,"viceme:error",{...rt(e),...r})}function it(t,e,r){let i,a;const d=new Promise((n,l)=>{if(a=()=>l(T()),e.signal.aborted){a();return}e.signal.addEventListener("abort",a,{once:!0}),i=globalThis.setTimeout(()=>{l(new w({code:"INTERNAL_ERROR",message:`Capability "${r}" did not load and mount in time.`,retryable:!0,capability:r})),e.abort()},ze)});return Promise.race([t,d]).finally(()=>{i!==void 0&&globalThis.clearTimeout(i),a&&e.signal.removeEventListener("abort",a)})}async function at(t){let e;try{e=ge(t)}catch(c){D(document,c);return}if(!t.src){D(document,p("Loader script requires a src URL."));return}const r=new URL("manifest.json",t.src);let i,a;try{({manifest:i,baseUrl:a}=await Ze(r))}catch(c){D(document,c,{clientKey:$(P,e.region,e.workKey)});return}await Je();let d;try{const c=document.querySelectorAll(e.target);if(c.length===0)throw p(`Loader target "${e.target}" matched no element; no node was created.`);if(c.length>1)throw p(`Loader target "${e.target}" matched ${c.length} elements; exactly one is required.`);d=c[0]}catch(c){D(document,c,{clientKey:$(i.apiMajor,e.region,e.workKey)});return}const n=$(i.apiMajor,e.region,e.workKey);Qe(i.version);let l=b().registry.getClient(n),f;if(l)f=l.client;else{try{f=Ge({workKey:e.workKey,region:e.region})}catch(O){D(d,O,{clientKey:n});return}const c=f.ready();c.catch(()=>{}),l={clientKey:n,client:f,ready:c,pendingMounts:new Set},b().registry.registerClient(l)}try{await l.ready}catch(c){b().registry.unregisterClient(n),f.destroy(),D(d,c,{clientKey:n});return}if(b().registry.getClient(n)!==l)return;const g=async c=>{if(b().registry.findInstance(n,c,d))return;const O=i.features[c];if(typeof O!="string"){te(f),D(d,new w({code:"CAPABILITY_DISABLED",message:`Capability "${c}" is not part of this release.`,retryable:!1,capability:c}),{clientKey:n,capability:c});return}const U=new AbortController;l.pendingMounts.add(U);try{const K=(async()=>{const s=await import(new URL(O,a).href),h=Ye[c],I=s[h];if(typeof I!="function")throw p(`Capability chunk "${c}" does not export ${h}().`);if(b().registry.getClient(n)!==l)throw T();return await I(f,{target:d,theme:e.theme,signal:U.signal,...c==="tip"&&e.features.includes("danmaku")?{presentation:"integrated"}:{}})})(),o=await it(K,U,c);if(b().registry.getClient(n)!==l){o.destroy();return}const u=b().registry.registerInstance(n,c,d,o);return F(d,"viceme:capability-ready",{clientKey:n,instanceKey:u.instanceKey,capability:c,version:i.version}),c}catch(K){if(b().registry.getClient(n)!==l)return;te(f),D(d,K,{clientKey:n,capability:c});return}finally{l.pendingMounts.delete(U)}},N=(await Promise.all(e.features.map(g))).filter(c=>c!==void 0);N.length>0&&b().registry.getClient(n)===l&&F(d,"viceme:ready",{clientKey:n,workKey:e.workKey,capabilities:N,version:i.version})}function nt(t){const{queue:e}=b(),r=e.current.then(()=>at(t));return e.current=r.catch(()=>{}),r}function oe(){if(typeof document>"u")return;let t=document.currentScript instanceof HTMLScriptElement?document.currentScript:null;if(!t){const e=document.querySelectorAll("script[data-viceme-loader]");e.length===1&&(t=e[0]??null)}t&&nt(t).catch(e=>{D(document,e)})}oe();const ct=oe})();
|
|
258
|
+
`;const n=i.querySelector("[data-viceme='panel']");n.dataset.action=this.interaction.action,n.dataset.frame="false";const s=i.querySelector("[data-viceme='description']");s.textContent=r.description;const a=i.querySelector("[data-viceme='action']"),d=a.parentElement,f=i.querySelector("[data-viceme='close']"),v=i.querySelector("[data-viceme='backdrop']"),S=i.querySelector("[data-viceme='error']"),u=i.querySelector("[data-viceme='frame']"),b=i.querySelector("[data-viceme='continue']"),x=i.querySelector("[data-viceme='profile']"),_=i.querySelector("[data-viceme='avatar']"),U=i.querySelector("[data-viceme='avatar-fallback']"),V=i.querySelector("[data-viceme='profile-name']"),F=i.querySelector("[data-viceme='profile-description']"),c=i.querySelector("[data-viceme='profile-stats']"),h=i.querySelector("[data-viceme='work']"),l=i.querySelector("[data-viceme='work-cover']"),o=i.querySelector("[data-viceme='work-title']"),m=i.querySelector("[data-viceme='work-summary']");a.textContent=r.label,a.hidden=!1,d.dataset.single="true";const g=r.label;u.title=this.interaction.action==="SIGN_IN"?"登录授权":this.interaction.action==="RESOLVE_BUYER"?"购买权益恢复":"支付";const p=this.interaction.followTarget;if(p){n.setAttribute("aria-label",this.interaction.action==="SIGN_IN"?`授权 ${p.displayName}`:`关注 ${p.displayName}`),x.dataset.visible="true",V.textContent=p.displayName;const y=[...p.description??""];F.textContent=y.length>Q?`${y.slice(0,Q).join("")}…`:y.join(""),y.length>Q&&(F.title=p.description),c.textContent=`${p.workCount} 个作品`,U.textContent=p.displayName.trim().slice(0,1)||"V",p.avatarUrl&&(_.src=p.avatarUrl,_.alt=`${p.displayName}的头像`,_.hidden=!1,U.hidden=!0)}const I=this.interaction.work;I&&(h.dataset.visible="true",o.textContent=I.title,m.textContent=I.summary,I.coverUrl&&(l.src=I.coverUrl,l.alt=I.title,l.hidden=!1));let R=null,C=!1;const q=y=>{C||(C=!0,this.interaction.signal?.removeEventListener("abort",D),this.dispatchEvent(new CustomEvent("viceme:access-layer-close",{detail:y})))},D=()=>{R?.cancel(),q("dismissed")};this.interaction.signal?.addEventListener("abort",D,{once:!0}),this.interaction.signal?.aborted&&queueMicrotask(D),v.addEventListener("click",D),f.addEventListener("click",D),b.addEventListener("click",()=>{try{R?.type==="frame"&&R.continueInSamePage?.()}catch(y){S.textContent=le(y),n.dataset.frame="false"}}),this.addEventListener("keydown",y=>{if(y.key==="Escape"&&D(),y.key==="Tab"){if(y.preventDefault(),R?.type==="frame"){const B=[f,u,...b.hidden?[]:[b]],yt=B.indexOf(i.activeElement);B[(yt+(y.shiftKey?-1:1)+B.length)%B.length]?.focus();return}const L=[f,...a.hidden?[]:[a]].filter(B=>!B.disabled&&!B.hidden);if(L.length===0)return;const re=L.indexOf(i.activeElement),mt=y.shiftKey?-1:1;L[(re+mt+L.length)%L.length]?.focus()}});const O=async()=>{a.disabled=!0,a.setAttribute("aria-busy","true"),a.textContent=N()?"Opening…":"正在打开…",S.textContent="";try{const y=await this.interaction.perform();if(C||this.interaction.signal?.aborted){y.type!=="completed"&&y.cancel();return}y.type==="frame"?(R=y,b.hidden=!y.continueInSamePage,n.dataset.frame="true",u.src=y.url,u.focus(),await y.completion):y.type==="external"&&(R=y,await y.completion),q("acted")}catch(y){if(C)return;R?.cancel(),R=null,b.hidden=!0,n.dataset.frame="false",u.removeAttribute("src"),S.textContent=le(y),a.hidden=!1,a.disabled=!1,a.removeAttribute("aria-busy"),a.textContent=g,a.focus()}};a.addEventListener("click",O),queueMicrotask(()=>{C||(this.interaction.autoStart?O():a.focus())})}}customElements.define(X,t)}const Ve=async t=>{if(typeof document>"u"||typeof customElements>"u"||t.signal?.aborted)return"dismissed";Ke();const e=document.createElement(X);e.interaction=t;const r=document.documentElement.style.overflow,i=document.activeElement instanceof HTMLElement?document.activeElement:null;document.documentElement.style.overflow="hidden",document.body.append(e);try{return await new Promise(n=>{e.addEventListener("viceme:access-layer-close",s=>n(s.detail),{once:!0})})}finally{e.remove(),document.documentElement.style.overflow=r,i?.focus()}};function P(){return new w({code:"INTERNAL_ERROR",message:"Malformed access bridge response.",retryable:!1})}function de(t){if(typeof t!="object"||t===null||Array.isArray(t))throw P();return t}function J(t){return btoa(String.fromCharCode(...t)).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function ue(t,e){if(typeof t!="string")throw P();let r;try{r=new URL(t)}catch{throw P()}if(r.protocol!=="https:"||r.origin!==e||r.username||r.password)throw P();return r.href}function W(){return new w({code:"SESSION_EXPIRED",message:"Access recovery expired. Please try again.",retryable:!0})}function $e(t){const e=`viceme:access-bridge:v3:${t.widgetOrigin}:${t.workKey}`;let r;const i=()=>{r?.abort(t.signal.aborted?t.signal.reason:void 0),r=void 0;try{sessionStorage.removeItem(e)}catch{}};return t.signal.addEventListener("abort",i,{once:!0}),{clear:i,async start(n,s){if(t.signal.aborted)throw t.signal.reason??T();if(r)throw new w({code:"CONFIG_INVALID",message:"An access interaction is already open.",retryable:!0});if(typeof window>"u"||!globalThis.crypto?.subtle)throw new w({code:"CONFIG_INVALID",message:"Access recovery requires a browser with Web Crypto.",retryable:!1});const a=new AbortController;r=a;const d=AbortSignal.any([t.signal,a.signal]),f=()=>{if(d.aborted)throw d.reason??T()};try{await t.session.establish();const v=t.session.identityGeneration,S=async(l,o)=>{f();const m=await t.session.establish(),g=await t.session.request({method:"POST",path:l,signal:d,body:{...o,workSessionToken:m.token}});return f(),de(g.body)};let u;try{const l=JSON.parse(sessionStorage.getItem(e)??"null");l&&(l.purpose===n||n==="IDENTIFY"&&["RESTORE","CLAIM"].includes(l.purpose))&&l.featureKey===s&&typeof l.expiresAt=="number"&&l.expiresAt>t.now()&&l.expiresAt<=t.now()+3e5&&typeof l.challengeId=="string"&&/^[A-Za-z0-9_-]+$/.test(l.challengeId)&&typeof l.verifier=="string"&&/^[A-Za-z0-9_-]{43,128}$/.test(l.verifier)&&typeof l.state=="string"&&(u={...l,bridgeUrl:ue(l.bridgeUrl,t.widgetOrigin)},n=u.purpose)}catch{}if(!u){const l=J(crypto.getRandomValues(new Uint8Array(32))),o=J(crypto.getRandomValues(new Uint8Array(32))),m=J(new Uint8Array(await crypto.subtle.digest("SHA-256",new TextEncoder().encode(l))));f();const g=/^https?:$/.test(window.location.protocol)?window.location.href:void 0,p=await S("/v1/public/work-sdk/buyer/challenges",{purpose:n,...s?{featureKey:s}:{},codeChallenge:m,state:o,requestId:crypto.randomUUID(),...g?{returnUrl:g}:{}}),I=typeof p.expiresAt=="string"?Date.parse(p.expiresAt):NaN;if(typeof p.challengeId!="string"||!/^[A-Za-z0-9_-]+$/.test(p.challengeId)||!Number.isFinite(I)||I<=t.now())throw P();u={challengeId:p.challengeId,bridgeUrl:ue(p.bridgeUrl,t.widgetOrigin),expiresAt:Math.min(I,t.now()+3e5),verifier:l,state:o,purpose:n,featureKey:s}}const b=u;let x=!1;const _=()=>{if(r===a&&(r=void 0),!x)try{sessionStorage.removeItem(e)}catch{}};let U,V;const F=()=>new Promise((l,o)=>{const m=()=>{U&&clearTimeout(U),o(d.reason)};d.addEventListener("abort",m,{once:!0}),U=setTimeout(()=>{d.removeEventListener("abort",m),l()},1e3),d.aborted&&m()}),c=async()=>{V=setTimeout(()=>a.abort(W()),Math.max(0,b.expiresAt-t.now()));try{for(;t.now()<b.expiresAt;){f();const l=await S(`/v1/public/work-sdk/buyer/challenges/${b.challengeId}/result`,{codeVerifier:b.verifier});if(l.status==="EXPIRED")throw W();if(l.status==="PENDING"){await F();continue}if(l.status!=="READY"||typeof l.code!="string"||!l.code)throw P();const o=await S("/v1/public/work-sdk/buyer/exchange",{code:l.code,codeVerifier:b.verifier});if(f(),t.session.identityGeneration!==v)throw W();if(o.purpose!==n)throw P();const m=typeof o.expiresAt=="string"?Date.parse(o.expiresAt):NaN;if(!Number.isFinite(m)||m<=t.now())throw P();if(typeof o.userToken=="string"&&o.userToken){if(n!=="SIGN_IN"&&n!=="CLAIM")throw P();const g=de(o.user);if(typeof g.id!="string"||!(typeof g.displayName=="string"||g.displayName===null)||!(typeof g.avatarUrl=="string"||g.avatarUrl===null))throw P();const p={subject:g.id,nickname:g.displayName,avatarUrl:g.avatarUrl};t.session.authenticate({userToken:o.userToken,user:p,expiresAt:m})}else{const g=typeof o.expiresAt=="string"?Date.parse(o.expiresAt):NaN;if(n==="SIGN_IN"||n==="CLAIM"||typeof o.buyerToken!="string"||!o.buyerToken||!Number.isFinite(g))throw P();t.session.identifyBuyer({buyerToken:o.buyerToken,expiresAt:g},v)}return}throw W()}finally{V&&clearTimeout(V),U&&clearTimeout(U),_()}};let h;return{type:"frame",url:b.bridgeUrl,get completion(){return h??=c()},cancel:()=>{a.abort(),_()},continueInSamePage:()=>{f();try{sessionStorage.setItem(e,JSON.stringify(b))}catch{throw new w({code:"CONFIG_INVALID",message:"Browser storage is unavailable. Use the recovery page in another window.",retryable:!0})}x=!0,a.abort(),window.location.assign(b.bridgeUrl)}}}catch(v){throw r===a&&(r=void 0),a.abort(),v}}}}function M(t){if(typeof t!="object"||t===null)throw A();return t}function A(){return new w({code:"INTERNAL_ERROR",message:"Malformed public API response.",retryable:!0})}function Fe(t){const e=M(t);if(typeof e.id!="string"||!(typeof e.displayName=="string"||e.displayName===null)||!(typeof e.avatarUrl=="string"||e.avatarUrl===null))throw A();return{subject:e.id,nickname:e.displayName,avatarUrl:e.avatarUrl}}function fe(t){const e=M(t);if(typeof e.following!="boolean"||!(typeof e.followedAt=="string"||e.followedAt===null))throw A();const r=M(e.creator);if(typeof r.displayName!="string"||!(typeof r.avatarUrl=="string"||r.avatarUrl===null)||!(typeof r.description=="string"||r.description===null)||!Number.isInteger(r.publishedWorkCount)||r.publishedWorkCount<0)throw A();return{following:e.following,followedAt:e.followedAt,target:{kind:"CREATOR",displayName:r.displayName,avatarUrl:r.avatarUrl,description:r.description,workCount:r.publishedWorkCount}}}function qe(t,e){const r=M(t),i=new Set(["PUBLIC","OWNER","FOLLOWING","ENTITLED","AUTH_REQUIRED","FOLLOW_REQUIRED","PURCHASE_REQUIRED","FEATURE_NOT_FOUND","FEATURE_DISABLED"]),n=new Set([null,"SIGN_IN","FOLLOW","CHECKOUT"]);if(e===3&&(i.add("BUYER_REQUIRED").add("FEATURE_NOT_READY").add("PAYMENT_CHANNEL_UNAVAILABLE"),n.add("RESOLVE_BUYER")),typeof r.allowed!="boolean"||typeof r.reason!="string"||!i.has(r.reason)||!n.has(r.nextAction))throw A();return{allowed:r.allowed,reason:r.reason,nextAction:r.nextAction}}function Be(t,e){const r=M(t);if(typeof r.featureKey!="string"||!/^[a-z][a-z0-9_-]{1,63}$/.test(r.featureKey)||typeof r.title!="string"||r.title.trim().length===0||r.title.length>120||!(r.policyType==="PUBLIC"||r.policyType==="FOLLOW_OWNER"||r.policyType==="WORK_ENTITLEMENT"))throw A();const i=r.price===null?null:M(r.price);if(e===3){const n=d=>{if(d===null)return null;const f=M(d);if(!Number.isSafeInteger(f.amountMinor)||f.amountMinor<=0||!(f.currency==="CNY"||f.currency==="USD"))throw A();return{amountMinor:f.amountMinor,currency:f.currency}};if(r.status!=="ACTIVE"&&r.status!=="PENDING_CHANNEL"&&r.status!=="DISABLED")throw A();const s=n(i),a=n(r.pricingIntent);if(r.policyType!=="WORK_ENTITLEMENT"&&(s!==null||r.status==="PENDING_CHANNEL")||r.policyType==="WORK_ENTITLEMENT"&&r.status==="ACTIVE"&&s===null||r.status==="PENDING_CHANNEL"&&(s!==null||a===null))throw A();return{featureKey:r.featureKey,title:r.title,policy:{type:r.policyType},price:s,status:r.status,pricingIntent:a}}if(i!==null&&(!Number.isInteger(i.amountCents)||i.amountCents<=0||i.currency!=="CNY")||r.policyType==="WORK_ENTITLEMENT"!=(i!==null))throw A();return{featureKey:r.featureKey,title:r.title,policy:{type:r.policyType},price:i===null?null:{amountCents:i.amountCents,currency:"CNY"}}}function Ge(){const t=crypto.getRandomValues(new Uint8Array(32));return je(t)}function je(t){let e="";for(const r of t)e+=String.fromCharCode(r);return btoa(e).replaceAll("+","-").replaceAll("/","_").replace(/=+$/,"")}function he(){return typeof document<"u"&&document.documentElement.lang.toLowerCase()==="en-us"?"en-US":"zh-CN"}function Ye(t){const e=$e(t),r=()=>new w({code:"AUTH_CANCELLED",message:"The interactive action was cancelled.",retryable:!1}),i=()=>t.signal.reason instanceof Error?t.signal.reason:T(),n=c=>{if(t.signal.aborted)return Promise.reject(i());let h;const l=new Promise((m,g)=>{h=()=>g(i()),t.signal.addEventListener("abort",h,{once:!0}),t.signal.aborted&&h()});let o;try{o=(t.presenter??Ve)({...c,signal:t.signal})}catch(m){o=Promise.reject(m)}return Promise.race([o,l]).then(m=>{if(t.signal.aborted)throw i();return m}).finally(()=>{h&&t.signal.removeEventListener("abort",h)})},s=(c,h,l,o,m,g)=>{if(typeof window>"u")throw new w({code:"CONFIG_INVALID",message:"Interactive access requires a browser window.",retryable:!1});let p=!0,I,R;const C=()=>{p&&(p=!1,window.removeEventListener("message",D))},q=new Promise((O,y)=>{I=O,R=y}),D=O=>{if(!p||O.origin!==h||typeof O.data!="object"||O.data===null)return;const y=O.data;if(!(y.workKey!==t.workKey||y.channel!==l)){if(y.type===`viceme:${o}:ready`){O.source&&"postMessage"in O.source&&O.source.postMessage({type:`viceme:${o}:init`,workKey:t.workKey,channel:l,...m},h);return}if(y.type===`viceme:${o}:cancelled`){C(),R(r());return}y.type===`viceme:${o}:complete`&&(C(),g(y).then(I,R))}};return window.addEventListener("message",D),{type:"frame",url:c,completion:q,cancel(){C(),I()}}},a=async()=>{if(await t.ready(),t.session.snapshot?.accessProtocolVersion===3)return e.start("SIGN_IN");if(typeof window>"u")throw new w({code:"CONFIG_INVALID",message:"Interactive access requires a browser window.",retryable:!1});const c=Ge(),h=new URL("/sdk/login",t.widgetOrigin);h.search=new URLSearchParams({workKey:t.workKey,channel:c,parentOrigin:window.location.origin,locale:he()}).toString();const l=t.session.snapshot?.token;if(!l)throw A();return s(h.toString(),t.widgetOrigin,c,"auth",{workSessionToken:l},async o=>{if(typeof o.userToken!="string")throw A();t.session.authenticate({userToken:o.userToken,user:Fe(o.user)})})},d=async()=>(await t.ready(),fe((await t.session.request({method:"GET",path:"/v1/public/work-sdk/follow"})).body)),f=async()=>(await t.ready(),fe((await t.session.request({method:"PUT",path:"/v1/public/work-sdk/follow"})).body)),v=()=>{const c=t.session.snapshot?.work;return{...c?.creator?{followTarget:{kind:"CREATOR",displayName:c.creator.displayName,avatarUrl:c.creator.avatarUrl,description:null,workCount:c.creator.publishedWorkCount}}:{},...c?.details?{work:c.details}:{}}},S={async getState(){await t.ready();const c=t.session.snapshot?.user??null;return{authenticated:c!==null,user:c}},async signIn(){if(await t.ready(),await n({featureKey:"auth",reason:"AUTH_REQUIRED",action:"SIGN_IN",autoStart:t.session.snapshot?.accessProtocolVersion===3,...v(),perform:a})==="dismissed")throw r();return this.getState()},async signOut(){await t.ready(),e.clear(),await t.session.signOut()}},u={getState:d,follow:f,unfollow:async()=>{throw new w({code:"CAPABILITY_DISABLED",message:"Unfollow is not exposed by website access.",retryable:!1})}},b=async c=>{await t.ready();const h=M((await t.session.request({method:"POST",path:"/v1/public/work-sdk/access/check",body:{featureKeys:c}})).body),l=M(h.decisions);return Object.fromEntries(Object.entries(l).map(([o,m])=>[o,qe(m,t.session.snapshot?.accessProtocolVersion)]))},x=async(c,h={})=>{await t.ready();const l={featureKey:c,locale:h.locale??(t.session.snapshot?.accessProtocolVersion===3?he():"zh-CN"),...t.session.snapshot?.accessProtocolVersion===3&&typeof window<"u"&&/^https?:$/.test(window.location.protocol)?{returnUrl:window.location.href}:{}},o=M((await t.session.request({method:"POST",path:"/v1/public/work-sdk/checkout",body:l})).body);if(typeof o.checkoutUrl!="string"||typeof o.alreadyOwned!="boolean"||!(o.expiresAt===null||typeof o.expiresAt=="string"&&!Number.isNaN(Date.parse(o.expiresAt)))||o.alreadyOwned!==(o.expiresAt===null))throw A();let m;try{m=new URL(o.checkoutUrl)}catch{throw A()}if(!o.alreadyOwned&&(m.protocol!=="https:"||m.origin!==t.widgetOrigin))throw A();return{checkoutUrl:o.checkoutUrl,alreadyOwned:o.alreadyOwned,expiresAt:o.expiresAt}},_=(c,h)=>{if(c.alreadyOwned)return{type:"completed"};const l=Date.parse(c.expiresAt);if(typeof window>"u")throw new w({code:"CONFIG_INVALID",message:"Hosted checkout requires a browser window.",retryable:!1});let o=!0,m,g,p,I;const R=new Promise((L,re)=>{p=L,I=re}),C=()=>{m&&clearTimeout(m),g&&clearTimeout(g),document.removeEventListener("visibilitychange",y)},q=()=>{o&&(o=!1,C(),I(new w({code:"SESSION_EXPIRED",message:"Hosted checkout session expired.",retryable:!0})))},D=()=>{if(!o||document.visibilityState==="hidden")return;const L=l-t.now();if(L<=0){q();return}m=setTimeout(()=>{O()},Math.min(1500,L))},O=async()=>{if(o)try{const L=(await b([h]))[h];if(!L)throw A();if(L.allowed){o=!1,C(),p();return}D()}catch(L){o=!1,C(),I(L)}};function y(){if(o){if(document.visibilityState==="hidden"){m&&clearTimeout(m),m=void 0;return}D()}}document.addEventListener("visibilitychange",y);const te=l-t.now();return te<=0?q():(g=setTimeout(q,te),D()),{type:"frame",url:c.checkoutUrl,completion:R,cancel(){o&&(o=!1,C(),p())}}},U={async open(c){if(await t.ready(),t.session.snapshot?.accessProtocolVersion===3){const o=(await b([c.featureKey]))[c.featureKey];if(!o)throw A();if(o.nextAction==="RESOLVE_BUYER"){if(await n({featureKey:c.featureKey,reason:o.reason,action:"RESOLVE_BUYER",autoStart:!0,perform:()=>e.start("IDENTIFY",c.featureKey)})==="dismissed")throw r()}else if(!o.allowed&&o.nextAction!=="CHECKOUT")throw new w({code:"CHECKOUT_UNAVAILABLE",message:"Checkout is not available for this feature.",retryable:!1})}const h=await x(c.featureKey,c);if(h.alreadyOwned)return h;if(await n({featureKey:c.featureKey,reason:"PURCHASE_REQUIRED",action:"CHECKOUT",autoStart:t.session.snapshot?.accessProtocolVersion===3,perform:async()=>_(h,c.featureKey)})==="dismissed")throw r();return h}},V={async getFeatures(){await t.ready();const c=M((await t.session.request({method:"GET",path:"/v1/public/work-sdk/access/features"})).body);if(!Array.isArray(c.features)||c.features.length>100)throw A();return c.features.map(h=>Be(h,t.session.snapshot?.accessProtocolVersion))},async check(c){const l=(await b([c]))[c];if(!l)throw A();return l},checkMany:b,async require(c){let h=await this.check(c);const l=new Set;for(let o=0;!h.allowed&&h.nextAction&&o<6;o+=1){const m=h.nextAction,g=`${h.reason}:${m}`;if(l.has(g))return h;if(l.add(g),m==="FOLLOW"&&t.session.snapshot?.accessProtocolVersion===3){await u.follow(),h=await this.check(c);continue}const p=m==="FOLLOW"?(await u.getState()).target:void 0,I=m==="CHECKOUT"?await x(c):void 0;if(I?.alreadyOwned){h=await this.check(c);continue}if(await n({featureKey:c,reason:h.reason,action:m,autoStart:t.session.snapshot?.accessProtocolVersion===3,...m==="SIGN_IN"?v():p?{followTarget:p}:{},perform:async()=>m==="SIGN_IN"?a():m==="RESOLVE_BUYER"?e.start("IDENTIFY",c):m==="FOLLOW"?(await u.follow(),{type:"completed"}):_(I,c)})==="dismissed")return h;h=await this.check(c)}return h},async refresh(){await t.ready()},restorePurchase:c=>F("RESTORE",c),claimPurchase:c=>F("CLAIM",c)};async function F(c,h){if(await t.ready(),t.session.snapshot?.accessProtocolVersion!==3)throw new w({code:"CAPABILITY_DISABLED",message:"This website has not enabled purchase recovery.",retryable:!1});if(await n({featureKey:h,reason:"BUYER_REQUIRED",action:"RESOLVE_BUYER",autoStart:!0,perform:()=>e.start(c,h)})==="dismissed")throw r();return V.check(h)}return{auth:S,follow:u,access:V,checkout:U}}function me(t){t instanceof ye&&t.markDegraded()}class ye{#e=new De;#r;#t;#i=new AbortController;#n;auth;access;checkout;#a;constructor(e){this.#t=e.config,this.#r=new Pe({workKey:e.config.workKey,region:e.config.region,transport:e.transport,signal:this.#i.signal,...e.now!==void 0?{now:e.now}:{}});const r=Ye({session:this.#r,workKey:e.config.workKey,widgetOrigin:Ie[e.config.region],now:e.now??(()=>Date.now()),presenter:e.presenter,signal:this.#i.signal,ready:()=>this.#o()});this.auth=r.auth,this.access=r.access,this.checkout=r.checkout;const i=e.config.signal;if(i){const n=()=>{this.#i.abort(i.reason instanceof Error?i.reason:new DOMException("Caller signal aborted.","AbortError"))};i.aborted?n():(i.addEventListener("abort",n,{once:!0}),this.#a=()=>{i.removeEventListener("abort",n)})}}get version(){return ce}get workKey(){return this.#t.workKey}get region(){return this.#t.region}get state(){return this.#e.state}get apiMajor(){return G}ready(){return this.#e.destroyed?Promise.reject(T()):(this.#n||(this.#e.transition("READY"),this.#n=Promise.resolve()),this.#n)}async#o(){if(this.#e.destroyed)throw T();await this.ready();try{if(await this.#r.establish(),this.#e.destroyed)throw T()}catch(e){throw this.#e.destroyed?T():(this.#r.invalidate(),e)}}hasCapability(e){if(this.#e.destroyed)return!1;const r=this.#r.snapshot?.work.capabilities;return e==="danmaku"||e==="tip"||r?.includes(e)===!0}get capabilities(){return this.#r.snapshot?.work.capabilities??[]}markDegraded(){this.#e.state==="READY"&&this.#e.transition("DEGRADED")}get sessionSnapshot(){return this.#r.snapshot}destroy(){this.#e.destroyed||(this.#e.transition("DESTROYED"),this.#i.abort(T()),this.#r.destroy(),this.#e.clearListeners(),this.#n=void 0,this.#a?.(),this.#a=void 0)}}const We=1e4,He=new Map([[400,"CONFIG_INVALID"],[401,"SESSION_EXPIRED"],[403,"CAPABILITY_DISABLED"],[404,"WORK_NOT_FOUND"],[409,"CONFIG_INVALID"],[422,"CONFIG_INVALID"],[429,"RATE_LIMITED"]]),ze=new Set(["CONFIG_INVALID","WORK_NOT_FOUND","CAPABILITY_DISABLED","SESSION_EXPIRED","AUTH_REQUIRED","AUTH_CANCELLED","RETURN_URL_NOT_ALLOWED","RATE_LIMITED","NETWORK_TIMEOUT","CHECKOUT_UNAVAILABLE","INTERNAL_ERROR"]);function Xe(t){if(typeof t!="object"||t===null)return{};const e=t,r=typeof e.error=="object"&&e.error!==null?e.error:e,i={};return typeof r.code=="string"&&ze.has(r.code)&&(i.code=r.code),typeof r.message=="string"&&(i.message=r.message.slice(0,200)),typeof r.retryable=="boolean"&&(i.retryable=r.retryable),typeof r.requestId=="string"&&(i.requestId=r.requestId),i}function Qe(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`req-${Math.random().toString(36).slice(2)}`}class Je{#e;#r;#t;#i;constructor(e){this.#e=e.apiBaseUrl.replace(/\/+$/,""),this.#r=e.fetchImpl??globalThis.fetch.bind(globalThis),this.#t=e.defaultTimeoutMs??We,this.#i=e.generateRequestId??Qe}async request(e){if(e.signal?.aborted)throw this.#n(e.signal);const r=e.timeoutMs??this.#t,i=new AbortController;let n=!1;const s=setTimeout(()=>{n=!0,i.abort(new pe)},r),a=()=>i.abort(new pe(!1));e.signal?.addEventListener("abort",a,{once:!0});const d=this.#i();try{const f=await this.#r(`${this.#e}${e.path}`,{method:e.method,credentials:"omit",mode:"cors",headers:{"content-type":"application/json","x-client-request-id":d,...e.authorization!==void 0?{authorization:`Bearer ${e.authorization}`}:{},...e.userAuthorization!==void 0?{"x-viceme-user-token":e.userAuthorization}:{},...e.buyerAuthorization!==void 0?{"x-viceme-buyer-token":e.buyerAuthorization}:{}},body:e.body!==void 0?JSON.stringify(e.body):void 0,signal:i.signal});let v;try{v=await f.json()}catch(u){if(e.signal?.aborted||n)throw u;v=void 0}if(i.signal.aborted)throw i.signal.reason;const S=f.headers.get("x-request-id")??void 0;if(!f.ok){const u=Xe(v),b=u.code??He.get(f.status)??"INTERNAL_ERROR";throw new w({code:b,message:u.message??"Public API request failed.",retryable:u.retryable,requestId:u.requestId??S})}return{status:f.status,body:v,requestId:S}}catch(f){throw e.signal?.aborted?this.#n(e.signal):n?new w({code:"NETWORK_TIMEOUT",message:"Public API request timed out.",retryable:!0,requestId:d}):f instanceof w?f:f instanceof DOMException&&f.name==="AbortError"?new DOMException("ViceMe request aborted by caller.","AbortError"):new w({code:"INTERNAL_ERROR",message:"Public API request failed.",retryable:!0,requestId:d})}finally{clearTimeout(s),e.signal?.removeEventListener("abort",a)}}#n(e){return e.reason instanceof Error?e.reason:new DOMException("ViceMe request aborted by caller.","AbortError")}}function Ze(t){return new Je(t)}class pe extends DOMException{constructor(e=!0){super(e?"ViceMe request timed out.":"ViceMe request aborted.","AbortError")}}function et(t){const e=Te(t),r=Ne(e.region),i=Ze({apiBaseUrl:r});return new ye({config:e,transport:i})}const tt=8e3,rt=8e3,we={danmaku:"danmaku.js",tip:"tip.js"},it={danmaku:"mountDanmaku",tip:"mountTip"},ge=Symbol.for("viceme.loader.state.v1");function k(){const e=globalThis[ge];if(e)return e;const r={registry:new Ce,queue:{current:Promise.resolve()}};return Object.defineProperty(globalThis,ge,{value:r,writable:!0,configurable:!0,enumerable:!1}),r}function Z(t){if(!t.destroyed){t.destroyed=!0,k().registry.removeInstance(t.instanceKey);try{t.raw.destroy()}finally{j(t.host,"viceme:destroyed",{clientKey:t.clientKey,instanceKey:t.instanceKey,capability:t.capability})}}}function nt(t){return{instanceKey:t.instanceKey,capability:t.capability,destroy:()=>Z(t)}}function ee(t,e,r){Object.defineProperty(t,e,{value:r,writable:!0,configurable:!0,enumerable:!1})}function at(t){let r=globalThis.ViceMe;r||(r={},ee(globalThis,"ViceMe",r));let i=r.versions;i||(i={},ee(r,"versions",i));const n=i[`v${G}`];if(n)return n;const s={version:t,whenReady(a){const d=k().registry.getClient(a);return d?d.ready.then(()=>d.client):Promise.reject(E(`Unknown clientKey "${a}".`))},getInstance(a){const d=k().registry.getInstance(a);return d?nt(d):void 0},destroyInstance(a){const d=k().registry.getInstance(a);d&&Z(d)},destroyClient(a){for(const f of k().registry.instancesForClient(a))Z(f);const d=k().registry.getClient(a);for(const f of d?.pendingMounts??[])f.abort();k().registry.unregisterClient(a),d?.client.destroy()}};return ee(i,`v${G}`,s),s}function ot(){return document.readyState!=="loading"?Promise.resolve():new Promise(t=>{document.addEventListener("DOMContentLoaded",()=>t(),{once:!0})})}async function st(t){const e=new AbortController,r=globalThis.setTimeout(()=>e.abort(),tt);try{let i;try{i=await fetch(t,{credentials:"omit",signal:e.signal})}catch{if(e.signal.aborted)throw new w({code:"INTERNAL_ERROR",message:"Release manifest request timed out.",retryable:!0});i={ok:!1,status:0}}return{manifest:await ct(i),baseUrl:t}}finally{globalThis.clearTimeout(r)}}async function ct(t){if(!t.ok)throw E(`Release manifest is not available (HTTP ${t.status}).`);const e=await t.json();if(typeof e!="object"||e===null||typeof e.version!="string"||typeof e.apiMajor!="number"||typeof e.features!="object"||e.features===null)throw E("Release manifest is malformed.");const r=e;if(r.version!==ce)throw E("Release manifest version does not match this loader.");if(r.apiMajor!==G)throw E("Release manifest major version does not match this loader.");const i=Object.keys(r.features).sort();if(i.length!==2||i[0]!=="danmaku"||i[1]!=="tip"||r.features.danmaku!==we.danmaku||r.features.tip!==we.tip)throw E("Release manifest features must be exactly danmaku.js and tip.js.");return r}const lt=new Set(["CONFIG_INVALID","CAPABILITY_DISABLED","CLIENT_DESTROYED","INTERNAL_ERROR"]);function dt(t){if(typeof t=="object"&&t!==null){const e=t;if(typeof e.code=="string"&<.has(e.code)&&typeof e.retryable=="boolean"){const r={code:e.code,retryable:e.retryable};return typeof e.requestId=="string"&&(r.requestId=e.requestId),typeof e.capability=="string"&&(r.capability=e.capability),r}}return{code:"INTERNAL_ERROR",retryable:!0}}function $(t,e,r={}){j(t,"viceme:error",{...dt(e),...r})}function ut(t,e,r){let i,n;const s=new Promise((a,d)=>{if(n=()=>d(T()),e.signal.aborted){n();return}e.signal.addEventListener("abort",n,{once:!0}),i=globalThis.setTimeout(()=>{d(new w({code:"INTERNAL_ERROR",message:`Capability "${r}" did not load and mount in time.`,retryable:!0,capability:r})),e.abort()},rt)});return Promise.race([t,s]).finally(()=>{i!==void 0&&globalThis.clearTimeout(i),n&&e.signal.removeEventListener("abort",n)})}async function ft(t){let e;try{e=Le(t)}catch(u){$(document,u);return}if(!t.src){$(document,E("Loader script requires a src URL."));return}const r=new URL("manifest.json",t.src);let i,n;try{({manifest:i,baseUrl:n}=await st(r))}catch(u){$(document,u,{clientKey:H(G,e.region,e.workKey)});return}await ot();let s;try{const u=document.querySelectorAll(e.target);if(u.length===0)throw E(`Loader target "${e.target}" matched no element; no node was created.`);if(u.length>1)throw E(`Loader target "${e.target}" matched ${u.length} elements; exactly one is required.`);s=u[0]}catch(u){$(document,u,{clientKey:H(i.apiMajor,e.region,e.workKey)});return}const a=H(i.apiMajor,e.region,e.workKey);at(i.version);let d=k().registry.getClient(a),f;if(d)f=d.client;else{try{f=et({workKey:e.workKey,region:e.region})}catch(b){$(s,b,{clientKey:a});return}const u=f.ready();u.catch(()=>{}),d={clientKey:a,client:f,ready:u,pendingMounts:new Set},k().registry.registerClient(d)}try{await d.ready}catch(u){k().registry.unregisterClient(a),f.destroy(),$(s,u,{clientKey:a});return}if(k().registry.getClient(a)!==d)return;const v=async u=>{if(k().registry.findInstance(a,u,s))return;const b=i.features[u];if(typeof b!="string"){me(f),$(s,new w({code:"CAPABILITY_DISABLED",message:`Capability "${u}" is not part of this release.`,retryable:!1,capability:u}),{clientKey:a,capability:u});return}const x=new AbortController;d.pendingMounts.add(x);try{const _=(async()=>{const c=await import(new URL(b,n).href),h=it[u],l=c[h];if(typeof l!="function")throw E(`Capability chunk "${u}" does not export ${h}().`);if(k().registry.getClient(a)!==d)throw T();return await l(f,{target:s,theme:e.theme,signal:x.signal,...u==="tip"&&e.features.includes("danmaku")?{presentation:"integrated"}:{}})})(),U=await ut(_,x,u);if(k().registry.getClient(a)!==d){U.destroy();return}const V=k().registry.registerInstance(a,u,s,U);return j(s,"viceme:capability-ready",{clientKey:a,instanceKey:V.instanceKey,capability:u,version:i.version}),u}catch(_){if(k().registry.getClient(a)!==d)return;me(f),$(s,_,{clientKey:a,capability:u});return}finally{d.pendingMounts.delete(x)}},S=(await Promise.all(e.features.map(v))).filter(u=>u!==void 0);S.length>0&&k().registry.getClient(a)===d&&j(s,"viceme:ready",{clientKey:a,workKey:e.workKey,capabilities:S,version:i.version})}function ht(t){const{queue:e}=k(),r=e.current.then(()=>ft(t));return e.current=r.catch(()=>{}),r}function be(){if(typeof document>"u")return;let t=document.currentScript instanceof HTMLScriptElement?document.currentScript:null;if(!t){const e=document.querySelectorAll("script[data-viceme-loader]");e.length===1&&(t=e[0]??null)}t&&ht(t).catch(e=>{$(document,e)})}be();const pt=be})();
|
|
258
259
|
//# sourceMappingURL=viceme.min.js.map
|