@walkeros/web-destination-piano 4.1.2
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/LICENSE +21 -0
- package/README.md +103 -0
- package/dist/dev.d.mts +100 -0
- package/dist/dev.d.ts +100 -0
- package/dist/dev.js +1 -0
- package/dist/dev.js.map +1 -0
- package/dist/dev.mjs +1 -0
- package/dist/dev.mjs.map +1 -0
- package/dist/examples/index.d.mts +62 -0
- package/dist/examples/index.d.ts +62 -0
- package/dist/examples/index.js +156 -0
- package/dist/examples/index.mjs +134 -0
- package/dist/index.browser.js +1 -0
- package/dist/index.d.mts +64 -0
- package/dist/index.d.ts +64 -0
- package/dist/index.es5.js +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1 -0
- package/dist/index.mjs.map +1 -0
- package/dist/walkerOS.json +352 -0
- package/package.json +78 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __export = (target, all) => {
|
|
3
|
+
for (var name in all)
|
|
4
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
// src/examples/env.ts
|
|
8
|
+
var env_exports = {};
|
|
9
|
+
__export(env_exports, {
|
|
10
|
+
init: () => init,
|
|
11
|
+
push: () => push,
|
|
12
|
+
simulation: () => simulation
|
|
13
|
+
});
|
|
14
|
+
var noop = () => {
|
|
15
|
+
};
|
|
16
|
+
function mockPa() {
|
|
17
|
+
return {
|
|
18
|
+
setConfigurations: noop,
|
|
19
|
+
sendEvent: noop,
|
|
20
|
+
sendEvents: noop
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
var init = {
|
|
24
|
+
window: {}
|
|
25
|
+
};
|
|
26
|
+
var push = {
|
|
27
|
+
window: {
|
|
28
|
+
pa: mockPa()
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
var simulation = [
|
|
32
|
+
"call:window.pa.sendEvent"
|
|
33
|
+
// Track Piano sendEvent calls
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
// src/examples/step.ts
|
|
37
|
+
var step_exports = {};
|
|
38
|
+
__export(step_exports, {
|
|
39
|
+
customEvent: () => customEvent,
|
|
40
|
+
init: () => init2,
|
|
41
|
+
pageView: () => pageView,
|
|
42
|
+
purchase: () => purchase
|
|
43
|
+
});
|
|
44
|
+
import { getEvent } from "@walkeros/core";
|
|
45
|
+
var settings = {
|
|
46
|
+
site: 123456789,
|
|
47
|
+
collectDomain: "https://example.pa-cd.com"
|
|
48
|
+
};
|
|
49
|
+
var init2 = {
|
|
50
|
+
title: "Initialization",
|
|
51
|
+
description: "Destination bootstrap configures Piano with the site id and collection domain.",
|
|
52
|
+
in: {
|
|
53
|
+
settings
|
|
54
|
+
},
|
|
55
|
+
out: [["pa.setConfigurations", settings]]
|
|
56
|
+
};
|
|
57
|
+
var pageView = {
|
|
58
|
+
title: "Page view",
|
|
59
|
+
description: "A page view fires a Piano page.display event with the page name and chapter.",
|
|
60
|
+
in: getEvent("page view", { timestamp: 1700000200 }),
|
|
61
|
+
mapping: {
|
|
62
|
+
name: "page.display",
|
|
63
|
+
data: {
|
|
64
|
+
map: {
|
|
65
|
+
page: "data.title",
|
|
66
|
+
page_chapter1: "globals.pagegroup"
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
out: [
|
|
71
|
+
[
|
|
72
|
+
"pa.sendEvent",
|
|
73
|
+
"page.display",
|
|
74
|
+
{
|
|
75
|
+
page: "walkerOS documentation",
|
|
76
|
+
page_chapter1: "docs"
|
|
77
|
+
}
|
|
78
|
+
]
|
|
79
|
+
]
|
|
80
|
+
};
|
|
81
|
+
var purchase = {
|
|
82
|
+
title: "Purchase",
|
|
83
|
+
description: "A completed order fires a Piano transaction.confirmation event with the transaction id, revenue and currency.",
|
|
84
|
+
in: getEvent("order complete", { timestamp: 1700000201 }),
|
|
85
|
+
mapping: {
|
|
86
|
+
name: "transaction.confirmation",
|
|
87
|
+
data: {
|
|
88
|
+
map: {
|
|
89
|
+
transaction_id: "data.id",
|
|
90
|
+
revenue: "data.total",
|
|
91
|
+
currency: "data.currency"
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
out: [
|
|
96
|
+
[
|
|
97
|
+
"pa.sendEvent",
|
|
98
|
+
"transaction.confirmation",
|
|
99
|
+
{
|
|
100
|
+
transaction_id: "0rd3r1d",
|
|
101
|
+
revenue: 555,
|
|
102
|
+
currency: "EUR"
|
|
103
|
+
}
|
|
104
|
+
]
|
|
105
|
+
]
|
|
106
|
+
};
|
|
107
|
+
var customEvent = {
|
|
108
|
+
title: "Custom event",
|
|
109
|
+
description: "A generic entity action fires a custom Piano event with mapped properties.",
|
|
110
|
+
in: getEvent("entity action", { timestamp: 1700000202 }),
|
|
111
|
+
mapping: {
|
|
112
|
+
name: "click.action",
|
|
113
|
+
data: {
|
|
114
|
+
map: {
|
|
115
|
+
label: "data.string",
|
|
116
|
+
value: "data.number"
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
out: [
|
|
121
|
+
[
|
|
122
|
+
"pa.sendEvent",
|
|
123
|
+
"click.action",
|
|
124
|
+
{
|
|
125
|
+
label: "foo",
|
|
126
|
+
value: 1
|
|
127
|
+
}
|
|
128
|
+
]
|
|
129
|
+
]
|
|
130
|
+
};
|
|
131
|
+
export {
|
|
132
|
+
env_exports as env,
|
|
133
|
+
step_exports as step
|
|
134
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var Destination=(()=>{var t=Object.defineProperty,e=Object.getOwnPropertyDescriptor,n=Object.getOwnPropertyNames,o=Object.prototype.hasOwnProperty,r={};((e,n)=>{for(var o in n)t(e,o,{get:n[o],enumerable:!0})})(r,{DestinationPiano:()=>m,default:()=>j,destinationPiano:()=>g});var i=Object.defineProperty,c=(t,e)=>{for(var n in e)i(t,n,{get:e[n],enumerable:!0})};function a(t,e){if("collector"===t)return"collector";if(!e)throw new Error(`stepId(${t}) requires an id`);return`${t}.${e}`}c({},{stepId:()=>a});function u(t,e){const n=t.destinations[e];if(!n)throw new Error(`Destination not found: ${e}`);return n}c({},{getDestination:()=>u});c({},{Level:()=>f});var s,f=((s=f||{})[s.ERROR=0]="ERROR",s[s.WARN=1]="WARN",s[s.INFO=2]="INFO",s[s.DEBUG=3]="DEBUG",s);function d(t,e){const n=t.transformers[e];if(!n)throw new Error(`Transformer not found: ${e}`);return n}c({},{getTransformer:()=>d});function l(t,e){const n=t.sources[e];if(!n)throw new Error(`Source not found: ${e}`);return n}c({},{getSource:()=>l});function p(t,e){const n=t.stores[e];if(!n)throw new Error(`Store not found: ${e}`);return n}function w(t){return void 0!==t}function v(t){return"object"==typeof t&&null!==t&&!function(t){return Array.isArray(t)}(t)&&"[object Object]"===Object.prototype.toString.call(t)}c({},{getStore:()=>p});var m={},y="https://tag.aticdn.net/piano-analytics.js",g={type:"piano",config:{},init({config:t,env:e}){const n=t.settings||{};t.loadScript&&function(t=y){if("undefined"==typeof document)return;const e=document.createElement("script");e.src=t,document.head.appendChild(e)}();const o=b(e);return o&&w(n.site)&&w(n.collectDomain)&&o.setConfigurations({site:n.site,collectDomain:n.collectDomain,...v(n.options)?n.options:{}}),t},push(t,{data:e,env:n}){const o=b(n);o&&o.sendEvent(t.name,v(e)?e:{})}};function b(t){var e,n;return null!=(n=null==(e=t.window)?void 0:e.pa)?n:"undefined"!=typeof window?window.pa:void 0}var O,j=g;return O=r,((r,i,c,a)=>{if(i&&"object"==typeof i||"function"==typeof i)for(let u of n(i))o.call(r,u)||u===c||t(r,u,{get:()=>i[u],enumerable:!(a=e(i,u))||a.enumerable});return r})(t({},"__esModule",{value:!0}),O)})();
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { WalkerOS, Destination as Destination$1, Mapping as Mapping$1 } from '@walkeros/core';
|
|
2
|
+
import { DestinationWeb } from '@walkeros/web-core';
|
|
3
|
+
|
|
4
|
+
declare global {
|
|
5
|
+
interface Window {
|
|
6
|
+
pa?: PianoAnalytics;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Surface of the official Piano Analytics browser SDK (the `pa` global from
|
|
11
|
+
* https://tag.aticdn.net/piano-analytics.js). Only the methods this
|
|
12
|
+
* destination calls are declared; the SDK exposes more.
|
|
13
|
+
*/
|
|
14
|
+
interface PianoAnalytics {
|
|
15
|
+
setConfigurations(configurations: WalkerOS.AnyObject): void;
|
|
16
|
+
sendEvent(name: string, data?: WalkerOS.AnyObject): void;
|
|
17
|
+
sendEvents(events: ReadonlyArray<{
|
|
18
|
+
name: string;
|
|
19
|
+
data?: WalkerOS.AnyObject;
|
|
20
|
+
}>): void;
|
|
21
|
+
}
|
|
22
|
+
interface Settings {
|
|
23
|
+
/** Piano Analytics site id (numeric), from your collection settings. */
|
|
24
|
+
site: number;
|
|
25
|
+
/** Collection domain endpoint, like https://xxxxxxx.pa-cd.com */
|
|
26
|
+
collectDomain: string;
|
|
27
|
+
/** Additional Piano `setConfigurations` options merged on init. */
|
|
28
|
+
options?: WalkerOS.AnyObject;
|
|
29
|
+
}
|
|
30
|
+
type InitSettings = Partial<Settings>;
|
|
31
|
+
interface Mapping {
|
|
32
|
+
}
|
|
33
|
+
interface Env extends DestinationWeb.Env {
|
|
34
|
+
window?: {
|
|
35
|
+
pa?: PianoAnalytics;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
type Types = Destination$1.Types<Settings, Mapping, Env, InitSettings>;
|
|
39
|
+
type Destination = DestinationWeb.Destination<Types>;
|
|
40
|
+
type Config = DestinationWeb.Config<Types>;
|
|
41
|
+
interface PianoDestination extends Destination {
|
|
42
|
+
env?: Env;
|
|
43
|
+
}
|
|
44
|
+
type Rule = Mapping$1.Rule<Mapping>;
|
|
45
|
+
type Rules = Mapping$1.Rules<Rule>;
|
|
46
|
+
|
|
47
|
+
type index_Config = Config;
|
|
48
|
+
type index_Destination = Destination;
|
|
49
|
+
type index_Env = Env;
|
|
50
|
+
type index_InitSettings = InitSettings;
|
|
51
|
+
type index_Mapping = Mapping;
|
|
52
|
+
type index_PianoAnalytics = PianoAnalytics;
|
|
53
|
+
type index_PianoDestination = PianoDestination;
|
|
54
|
+
type index_Rule = Rule;
|
|
55
|
+
type index_Rules = Rules;
|
|
56
|
+
type index_Settings = Settings;
|
|
57
|
+
type index_Types = Types;
|
|
58
|
+
declare namespace index {
|
|
59
|
+
export type { index_Config as Config, index_Destination as Destination, index_Env as Env, index_InitSettings as InitSettings, index_Mapping as Mapping, index_PianoAnalytics as PianoAnalytics, index_PianoDestination as PianoDestination, index_Rule as Rule, index_Rules as Rules, index_Settings as Settings, index_Types as Types };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
declare const destinationPiano: Destination;
|
|
63
|
+
|
|
64
|
+
export { index as DestinationPiano, destinationPiano as default, destinationPiano };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { WalkerOS, Destination as Destination$1, Mapping as Mapping$1 } from '@walkeros/core';
|
|
2
|
+
import { DestinationWeb } from '@walkeros/web-core';
|
|
3
|
+
|
|
4
|
+
declare global {
|
|
5
|
+
interface Window {
|
|
6
|
+
pa?: PianoAnalytics;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Surface of the official Piano Analytics browser SDK (the `pa` global from
|
|
11
|
+
* https://tag.aticdn.net/piano-analytics.js). Only the methods this
|
|
12
|
+
* destination calls are declared; the SDK exposes more.
|
|
13
|
+
*/
|
|
14
|
+
interface PianoAnalytics {
|
|
15
|
+
setConfigurations(configurations: WalkerOS.AnyObject): void;
|
|
16
|
+
sendEvent(name: string, data?: WalkerOS.AnyObject): void;
|
|
17
|
+
sendEvents(events: ReadonlyArray<{
|
|
18
|
+
name: string;
|
|
19
|
+
data?: WalkerOS.AnyObject;
|
|
20
|
+
}>): void;
|
|
21
|
+
}
|
|
22
|
+
interface Settings {
|
|
23
|
+
/** Piano Analytics site id (numeric), from your collection settings. */
|
|
24
|
+
site: number;
|
|
25
|
+
/** Collection domain endpoint, like https://xxxxxxx.pa-cd.com */
|
|
26
|
+
collectDomain: string;
|
|
27
|
+
/** Additional Piano `setConfigurations` options merged on init. */
|
|
28
|
+
options?: WalkerOS.AnyObject;
|
|
29
|
+
}
|
|
30
|
+
type InitSettings = Partial<Settings>;
|
|
31
|
+
interface Mapping {
|
|
32
|
+
}
|
|
33
|
+
interface Env extends DestinationWeb.Env {
|
|
34
|
+
window?: {
|
|
35
|
+
pa?: PianoAnalytics;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
type Types = Destination$1.Types<Settings, Mapping, Env, InitSettings>;
|
|
39
|
+
type Destination = DestinationWeb.Destination<Types>;
|
|
40
|
+
type Config = DestinationWeb.Config<Types>;
|
|
41
|
+
interface PianoDestination extends Destination {
|
|
42
|
+
env?: Env;
|
|
43
|
+
}
|
|
44
|
+
type Rule = Mapping$1.Rule<Mapping>;
|
|
45
|
+
type Rules = Mapping$1.Rules<Rule>;
|
|
46
|
+
|
|
47
|
+
type index_Config = Config;
|
|
48
|
+
type index_Destination = Destination;
|
|
49
|
+
type index_Env = Env;
|
|
50
|
+
type index_InitSettings = InitSettings;
|
|
51
|
+
type index_Mapping = Mapping;
|
|
52
|
+
type index_PianoAnalytics = PianoAnalytics;
|
|
53
|
+
type index_PianoDestination = PianoDestination;
|
|
54
|
+
type index_Rule = Rule;
|
|
55
|
+
type index_Rules = Rules;
|
|
56
|
+
type index_Settings = Settings;
|
|
57
|
+
type index_Types = Types;
|
|
58
|
+
declare namespace index {
|
|
59
|
+
export type { index_Config as Config, index_Destination as Destination, index_Env as Env, index_InitSettings as InitSettings, index_Mapping as Mapping, index_PianoAnalytics as PianoAnalytics, index_PianoDestination as PianoDestination, index_Rule as Rule, index_Rules as Rules, index_Settings as Settings, index_Types as Types };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
declare const destinationPiano: Destination;
|
|
63
|
+
|
|
64
|
+
export { index as DestinationPiano, destinationPiano as default, destinationPiano };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";function _define_property(n,t,e){return t in n?Object.defineProperty(n,t,{value:e,enumerable:!0,configurable:!0,writable:!0}):n[t]=e,n}function _object_spread(n){for(var t=1;t<arguments.length;t++){var e=null!=arguments[t]?arguments[t]:{},r=Object.keys(e);"function"==typeof Object.getOwnPropertySymbols&&(r=r.concat(Object.getOwnPropertySymbols(e).filter(function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.forEach(function(t){_define_property(n,t,e[t])})}return n}function _type_of(n){return n&&"undefined"!=typeof Symbol&&n.constructor===Symbol?"symbol":typeof n}var Destination=function(){var n=function(n,t){if("collector"===n)return"collector";if(!t)throw new Error("stepId(".concat(n,") requires an id"));return"".concat(n,".").concat(t)},t=function(n,t){var e=n.destinations[t];if(!e)throw new Error("Destination not found: ".concat(t));return e},e=function(n,t){var e=n.transformers[t];if(!e)throw new Error("Transformer not found: ".concat(t));return e},r=function(n,t){var e=n.sources[t];if(!e)throw new Error("Source not found: ".concat(t));return e},o=function(n,t){var e=n.stores[t];if(!e)throw new Error("Store not found: ".concat(t));return e},i=function(n){return void 0!==n},c=function(n){return"object"==(void 0===n?"undefined":_type_of(n))&&null!==n&&!function(n){return Array.isArray(n)}(n)&&"[object Object]"===Object.prototype.toString.call(n)},u=function(n){var t,e;return null!==(t=null===(e=n.window)||void 0===e?void 0:e.pa)&&void 0!==t?t:"undefined"!=typeof window?window.pa:void 0},a=Object.defineProperty,f=Object.getOwnPropertyDescriptor,l=Object.getOwnPropertyNames,d=Object.prototype.hasOwnProperty,s={};!function(n,t){for(var e in t)a(n,e,{get:t[e],enumerable:!0})}(s,{DestinationPiano:function(){return w},default:function(){return j},destinationPiano:function(){return g}});var p=Object.defineProperty,v=function(n,t){for(var e in t)p(n,e,{get:t[e],enumerable:!0})};v({},{stepId:function(){return n}});v({},{getDestination:function(){return t}});v({},{Level:function(){return b}});var y,b=((y=b||{})[y.ERROR=0]="ERROR",y[y.WARN=1]="WARN",y[y.INFO=2]="INFO",y[y.DEBUG=3]="DEBUG",y);v({},{getTransformer:function(){return e}});v({},{getSource:function(){return r}});v({},{getStore:function(){return o}});var m,w={},O="https://tag.aticdn.net/piano-analytics.js",g={type:"piano",config:{},init:function(n){var t=n.config,e=n.env,r=t.settings||{};t.loadScript&&function(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:O;if("undefined"!=typeof document){var t=document.createElement("script");t.src=n,document.head.appendChild(t)}}();var o=u(e);return o&&i(r.site)&&i(r.collectDomain)&&o.setConfigurations(_object_spread({site:r.site,collectDomain:r.collectDomain},c(r.options)?r.options:{})),t},push:function(n,t){var e=t.data,r=t.env,o=u(r);o&&o.sendEvent(n.name,c(e)?e:{})}},j=g;return m=s,function(n,t,e,r){if(t&&"object"===(void 0===t?"undefined":_type_of(t))||"function"==typeof t){var o=!0,i=!1,c=void 0;try{for(var u,s=function(){var o=u.value;d.call(n,o)||o===e||a(n,o,{get:function(){return t[o]},enumerable:!(r=f(t,o))||r.enumerable})},p=l(t)[Symbol.iterator]();!(o=(u=p.next()).done);o=!0)s()}catch(n){i=!0,c=n}finally{try{o||null==p.return||p.return()}finally{if(i)throw c}}}return n}(a({},"__esModule",{value:!0}),m)}();
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var e,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,i=Object.prototype.hasOwnProperty,r={};((e,n)=>{for(var o in n)t(e,o,{get:n[o],enumerable:!0})})(r,{DestinationPiano:()=>c,default:()=>p,destinationPiano:()=>d}),module.exports=(e=r,((e,r,a,c)=>{if(r&&"object"==typeof r||"function"==typeof r)for(let s of o(r))i.call(e,s)||s===a||t(e,s,{get:()=>r[s],enumerable:!(c=n(r,s))||c.enumerable});return e})(t({},"__esModule",{value:!0}),e));var a=require("@walkeros/core"),c={},s="https://tag.aticdn.net/piano-analytics.js",d={type:"piano",config:{},init({config:e,env:t}){const n=e.settings||{};e.loadScript&&function(e=s){if("undefined"==typeof document)return;const t=document.createElement("script");t.src=e,document.head.appendChild(t)}();const o=l(t);return o&&(0,a.isDefined)(n.site)&&(0,a.isDefined)(n.collectDomain)&&o.setConfigurations({site:n.site,collectDomain:n.collectDomain,...(0,a.isObject)(n.options)?n.options:{}}),e},push(e,{data:t,env:n}){const o=l(n);o&&o.sendEvent(e.name,(0,a.isObject)(t)?t:{})}};function l(e){var t,n;return null!=(n=null==(t=e.window)?void 0:t.pa)?n:"undefined"!=typeof window?window.pa:void 0}var p=d;//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/types/index.ts"],"sourcesContent":["import type { Env, Destination, PianoAnalytics } from './types';\nimport { isDefined, isObject } from '@walkeros/core';\n\n// Types\nexport * as DestinationPiano from './types';\n\nconst SCRIPT_SRC = 'https://tag.aticdn.net/piano-analytics.js';\n\nexport const destinationPiano: Destination = {\n type: 'piano',\n\n config: {},\n\n init({ config, env }) {\n const settings = config.settings || {};\n\n if (config.loadScript) addScript();\n\n const pa = resolvePa(env);\n if (pa && isDefined(settings.site) && isDefined(settings.collectDomain)) {\n pa.setConfigurations({\n site: settings.site,\n collectDomain: settings.collectDomain,\n ...(isObject(settings.options) ? settings.options : {}),\n });\n }\n\n return config;\n },\n\n push(event, { data, env }) {\n const pa = resolvePa(env);\n if (!pa) return;\n\n pa.sendEvent(event.name, isObject(data) ? data : {});\n },\n};\n\n/**\n * Resolve the Piano `pa` SDK without casts: prefer the injected env (tests,\n * simulation), fall back to the browser global declared on `Window`.\n */\nfunction resolvePa(env: Env): PianoAnalytics | undefined {\n return (\n env.window?.pa ?? (typeof window !== 'undefined' ? window.pa : undefined)\n );\n}\n\nfunction addScript(src = SCRIPT_SRC) {\n if (typeof document === 'undefined') return;\n const script = document.createElement('script');\n script.src = src;\n document.head.appendChild(script);\n}\n\nexport default destinationPiano;\n","import type {\n Mapping as WalkerOSMapping,\n WalkerOS,\n Destination as CoreDestination,\n} from '@walkeros/core';\nimport type { DestinationWeb } from '@walkeros/web-core';\n\ndeclare global {\n interface Window {\n pa?: PianoAnalytics;\n }\n}\n\n/**\n * Surface of the official Piano Analytics browser SDK (the `pa` global from\n * https://tag.aticdn.net/piano-analytics.js). Only the methods this\n * destination calls are declared; the SDK exposes more.\n */\nexport interface PianoAnalytics {\n setConfigurations(configurations: WalkerOS.AnyObject): void;\n sendEvent(name: string, data?: WalkerOS.AnyObject): void;\n sendEvents(\n events: ReadonlyArray<{ name: string; data?: WalkerOS.AnyObject }>,\n ): void;\n}\n\nexport interface Settings {\n /** Piano Analytics site id (numeric), from your collection settings. */\n site: number;\n /** Collection domain endpoint, like https://xxxxxxx.pa-cd.com */\n collectDomain: string;\n /** Additional Piano `setConfigurations` options merged on init. */\n options?: WalkerOS.AnyObject;\n}\n\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {}\n\nexport interface Env extends DestinationWeb.Env {\n window?: {\n pa?: PianoAnalytics;\n };\n}\n\nexport type Types = CoreDestination.Types<Settings, Mapping, Env, InitSettings>;\n\nexport type Destination = DestinationWeb.Destination<Types>;\nexport type Config = DestinationWeb.Config<Types>;\n\nexport interface PianoDestination extends Destination {\n env?: Env;\n}\n\nexport type Rule = WalkerOSMapping.Rule<Mapping>;\nexport type Rules = WalkerOSMapping.Rules<Rule>;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,kBAAoC;;;ACDpC;;;ADMA,IAAM,aAAa;AAEZ,IAAM,mBAAgC;AAAA,EAC3C,MAAM;AAAA,EAEN,QAAQ,CAAC;AAAA,EAET,KAAK,EAAE,QAAQ,IAAI,GAAG;AACpB,UAAM,WAAW,OAAO,YAAY,CAAC;AAErC,QAAI,OAAO,WAAY,WAAU;AAEjC,UAAM,KAAK,UAAU,GAAG;AACxB,QAAI,UAAM,uBAAU,SAAS,IAAI,SAAK,uBAAU,SAAS,aAAa,GAAG;AACvE,SAAG,kBAAkB;AAAA,QACnB,MAAM,SAAS;AAAA,QACf,eAAe,SAAS;AAAA,QACxB,OAAI,sBAAS,SAAS,OAAO,IAAI,SAAS,UAAU,CAAC;AAAA,MACvD,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,KAAK,OAAO,EAAE,MAAM,IAAI,GAAG;AACzB,UAAM,KAAK,UAAU,GAAG;AACxB,QAAI,CAAC,GAAI;AAET,OAAG,UAAU,MAAM,UAAM,sBAAS,IAAI,IAAI,OAAO,CAAC,CAAC;AAAA,EACrD;AACF;AAMA,SAAS,UAAU,KAAsC;AA1CzD;AA2CE,UACE,eAAI,WAAJ,mBAAY,OAAZ,YAAmB,OAAO,WAAW,cAAc,OAAO,KAAK;AAEnE;AAEA,SAAS,UAAU,MAAM,YAAY;AACnC,MAAI,OAAO,aAAa,YAAa;AACrC,QAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,SAAO,MAAM;AACb,WAAS,KAAK,YAAY,MAAM;AAClC;AAEA,IAAO,gBAAQ;","names":[]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{isDefined as n,isObject as t}from"@walkeros/core";var o={},e="https://tag.aticdn.net/piano-analytics.js",i={type:"piano",config:{},init({config:o,env:i}){const c=o.settings||{};o.loadScript&&function(n=e){if("undefined"==typeof document)return;const t=document.createElement("script");t.src=n,document.head.appendChild(t)}();const s=a(i);return s&&n(c.site)&&n(c.collectDomain)&&s.setConfigurations({site:c.site,collectDomain:c.collectDomain,...t(c.options)?c.options:{}}),o},push(n,{data:o,env:e}){const i=a(e);i&&i.sendEvent(n.name,t(o)?o:{})}};function a(n){var t,o;return null!=(o=null==(t=n.window)?void 0:t.pa)?o:"undefined"!=typeof window?window.pa:void 0}var c=i;export{o as DestinationPiano,c as default,i as destinationPiano};//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/types/index.ts"],"sourcesContent":["import type { Env, Destination, PianoAnalytics } from './types';\nimport { isDefined, isObject } from '@walkeros/core';\n\n// Types\nexport * as DestinationPiano from './types';\n\nconst SCRIPT_SRC = 'https://tag.aticdn.net/piano-analytics.js';\n\nexport const destinationPiano: Destination = {\n type: 'piano',\n\n config: {},\n\n init({ config, env }) {\n const settings = config.settings || {};\n\n if (config.loadScript) addScript();\n\n const pa = resolvePa(env);\n if (pa && isDefined(settings.site) && isDefined(settings.collectDomain)) {\n pa.setConfigurations({\n site: settings.site,\n collectDomain: settings.collectDomain,\n ...(isObject(settings.options) ? settings.options : {}),\n });\n }\n\n return config;\n },\n\n push(event, { data, env }) {\n const pa = resolvePa(env);\n if (!pa) return;\n\n pa.sendEvent(event.name, isObject(data) ? data : {});\n },\n};\n\n/**\n * Resolve the Piano `pa` SDK without casts: prefer the injected env (tests,\n * simulation), fall back to the browser global declared on `Window`.\n */\nfunction resolvePa(env: Env): PianoAnalytics | undefined {\n return (\n env.window?.pa ?? (typeof window !== 'undefined' ? window.pa : undefined)\n );\n}\n\nfunction addScript(src = SCRIPT_SRC) {\n if (typeof document === 'undefined') return;\n const script = document.createElement('script');\n script.src = src;\n document.head.appendChild(script);\n}\n\nexport default destinationPiano;\n","import type {\n Mapping as WalkerOSMapping,\n WalkerOS,\n Destination as CoreDestination,\n} from '@walkeros/core';\nimport type { DestinationWeb } from '@walkeros/web-core';\n\ndeclare global {\n interface Window {\n pa?: PianoAnalytics;\n }\n}\n\n/**\n * Surface of the official Piano Analytics browser SDK (the `pa` global from\n * https://tag.aticdn.net/piano-analytics.js). Only the methods this\n * destination calls are declared; the SDK exposes more.\n */\nexport interface PianoAnalytics {\n setConfigurations(configurations: WalkerOS.AnyObject): void;\n sendEvent(name: string, data?: WalkerOS.AnyObject): void;\n sendEvents(\n events: ReadonlyArray<{ name: string; data?: WalkerOS.AnyObject }>,\n ): void;\n}\n\nexport interface Settings {\n /** Piano Analytics site id (numeric), from your collection settings. */\n site: number;\n /** Collection domain endpoint, like https://xxxxxxx.pa-cd.com */\n collectDomain: string;\n /** Additional Piano `setConfigurations` options merged on init. */\n options?: WalkerOS.AnyObject;\n}\n\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {}\n\nexport interface Env extends DestinationWeb.Env {\n window?: {\n pa?: PianoAnalytics;\n };\n}\n\nexport type Types = CoreDestination.Types<Settings, Mapping, Env, InitSettings>;\n\nexport type Destination = DestinationWeb.Destination<Types>;\nexport type Config = DestinationWeb.Config<Types>;\n\nexport interface PianoDestination extends Destination {\n env?: Env;\n}\n\nexport type Rule = WalkerOSMapping.Rule<Mapping>;\nexport type Rules = WalkerOSMapping.Rules<Rule>;\n"],"mappings":";AACA,SAAS,WAAW,gBAAgB;;;ACDpC;;;ADMA,IAAM,aAAa;AAEZ,IAAM,mBAAgC;AAAA,EAC3C,MAAM;AAAA,EAEN,QAAQ,CAAC;AAAA,EAET,KAAK,EAAE,QAAQ,IAAI,GAAG;AACpB,UAAM,WAAW,OAAO,YAAY,CAAC;AAErC,QAAI,OAAO,WAAY,WAAU;AAEjC,UAAM,KAAK,UAAU,GAAG;AACxB,QAAI,MAAM,UAAU,SAAS,IAAI,KAAK,UAAU,SAAS,aAAa,GAAG;AACvE,SAAG,kBAAkB;AAAA,QACnB,MAAM,SAAS;AAAA,QACf,eAAe,SAAS;AAAA,QACxB,GAAI,SAAS,SAAS,OAAO,IAAI,SAAS,UAAU,CAAC;AAAA,MACvD,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,KAAK,OAAO,EAAE,MAAM,IAAI,GAAG;AACzB,UAAM,KAAK,UAAU,GAAG;AACxB,QAAI,CAAC,GAAI;AAET,OAAG,UAAU,MAAM,MAAM,SAAS,IAAI,IAAI,OAAO,CAAC,CAAC;AAAA,EACrD;AACF;AAMA,SAAS,UAAU,KAAsC;AA1CzD;AA2CE,UACE,eAAI,WAAJ,mBAAY,OAAZ,YAAmB,OAAO,WAAW,cAAc,OAAO,KAAK;AAEnE;AAEA,SAAS,UAAU,MAAM,YAAY;AACnC,MAAI,OAAO,aAAa,YAAa;AACrC,QAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,SAAO,MAAM;AACb,WAAS,KAAK,YAAY,MAAM;AAClC;AAEA,IAAO,gBAAQ;","names":[]}
|
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$meta": {
|
|
3
|
+
"package": "@walkeros/web-destination-piano",
|
|
4
|
+
"version": "4.1.2",
|
|
5
|
+
"type": "destination",
|
|
6
|
+
"platform": [
|
|
7
|
+
"web"
|
|
8
|
+
],
|
|
9
|
+
"docs": "https://www.walkeros.io/docs/destinations/web/piano",
|
|
10
|
+
"source": "https://github.com/elbwalker/walkerOS/tree/main/packages/web/destinations/piano/src"
|
|
11
|
+
},
|
|
12
|
+
"schemas": {
|
|
13
|
+
"mapping": {
|
|
14
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
15
|
+
"type": "object",
|
|
16
|
+
"properties": {},
|
|
17
|
+
"additionalProperties": false
|
|
18
|
+
},
|
|
19
|
+
"settings": {
|
|
20
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
21
|
+
"type": "object",
|
|
22
|
+
"properties": {
|
|
23
|
+
"site": {
|
|
24
|
+
"type": "number",
|
|
25
|
+
"description": "Piano Analytics site id (numeric), from your collection settings"
|
|
26
|
+
},
|
|
27
|
+
"collectDomain": {
|
|
28
|
+
"type": "string",
|
|
29
|
+
"description": "Collection domain endpoint, like https://xxxxxxx.pa-cd.com"
|
|
30
|
+
},
|
|
31
|
+
"options": {
|
|
32
|
+
"type": "object",
|
|
33
|
+
"propertyNames": {
|
|
34
|
+
"type": "string"
|
|
35
|
+
},
|
|
36
|
+
"additionalProperties": {},
|
|
37
|
+
"description": "Additional Piano setConfigurations options merged on init"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"required": [
|
|
41
|
+
"site",
|
|
42
|
+
"collectDomain"
|
|
43
|
+
],
|
|
44
|
+
"additionalProperties": false
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"examples": {
|
|
48
|
+
"env": {
|
|
49
|
+
"init": {
|
|
50
|
+
"window": {}
|
|
51
|
+
},
|
|
52
|
+
"push": {
|
|
53
|
+
"window": {
|
|
54
|
+
"pa": {
|
|
55
|
+
"setConfigurations": {
|
|
56
|
+
"$code": "()=>{}"
|
|
57
|
+
},
|
|
58
|
+
"sendEvent": {
|
|
59
|
+
"$code": "()=>{}"
|
|
60
|
+
},
|
|
61
|
+
"sendEvents": {
|
|
62
|
+
"$code": "()=>{}"
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
"simulation": [
|
|
68
|
+
"call:window.pa.sendEvent"
|
|
69
|
+
]
|
|
70
|
+
},
|
|
71
|
+
"step": {
|
|
72
|
+
"customEvent": {
|
|
73
|
+
"title": "Custom event",
|
|
74
|
+
"description": "A generic entity action fires a custom Piano event with mapped properties.",
|
|
75
|
+
"in": {
|
|
76
|
+
"name": "entity action",
|
|
77
|
+
"data": {
|
|
78
|
+
"string": "foo",
|
|
79
|
+
"number": 1,
|
|
80
|
+
"boolean": true,
|
|
81
|
+
"array": [
|
|
82
|
+
0,
|
|
83
|
+
"text",
|
|
84
|
+
false
|
|
85
|
+
]
|
|
86
|
+
},
|
|
87
|
+
"context": {
|
|
88
|
+
"dev": [
|
|
89
|
+
"test",
|
|
90
|
+
1
|
|
91
|
+
]
|
|
92
|
+
},
|
|
93
|
+
"globals": {
|
|
94
|
+
"lang": "elb"
|
|
95
|
+
},
|
|
96
|
+
"custom": {
|
|
97
|
+
"completely": "random"
|
|
98
|
+
},
|
|
99
|
+
"user": {
|
|
100
|
+
"id": "us3r",
|
|
101
|
+
"device": "c00k13",
|
|
102
|
+
"session": "s3ss10n"
|
|
103
|
+
},
|
|
104
|
+
"nested": [
|
|
105
|
+
{
|
|
106
|
+
"entity": "child",
|
|
107
|
+
"data": {
|
|
108
|
+
"is": "subordinated"
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
],
|
|
112
|
+
"consent": {
|
|
113
|
+
"functional": true
|
|
114
|
+
},
|
|
115
|
+
"id": "750e6885fc46796b",
|
|
116
|
+
"trigger": "test",
|
|
117
|
+
"entity": "entity",
|
|
118
|
+
"action": "action",
|
|
119
|
+
"timestamp": 1700000202,
|
|
120
|
+
"timing": 3.14,
|
|
121
|
+
"source": {
|
|
122
|
+
"type": "collector",
|
|
123
|
+
"schema": "4"
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
"mapping": {
|
|
127
|
+
"name": "click.action",
|
|
128
|
+
"data": {
|
|
129
|
+
"map": {
|
|
130
|
+
"label": "data.string",
|
|
131
|
+
"value": "data.number"
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
"out": [
|
|
136
|
+
[
|
|
137
|
+
"pa.sendEvent",
|
|
138
|
+
"click.action",
|
|
139
|
+
{
|
|
140
|
+
"label": "foo",
|
|
141
|
+
"value": 1
|
|
142
|
+
}
|
|
143
|
+
]
|
|
144
|
+
]
|
|
145
|
+
},
|
|
146
|
+
"init": {
|
|
147
|
+
"title": "Initialization",
|
|
148
|
+
"description": "Destination bootstrap configures Piano with the site id and collection domain.",
|
|
149
|
+
"in": {
|
|
150
|
+
"settings": {
|
|
151
|
+
"site": 123456789,
|
|
152
|
+
"collectDomain": "https://example.pa-cd.com"
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
"out": [
|
|
156
|
+
[
|
|
157
|
+
"pa.setConfigurations",
|
|
158
|
+
{
|
|
159
|
+
"site": 123456789,
|
|
160
|
+
"collectDomain": "https://example.pa-cd.com"
|
|
161
|
+
}
|
|
162
|
+
]
|
|
163
|
+
]
|
|
164
|
+
},
|
|
165
|
+
"pageView": {
|
|
166
|
+
"title": "Page view",
|
|
167
|
+
"description": "A page view fires a Piano page.display event with the page name and chapter.",
|
|
168
|
+
"in": {
|
|
169
|
+
"name": "page view",
|
|
170
|
+
"data": {
|
|
171
|
+
"domain": "www.example.com",
|
|
172
|
+
"title": "walkerOS documentation",
|
|
173
|
+
"referrer": "https://www.walkeros.io/",
|
|
174
|
+
"search": "?foo=bar",
|
|
175
|
+
"hash": "#hash",
|
|
176
|
+
"id": "/docs/"
|
|
177
|
+
},
|
|
178
|
+
"context": {
|
|
179
|
+
"dev": [
|
|
180
|
+
"test",
|
|
181
|
+
1
|
|
182
|
+
]
|
|
183
|
+
},
|
|
184
|
+
"globals": {
|
|
185
|
+
"pagegroup": "docs"
|
|
186
|
+
},
|
|
187
|
+
"custom": {
|
|
188
|
+
"completely": "random"
|
|
189
|
+
},
|
|
190
|
+
"user": {
|
|
191
|
+
"id": "us3r",
|
|
192
|
+
"device": "c00k13",
|
|
193
|
+
"session": "s3ss10n"
|
|
194
|
+
},
|
|
195
|
+
"nested": [
|
|
196
|
+
{
|
|
197
|
+
"entity": "child",
|
|
198
|
+
"data": {
|
|
199
|
+
"is": "subordinated"
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
],
|
|
203
|
+
"consent": {
|
|
204
|
+
"functional": true
|
|
205
|
+
},
|
|
206
|
+
"id": "946d490d928195d4",
|
|
207
|
+
"trigger": "load",
|
|
208
|
+
"entity": "page",
|
|
209
|
+
"action": "view",
|
|
210
|
+
"timestamp": 1700000200,
|
|
211
|
+
"timing": 3.14,
|
|
212
|
+
"source": {
|
|
213
|
+
"type": "collector",
|
|
214
|
+
"schema": "4"
|
|
215
|
+
}
|
|
216
|
+
},
|
|
217
|
+
"mapping": {
|
|
218
|
+
"name": "page.display",
|
|
219
|
+
"data": {
|
|
220
|
+
"map": {
|
|
221
|
+
"page": "data.title",
|
|
222
|
+
"page_chapter1": "globals.pagegroup"
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
},
|
|
226
|
+
"out": [
|
|
227
|
+
[
|
|
228
|
+
"pa.sendEvent",
|
|
229
|
+
"page.display",
|
|
230
|
+
{
|
|
231
|
+
"page": "walkerOS documentation",
|
|
232
|
+
"page_chapter1": "docs"
|
|
233
|
+
}
|
|
234
|
+
]
|
|
235
|
+
]
|
|
236
|
+
},
|
|
237
|
+
"purchase": {
|
|
238
|
+
"title": "Purchase",
|
|
239
|
+
"description": "A completed order fires a Piano transaction.confirmation event with the transaction id, revenue and currency.",
|
|
240
|
+
"in": {
|
|
241
|
+
"name": "order complete",
|
|
242
|
+
"data": {
|
|
243
|
+
"id": "0rd3r1d",
|
|
244
|
+
"currency": "EUR",
|
|
245
|
+
"shipping": 5.22,
|
|
246
|
+
"taxes": 73.76,
|
|
247
|
+
"total": 555
|
|
248
|
+
},
|
|
249
|
+
"context": {
|
|
250
|
+
"shopping": [
|
|
251
|
+
"complete",
|
|
252
|
+
0
|
|
253
|
+
]
|
|
254
|
+
},
|
|
255
|
+
"globals": {
|
|
256
|
+
"pagegroup": "shop"
|
|
257
|
+
},
|
|
258
|
+
"custom": {
|
|
259
|
+
"completely": "random"
|
|
260
|
+
},
|
|
261
|
+
"user": {
|
|
262
|
+
"id": "us3r",
|
|
263
|
+
"device": "c00k13",
|
|
264
|
+
"session": "s3ss10n"
|
|
265
|
+
},
|
|
266
|
+
"nested": [
|
|
267
|
+
{
|
|
268
|
+
"entity": "product",
|
|
269
|
+
"data": {
|
|
270
|
+
"id": "ers",
|
|
271
|
+
"name": "Everyday Ruck Snack",
|
|
272
|
+
"color": "black",
|
|
273
|
+
"size": "l",
|
|
274
|
+
"price": 420
|
|
275
|
+
},
|
|
276
|
+
"context": {
|
|
277
|
+
"shopping": [
|
|
278
|
+
"complete",
|
|
279
|
+
0
|
|
280
|
+
]
|
|
281
|
+
},
|
|
282
|
+
"nested": []
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
"entity": "product",
|
|
286
|
+
"data": {
|
|
287
|
+
"id": "cc",
|
|
288
|
+
"name": "Cool Cap",
|
|
289
|
+
"size": "one size",
|
|
290
|
+
"price": 42
|
|
291
|
+
},
|
|
292
|
+
"context": {
|
|
293
|
+
"shopping": [
|
|
294
|
+
"complete",
|
|
295
|
+
0
|
|
296
|
+
]
|
|
297
|
+
},
|
|
298
|
+
"nested": []
|
|
299
|
+
},
|
|
300
|
+
{
|
|
301
|
+
"entity": "gift",
|
|
302
|
+
"data": {
|
|
303
|
+
"name": "Surprise"
|
|
304
|
+
},
|
|
305
|
+
"context": {
|
|
306
|
+
"shopping": [
|
|
307
|
+
"complete",
|
|
308
|
+
0
|
|
309
|
+
]
|
|
310
|
+
},
|
|
311
|
+
"nested": []
|
|
312
|
+
}
|
|
313
|
+
],
|
|
314
|
+
"consent": {
|
|
315
|
+
"functional": true
|
|
316
|
+
},
|
|
317
|
+
"id": "11a414bc64df1ebd",
|
|
318
|
+
"trigger": "load",
|
|
319
|
+
"entity": "order",
|
|
320
|
+
"action": "complete",
|
|
321
|
+
"timestamp": 1700000201,
|
|
322
|
+
"timing": 3.14,
|
|
323
|
+
"source": {
|
|
324
|
+
"type": "collector",
|
|
325
|
+
"schema": "4"
|
|
326
|
+
}
|
|
327
|
+
},
|
|
328
|
+
"mapping": {
|
|
329
|
+
"name": "transaction.confirmation",
|
|
330
|
+
"data": {
|
|
331
|
+
"map": {
|
|
332
|
+
"transaction_id": "data.id",
|
|
333
|
+
"revenue": "data.total",
|
|
334
|
+
"currency": "data.currency"
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
},
|
|
338
|
+
"out": [
|
|
339
|
+
[
|
|
340
|
+
"pa.sendEvent",
|
|
341
|
+
"transaction.confirmation",
|
|
342
|
+
{
|
|
343
|
+
"transaction_id": "0rd3r1d",
|
|
344
|
+
"revenue": 555,
|
|
345
|
+
"currency": "EUR"
|
|
346
|
+
}
|
|
347
|
+
]
|
|
348
|
+
]
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|