@hsuite/native-connect-angular 2.1.0 → 2.1.1
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/coverage/coverage-summary.json +25 -21
- package/coverage/index.html +108 -108
- package/coverage/lcov-report/index.html +108 -108
- package/coverage/lcov-report/lib/components/account-selector/account-actions/account-actions.component.ts.html +1 -1
- package/coverage/lcov-report/lib/components/account-selector/account-actions/index.html +1 -1
- package/coverage/lcov-report/lib/components/account-selector/account-filter/account-filter.component.ts.html +1 -1
- package/coverage/lcov-report/lib/components/account-selector/account-filter/index.html +1 -1
- package/coverage/lcov-report/lib/components/account-selector/account-formatting.service.ts.html +13 -19
- package/coverage/lcov-report/lib/components/account-selector/account-grouping.service.ts.html +1 -1
- package/coverage/lcov-report/lib/components/account-selector/account-list/account-list.component.ts.html +1 -1
- package/coverage/lcov-report/lib/components/account-selector/account-list/index.html +1 -1
- package/coverage/lcov-report/lib/components/account-selector/account-selector.component.ts.html +1 -1
- package/coverage/lcov-report/lib/components/account-selector/account-selector.service.ts.html +1 -1
- package/coverage/lcov-report/lib/components/account-selector/index.html +5 -5
- package/coverage/lcov-report/lib/components/wallet-account-display/index.html +1 -1
- package/coverage/lcov-report/lib/components/wallet-account-display/wallet-account-display.component.ts.html +10 -10
- package/coverage/lcov-report/lib/components/wallet-connect-button/index.html +1 -1
- package/coverage/lcov-report/lib/components/wallet-connect-button/wallet-connect-button.component.ts.html +1 -1
- package/coverage/lcov-report/lib/components/wallet-connect-prompt/index.html +1 -1
- package/coverage/lcov-report/lib/components/wallet-connect-prompt/wallet-connect-prompt.component.ts.html +1 -1
- package/coverage/lcov-report/lib/components/wallet-connected-guard/index.html +1 -1
- package/coverage/lcov-report/lib/components/wallet-connected-guard/wallet-connected-guard.component.ts.html +1 -1
- package/coverage/lcov-report/lib/components/wallet-connection-modal/connection-method-step/connection-method-step.component.ts.html +1 -1
- package/coverage/lcov-report/lib/components/wallet-connection-modal/connection-method-step/index.html +1 -1
- package/coverage/lcov-report/lib/components/wallet-connection-modal/index.html +15 -15
- package/coverage/lcov-report/lib/components/wallet-connection-modal/qr-pairing-step/index.html +1 -1
- package/coverage/lcov-report/lib/components/wallet-connection-modal/qr-pairing-step/qr-pairing-step.component.ts.html +1 -1
- package/coverage/lcov-report/lib/components/wallet-connection-modal/wallet-connection-modal.component.ts.html +84 -36
- package/coverage/lcov-report/lib/components/wallet-session-display/index.html +1 -1
- package/coverage/lcov-report/lib/components/wallet-session-display/wallet-session-display.component.ts.html +1 -1
- package/coverage/lcov-report/lib/components/wallet-transaction-status/index.html +1 -1
- package/coverage/lcov-report/lib/components/wallet-transaction-status/wallet-transaction-status.component.ts.html +1 -1
- package/coverage/lcov-report/lib/directives/index.html +1 -1
- package/coverage/lcov-report/lib/directives/wallet-connected.directive.ts.html +1 -1
- package/coverage/lcov-report/lib/directives/wallet-context.directive.ts.html +1 -1
- package/coverage/lcov-report/lib/directives/wallet-events.directive.ts.html +1 -1
- package/coverage/lcov-report/lib/hsuite-wallet.module.ts.html +1 -1
- package/coverage/lcov-report/lib/index.html +1 -1
- package/coverage/lcov-report/lib/models/connection-config.model.ts.html +1 -1
- package/coverage/lcov-report/lib/models/index.html +7 -7
- package/coverage/lcov-report/lib/models/provider-types.ts.html +11 -5
- package/coverage/lcov-report/lib/providers/base-wallet-provider.ts.html +20 -20
- package/coverage/lcov-report/lib/providers/hsuite-native/channel-client.service.ts.html +639 -636
- package/coverage/lcov-report/lib/providers/hsuite-native/index.html +19 -19
- package/coverage/lcov-report/lib/providers/hsuite-native-provider.ts.html +1 -1
- package/coverage/lcov-report/lib/providers/index.html +18 -18
- package/coverage/lcov-report/lib/providers/p2p-native/index.html +22 -22
- package/coverage/lcov-report/lib/providers/p2p-native/p2p-native.provider.ts.html +993 -993
- package/coverage/lcov-report/lib/providers/p2p-native/p2p-session-manager.ts.html +7 -4
- package/coverage/lcov-report/lib/providers/wallet-error-handler.ts.html +1 -1
- package/coverage/lcov-report/lib/providers/walletconnect/core/index.html +65 -65
- package/coverage/lcov-report/lib/providers/walletconnect/core/session-health.ts.html +240 -240
- package/coverage/lcov-report/lib/providers/walletconnect/core/walletconnect-client-manager.ts.html +559 -559
- package/coverage/lcov-report/lib/providers/walletconnect/core/walletconnect-provider.ts.html +1108 -1105
- package/coverage/lcov-report/lib/providers/walletconnect/core/walletconnect-session-store.ts.html +493 -493
- package/coverage/lcov-report/lib/providers/walletconnect/core/walletconnect-signing-orchestrator.ts.html +366 -366
- package/coverage/lcov-report/lib/providers/walletconnect/signers/hedera-signer.ts.html +730 -730
- package/coverage/lcov-report/lib/providers/walletconnect/signers/index.html +43 -43
- package/coverage/lcov-report/lib/providers/walletconnect/signers/signer-factory.ts.html +234 -234
- package/coverage/lcov-report/lib/providers/walletconnect/signers/xrpl-signer.ts.html +650 -650
- package/coverage/lcov-report/lib/services/hsuite-auth.interceptor.ts.html +568 -0
- package/coverage/lcov-report/lib/services/index.html +50 -20
- package/coverage/lcov-report/lib/services/logger.service.ts.html +1 -1
- package/coverage/lcov-report/lib/services/smart-session.service.ts.html +1264 -0
- package/coverage/lcov-report/lib/services/transaction-builders/active-account-source.ts.html +250 -0
- package/coverage/lcov-report/lib/services/transaction-builders/base-transaction-builder.service.ts.html +1 -1
- package/coverage/lcov-report/lib/services/transaction-builders/hedera-amount-utils.ts.html +155 -155
- package/coverage/lcov-report/lib/services/transaction-builders/hedera-transaction-builder.service.ts.html +2156 -2156
- package/coverage/lcov-report/lib/services/transaction-builders/index.html +58 -43
- package/coverage/lcov-report/lib/services/transaction-builders/xrpl-transaction-builder.service.ts.html +1674 -1674
- package/coverage/lcov-report/lib/services/transaction.service.ts.html +4 -4
- package/coverage/lcov-report/lib/services/unified-wallet.service.ts.html +3 -3
- package/coverage/lcov-report/lib/services/wallet-context.service.ts.html +1 -1
- package/coverage/lcov-report/lib/services/wallet-event-bus.service.ts.html +249 -249
- package/coverage/lcov-report/lib/services/wallet-providers.service.ts.html +1 -1
- package/coverage/lcov-report/lib/transports/chrome-extension-transport.ts.html +1 -1
- package/coverage/lcov-report/lib/transports/index.html +1 -1
- package/coverage/lcov-report/lib/utils/index.html +36 -21
- package/coverage/lcov-report/lib/utils/ledger-icons.util.ts.html +254 -161
- package/coverage/lcov-report/lib/utils/ledger-ui-registry.ts.html +676 -0
- package/coverage/lcov.info +8567 -6896
- package/coverage/lib/components/account-selector/account-actions/account-actions.component.ts.html +1 -1
- package/coverage/lib/components/account-selector/account-actions/index.html +1 -1
- package/coverage/lib/components/account-selector/account-filter/account-filter.component.ts.html +1 -1
- package/coverage/lib/components/account-selector/account-filter/index.html +1 -1
- package/coverage/lib/components/account-selector/account-formatting.service.ts.html +13 -19
- package/coverage/lib/components/account-selector/account-grouping.service.ts.html +1 -1
- package/coverage/lib/components/account-selector/account-list/account-list.component.ts.html +1 -1
- package/coverage/lib/components/account-selector/account-list/index.html +1 -1
- package/coverage/lib/components/account-selector/account-selector.component.ts.html +1 -1
- package/coverage/lib/components/account-selector/account-selector.service.ts.html +1 -1
- package/coverage/lib/components/account-selector/index.html +5 -5
- package/coverage/lib/components/wallet-account-display/index.html +1 -1
- package/coverage/lib/components/wallet-account-display/wallet-account-display.component.ts.html +10 -10
- package/coverage/lib/components/wallet-connect-button/index.html +1 -1
- package/coverage/lib/components/wallet-connect-button/wallet-connect-button.component.ts.html +1 -1
- package/coverage/lib/components/wallet-connect-prompt/index.html +1 -1
- package/coverage/lib/components/wallet-connect-prompt/wallet-connect-prompt.component.ts.html +1 -1
- package/coverage/lib/components/wallet-connected-guard/index.html +1 -1
- package/coverage/lib/components/wallet-connected-guard/wallet-connected-guard.component.ts.html +1 -1
- package/coverage/lib/components/wallet-connection-modal/connection-method-step/connection-method-step.component.ts.html +1 -1
- package/coverage/lib/components/wallet-connection-modal/connection-method-step/index.html +1 -1
- package/coverage/lib/components/wallet-connection-modal/index.html +15 -15
- package/coverage/lib/components/wallet-connection-modal/qr-pairing-step/index.html +1 -1
- package/coverage/lib/components/wallet-connection-modal/qr-pairing-step/qr-pairing-step.component.ts.html +1 -1
- package/coverage/lib/components/wallet-connection-modal/wallet-connection-modal.component.ts.html +84 -36
- package/coverage/lib/components/wallet-session-display/index.html +1 -1
- package/coverage/lib/components/wallet-session-display/wallet-session-display.component.ts.html +1 -1
- package/coverage/lib/components/wallet-transaction-status/index.html +1 -1
- package/coverage/lib/components/wallet-transaction-status/wallet-transaction-status.component.ts.html +1 -1
- package/coverage/lib/directives/index.html +1 -1
- package/coverage/lib/directives/wallet-connected.directive.ts.html +1 -1
- package/coverage/lib/directives/wallet-context.directive.ts.html +1 -1
- package/coverage/lib/directives/wallet-events.directive.ts.html +1 -1
- package/coverage/lib/hsuite-wallet.module.ts.html +1 -1
- package/coverage/lib/index.html +1 -1
- package/coverage/lib/models/connection-config.model.ts.html +1 -1
- package/coverage/lib/models/index.html +7 -7
- package/coverage/lib/models/provider-types.ts.html +11 -5
- package/coverage/lib/providers/base-wallet-provider.ts.html +20 -20
- package/coverage/lib/providers/hsuite-native/channel-client.service.ts.html +639 -636
- package/coverage/lib/providers/hsuite-native/index.html +19 -19
- package/coverage/lib/providers/hsuite-native-provider.ts.html +1 -1
- package/coverage/lib/providers/index.html +18 -18
- package/coverage/lib/providers/p2p-native/index.html +22 -22
- package/coverage/lib/providers/p2p-native/p2p-native.provider.ts.html +993 -993
- package/coverage/lib/providers/p2p-native/p2p-session-manager.ts.html +7 -4
- package/coverage/lib/providers/wallet-error-handler.ts.html +1 -1
- package/coverage/lib/providers/walletconnect/core/index.html +65 -65
- package/coverage/lib/providers/walletconnect/core/session-health.ts.html +240 -240
- package/coverage/lib/providers/walletconnect/core/walletconnect-client-manager.ts.html +559 -559
- package/coverage/lib/providers/walletconnect/core/walletconnect-provider.ts.html +1108 -1105
- package/coverage/lib/providers/walletconnect/core/walletconnect-session-store.ts.html +493 -493
- package/coverage/lib/providers/walletconnect/core/walletconnect-signing-orchestrator.ts.html +366 -366
- package/coverage/lib/providers/walletconnect/signers/hedera-signer.ts.html +730 -730
- package/coverage/lib/providers/walletconnect/signers/index.html +43 -43
- package/coverage/lib/providers/walletconnect/signers/signer-factory.ts.html +234 -234
- package/coverage/lib/providers/walletconnect/signers/xrpl-signer.ts.html +650 -650
- package/coverage/lib/services/hsuite-auth.interceptor.ts.html +568 -0
- package/coverage/lib/services/index.html +50 -20
- package/coverage/lib/services/logger.service.ts.html +1 -1
- package/coverage/lib/services/smart-session.service.ts.html +1264 -0
- package/coverage/lib/services/transaction-builders/active-account-source.ts.html +250 -0
- package/coverage/lib/services/transaction-builders/base-transaction-builder.service.ts.html +1 -1
- package/coverage/lib/services/transaction-builders/hedera-amount-utils.ts.html +155 -155
- package/coverage/lib/services/transaction-builders/hedera-transaction-builder.service.ts.html +2156 -2156
- package/coverage/lib/services/transaction-builders/index.html +58 -43
- package/coverage/lib/services/transaction-builders/xrpl-transaction-builder.service.ts.html +1674 -1674
- package/coverage/lib/services/transaction.service.ts.html +4 -4
- package/coverage/lib/services/unified-wallet.service.ts.html +3 -3
- package/coverage/lib/services/wallet-context.service.ts.html +1 -1
- package/coverage/lib/services/wallet-event-bus.service.ts.html +249 -249
- package/coverage/lib/services/wallet-providers.service.ts.html +1 -1
- package/coverage/lib/transports/chrome-extension-transport.ts.html +1 -1
- package/coverage/lib/transports/index.html +1 -1
- package/coverage/lib/utils/index.html +36 -21
- package/coverage/lib/utils/ledger-icons.util.ts.html +254 -161
- package/coverage/lib/utils/ledger-ui-registry.ts.html +676 -0
- package/dist/fesm2022/hsuite-native-connect-angular.mjs +854 -308
- package/dist/fesm2022/hsuite-native-connect-angular.mjs.map +1 -1
- package/dist/index.d.ts +456 -30
- package/package.json +4 -4
- package/src/index.ts +26 -0
- package/src/lib/components/account-selector/account-formatting.service.ts +8 -10
- package/src/lib/components/wallet-account-display/wallet-account-display.component.ts +9 -9
- package/src/lib/components/wallet-connection-modal/wallet-connection-modal.component.ts +34 -18
- package/src/lib/models/provider-types.ts +3 -1
- package/src/lib/models/unified-account.model.ts +4 -1
- package/src/lib/providers/hsuite-native/channel-client.service.ts +1 -0
- package/src/lib/providers/p2p-native/p2p-session-manager.ts +1 -0
- package/src/lib/providers/walletconnect/core/walletconnect-provider.ts +2 -1
- package/src/lib/services/hsuite-auth.interceptor.ts +159 -0
- package/src/lib/services/smart-session.service.ts +378 -0
- package/src/lib/services/transaction-builders/active-account-source.spec.ts +75 -0
- package/src/lib/services/transaction-builders/active-account-source.ts +55 -0
- package/src/lib/services/transaction-builders/hedera-transaction-builder.service.ts +4 -4
- package/src/lib/services/transaction-builders/index.ts +1 -0
- package/src/lib/services/transaction.service.ts +7 -3
- package/src/lib/services/unified-wallet.service.spec.ts +1 -1
- package/src/lib/services/unified-wallet.service.ts +2 -2
- package/src/lib/utils/index.ts +1 -0
- package/src/lib/utils/ledger-icons.util.ts +61 -30
- package/src/lib/utils/ledger-ui-registry.ts +197 -0
|
@@ -0,0 +1,1264 @@
|
|
|
1
|
+
|
|
2
|
+
<!doctype html>
|
|
3
|
+
<html lang="en">
|
|
4
|
+
|
|
5
|
+
<head>
|
|
6
|
+
<title>Code coverage report for lib/services/smart-session.service.ts</title>
|
|
7
|
+
<meta charset="utf-8" />
|
|
8
|
+
<link rel="stylesheet" href="../../prettify.css" />
|
|
9
|
+
<link rel="stylesheet" href="../../base.css" />
|
|
10
|
+
<link rel="shortcut icon" type="image/x-icon" href="../../favicon.png" />
|
|
11
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
12
|
+
<style type='text/css'>
|
|
13
|
+
.coverage-summary .sorter {
|
|
14
|
+
background-image: url(../../sort-arrow-sprite.png);
|
|
15
|
+
}
|
|
16
|
+
</style>
|
|
17
|
+
</head>
|
|
18
|
+
|
|
19
|
+
<body>
|
|
20
|
+
<div class='wrapper'>
|
|
21
|
+
<div class='pad1'>
|
|
22
|
+
<h1><a href="../../index.html">All files</a> / <a href="index.html">lib/services</a> smart-session.service.ts</h1>
|
|
23
|
+
<div class='clearfix'>
|
|
24
|
+
|
|
25
|
+
<div class='fl pad1y space-right2'>
|
|
26
|
+
<span class="strong">0% </span>
|
|
27
|
+
<span class="quiet">Statements</span>
|
|
28
|
+
<span class='fraction'>0/393</span>
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
<div class='fl pad1y space-right2'>
|
|
33
|
+
<span class="strong">0% </span>
|
|
34
|
+
<span class="quiet">Branches</span>
|
|
35
|
+
<span class='fraction'>0/1</span>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
<div class='fl pad1y space-right2'>
|
|
40
|
+
<span class="strong">0% </span>
|
|
41
|
+
<span class="quiet">Functions</span>
|
|
42
|
+
<span class='fraction'>0/1</span>
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
<div class='fl pad1y space-right2'>
|
|
47
|
+
<span class="strong">0% </span>
|
|
48
|
+
<span class="quiet">Lines</span>
|
|
49
|
+
<span class='fraction'>0/393</span>
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
</div>
|
|
54
|
+
<p class="quiet">
|
|
55
|
+
Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
|
|
56
|
+
</p>
|
|
57
|
+
<template id="filterTemplate">
|
|
58
|
+
<div class="quiet">
|
|
59
|
+
Filter:
|
|
60
|
+
<input type="search" id="fileSearch">
|
|
61
|
+
</div>
|
|
62
|
+
</template>
|
|
63
|
+
</div>
|
|
64
|
+
<div class='status-line low'></div>
|
|
65
|
+
<pre><table class="coverage">
|
|
66
|
+
<tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
|
|
67
|
+
<a name='L2'></a><a href='#L2'>2</a>
|
|
68
|
+
<a name='L3'></a><a href='#L3'>3</a>
|
|
69
|
+
<a name='L4'></a><a href='#L4'>4</a>
|
|
70
|
+
<a name='L5'></a><a href='#L5'>5</a>
|
|
71
|
+
<a name='L6'></a><a href='#L6'>6</a>
|
|
72
|
+
<a name='L7'></a><a href='#L7'>7</a>
|
|
73
|
+
<a name='L8'></a><a href='#L8'>8</a>
|
|
74
|
+
<a name='L9'></a><a href='#L9'>9</a>
|
|
75
|
+
<a name='L10'></a><a href='#L10'>10</a>
|
|
76
|
+
<a name='L11'></a><a href='#L11'>11</a>
|
|
77
|
+
<a name='L12'></a><a href='#L12'>12</a>
|
|
78
|
+
<a name='L13'></a><a href='#L13'>13</a>
|
|
79
|
+
<a name='L14'></a><a href='#L14'>14</a>
|
|
80
|
+
<a name='L15'></a><a href='#L15'>15</a>
|
|
81
|
+
<a name='L16'></a><a href='#L16'>16</a>
|
|
82
|
+
<a name='L17'></a><a href='#L17'>17</a>
|
|
83
|
+
<a name='L18'></a><a href='#L18'>18</a>
|
|
84
|
+
<a name='L19'></a><a href='#L19'>19</a>
|
|
85
|
+
<a name='L20'></a><a href='#L20'>20</a>
|
|
86
|
+
<a name='L21'></a><a href='#L21'>21</a>
|
|
87
|
+
<a name='L22'></a><a href='#L22'>22</a>
|
|
88
|
+
<a name='L23'></a><a href='#L23'>23</a>
|
|
89
|
+
<a name='L24'></a><a href='#L24'>24</a>
|
|
90
|
+
<a name='L25'></a><a href='#L25'>25</a>
|
|
91
|
+
<a name='L26'></a><a href='#L26'>26</a>
|
|
92
|
+
<a name='L27'></a><a href='#L27'>27</a>
|
|
93
|
+
<a name='L28'></a><a href='#L28'>28</a>
|
|
94
|
+
<a name='L29'></a><a href='#L29'>29</a>
|
|
95
|
+
<a name='L30'></a><a href='#L30'>30</a>
|
|
96
|
+
<a name='L31'></a><a href='#L31'>31</a>
|
|
97
|
+
<a name='L32'></a><a href='#L32'>32</a>
|
|
98
|
+
<a name='L33'></a><a href='#L33'>33</a>
|
|
99
|
+
<a name='L34'></a><a href='#L34'>34</a>
|
|
100
|
+
<a name='L35'></a><a href='#L35'>35</a>
|
|
101
|
+
<a name='L36'></a><a href='#L36'>36</a>
|
|
102
|
+
<a name='L37'></a><a href='#L37'>37</a>
|
|
103
|
+
<a name='L38'></a><a href='#L38'>38</a>
|
|
104
|
+
<a name='L39'></a><a href='#L39'>39</a>
|
|
105
|
+
<a name='L40'></a><a href='#L40'>40</a>
|
|
106
|
+
<a name='L41'></a><a href='#L41'>41</a>
|
|
107
|
+
<a name='L42'></a><a href='#L42'>42</a>
|
|
108
|
+
<a name='L43'></a><a href='#L43'>43</a>
|
|
109
|
+
<a name='L44'></a><a href='#L44'>44</a>
|
|
110
|
+
<a name='L45'></a><a href='#L45'>45</a>
|
|
111
|
+
<a name='L46'></a><a href='#L46'>46</a>
|
|
112
|
+
<a name='L47'></a><a href='#L47'>47</a>
|
|
113
|
+
<a name='L48'></a><a href='#L48'>48</a>
|
|
114
|
+
<a name='L49'></a><a href='#L49'>49</a>
|
|
115
|
+
<a name='L50'></a><a href='#L50'>50</a>
|
|
116
|
+
<a name='L51'></a><a href='#L51'>51</a>
|
|
117
|
+
<a name='L52'></a><a href='#L52'>52</a>
|
|
118
|
+
<a name='L53'></a><a href='#L53'>53</a>
|
|
119
|
+
<a name='L54'></a><a href='#L54'>54</a>
|
|
120
|
+
<a name='L55'></a><a href='#L55'>55</a>
|
|
121
|
+
<a name='L56'></a><a href='#L56'>56</a>
|
|
122
|
+
<a name='L57'></a><a href='#L57'>57</a>
|
|
123
|
+
<a name='L58'></a><a href='#L58'>58</a>
|
|
124
|
+
<a name='L59'></a><a href='#L59'>59</a>
|
|
125
|
+
<a name='L60'></a><a href='#L60'>60</a>
|
|
126
|
+
<a name='L61'></a><a href='#L61'>61</a>
|
|
127
|
+
<a name='L62'></a><a href='#L62'>62</a>
|
|
128
|
+
<a name='L63'></a><a href='#L63'>63</a>
|
|
129
|
+
<a name='L64'></a><a href='#L64'>64</a>
|
|
130
|
+
<a name='L65'></a><a href='#L65'>65</a>
|
|
131
|
+
<a name='L66'></a><a href='#L66'>66</a>
|
|
132
|
+
<a name='L67'></a><a href='#L67'>67</a>
|
|
133
|
+
<a name='L68'></a><a href='#L68'>68</a>
|
|
134
|
+
<a name='L69'></a><a href='#L69'>69</a>
|
|
135
|
+
<a name='L70'></a><a href='#L70'>70</a>
|
|
136
|
+
<a name='L71'></a><a href='#L71'>71</a>
|
|
137
|
+
<a name='L72'></a><a href='#L72'>72</a>
|
|
138
|
+
<a name='L73'></a><a href='#L73'>73</a>
|
|
139
|
+
<a name='L74'></a><a href='#L74'>74</a>
|
|
140
|
+
<a name='L75'></a><a href='#L75'>75</a>
|
|
141
|
+
<a name='L76'></a><a href='#L76'>76</a>
|
|
142
|
+
<a name='L77'></a><a href='#L77'>77</a>
|
|
143
|
+
<a name='L78'></a><a href='#L78'>78</a>
|
|
144
|
+
<a name='L79'></a><a href='#L79'>79</a>
|
|
145
|
+
<a name='L80'></a><a href='#L80'>80</a>
|
|
146
|
+
<a name='L81'></a><a href='#L81'>81</a>
|
|
147
|
+
<a name='L82'></a><a href='#L82'>82</a>
|
|
148
|
+
<a name='L83'></a><a href='#L83'>83</a>
|
|
149
|
+
<a name='L84'></a><a href='#L84'>84</a>
|
|
150
|
+
<a name='L85'></a><a href='#L85'>85</a>
|
|
151
|
+
<a name='L86'></a><a href='#L86'>86</a>
|
|
152
|
+
<a name='L87'></a><a href='#L87'>87</a>
|
|
153
|
+
<a name='L88'></a><a href='#L88'>88</a>
|
|
154
|
+
<a name='L89'></a><a href='#L89'>89</a>
|
|
155
|
+
<a name='L90'></a><a href='#L90'>90</a>
|
|
156
|
+
<a name='L91'></a><a href='#L91'>91</a>
|
|
157
|
+
<a name='L92'></a><a href='#L92'>92</a>
|
|
158
|
+
<a name='L93'></a><a href='#L93'>93</a>
|
|
159
|
+
<a name='L94'></a><a href='#L94'>94</a>
|
|
160
|
+
<a name='L95'></a><a href='#L95'>95</a>
|
|
161
|
+
<a name='L96'></a><a href='#L96'>96</a>
|
|
162
|
+
<a name='L97'></a><a href='#L97'>97</a>
|
|
163
|
+
<a name='L98'></a><a href='#L98'>98</a>
|
|
164
|
+
<a name='L99'></a><a href='#L99'>99</a>
|
|
165
|
+
<a name='L100'></a><a href='#L100'>100</a>
|
|
166
|
+
<a name='L101'></a><a href='#L101'>101</a>
|
|
167
|
+
<a name='L102'></a><a href='#L102'>102</a>
|
|
168
|
+
<a name='L103'></a><a href='#L103'>103</a>
|
|
169
|
+
<a name='L104'></a><a href='#L104'>104</a>
|
|
170
|
+
<a name='L105'></a><a href='#L105'>105</a>
|
|
171
|
+
<a name='L106'></a><a href='#L106'>106</a>
|
|
172
|
+
<a name='L107'></a><a href='#L107'>107</a>
|
|
173
|
+
<a name='L108'></a><a href='#L108'>108</a>
|
|
174
|
+
<a name='L109'></a><a href='#L109'>109</a>
|
|
175
|
+
<a name='L110'></a><a href='#L110'>110</a>
|
|
176
|
+
<a name='L111'></a><a href='#L111'>111</a>
|
|
177
|
+
<a name='L112'></a><a href='#L112'>112</a>
|
|
178
|
+
<a name='L113'></a><a href='#L113'>113</a>
|
|
179
|
+
<a name='L114'></a><a href='#L114'>114</a>
|
|
180
|
+
<a name='L115'></a><a href='#L115'>115</a>
|
|
181
|
+
<a name='L116'></a><a href='#L116'>116</a>
|
|
182
|
+
<a name='L117'></a><a href='#L117'>117</a>
|
|
183
|
+
<a name='L118'></a><a href='#L118'>118</a>
|
|
184
|
+
<a name='L119'></a><a href='#L119'>119</a>
|
|
185
|
+
<a name='L120'></a><a href='#L120'>120</a>
|
|
186
|
+
<a name='L121'></a><a href='#L121'>121</a>
|
|
187
|
+
<a name='L122'></a><a href='#L122'>122</a>
|
|
188
|
+
<a name='L123'></a><a href='#L123'>123</a>
|
|
189
|
+
<a name='L124'></a><a href='#L124'>124</a>
|
|
190
|
+
<a name='L125'></a><a href='#L125'>125</a>
|
|
191
|
+
<a name='L126'></a><a href='#L126'>126</a>
|
|
192
|
+
<a name='L127'></a><a href='#L127'>127</a>
|
|
193
|
+
<a name='L128'></a><a href='#L128'>128</a>
|
|
194
|
+
<a name='L129'></a><a href='#L129'>129</a>
|
|
195
|
+
<a name='L130'></a><a href='#L130'>130</a>
|
|
196
|
+
<a name='L131'></a><a href='#L131'>131</a>
|
|
197
|
+
<a name='L132'></a><a href='#L132'>132</a>
|
|
198
|
+
<a name='L133'></a><a href='#L133'>133</a>
|
|
199
|
+
<a name='L134'></a><a href='#L134'>134</a>
|
|
200
|
+
<a name='L135'></a><a href='#L135'>135</a>
|
|
201
|
+
<a name='L136'></a><a href='#L136'>136</a>
|
|
202
|
+
<a name='L137'></a><a href='#L137'>137</a>
|
|
203
|
+
<a name='L138'></a><a href='#L138'>138</a>
|
|
204
|
+
<a name='L139'></a><a href='#L139'>139</a>
|
|
205
|
+
<a name='L140'></a><a href='#L140'>140</a>
|
|
206
|
+
<a name='L141'></a><a href='#L141'>141</a>
|
|
207
|
+
<a name='L142'></a><a href='#L142'>142</a>
|
|
208
|
+
<a name='L143'></a><a href='#L143'>143</a>
|
|
209
|
+
<a name='L144'></a><a href='#L144'>144</a>
|
|
210
|
+
<a name='L145'></a><a href='#L145'>145</a>
|
|
211
|
+
<a name='L146'></a><a href='#L146'>146</a>
|
|
212
|
+
<a name='L147'></a><a href='#L147'>147</a>
|
|
213
|
+
<a name='L148'></a><a href='#L148'>148</a>
|
|
214
|
+
<a name='L149'></a><a href='#L149'>149</a>
|
|
215
|
+
<a name='L150'></a><a href='#L150'>150</a>
|
|
216
|
+
<a name='L151'></a><a href='#L151'>151</a>
|
|
217
|
+
<a name='L152'></a><a href='#L152'>152</a>
|
|
218
|
+
<a name='L153'></a><a href='#L153'>153</a>
|
|
219
|
+
<a name='L154'></a><a href='#L154'>154</a>
|
|
220
|
+
<a name='L155'></a><a href='#L155'>155</a>
|
|
221
|
+
<a name='L156'></a><a href='#L156'>156</a>
|
|
222
|
+
<a name='L157'></a><a href='#L157'>157</a>
|
|
223
|
+
<a name='L158'></a><a href='#L158'>158</a>
|
|
224
|
+
<a name='L159'></a><a href='#L159'>159</a>
|
|
225
|
+
<a name='L160'></a><a href='#L160'>160</a>
|
|
226
|
+
<a name='L161'></a><a href='#L161'>161</a>
|
|
227
|
+
<a name='L162'></a><a href='#L162'>162</a>
|
|
228
|
+
<a name='L163'></a><a href='#L163'>163</a>
|
|
229
|
+
<a name='L164'></a><a href='#L164'>164</a>
|
|
230
|
+
<a name='L165'></a><a href='#L165'>165</a>
|
|
231
|
+
<a name='L166'></a><a href='#L166'>166</a>
|
|
232
|
+
<a name='L167'></a><a href='#L167'>167</a>
|
|
233
|
+
<a name='L168'></a><a href='#L168'>168</a>
|
|
234
|
+
<a name='L169'></a><a href='#L169'>169</a>
|
|
235
|
+
<a name='L170'></a><a href='#L170'>170</a>
|
|
236
|
+
<a name='L171'></a><a href='#L171'>171</a>
|
|
237
|
+
<a name='L172'></a><a href='#L172'>172</a>
|
|
238
|
+
<a name='L173'></a><a href='#L173'>173</a>
|
|
239
|
+
<a name='L174'></a><a href='#L174'>174</a>
|
|
240
|
+
<a name='L175'></a><a href='#L175'>175</a>
|
|
241
|
+
<a name='L176'></a><a href='#L176'>176</a>
|
|
242
|
+
<a name='L177'></a><a href='#L177'>177</a>
|
|
243
|
+
<a name='L178'></a><a href='#L178'>178</a>
|
|
244
|
+
<a name='L179'></a><a href='#L179'>179</a>
|
|
245
|
+
<a name='L180'></a><a href='#L180'>180</a>
|
|
246
|
+
<a name='L181'></a><a href='#L181'>181</a>
|
|
247
|
+
<a name='L182'></a><a href='#L182'>182</a>
|
|
248
|
+
<a name='L183'></a><a href='#L183'>183</a>
|
|
249
|
+
<a name='L184'></a><a href='#L184'>184</a>
|
|
250
|
+
<a name='L185'></a><a href='#L185'>185</a>
|
|
251
|
+
<a name='L186'></a><a href='#L186'>186</a>
|
|
252
|
+
<a name='L187'></a><a href='#L187'>187</a>
|
|
253
|
+
<a name='L188'></a><a href='#L188'>188</a>
|
|
254
|
+
<a name='L189'></a><a href='#L189'>189</a>
|
|
255
|
+
<a name='L190'></a><a href='#L190'>190</a>
|
|
256
|
+
<a name='L191'></a><a href='#L191'>191</a>
|
|
257
|
+
<a name='L192'></a><a href='#L192'>192</a>
|
|
258
|
+
<a name='L193'></a><a href='#L193'>193</a>
|
|
259
|
+
<a name='L194'></a><a href='#L194'>194</a>
|
|
260
|
+
<a name='L195'></a><a href='#L195'>195</a>
|
|
261
|
+
<a name='L196'></a><a href='#L196'>196</a>
|
|
262
|
+
<a name='L197'></a><a href='#L197'>197</a>
|
|
263
|
+
<a name='L198'></a><a href='#L198'>198</a>
|
|
264
|
+
<a name='L199'></a><a href='#L199'>199</a>
|
|
265
|
+
<a name='L200'></a><a href='#L200'>200</a>
|
|
266
|
+
<a name='L201'></a><a href='#L201'>201</a>
|
|
267
|
+
<a name='L202'></a><a href='#L202'>202</a>
|
|
268
|
+
<a name='L203'></a><a href='#L203'>203</a>
|
|
269
|
+
<a name='L204'></a><a href='#L204'>204</a>
|
|
270
|
+
<a name='L205'></a><a href='#L205'>205</a>
|
|
271
|
+
<a name='L206'></a><a href='#L206'>206</a>
|
|
272
|
+
<a name='L207'></a><a href='#L207'>207</a>
|
|
273
|
+
<a name='L208'></a><a href='#L208'>208</a>
|
|
274
|
+
<a name='L209'></a><a href='#L209'>209</a>
|
|
275
|
+
<a name='L210'></a><a href='#L210'>210</a>
|
|
276
|
+
<a name='L211'></a><a href='#L211'>211</a>
|
|
277
|
+
<a name='L212'></a><a href='#L212'>212</a>
|
|
278
|
+
<a name='L213'></a><a href='#L213'>213</a>
|
|
279
|
+
<a name='L214'></a><a href='#L214'>214</a>
|
|
280
|
+
<a name='L215'></a><a href='#L215'>215</a>
|
|
281
|
+
<a name='L216'></a><a href='#L216'>216</a>
|
|
282
|
+
<a name='L217'></a><a href='#L217'>217</a>
|
|
283
|
+
<a name='L218'></a><a href='#L218'>218</a>
|
|
284
|
+
<a name='L219'></a><a href='#L219'>219</a>
|
|
285
|
+
<a name='L220'></a><a href='#L220'>220</a>
|
|
286
|
+
<a name='L221'></a><a href='#L221'>221</a>
|
|
287
|
+
<a name='L222'></a><a href='#L222'>222</a>
|
|
288
|
+
<a name='L223'></a><a href='#L223'>223</a>
|
|
289
|
+
<a name='L224'></a><a href='#L224'>224</a>
|
|
290
|
+
<a name='L225'></a><a href='#L225'>225</a>
|
|
291
|
+
<a name='L226'></a><a href='#L226'>226</a>
|
|
292
|
+
<a name='L227'></a><a href='#L227'>227</a>
|
|
293
|
+
<a name='L228'></a><a href='#L228'>228</a>
|
|
294
|
+
<a name='L229'></a><a href='#L229'>229</a>
|
|
295
|
+
<a name='L230'></a><a href='#L230'>230</a>
|
|
296
|
+
<a name='L231'></a><a href='#L231'>231</a>
|
|
297
|
+
<a name='L232'></a><a href='#L232'>232</a>
|
|
298
|
+
<a name='L233'></a><a href='#L233'>233</a>
|
|
299
|
+
<a name='L234'></a><a href='#L234'>234</a>
|
|
300
|
+
<a name='L235'></a><a href='#L235'>235</a>
|
|
301
|
+
<a name='L236'></a><a href='#L236'>236</a>
|
|
302
|
+
<a name='L237'></a><a href='#L237'>237</a>
|
|
303
|
+
<a name='L238'></a><a href='#L238'>238</a>
|
|
304
|
+
<a name='L239'></a><a href='#L239'>239</a>
|
|
305
|
+
<a name='L240'></a><a href='#L240'>240</a>
|
|
306
|
+
<a name='L241'></a><a href='#L241'>241</a>
|
|
307
|
+
<a name='L242'></a><a href='#L242'>242</a>
|
|
308
|
+
<a name='L243'></a><a href='#L243'>243</a>
|
|
309
|
+
<a name='L244'></a><a href='#L244'>244</a>
|
|
310
|
+
<a name='L245'></a><a href='#L245'>245</a>
|
|
311
|
+
<a name='L246'></a><a href='#L246'>246</a>
|
|
312
|
+
<a name='L247'></a><a href='#L247'>247</a>
|
|
313
|
+
<a name='L248'></a><a href='#L248'>248</a>
|
|
314
|
+
<a name='L249'></a><a href='#L249'>249</a>
|
|
315
|
+
<a name='L250'></a><a href='#L250'>250</a>
|
|
316
|
+
<a name='L251'></a><a href='#L251'>251</a>
|
|
317
|
+
<a name='L252'></a><a href='#L252'>252</a>
|
|
318
|
+
<a name='L253'></a><a href='#L253'>253</a>
|
|
319
|
+
<a name='L254'></a><a href='#L254'>254</a>
|
|
320
|
+
<a name='L255'></a><a href='#L255'>255</a>
|
|
321
|
+
<a name='L256'></a><a href='#L256'>256</a>
|
|
322
|
+
<a name='L257'></a><a href='#L257'>257</a>
|
|
323
|
+
<a name='L258'></a><a href='#L258'>258</a>
|
|
324
|
+
<a name='L259'></a><a href='#L259'>259</a>
|
|
325
|
+
<a name='L260'></a><a href='#L260'>260</a>
|
|
326
|
+
<a name='L261'></a><a href='#L261'>261</a>
|
|
327
|
+
<a name='L262'></a><a href='#L262'>262</a>
|
|
328
|
+
<a name='L263'></a><a href='#L263'>263</a>
|
|
329
|
+
<a name='L264'></a><a href='#L264'>264</a>
|
|
330
|
+
<a name='L265'></a><a href='#L265'>265</a>
|
|
331
|
+
<a name='L266'></a><a href='#L266'>266</a>
|
|
332
|
+
<a name='L267'></a><a href='#L267'>267</a>
|
|
333
|
+
<a name='L268'></a><a href='#L268'>268</a>
|
|
334
|
+
<a name='L269'></a><a href='#L269'>269</a>
|
|
335
|
+
<a name='L270'></a><a href='#L270'>270</a>
|
|
336
|
+
<a name='L271'></a><a href='#L271'>271</a>
|
|
337
|
+
<a name='L272'></a><a href='#L272'>272</a>
|
|
338
|
+
<a name='L273'></a><a href='#L273'>273</a>
|
|
339
|
+
<a name='L274'></a><a href='#L274'>274</a>
|
|
340
|
+
<a name='L275'></a><a href='#L275'>275</a>
|
|
341
|
+
<a name='L276'></a><a href='#L276'>276</a>
|
|
342
|
+
<a name='L277'></a><a href='#L277'>277</a>
|
|
343
|
+
<a name='L278'></a><a href='#L278'>278</a>
|
|
344
|
+
<a name='L279'></a><a href='#L279'>279</a>
|
|
345
|
+
<a name='L280'></a><a href='#L280'>280</a>
|
|
346
|
+
<a name='L281'></a><a href='#L281'>281</a>
|
|
347
|
+
<a name='L282'></a><a href='#L282'>282</a>
|
|
348
|
+
<a name='L283'></a><a href='#L283'>283</a>
|
|
349
|
+
<a name='L284'></a><a href='#L284'>284</a>
|
|
350
|
+
<a name='L285'></a><a href='#L285'>285</a>
|
|
351
|
+
<a name='L286'></a><a href='#L286'>286</a>
|
|
352
|
+
<a name='L287'></a><a href='#L287'>287</a>
|
|
353
|
+
<a name='L288'></a><a href='#L288'>288</a>
|
|
354
|
+
<a name='L289'></a><a href='#L289'>289</a>
|
|
355
|
+
<a name='L290'></a><a href='#L290'>290</a>
|
|
356
|
+
<a name='L291'></a><a href='#L291'>291</a>
|
|
357
|
+
<a name='L292'></a><a href='#L292'>292</a>
|
|
358
|
+
<a name='L293'></a><a href='#L293'>293</a>
|
|
359
|
+
<a name='L294'></a><a href='#L294'>294</a>
|
|
360
|
+
<a name='L295'></a><a href='#L295'>295</a>
|
|
361
|
+
<a name='L296'></a><a href='#L296'>296</a>
|
|
362
|
+
<a name='L297'></a><a href='#L297'>297</a>
|
|
363
|
+
<a name='L298'></a><a href='#L298'>298</a>
|
|
364
|
+
<a name='L299'></a><a href='#L299'>299</a>
|
|
365
|
+
<a name='L300'></a><a href='#L300'>300</a>
|
|
366
|
+
<a name='L301'></a><a href='#L301'>301</a>
|
|
367
|
+
<a name='L302'></a><a href='#L302'>302</a>
|
|
368
|
+
<a name='L303'></a><a href='#L303'>303</a>
|
|
369
|
+
<a name='L304'></a><a href='#L304'>304</a>
|
|
370
|
+
<a name='L305'></a><a href='#L305'>305</a>
|
|
371
|
+
<a name='L306'></a><a href='#L306'>306</a>
|
|
372
|
+
<a name='L307'></a><a href='#L307'>307</a>
|
|
373
|
+
<a name='L308'></a><a href='#L308'>308</a>
|
|
374
|
+
<a name='L309'></a><a href='#L309'>309</a>
|
|
375
|
+
<a name='L310'></a><a href='#L310'>310</a>
|
|
376
|
+
<a name='L311'></a><a href='#L311'>311</a>
|
|
377
|
+
<a name='L312'></a><a href='#L312'>312</a>
|
|
378
|
+
<a name='L313'></a><a href='#L313'>313</a>
|
|
379
|
+
<a name='L314'></a><a href='#L314'>314</a>
|
|
380
|
+
<a name='L315'></a><a href='#L315'>315</a>
|
|
381
|
+
<a name='L316'></a><a href='#L316'>316</a>
|
|
382
|
+
<a name='L317'></a><a href='#L317'>317</a>
|
|
383
|
+
<a name='L318'></a><a href='#L318'>318</a>
|
|
384
|
+
<a name='L319'></a><a href='#L319'>319</a>
|
|
385
|
+
<a name='L320'></a><a href='#L320'>320</a>
|
|
386
|
+
<a name='L321'></a><a href='#L321'>321</a>
|
|
387
|
+
<a name='L322'></a><a href='#L322'>322</a>
|
|
388
|
+
<a name='L323'></a><a href='#L323'>323</a>
|
|
389
|
+
<a name='L324'></a><a href='#L324'>324</a>
|
|
390
|
+
<a name='L325'></a><a href='#L325'>325</a>
|
|
391
|
+
<a name='L326'></a><a href='#L326'>326</a>
|
|
392
|
+
<a name='L327'></a><a href='#L327'>327</a>
|
|
393
|
+
<a name='L328'></a><a href='#L328'>328</a>
|
|
394
|
+
<a name='L329'></a><a href='#L329'>329</a>
|
|
395
|
+
<a name='L330'></a><a href='#L330'>330</a>
|
|
396
|
+
<a name='L331'></a><a href='#L331'>331</a>
|
|
397
|
+
<a name='L332'></a><a href='#L332'>332</a>
|
|
398
|
+
<a name='L333'></a><a href='#L333'>333</a>
|
|
399
|
+
<a name='L334'></a><a href='#L334'>334</a>
|
|
400
|
+
<a name='L335'></a><a href='#L335'>335</a>
|
|
401
|
+
<a name='L336'></a><a href='#L336'>336</a>
|
|
402
|
+
<a name='L337'></a><a href='#L337'>337</a>
|
|
403
|
+
<a name='L338'></a><a href='#L338'>338</a>
|
|
404
|
+
<a name='L339'></a><a href='#L339'>339</a>
|
|
405
|
+
<a name='L340'></a><a href='#L340'>340</a>
|
|
406
|
+
<a name='L341'></a><a href='#L341'>341</a>
|
|
407
|
+
<a name='L342'></a><a href='#L342'>342</a>
|
|
408
|
+
<a name='L343'></a><a href='#L343'>343</a>
|
|
409
|
+
<a name='L344'></a><a href='#L344'>344</a>
|
|
410
|
+
<a name='L345'></a><a href='#L345'>345</a>
|
|
411
|
+
<a name='L346'></a><a href='#L346'>346</a>
|
|
412
|
+
<a name='L347'></a><a href='#L347'>347</a>
|
|
413
|
+
<a name='L348'></a><a href='#L348'>348</a>
|
|
414
|
+
<a name='L349'></a><a href='#L349'>349</a>
|
|
415
|
+
<a name='L350'></a><a href='#L350'>350</a>
|
|
416
|
+
<a name='L351'></a><a href='#L351'>351</a>
|
|
417
|
+
<a name='L352'></a><a href='#L352'>352</a>
|
|
418
|
+
<a name='L353'></a><a href='#L353'>353</a>
|
|
419
|
+
<a name='L354'></a><a href='#L354'>354</a>
|
|
420
|
+
<a name='L355'></a><a href='#L355'>355</a>
|
|
421
|
+
<a name='L356'></a><a href='#L356'>356</a>
|
|
422
|
+
<a name='L357'></a><a href='#L357'>357</a>
|
|
423
|
+
<a name='L358'></a><a href='#L358'>358</a>
|
|
424
|
+
<a name='L359'></a><a href='#L359'>359</a>
|
|
425
|
+
<a name='L360'></a><a href='#L360'>360</a>
|
|
426
|
+
<a name='L361'></a><a href='#L361'>361</a>
|
|
427
|
+
<a name='L362'></a><a href='#L362'>362</a>
|
|
428
|
+
<a name='L363'></a><a href='#L363'>363</a>
|
|
429
|
+
<a name='L364'></a><a href='#L364'>364</a>
|
|
430
|
+
<a name='L365'></a><a href='#L365'>365</a>
|
|
431
|
+
<a name='L366'></a><a href='#L366'>366</a>
|
|
432
|
+
<a name='L367'></a><a href='#L367'>367</a>
|
|
433
|
+
<a name='L368'></a><a href='#L368'>368</a>
|
|
434
|
+
<a name='L369'></a><a href='#L369'>369</a>
|
|
435
|
+
<a name='L370'></a><a href='#L370'>370</a>
|
|
436
|
+
<a name='L371'></a><a href='#L371'>371</a>
|
|
437
|
+
<a name='L372'></a><a href='#L372'>372</a>
|
|
438
|
+
<a name='L373'></a><a href='#L373'>373</a>
|
|
439
|
+
<a name='L374'></a><a href='#L374'>374</a>
|
|
440
|
+
<a name='L375'></a><a href='#L375'>375</a>
|
|
441
|
+
<a name='L376'></a><a href='#L376'>376</a>
|
|
442
|
+
<a name='L377'></a><a href='#L377'>377</a>
|
|
443
|
+
<a name='L378'></a><a href='#L378'>378</a>
|
|
444
|
+
<a name='L379'></a><a href='#L379'>379</a>
|
|
445
|
+
<a name='L380'></a><a href='#L380'>380</a>
|
|
446
|
+
<a name='L381'></a><a href='#L381'>381</a>
|
|
447
|
+
<a name='L382'></a><a href='#L382'>382</a>
|
|
448
|
+
<a name='L383'></a><a href='#L383'>383</a>
|
|
449
|
+
<a name='L384'></a><a href='#L384'>384</a>
|
|
450
|
+
<a name='L385'></a><a href='#L385'>385</a>
|
|
451
|
+
<a name='L386'></a><a href='#L386'>386</a>
|
|
452
|
+
<a name='L387'></a><a href='#L387'>387</a>
|
|
453
|
+
<a name='L388'></a><a href='#L388'>388</a>
|
|
454
|
+
<a name='L389'></a><a href='#L389'>389</a>
|
|
455
|
+
<a name='L390'></a><a href='#L390'>390</a>
|
|
456
|
+
<a name='L391'></a><a href='#L391'>391</a>
|
|
457
|
+
<a name='L392'></a><a href='#L392'>392</a>
|
|
458
|
+
<a name='L393'></a><a href='#L393'>393</a>
|
|
459
|
+
<a name='L394'></a><a href='#L394'>394</a></td><td class="line-coverage quiet"><span class="cline-any cline-no"> </span>
|
|
460
|
+
<span class="cline-any cline-no"> </span>
|
|
461
|
+
<span class="cline-any cline-no"> </span>
|
|
462
|
+
<span class="cline-any cline-no"> </span>
|
|
463
|
+
<span class="cline-any cline-no"> </span>
|
|
464
|
+
<span class="cline-any cline-no"> </span>
|
|
465
|
+
<span class="cline-any cline-no"> </span>
|
|
466
|
+
<span class="cline-any cline-no"> </span>
|
|
467
|
+
<span class="cline-any cline-no"> </span>
|
|
468
|
+
<span class="cline-any cline-no"> </span>
|
|
469
|
+
<span class="cline-any cline-no"> </span>
|
|
470
|
+
<span class="cline-any cline-no"> </span>
|
|
471
|
+
<span class="cline-any cline-no"> </span>
|
|
472
|
+
<span class="cline-any cline-no"> </span>
|
|
473
|
+
<span class="cline-any cline-no"> </span>
|
|
474
|
+
<span class="cline-any cline-no"> </span>
|
|
475
|
+
<span class="cline-any cline-no"> </span>
|
|
476
|
+
<span class="cline-any cline-no"> </span>
|
|
477
|
+
<span class="cline-any cline-no"> </span>
|
|
478
|
+
<span class="cline-any cline-no"> </span>
|
|
479
|
+
<span class="cline-any cline-no"> </span>
|
|
480
|
+
<span class="cline-any cline-no"> </span>
|
|
481
|
+
<span class="cline-any cline-no"> </span>
|
|
482
|
+
<span class="cline-any cline-no"> </span>
|
|
483
|
+
<span class="cline-any cline-no"> </span>
|
|
484
|
+
<span class="cline-any cline-no"> </span>
|
|
485
|
+
<span class="cline-any cline-no"> </span>
|
|
486
|
+
<span class="cline-any cline-no"> </span>
|
|
487
|
+
<span class="cline-any cline-no"> </span>
|
|
488
|
+
<span class="cline-any cline-no"> </span>
|
|
489
|
+
<span class="cline-any cline-no"> </span>
|
|
490
|
+
<span class="cline-any cline-no"> </span>
|
|
491
|
+
<span class="cline-any cline-no"> </span>
|
|
492
|
+
<span class="cline-any cline-no"> </span>
|
|
493
|
+
<span class="cline-any cline-no"> </span>
|
|
494
|
+
<span class="cline-any cline-no"> </span>
|
|
495
|
+
<span class="cline-any cline-no"> </span>
|
|
496
|
+
<span class="cline-any cline-no"> </span>
|
|
497
|
+
<span class="cline-any cline-no"> </span>
|
|
498
|
+
<span class="cline-any cline-no"> </span>
|
|
499
|
+
<span class="cline-any cline-no"> </span>
|
|
500
|
+
<span class="cline-any cline-no"> </span>
|
|
501
|
+
<span class="cline-any cline-no"> </span>
|
|
502
|
+
<span class="cline-any cline-no"> </span>
|
|
503
|
+
<span class="cline-any cline-no"> </span>
|
|
504
|
+
<span class="cline-any cline-no"> </span>
|
|
505
|
+
<span class="cline-any cline-no"> </span>
|
|
506
|
+
<span class="cline-any cline-no"> </span>
|
|
507
|
+
<span class="cline-any cline-no"> </span>
|
|
508
|
+
<span class="cline-any cline-no"> </span>
|
|
509
|
+
<span class="cline-any cline-no"> </span>
|
|
510
|
+
<span class="cline-any cline-no"> </span>
|
|
511
|
+
<span class="cline-any cline-no"> </span>
|
|
512
|
+
<span class="cline-any cline-no"> </span>
|
|
513
|
+
<span class="cline-any cline-no"> </span>
|
|
514
|
+
<span class="cline-any cline-no"> </span>
|
|
515
|
+
<span class="cline-any cline-no"> </span>
|
|
516
|
+
<span class="cline-any cline-no"> </span>
|
|
517
|
+
<span class="cline-any cline-no"> </span>
|
|
518
|
+
<span class="cline-any cline-no"> </span>
|
|
519
|
+
<span class="cline-any cline-no"> </span>
|
|
520
|
+
<span class="cline-any cline-no"> </span>
|
|
521
|
+
<span class="cline-any cline-no"> </span>
|
|
522
|
+
<span class="cline-any cline-no"> </span>
|
|
523
|
+
<span class="cline-any cline-no"> </span>
|
|
524
|
+
<span class="cline-any cline-no"> </span>
|
|
525
|
+
<span class="cline-any cline-no"> </span>
|
|
526
|
+
<span class="cline-any cline-no"> </span>
|
|
527
|
+
<span class="cline-any cline-no"> </span>
|
|
528
|
+
<span class="cline-any cline-no"> </span>
|
|
529
|
+
<span class="cline-any cline-no"> </span>
|
|
530
|
+
<span class="cline-any cline-no"> </span>
|
|
531
|
+
<span class="cline-any cline-no"> </span>
|
|
532
|
+
<span class="cline-any cline-no"> </span>
|
|
533
|
+
<span class="cline-any cline-no"> </span>
|
|
534
|
+
<span class="cline-any cline-no"> </span>
|
|
535
|
+
<span class="cline-any cline-no"> </span>
|
|
536
|
+
<span class="cline-any cline-no"> </span>
|
|
537
|
+
<span class="cline-any cline-no"> </span>
|
|
538
|
+
<span class="cline-any cline-no"> </span>
|
|
539
|
+
<span class="cline-any cline-no"> </span>
|
|
540
|
+
<span class="cline-any cline-no"> </span>
|
|
541
|
+
<span class="cline-any cline-no"> </span>
|
|
542
|
+
<span class="cline-any cline-no"> </span>
|
|
543
|
+
<span class="cline-any cline-no"> </span>
|
|
544
|
+
<span class="cline-any cline-no"> </span>
|
|
545
|
+
<span class="cline-any cline-no"> </span>
|
|
546
|
+
<span class="cline-any cline-no"> </span>
|
|
547
|
+
<span class="cline-any cline-no"> </span>
|
|
548
|
+
<span class="cline-any cline-no"> </span>
|
|
549
|
+
<span class="cline-any cline-no"> </span>
|
|
550
|
+
<span class="cline-any cline-no"> </span>
|
|
551
|
+
<span class="cline-any cline-no"> </span>
|
|
552
|
+
<span class="cline-any cline-no"> </span>
|
|
553
|
+
<span class="cline-any cline-no"> </span>
|
|
554
|
+
<span class="cline-any cline-no"> </span>
|
|
555
|
+
<span class="cline-any cline-no"> </span>
|
|
556
|
+
<span class="cline-any cline-no"> </span>
|
|
557
|
+
<span class="cline-any cline-no"> </span>
|
|
558
|
+
<span class="cline-any cline-no"> </span>
|
|
559
|
+
<span class="cline-any cline-no"> </span>
|
|
560
|
+
<span class="cline-any cline-no"> </span>
|
|
561
|
+
<span class="cline-any cline-no"> </span>
|
|
562
|
+
<span class="cline-any cline-no"> </span>
|
|
563
|
+
<span class="cline-any cline-no"> </span>
|
|
564
|
+
<span class="cline-any cline-no"> </span>
|
|
565
|
+
<span class="cline-any cline-no"> </span>
|
|
566
|
+
<span class="cline-any cline-no"> </span>
|
|
567
|
+
<span class="cline-any cline-no"> </span>
|
|
568
|
+
<span class="cline-any cline-no"> </span>
|
|
569
|
+
<span class="cline-any cline-no"> </span>
|
|
570
|
+
<span class="cline-any cline-no"> </span>
|
|
571
|
+
<span class="cline-any cline-no"> </span>
|
|
572
|
+
<span class="cline-any cline-no"> </span>
|
|
573
|
+
<span class="cline-any cline-no"> </span>
|
|
574
|
+
<span class="cline-any cline-no"> </span>
|
|
575
|
+
<span class="cline-any cline-no"> </span>
|
|
576
|
+
<span class="cline-any cline-no"> </span>
|
|
577
|
+
<span class="cline-any cline-no"> </span>
|
|
578
|
+
<span class="cline-any cline-no"> </span>
|
|
579
|
+
<span class="cline-any cline-no"> </span>
|
|
580
|
+
<span class="cline-any cline-no"> </span>
|
|
581
|
+
<span class="cline-any cline-no"> </span>
|
|
582
|
+
<span class="cline-any cline-no"> </span>
|
|
583
|
+
<span class="cline-any cline-no"> </span>
|
|
584
|
+
<span class="cline-any cline-no"> </span>
|
|
585
|
+
<span class="cline-any cline-no"> </span>
|
|
586
|
+
<span class="cline-any cline-no"> </span>
|
|
587
|
+
<span class="cline-any cline-no"> </span>
|
|
588
|
+
<span class="cline-any cline-no"> </span>
|
|
589
|
+
<span class="cline-any cline-no"> </span>
|
|
590
|
+
<span class="cline-any cline-no"> </span>
|
|
591
|
+
<span class="cline-any cline-no"> </span>
|
|
592
|
+
<span class="cline-any cline-no"> </span>
|
|
593
|
+
<span class="cline-any cline-no"> </span>
|
|
594
|
+
<span class="cline-any cline-no"> </span>
|
|
595
|
+
<span class="cline-any cline-no"> </span>
|
|
596
|
+
<span class="cline-any cline-no"> </span>
|
|
597
|
+
<span class="cline-any cline-no"> </span>
|
|
598
|
+
<span class="cline-any cline-no"> </span>
|
|
599
|
+
<span class="cline-any cline-no"> </span>
|
|
600
|
+
<span class="cline-any cline-no"> </span>
|
|
601
|
+
<span class="cline-any cline-no"> </span>
|
|
602
|
+
<span class="cline-any cline-no"> </span>
|
|
603
|
+
<span class="cline-any cline-no"> </span>
|
|
604
|
+
<span class="cline-any cline-no"> </span>
|
|
605
|
+
<span class="cline-any cline-no"> </span>
|
|
606
|
+
<span class="cline-any cline-no"> </span>
|
|
607
|
+
<span class="cline-any cline-no"> </span>
|
|
608
|
+
<span class="cline-any cline-no"> </span>
|
|
609
|
+
<span class="cline-any cline-no"> </span>
|
|
610
|
+
<span class="cline-any cline-no"> </span>
|
|
611
|
+
<span class="cline-any cline-no"> </span>
|
|
612
|
+
<span class="cline-any cline-no"> </span>
|
|
613
|
+
<span class="cline-any cline-no"> </span>
|
|
614
|
+
<span class="cline-any cline-no"> </span>
|
|
615
|
+
<span class="cline-any cline-no"> </span>
|
|
616
|
+
<span class="cline-any cline-no"> </span>
|
|
617
|
+
<span class="cline-any cline-no"> </span>
|
|
618
|
+
<span class="cline-any cline-no"> </span>
|
|
619
|
+
<span class="cline-any cline-no"> </span>
|
|
620
|
+
<span class="cline-any cline-no"> </span>
|
|
621
|
+
<span class="cline-any cline-no"> </span>
|
|
622
|
+
<span class="cline-any cline-no"> </span>
|
|
623
|
+
<span class="cline-any cline-no"> </span>
|
|
624
|
+
<span class="cline-any cline-no"> </span>
|
|
625
|
+
<span class="cline-any cline-no"> </span>
|
|
626
|
+
<span class="cline-any cline-no"> </span>
|
|
627
|
+
<span class="cline-any cline-no"> </span>
|
|
628
|
+
<span class="cline-any cline-no"> </span>
|
|
629
|
+
<span class="cline-any cline-no"> </span>
|
|
630
|
+
<span class="cline-any cline-no"> </span>
|
|
631
|
+
<span class="cline-any cline-no"> </span>
|
|
632
|
+
<span class="cline-any cline-no"> </span>
|
|
633
|
+
<span class="cline-any cline-no"> </span>
|
|
634
|
+
<span class="cline-any cline-no"> </span>
|
|
635
|
+
<span class="cline-any cline-no"> </span>
|
|
636
|
+
<span class="cline-any cline-no"> </span>
|
|
637
|
+
<span class="cline-any cline-no"> </span>
|
|
638
|
+
<span class="cline-any cline-no"> </span>
|
|
639
|
+
<span class="cline-any cline-no"> </span>
|
|
640
|
+
<span class="cline-any cline-no"> </span>
|
|
641
|
+
<span class="cline-any cline-no"> </span>
|
|
642
|
+
<span class="cline-any cline-no"> </span>
|
|
643
|
+
<span class="cline-any cline-no"> </span>
|
|
644
|
+
<span class="cline-any cline-no"> </span>
|
|
645
|
+
<span class="cline-any cline-no"> </span>
|
|
646
|
+
<span class="cline-any cline-no"> </span>
|
|
647
|
+
<span class="cline-any cline-no"> </span>
|
|
648
|
+
<span class="cline-any cline-no"> </span>
|
|
649
|
+
<span class="cline-any cline-no"> </span>
|
|
650
|
+
<span class="cline-any cline-no"> </span>
|
|
651
|
+
<span class="cline-any cline-no"> </span>
|
|
652
|
+
<span class="cline-any cline-no"> </span>
|
|
653
|
+
<span class="cline-any cline-no"> </span>
|
|
654
|
+
<span class="cline-any cline-no"> </span>
|
|
655
|
+
<span class="cline-any cline-no"> </span>
|
|
656
|
+
<span class="cline-any cline-no"> </span>
|
|
657
|
+
<span class="cline-any cline-no"> </span>
|
|
658
|
+
<span class="cline-any cline-no"> </span>
|
|
659
|
+
<span class="cline-any cline-no"> </span>
|
|
660
|
+
<span class="cline-any cline-no"> </span>
|
|
661
|
+
<span class="cline-any cline-no"> </span>
|
|
662
|
+
<span class="cline-any cline-no"> </span>
|
|
663
|
+
<span class="cline-any cline-no"> </span>
|
|
664
|
+
<span class="cline-any cline-no"> </span>
|
|
665
|
+
<span class="cline-any cline-no"> </span>
|
|
666
|
+
<span class="cline-any cline-no"> </span>
|
|
667
|
+
<span class="cline-any cline-no"> </span>
|
|
668
|
+
<span class="cline-any cline-no"> </span>
|
|
669
|
+
<span class="cline-any cline-no"> </span>
|
|
670
|
+
<span class="cline-any cline-no"> </span>
|
|
671
|
+
<span class="cline-any cline-no"> </span>
|
|
672
|
+
<span class="cline-any cline-no"> </span>
|
|
673
|
+
<span class="cline-any cline-no"> </span>
|
|
674
|
+
<span class="cline-any cline-no"> </span>
|
|
675
|
+
<span class="cline-any cline-no"> </span>
|
|
676
|
+
<span class="cline-any cline-no"> </span>
|
|
677
|
+
<span class="cline-any cline-no"> </span>
|
|
678
|
+
<span class="cline-any cline-no"> </span>
|
|
679
|
+
<span class="cline-any cline-no"> </span>
|
|
680
|
+
<span class="cline-any cline-no"> </span>
|
|
681
|
+
<span class="cline-any cline-no"> </span>
|
|
682
|
+
<span class="cline-any cline-no"> </span>
|
|
683
|
+
<span class="cline-any cline-no"> </span>
|
|
684
|
+
<span class="cline-any cline-no"> </span>
|
|
685
|
+
<span class="cline-any cline-no"> </span>
|
|
686
|
+
<span class="cline-any cline-no"> </span>
|
|
687
|
+
<span class="cline-any cline-no"> </span>
|
|
688
|
+
<span class="cline-any cline-no"> </span>
|
|
689
|
+
<span class="cline-any cline-no"> </span>
|
|
690
|
+
<span class="cline-any cline-no"> </span>
|
|
691
|
+
<span class="cline-any cline-no"> </span>
|
|
692
|
+
<span class="cline-any cline-no"> </span>
|
|
693
|
+
<span class="cline-any cline-no"> </span>
|
|
694
|
+
<span class="cline-any cline-no"> </span>
|
|
695
|
+
<span class="cline-any cline-no"> </span>
|
|
696
|
+
<span class="cline-any cline-no"> </span>
|
|
697
|
+
<span class="cline-any cline-no"> </span>
|
|
698
|
+
<span class="cline-any cline-no"> </span>
|
|
699
|
+
<span class="cline-any cline-no"> </span>
|
|
700
|
+
<span class="cline-any cline-no"> </span>
|
|
701
|
+
<span class="cline-any cline-no"> </span>
|
|
702
|
+
<span class="cline-any cline-no"> </span>
|
|
703
|
+
<span class="cline-any cline-no"> </span>
|
|
704
|
+
<span class="cline-any cline-no"> </span>
|
|
705
|
+
<span class="cline-any cline-no"> </span>
|
|
706
|
+
<span class="cline-any cline-no"> </span>
|
|
707
|
+
<span class="cline-any cline-no"> </span>
|
|
708
|
+
<span class="cline-any cline-no"> </span>
|
|
709
|
+
<span class="cline-any cline-no"> </span>
|
|
710
|
+
<span class="cline-any cline-no"> </span>
|
|
711
|
+
<span class="cline-any cline-no"> </span>
|
|
712
|
+
<span class="cline-any cline-no"> </span>
|
|
713
|
+
<span class="cline-any cline-no"> </span>
|
|
714
|
+
<span class="cline-any cline-no"> </span>
|
|
715
|
+
<span class="cline-any cline-no"> </span>
|
|
716
|
+
<span class="cline-any cline-no"> </span>
|
|
717
|
+
<span class="cline-any cline-no"> </span>
|
|
718
|
+
<span class="cline-any cline-no"> </span>
|
|
719
|
+
<span class="cline-any cline-no"> </span>
|
|
720
|
+
<span class="cline-any cline-no"> </span>
|
|
721
|
+
<span class="cline-any cline-no"> </span>
|
|
722
|
+
<span class="cline-any cline-no"> </span>
|
|
723
|
+
<span class="cline-any cline-no"> </span>
|
|
724
|
+
<span class="cline-any cline-no"> </span>
|
|
725
|
+
<span class="cline-any cline-no"> </span>
|
|
726
|
+
<span class="cline-any cline-no"> </span>
|
|
727
|
+
<span class="cline-any cline-no"> </span>
|
|
728
|
+
<span class="cline-any cline-no"> </span>
|
|
729
|
+
<span class="cline-any cline-no"> </span>
|
|
730
|
+
<span class="cline-any cline-no"> </span>
|
|
731
|
+
<span class="cline-any cline-no"> </span>
|
|
732
|
+
<span class="cline-any cline-no"> </span>
|
|
733
|
+
<span class="cline-any cline-no"> </span>
|
|
734
|
+
<span class="cline-any cline-no"> </span>
|
|
735
|
+
<span class="cline-any cline-no"> </span>
|
|
736
|
+
<span class="cline-any cline-no"> </span>
|
|
737
|
+
<span class="cline-any cline-no"> </span>
|
|
738
|
+
<span class="cline-any cline-no"> </span>
|
|
739
|
+
<span class="cline-any cline-no"> </span>
|
|
740
|
+
<span class="cline-any cline-no"> </span>
|
|
741
|
+
<span class="cline-any cline-no"> </span>
|
|
742
|
+
<span class="cline-any cline-no"> </span>
|
|
743
|
+
<span class="cline-any cline-no"> </span>
|
|
744
|
+
<span class="cline-any cline-no"> </span>
|
|
745
|
+
<span class="cline-any cline-no"> </span>
|
|
746
|
+
<span class="cline-any cline-no"> </span>
|
|
747
|
+
<span class="cline-any cline-no"> </span>
|
|
748
|
+
<span class="cline-any cline-no"> </span>
|
|
749
|
+
<span class="cline-any cline-no"> </span>
|
|
750
|
+
<span class="cline-any cline-no"> </span>
|
|
751
|
+
<span class="cline-any cline-no"> </span>
|
|
752
|
+
<span class="cline-any cline-no"> </span>
|
|
753
|
+
<span class="cline-any cline-no"> </span>
|
|
754
|
+
<span class="cline-any cline-no"> </span>
|
|
755
|
+
<span class="cline-any cline-no"> </span>
|
|
756
|
+
<span class="cline-any cline-no"> </span>
|
|
757
|
+
<span class="cline-any cline-no"> </span>
|
|
758
|
+
<span class="cline-any cline-no"> </span>
|
|
759
|
+
<span class="cline-any cline-no"> </span>
|
|
760
|
+
<span class="cline-any cline-no"> </span>
|
|
761
|
+
<span class="cline-any cline-no"> </span>
|
|
762
|
+
<span class="cline-any cline-no"> </span>
|
|
763
|
+
<span class="cline-any cline-no"> </span>
|
|
764
|
+
<span class="cline-any cline-no"> </span>
|
|
765
|
+
<span class="cline-any cline-no"> </span>
|
|
766
|
+
<span class="cline-any cline-no"> </span>
|
|
767
|
+
<span class="cline-any cline-no"> </span>
|
|
768
|
+
<span class="cline-any cline-no"> </span>
|
|
769
|
+
<span class="cline-any cline-no"> </span>
|
|
770
|
+
<span class="cline-any cline-no"> </span>
|
|
771
|
+
<span class="cline-any cline-no"> </span>
|
|
772
|
+
<span class="cline-any cline-no"> </span>
|
|
773
|
+
<span class="cline-any cline-no"> </span>
|
|
774
|
+
<span class="cline-any cline-no"> </span>
|
|
775
|
+
<span class="cline-any cline-no"> </span>
|
|
776
|
+
<span class="cline-any cline-no"> </span>
|
|
777
|
+
<span class="cline-any cline-no"> </span>
|
|
778
|
+
<span class="cline-any cline-no"> </span>
|
|
779
|
+
<span class="cline-any cline-no"> </span>
|
|
780
|
+
<span class="cline-any cline-no"> </span>
|
|
781
|
+
<span class="cline-any cline-no"> </span>
|
|
782
|
+
<span class="cline-any cline-no"> </span>
|
|
783
|
+
<span class="cline-any cline-no"> </span>
|
|
784
|
+
<span class="cline-any cline-no"> </span>
|
|
785
|
+
<span class="cline-any cline-no"> </span>
|
|
786
|
+
<span class="cline-any cline-no"> </span>
|
|
787
|
+
<span class="cline-any cline-no"> </span>
|
|
788
|
+
<span class="cline-any cline-no"> </span>
|
|
789
|
+
<span class="cline-any cline-no"> </span>
|
|
790
|
+
<span class="cline-any cline-no"> </span>
|
|
791
|
+
<span class="cline-any cline-no"> </span>
|
|
792
|
+
<span class="cline-any cline-no"> </span>
|
|
793
|
+
<span class="cline-any cline-no"> </span>
|
|
794
|
+
<span class="cline-any cline-no"> </span>
|
|
795
|
+
<span class="cline-any cline-no"> </span>
|
|
796
|
+
<span class="cline-any cline-no"> </span>
|
|
797
|
+
<span class="cline-any cline-no"> </span>
|
|
798
|
+
<span class="cline-any cline-no"> </span>
|
|
799
|
+
<span class="cline-any cline-no"> </span>
|
|
800
|
+
<span class="cline-any cline-no"> </span>
|
|
801
|
+
<span class="cline-any cline-no"> </span>
|
|
802
|
+
<span class="cline-any cline-no"> </span>
|
|
803
|
+
<span class="cline-any cline-no"> </span>
|
|
804
|
+
<span class="cline-any cline-no"> </span>
|
|
805
|
+
<span class="cline-any cline-no"> </span>
|
|
806
|
+
<span class="cline-any cline-no"> </span>
|
|
807
|
+
<span class="cline-any cline-no"> </span>
|
|
808
|
+
<span class="cline-any cline-no"> </span>
|
|
809
|
+
<span class="cline-any cline-no"> </span>
|
|
810
|
+
<span class="cline-any cline-no"> </span>
|
|
811
|
+
<span class="cline-any cline-no"> </span>
|
|
812
|
+
<span class="cline-any cline-no"> </span>
|
|
813
|
+
<span class="cline-any cline-no"> </span>
|
|
814
|
+
<span class="cline-any cline-no"> </span>
|
|
815
|
+
<span class="cline-any cline-no"> </span>
|
|
816
|
+
<span class="cline-any cline-no"> </span>
|
|
817
|
+
<span class="cline-any cline-no"> </span>
|
|
818
|
+
<span class="cline-any cline-no"> </span>
|
|
819
|
+
<span class="cline-any cline-no"> </span>
|
|
820
|
+
<span class="cline-any cline-no"> </span>
|
|
821
|
+
<span class="cline-any cline-no"> </span>
|
|
822
|
+
<span class="cline-any cline-no"> </span>
|
|
823
|
+
<span class="cline-any cline-no"> </span>
|
|
824
|
+
<span class="cline-any cline-no"> </span>
|
|
825
|
+
<span class="cline-any cline-no"> </span>
|
|
826
|
+
<span class="cline-any cline-no"> </span>
|
|
827
|
+
<span class="cline-any cline-no"> </span>
|
|
828
|
+
<span class="cline-any cline-no"> </span>
|
|
829
|
+
<span class="cline-any cline-no"> </span>
|
|
830
|
+
<span class="cline-any cline-no"> </span>
|
|
831
|
+
<span class="cline-any cline-no"> </span>
|
|
832
|
+
<span class="cline-any cline-no"> </span>
|
|
833
|
+
<span class="cline-any cline-no"> </span>
|
|
834
|
+
<span class="cline-any cline-no"> </span>
|
|
835
|
+
<span class="cline-any cline-no"> </span>
|
|
836
|
+
<span class="cline-any cline-no"> </span>
|
|
837
|
+
<span class="cline-any cline-no"> </span>
|
|
838
|
+
<span class="cline-any cline-no"> </span>
|
|
839
|
+
<span class="cline-any cline-no"> </span>
|
|
840
|
+
<span class="cline-any cline-no"> </span>
|
|
841
|
+
<span class="cline-any cline-no"> </span>
|
|
842
|
+
<span class="cline-any cline-no"> </span>
|
|
843
|
+
<span class="cline-any cline-no"> </span>
|
|
844
|
+
<span class="cline-any cline-no"> </span>
|
|
845
|
+
<span class="cline-any cline-no"> </span>
|
|
846
|
+
<span class="cline-any cline-no"> </span>
|
|
847
|
+
<span class="cline-any cline-no"> </span>
|
|
848
|
+
<span class="cline-any cline-no"> </span>
|
|
849
|
+
<span class="cline-any cline-no"> </span>
|
|
850
|
+
<span class="cline-any cline-no"> </span>
|
|
851
|
+
<span class="cline-any cline-no"> </span>
|
|
852
|
+
<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js"><span class="cstat-no" title="statement not covered" >/**<span class="fstat-no" title="function not covered" ><span class="branch-0 cbranch-no" title="branch not covered" ></span></span></span>
|
|
853
|
+
<span class="cstat-no" title="statement not covered" > * HSuite Native Connect</span>
|
|
854
|
+
<span class="cstat-no" title="statement not covered" > * Copyright 2024-2025 HSuite (https://hsuite.finance)</span>
|
|
855
|
+
<span class="cstat-no" title="statement not covered" > *</span>
|
|
856
|
+
<span class="cstat-no" title="statement not covered" > * SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0</span>
|
|
857
|
+
<span class="cstat-no" title="statement not covered" > *</span>
|
|
858
|
+
<span class="cstat-no" title="statement not covered" > * This file is part of HSuite Native Connect. For commercial licensing,</span>
|
|
859
|
+
<span class="cstat-no" title="statement not covered" > * visit https://hsuite.finance/licensing</span>
|
|
860
|
+
<span class="cstat-no" title="statement not covered" > */</span>
|
|
861
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
862
|
+
<span class="cstat-no" title="statement not covered" >/**</span>
|
|
863
|
+
<span class="cstat-no" title="statement not covered" > * @file Smart-host customer session helper.</span>
|
|
864
|
+
<span class="cstat-no" title="statement not covered" > *</span>
|
|
865
|
+
<span class="cstat-no" title="statement not covered" > * @module services/smart-session</span>
|
|
866
|
+
<span class="cstat-no" title="statement not covered" > *</span>
|
|
867
|
+
<span class="cstat-no" title="statement not covered" > * @description</span>
|
|
868
|
+
<span class="cstat-no" title="statement not covered" > * SmartSessionService automates the smart-host authentication handshake for</span>
|
|
869
|
+
<span class="cstat-no" title="statement not covered" > * HSuite dApps. It discovers the host's `appId`, requests a challenge, signs it</span>
|
|
870
|
+
<span class="cstat-no" title="statement not covered" > * with the active wallet account, and exchanges the signed challenge for a</span>
|
|
871
|
+
<span class="cstat-no" title="statement not covered" > * short-lived bearer token.</span>
|
|
872
|
+
<span class="cstat-no" title="statement not covered" > *</span>
|
|
873
|
+
<span class="cstat-no" title="statement not covered" > * **Typical flow:**</span>
|
|
874
|
+
<span class="cstat-no" title="statement not covered" > * ```typescript</span>
|
|
875
|
+
<span class="cstat-no" title="statement not covered" > * const session = inject(SmartSessionService);</span>
|
|
876
|
+
<span class="cstat-no" title="statement not covered" > * await session.login();</span>
|
|
877
|
+
<span class="cstat-no" title="statement not covered" > * const bearer = session.getBearer();</span>
|
|
878
|
+
<span class="cstat-no" title="statement not covered" > * ```</span>
|
|
879
|
+
<span class="cstat-no" title="statement not covered" > *</span>
|
|
880
|
+
<span class="cstat-no" title="statement not covered" > * The service also exposes {@link withSession} for automatic 401 recovery:</span>
|
|
881
|
+
<span class="cstat-no" title="statement not covered" > * operations that fail with HTTP 401 are retried once after a fresh login.</span>
|
|
882
|
+
<span class="cstat-no" title="statement not covered" > */</span>
|
|
883
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
884
|
+
<span class="cstat-no" title="statement not covered" >import { HttpClient } from '@angular/common/http';</span>
|
|
885
|
+
<span class="cstat-no" title="statement not covered" >import { Injectable, inject, InjectionToken } from '@angular/core';</span>
|
|
886
|
+
<span class="cstat-no" title="statement not covered" >import { getLogger } from '@hsuite/native-connect-sdk';</span>
|
|
887
|
+
<span class="cstat-no" title="statement not covered" >import { firstValueFrom } from 'rxjs';</span>
|
|
888
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
889
|
+
<span class="cstat-no" title="statement not covered" >import type { SignMessageResult } from '../providers/base-wallet-provider';</span>
|
|
890
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
891
|
+
<span class="cstat-no" title="statement not covered" >import { TransactionService } from './transaction.service';</span>
|
|
892
|
+
<span class="cstat-no" title="statement not covered" >import { UnifiedWalletService } from './unified-wallet.service';</span>
|
|
893
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
894
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
895
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
896
|
+
<span class="cstat-no" title="statement not covered" >const logger = getLogger().scoped?.('SmartSessionService') ?? getLogger();</span>
|
|
897
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
898
|
+
<span class="cstat-no" title="statement not covered" >/**</span>
|
|
899
|
+
<span class="cstat-no" title="statement not covered" > * Configuration token for {@link SmartSessionService}.</span>
|
|
900
|
+
<span class="cstat-no" title="statement not covered" > */</span>
|
|
901
|
+
<span class="cstat-no" title="statement not covered" >export const SMART_SESSION_CONFIG = new InjectionToken<SmartSessionConfig>(</span>
|
|
902
|
+
<span class="cstat-no" title="statement not covered" > 'SMART_SESSION_CONFIG',</span>
|
|
903
|
+
<span class="cstat-no" title="statement not covered" > {</span>
|
|
904
|
+
<span class="cstat-no" title="statement not covered" > factory: () => ({}),</span>
|
|
905
|
+
<span class="cstat-no" title="statement not covered" > },</span>
|
|
906
|
+
<span class="cstat-no" title="statement not covered" >);</span>
|
|
907
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
908
|
+
<span class="cstat-no" title="statement not covered" >/**</span>
|
|
909
|
+
<span class="cstat-no" title="statement not covered" > * Configuration for the smart-host session handshake.</span>
|
|
910
|
+
<span class="cstat-no" title="statement not covered" > */</span>
|
|
911
|
+
<span class="cstat-no" title="statement not covered" >export interface SmartSessionConfig {</span>
|
|
912
|
+
<span class="cstat-no" title="statement not covered" > /**</span>
|
|
913
|
+
<span class="cstat-no" title="statement not covered" > * Base URL for the smart-host API.</span>
|
|
914
|
+
<span class="cstat-no" title="statement not covered" > * @default '' (relative to the current origin)</span>
|
|
915
|
+
<span class="cstat-no" title="statement not covered" > */</span>
|
|
916
|
+
<span class="cstat-no" title="statement not covered" > baseUrl?: string;</span>
|
|
917
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
918
|
+
<span class="cstat-no" title="statement not covered" > /**</span>
|
|
919
|
+
<span class="cstat-no" title="statement not covered" > * Health endpoint used to discover the host `appId`.</span>
|
|
920
|
+
<span class="cstat-no" title="statement not covered" > * @default '/api/health'</span>
|
|
921
|
+
<span class="cstat-no" title="statement not covered" > */</span>
|
|
922
|
+
<span class="cstat-no" title="statement not covered" > healthEndpoint?: string;</span>
|
|
923
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
924
|
+
<span class="cstat-no" title="statement not covered" > /**</span>
|
|
925
|
+
<span class="cstat-no" title="statement not covered" > * Challenge endpoint used to obtain a message to sign.</span>
|
|
926
|
+
<span class="cstat-no" title="statement not covered" > * @default '/api/auth/challenge'</span>
|
|
927
|
+
<span class="cstat-no" title="statement not covered" > */</span>
|
|
928
|
+
<span class="cstat-no" title="statement not covered" > challengeEndpoint?: string;</span>
|
|
929
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
930
|
+
<span class="cstat-no" title="statement not covered" > /**</span>
|
|
931
|
+
<span class="cstat-no" title="statement not covered" > * Verify endpoint used to exchange the signed challenge for a bearer token.</span>
|
|
932
|
+
<span class="cstat-no" title="statement not covered" > * @default '/api/auth/verify'</span>
|
|
933
|
+
<span class="cstat-no" title="statement not covered" > */</span>
|
|
934
|
+
<span class="cstat-no" title="statement not covered" > verifyEndpoint?: string;</span>
|
|
935
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
936
|
+
<span class="cstat-no" title="statement not covered" > /**</span>
|
|
937
|
+
<span class="cstat-no" title="statement not covered" > * sessionStorage key used to persist the session token and expiry.</span>
|
|
938
|
+
<span class="cstat-no" title="statement not covered" > * @default 'hsuite.smart-session'</span>
|
|
939
|
+
<span class="cstat-no" title="statement not covered" > */</span>
|
|
940
|
+
<span class="cstat-no" title="statement not covered" > storageKey?: string;</span>
|
|
941
|
+
<span class="cstat-no" title="statement not covered" >}</span>
|
|
942
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
943
|
+
<span class="cstat-no" title="statement not covered" >/**</span>
|
|
944
|
+
<span class="cstat-no" title="statement not covered" > * Health response shape expected from the smart host.</span>
|
|
945
|
+
<span class="cstat-no" title="statement not covered" > */</span>
|
|
946
|
+
<span class="cstat-no" title="statement not covered" >export interface SmartHostHealth {</span>
|
|
947
|
+
<span class="cstat-no" title="statement not covered" > appId: string;</span>
|
|
948
|
+
<span class="cstat-no" title="statement not covered" > [key: string]: unknown;</span>
|
|
949
|
+
<span class="cstat-no" title="statement not covered" >}</span>
|
|
950
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
951
|
+
<span class="cstat-no" title="statement not covered" >/**</span>
|
|
952
|
+
<span class="cstat-no" title="statement not covered" > * Challenge response shape expected from the smart host.</span>
|
|
953
|
+
<span class="cstat-no" title="statement not covered" > */</span>
|
|
954
|
+
<span class="cstat-no" title="statement not covered" >export interface SmartHostChallenge {</span>
|
|
955
|
+
<span class="cstat-no" title="statement not covered" > challenge: string;</span>
|
|
956
|
+
<span class="cstat-no" title="statement not covered" > [key: string]: unknown;</span>
|
|
957
|
+
<span class="cstat-no" title="statement not covered" >}</span>
|
|
958
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
959
|
+
<span class="cstat-no" title="statement not covered" >/**</span>
|
|
960
|
+
<span class="cstat-no" title="statement not covered" > * Verify request payload sent to the smart host.</span>
|
|
961
|
+
<span class="cstat-no" title="statement not covered" > */</span>
|
|
962
|
+
<span class="cstat-no" title="statement not covered" >export interface SmartHostVerifyRequest {</span>
|
|
963
|
+
<span class="cstat-no" title="statement not covered" > appId: string;</span>
|
|
964
|
+
<span class="cstat-no" title="statement not covered" > accountAddress: string;</span>
|
|
965
|
+
<span class="cstat-no" title="statement not covered" > publicKey?: string;</span>
|
|
966
|
+
<span class="cstat-no" title="statement not covered" > signature: string;</span>
|
|
967
|
+
<span class="cstat-no" title="statement not covered" > algorithm?: string;</span>
|
|
968
|
+
<span class="cstat-no" title="statement not covered" > message: string;</span>
|
|
969
|
+
<span class="cstat-no" title="statement not covered" > caipChainId?: string;</span>
|
|
970
|
+
<span class="cstat-no" title="statement not covered" > ledgerId?: string;</span>
|
|
971
|
+
<span class="cstat-no" title="statement not covered" > networkId?: string;</span>
|
|
972
|
+
<span class="cstat-no" title="statement not covered" >}</span>
|
|
973
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
974
|
+
<span class="cstat-no" title="statement not covered" >/**</span>
|
|
975
|
+
<span class="cstat-no" title="statement not covered" > * Verify response shape expected from the smart host.</span>
|
|
976
|
+
<span class="cstat-no" title="statement not covered" > */</span>
|
|
977
|
+
<span class="cstat-no" title="statement not covered" >export interface SmartHostVerifyResponse {</span>
|
|
978
|
+
<span class="cstat-no" title="statement not covered" > bearer: string;</span>
|
|
979
|
+
<span class="cstat-no" title="statement not covered" > expiresAt?: number;</span>
|
|
980
|
+
<span class="cstat-no" title="statement not covered" > expiresIn?: number;</span>
|
|
981
|
+
<span class="cstat-no" title="statement not covered" > [key: string]: unknown;</span>
|
|
982
|
+
<span class="cstat-no" title="statement not covered" >}</span>
|
|
983
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
984
|
+
<span class="cstat-no" title="statement not covered" >/**</span>
|
|
985
|
+
<span class="cstat-no" title="statement not covered" > * Persisted smart session.</span>
|
|
986
|
+
<span class="cstat-no" title="statement not covered" > */</span>
|
|
987
|
+
<span class="cstat-no" title="statement not covered" >interface StoredSession {</span>
|
|
988
|
+
<span class="cstat-no" title="statement not covered" > bearer: string;</span>
|
|
989
|
+
<span class="cstat-no" title="statement not covered" > expiresAt: number;</span>
|
|
990
|
+
<span class="cstat-no" title="statement not covered" >}</span>
|
|
991
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
992
|
+
<span class="cstat-no" title="statement not covered" >/**</span>
|
|
993
|
+
<span class="cstat-no" title="statement not covered" > * Smart-host customer session helper.</span>
|
|
994
|
+
<span class="cstat-no" title="statement not covered" > *</span>
|
|
995
|
+
<span class="cstat-no" title="statement not covered" > * @service SmartSessionService</span>
|
|
996
|
+
<span class="cstat-no" title="statement not covered" > *</span>
|
|
997
|
+
<span class="cstat-no" title="statement not covered" > * @description</span>
|
|
998
|
+
<span class="cstat-no" title="statement not covered" > * Encapsulates the full challenge → sign → verify → store JWT flow required by</span>
|
|
999
|
+
<span class="cstat-no" title="statement not covered" > * HSuite smart hosts. The service is intentionally thin: it delegates signing to</span>
|
|
1000
|
+
<span class="cstat-no" title="statement not covered" > * {@link TransactionService} and relies on standard Angular `HttpClient` for the</span>
|
|
1001
|
+
<span class="cstat-no" title="statement not covered" > * host HTTP calls.</span>
|
|
1002
|
+
<span class="cstat-no" title="statement not covered" > *</span>
|
|
1003
|
+
<span class="cstat-no" title="statement not covered" > * @providedIn root</span>
|
|
1004
|
+
<span class="cstat-no" title="statement not covered" > */</span>
|
|
1005
|
+
<span class="cstat-no" title="statement not covered" >@Injectable({ providedIn: 'root' })</span>
|
|
1006
|
+
<span class="cstat-no" title="statement not covered" >export class SmartSessionService {</span>
|
|
1007
|
+
<span class="cstat-no" title="statement not covered" > private readonly http = inject(HttpClient);</span>
|
|
1008
|
+
<span class="cstat-no" title="statement not covered" > private readonly walletService = inject(UnifiedWalletService);</span>
|
|
1009
|
+
<span class="cstat-no" title="statement not covered" > private readonly transactionService = inject(TransactionService);</span>
|
|
1010
|
+
<span class="cstat-no" title="statement not covered" > private readonly config = inject(SMART_SESSION_CONFIG);</span>
|
|
1011
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
1012
|
+
<span class="cstat-no" title="statement not covered" > private get baseUrl(): string {</span>
|
|
1013
|
+
<span class="cstat-no" title="statement not covered" > return this.config.baseUrl ?? '';</span>
|
|
1014
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1015
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
1016
|
+
<span class="cstat-no" title="statement not covered" > private get healthEndpoint(): string {</span>
|
|
1017
|
+
<span class="cstat-no" title="statement not covered" > return this.config.healthEndpoint ?? '/api/health';</span>
|
|
1018
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1019
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
1020
|
+
<span class="cstat-no" title="statement not covered" > private get challengeEndpoint(): string {</span>
|
|
1021
|
+
<span class="cstat-no" title="statement not covered" > return this.config.challengeEndpoint ?? '/api/auth/challenge';</span>
|
|
1022
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1023
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
1024
|
+
<span class="cstat-no" title="statement not covered" > private get verifyEndpoint(): string {</span>
|
|
1025
|
+
<span class="cstat-no" title="statement not covered" > return this.config.verifyEndpoint ?? '/api/auth/verify';</span>
|
|
1026
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1027
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
1028
|
+
<span class="cstat-no" title="statement not covered" > private get storageKey(): string {</span>
|
|
1029
|
+
<span class="cstat-no" title="statement not covered" > return this.config.storageKey ?? 'hsuite.smart-session';</span>
|
|
1030
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1031
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
1032
|
+
<span class="cstat-no" title="statement not covered" > /**</span>
|
|
1033
|
+
<span class="cstat-no" title="statement not covered" > * Returns the currently stored bearer token, or `null` if there is no session.</span>
|
|
1034
|
+
<span class="cstat-no" title="statement not covered" > *</span>
|
|
1035
|
+
<span class="cstat-no" title="statement not covered" > * @returns Bearer token string or null</span>
|
|
1036
|
+
<span class="cstat-no" title="statement not covered" > */</span>
|
|
1037
|
+
<span class="cstat-no" title="statement not covered" > getBearer(): string | null {</span>
|
|
1038
|
+
<span class="cstat-no" title="statement not covered" > const stored = this.readStoredSession();</span>
|
|
1039
|
+
<span class="cstat-no" title="statement not covered" > return stored && stored.expiresAt > Date.now() ? stored.bearer : null;</span>
|
|
1040
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1041
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
1042
|
+
<span class="cstat-no" title="statement not covered" > /**</span>
|
|
1043
|
+
<span class="cstat-no" title="statement not covered" > * Checks whether a non-expired session is available.</span>
|
|
1044
|
+
<span class="cstat-no" title="statement not covered" > *</span>
|
|
1045
|
+
<span class="cstat-no" title="statement not covered" > * @returns true if logged in and the bearer has not expired</span>
|
|
1046
|
+
<span class="cstat-no" title="statement not covered" > */</span>
|
|
1047
|
+
<span class="cstat-no" title="statement not covered" > isLoggedIn(): boolean {</span>
|
|
1048
|
+
<span class="cstat-no" title="statement not covered" > return this.getBearer() !== null;</span>
|
|
1049
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1050
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
1051
|
+
<span class="cstat-no" title="statement not covered" > /**</span>
|
|
1052
|
+
<span class="cstat-no" title="statement not covered" > * Performs the full smart-host login handshake.</span>
|
|
1053
|
+
<span class="cstat-no" title="statement not covered" > *</span>
|
|
1054
|
+
<span class="cstat-no" title="statement not covered" > * @description</span>
|
|
1055
|
+
<span class="cstat-no" title="statement not covered" > * 1. Discovers `appId` from the health endpoint.</span>
|
|
1056
|
+
<span class="cstat-no" title="statement not covered" > * 2. Fetches a challenge from the challenge endpoint.</span>
|
|
1057
|
+
<span class="cstat-no" title="statement not covered" > * 3. Signs the challenge with the active wallet account.</span>
|
|
1058
|
+
<span class="cstat-no" title="statement not covered" > * 4. Exchanges the signed challenge for a bearer token.</span>
|
|
1059
|
+
<span class="cstat-no" title="statement not covered" > * 5. Stores the bearer and expiry in `sessionStorage`.</span>
|
|
1060
|
+
<span class="cstat-no" title="statement not covered" > *</span>
|
|
1061
|
+
<span class="cstat-no" title="statement not covered" > * @returns The verify response from the host</span>
|
|
1062
|
+
<span class="cstat-no" title="statement not covered" > *</span>
|
|
1063
|
+
<span class="cstat-no" title="statement not covered" > * @throws {Error} If no active account is available</span>
|
|
1064
|
+
<span class="cstat-no" title="statement not covered" > * @throws {Error} If the health endpoint does not return an `appId`</span>
|
|
1065
|
+
<span class="cstat-no" title="statement not covered" > * @throws {Error} If the challenge endpoint does not return a `challenge`</span>
|
|
1066
|
+
<span class="cstat-no" title="statement not covered" > * @throws {Error} If the verify call fails</span>
|
|
1067
|
+
<span class="cstat-no" title="statement not covered" > */</span>
|
|
1068
|
+
<span class="cstat-no" title="statement not covered" > async login(): Promise<SmartHostVerifyResponse> {</span>
|
|
1069
|
+
<span class="cstat-no" title="statement not covered" > const account = this.walletService.activeAccount();</span>
|
|
1070
|
+
<span class="cstat-no" title="statement not covered" > if (!account) {</span>
|
|
1071
|
+
<span class="cstat-no" title="statement not covered" > throw new Error('No active account');</span>
|
|
1072
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1073
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
1074
|
+
<span class="cstat-no" title="statement not covered" > logger.info('Starting smart-host login handshake', {</span>
|
|
1075
|
+
<span class="cstat-no" title="statement not covered" > accountAddress: account.address,</span>
|
|
1076
|
+
<span class="cstat-no" title="statement not covered" > });</span>
|
|
1077
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
1078
|
+
<span class="cstat-no" title="statement not covered" > const health = await this.fetchHealth();</span>
|
|
1079
|
+
<span class="cstat-no" title="statement not covered" > if (!health.appId) {</span>
|
|
1080
|
+
<span class="cstat-no" title="statement not covered" > throw new Error('Smart host health endpoint did not return appId');</span>
|
|
1081
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1082
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
1083
|
+
<span class="cstat-no" title="statement not covered" > const challengeResponse = await this.fetchChallenge(health.appId);</span>
|
|
1084
|
+
<span class="cstat-no" title="statement not covered" > if (!challengeResponse.challenge) {</span>
|
|
1085
|
+
<span class="cstat-no" title="statement not covered" > throw new Error('Smart host challenge endpoint did not return challenge');</span>
|
|
1086
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1087
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
1088
|
+
<span class="cstat-no" title="statement not covered" > const signResult = await this.transactionService.signMessage(</span>
|
|
1089
|
+
<span class="cstat-no" title="statement not covered" > challengeResponse.challenge,</span>
|
|
1090
|
+
<span class="cstat-no" title="statement not covered" > );</span>
|
|
1091
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
1092
|
+
<span class="cstat-no" title="statement not covered" > const verifyResponse = await this.verifyChallenge(</span>
|
|
1093
|
+
<span class="cstat-no" title="statement not covered" > health.appId,</span>
|
|
1094
|
+
<span class="cstat-no" title="statement not covered" > account,</span>
|
|
1095
|
+
<span class="cstat-no" title="statement not covered" > challengeResponse.challenge,</span>
|
|
1096
|
+
<span class="cstat-no" title="statement not covered" > signResult,</span>
|
|
1097
|
+
<span class="cstat-no" title="statement not covered" > );</span>
|
|
1098
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
1099
|
+
<span class="cstat-no" title="statement not covered" > if (!verifyResponse.bearer) {</span>
|
|
1100
|
+
<span class="cstat-no" title="statement not covered" > throw new Error('Smart host verify endpoint did not return bearer');</span>
|
|
1101
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1102
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
1103
|
+
<span class="cstat-no" title="statement not covered" > const expiresAt = this.resolveExpiry(verifyResponse);</span>
|
|
1104
|
+
<span class="cstat-no" title="statement not covered" > this.storeSession({ bearer: verifyResponse.bearer, expiresAt });</span>
|
|
1105
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
1106
|
+
<span class="cstat-no" title="statement not covered" > logger.info('Smart-host login successful', {</span>
|
|
1107
|
+
<span class="cstat-no" title="statement not covered" > appId: health.appId,</span>
|
|
1108
|
+
<span class="cstat-no" title="statement not covered" > expiresAt,</span>
|
|
1109
|
+
<span class="cstat-no" title="statement not covered" > });</span>
|
|
1110
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
1111
|
+
<span class="cstat-no" title="statement not covered" > return verifyResponse;</span>
|
|
1112
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1113
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
1114
|
+
<span class="cstat-no" title="statement not covered" > /**</span>
|
|
1115
|
+
<span class="cstat-no" title="statement not covered" > * Clears the stored session.</span>
|
|
1116
|
+
<span class="cstat-no" title="statement not covered" > */</span>
|
|
1117
|
+
<span class="cstat-no" title="statement not covered" > logout(): void {</span>
|
|
1118
|
+
<span class="cstat-no" title="statement not covered" > this.clearStoredSession();</span>
|
|
1119
|
+
<span class="cstat-no" title="statement not covered" > logger.info('Smart-host session cleared');</span>
|
|
1120
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1121
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
1122
|
+
<span class="cstat-no" title="statement not covered" > /**</span>
|
|
1123
|
+
<span class="cstat-no" title="statement not covered" > * Runs an HTTP operation with automatic 401 recovery.</span>
|
|
1124
|
+
<span class="cstat-no" title="statement not covered" > *</span>
|
|
1125
|
+
<span class="cstat-no" title="statement not covered" > * @description</span>
|
|
1126
|
+
<span class="cstat-no" title="statement not covered" > * Executes the provided operation. If it rejects with an HTTP 401 error,</span>
|
|
1127
|
+
<span class="cstat-no" title="statement not covered" > * the service clears the current bearer, performs a fresh login, and retries</span>
|
|
1128
|
+
<span class="cstat-no" title="statement not covered" > * the operation once. Any other error is propagated immediately.</span>
|
|
1129
|
+
<span class="cstat-no" title="statement not covered" > *</span>
|
|
1130
|
+
<span class="cstat-no" title="statement not covered" > * @param operation - Async operation that needs a valid session</span>
|
|
1131
|
+
<span class="cstat-no" title="statement not covered" > * @returns The result of the operation</span>
|
|
1132
|
+
<span class="cstat-no" title="statement not covered" > *</span>
|
|
1133
|
+
<span class="cstat-no" title="statement not covered" > * @throws {Error} The original error if retry is not possible or fails</span>
|
|
1134
|
+
<span class="cstat-no" title="statement not covered" > */</span>
|
|
1135
|
+
<span class="cstat-no" title="statement not covered" > async withSession<T>(operation: () => Promise<T>): Promise<T> {</span>
|
|
1136
|
+
<span class="cstat-no" title="statement not covered" > try {</span>
|
|
1137
|
+
<span class="cstat-no" title="statement not covered" > return await operation();</span>
|
|
1138
|
+
<span class="cstat-no" title="statement not covered" > } catch (error) {</span>
|
|
1139
|
+
<span class="cstat-no" title="statement not covered" > if (this.isUnauthorizedError(error)) {</span>
|
|
1140
|
+
<span class="cstat-no" title="statement not covered" > logger.warn('Operation received 401; attempting single session refresh');</span>
|
|
1141
|
+
<span class="cstat-no" title="statement not covered" > this.logout();</span>
|
|
1142
|
+
<span class="cstat-no" title="statement not covered" > await this.login();</span>
|
|
1143
|
+
<span class="cstat-no" title="statement not covered" > return await operation();</span>
|
|
1144
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1145
|
+
<span class="cstat-no" title="statement not covered" > throw error;</span>
|
|
1146
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1147
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1148
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
1149
|
+
<span class="cstat-no" title="statement not covered" > private async fetchHealth(): Promise<SmartHostHealth> {</span>
|
|
1150
|
+
<span class="cstat-no" title="statement not covered" > return firstValueFrom(</span>
|
|
1151
|
+
<span class="cstat-no" title="statement not covered" > this.http.get<SmartHostHealth>(`${this.baseUrl}${this.healthEndpoint}`),</span>
|
|
1152
|
+
<span class="cstat-no" title="statement not covered" > );</span>
|
|
1153
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1154
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
1155
|
+
<span class="cstat-no" title="statement not covered" > private async fetchChallenge(appId: string): Promise<SmartHostChallenge> {</span>
|
|
1156
|
+
<span class="cstat-no" title="statement not covered" > return firstValueFrom(</span>
|
|
1157
|
+
<span class="cstat-no" title="statement not covered" > this.http.post<SmartHostChallenge>(</span>
|
|
1158
|
+
<span class="cstat-no" title="statement not covered" > `${this.baseUrl}${this.challengeEndpoint}`,</span>
|
|
1159
|
+
<span class="cstat-no" title="statement not covered" > { appId },</span>
|
|
1160
|
+
<span class="cstat-no" title="statement not covered" > ),</span>
|
|
1161
|
+
<span class="cstat-no" title="statement not covered" > );</span>
|
|
1162
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1163
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
1164
|
+
<span class="cstat-no" title="statement not covered" > private async verifyChallenge(</span>
|
|
1165
|
+
<span class="cstat-no" title="statement not covered" > appId: string,</span>
|
|
1166
|
+
<span class="cstat-no" title="statement not covered" > account: import('../models/unified-account.model').UnifiedAccount,</span>
|
|
1167
|
+
<span class="cstat-no" title="statement not covered" > challenge: string,</span>
|
|
1168
|
+
<span class="cstat-no" title="statement not covered" > signResult: SignMessageResult,</span>
|
|
1169
|
+
<span class="cstat-no" title="statement not covered" > ): Promise<SmartHostVerifyResponse> {</span>
|
|
1170
|
+
<span class="cstat-no" title="statement not covered" > const payload: SmartHostVerifyRequest = {</span>
|
|
1171
|
+
<span class="cstat-no" title="statement not covered" > appId,</span>
|
|
1172
|
+
<span class="cstat-no" title="statement not covered" > accountAddress: account.address,</span>
|
|
1173
|
+
<span class="cstat-no" title="statement not covered" > publicKey: signResult.publicKey ?? account.publicKey,</span>
|
|
1174
|
+
<span class="cstat-no" title="statement not covered" > signature: signResult.signature,</span>
|
|
1175
|
+
<span class="cstat-no" title="statement not covered" > algorithm: signResult.algorithm,</span>
|
|
1176
|
+
<span class="cstat-no" title="statement not covered" > message: challenge,</span>
|
|
1177
|
+
<span class="cstat-no" title="statement not covered" > caipChainId: signResult.caipChainId,</span>
|
|
1178
|
+
<span class="cstat-no" title="statement not covered" > ledgerId: account.ledgerId,</span>
|
|
1179
|
+
<span class="cstat-no" title="statement not covered" > networkId: account.networkId,</span>
|
|
1180
|
+
<span class="cstat-no" title="statement not covered" > };</span>
|
|
1181
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
1182
|
+
<span class="cstat-no" title="statement not covered" > return firstValueFrom(</span>
|
|
1183
|
+
<span class="cstat-no" title="statement not covered" > this.http.post<SmartHostVerifyResponse>(</span>
|
|
1184
|
+
<span class="cstat-no" title="statement not covered" > `${this.baseUrl}${this.verifyEndpoint}`,</span>
|
|
1185
|
+
<span class="cstat-no" title="statement not covered" > payload,</span>
|
|
1186
|
+
<span class="cstat-no" title="statement not covered" > ),</span>
|
|
1187
|
+
<span class="cstat-no" title="statement not covered" > );</span>
|
|
1188
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1189
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
1190
|
+
<span class="cstat-no" title="statement not covered" > private resolveExpiry(response: SmartHostVerifyResponse): number {</span>
|
|
1191
|
+
<span class="cstat-no" title="statement not covered" > if (response.expiresAt) {</span>
|
|
1192
|
+
<span class="cstat-no" title="statement not covered" > return response.expiresAt;</span>
|
|
1193
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1194
|
+
<span class="cstat-no" title="statement not covered" > if (response.expiresIn) {</span>
|
|
1195
|
+
<span class="cstat-no" title="statement not covered" > return Date.now() + response.expiresIn * 1000;</span>
|
|
1196
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1197
|
+
<span class="cstat-no" title="statement not covered" > // Default to 5 minutes if no expiry is provided</span>
|
|
1198
|
+
<span class="cstat-no" title="statement not covered" > return Date.now() + 5 * 60 * 1000;</span>
|
|
1199
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1200
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
1201
|
+
<span class="cstat-no" title="statement not covered" > private readStoredSession(): StoredSession | null {</span>
|
|
1202
|
+
<span class="cstat-no" title="statement not covered" > try {</span>
|
|
1203
|
+
<span class="cstat-no" title="statement not covered" > const raw = sessionStorage.getItem(this.storageKey);</span>
|
|
1204
|
+
<span class="cstat-no" title="statement not covered" > if (!raw) {</span>
|
|
1205
|
+
<span class="cstat-no" title="statement not covered" > return null;</span>
|
|
1206
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1207
|
+
<span class="cstat-no" title="statement not covered" > const parsed = JSON.parse(raw) as StoredSession;</span>
|
|
1208
|
+
<span class="cstat-no" title="statement not covered" > if (!parsed.bearer || typeof parsed.expiresAt !== 'number') {</span>
|
|
1209
|
+
<span class="cstat-no" title="statement not covered" > return null;</span>
|
|
1210
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1211
|
+
<span class="cstat-no" title="statement not covered" > return parsed;</span>
|
|
1212
|
+
<span class="cstat-no" title="statement not covered" > } catch {</span>
|
|
1213
|
+
<span class="cstat-no" title="statement not covered" > return null;</span>
|
|
1214
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1215
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1216
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
1217
|
+
<span class="cstat-no" title="statement not covered" > private storeSession(session: StoredSession): void {</span>
|
|
1218
|
+
<span class="cstat-no" title="statement not covered" > try {</span>
|
|
1219
|
+
<span class="cstat-no" title="statement not covered" > sessionStorage.setItem(this.storageKey, JSON.stringify(session));</span>
|
|
1220
|
+
<span class="cstat-no" title="statement not covered" > } catch (error) {</span>
|
|
1221
|
+
<span class="cstat-no" title="statement not covered" > logger.warn('Failed to store smart session', { error });</span>
|
|
1222
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1223
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1224
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
1225
|
+
<span class="cstat-no" title="statement not covered" > private clearStoredSession(): void {</span>
|
|
1226
|
+
<span class="cstat-no" title="statement not covered" > try {</span>
|
|
1227
|
+
<span class="cstat-no" title="statement not covered" > sessionStorage.removeItem(this.storageKey);</span>
|
|
1228
|
+
<span class="cstat-no" title="statement not covered" > } catch (error) {</span>
|
|
1229
|
+
<span class="cstat-no" title="statement not covered" > logger.warn('Failed to clear smart session', { error });</span>
|
|
1230
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1231
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1232
|
+
<span class="cstat-no" title="statement not covered" ></span>
|
|
1233
|
+
<span class="cstat-no" title="statement not covered" > private isUnauthorizedError(error: unknown): boolean {</span>
|
|
1234
|
+
<span class="cstat-no" title="statement not covered" > if (!error || typeof error !== 'object') {</span>
|
|
1235
|
+
<span class="cstat-no" title="statement not covered" > return false;</span>
|
|
1236
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1237
|
+
<span class="cstat-no" title="statement not covered" > const status = (error as { status?: number }).status;</span>
|
|
1238
|
+
<span class="cstat-no" title="statement not covered" > if (typeof status === 'number') {</span>
|
|
1239
|
+
<span class="cstat-no" title="statement not covered" > return status === 401;</span>
|
|
1240
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1241
|
+
<span class="cstat-no" title="statement not covered" > const message = String((error as { message?: unknown }).message ?? '');</span>
|
|
1242
|
+
<span class="cstat-no" title="statement not covered" > return /\b401\b|unauthorized/i.test(message);</span>
|
|
1243
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1244
|
+
<span class="cstat-no" title="statement not covered" >}</span>
|
|
1245
|
+
</pre></td></tr></table></pre>
|
|
1246
|
+
|
|
1247
|
+
<div class='push'></div><!-- for sticky footer -->
|
|
1248
|
+
</div><!-- /wrapper -->
|
|
1249
|
+
<div class='footer quiet pad2 space-top1 center small'>
|
|
1250
|
+
Code coverage generated by
|
|
1251
|
+
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
1252
|
+
at 2026-06-27T21:00:37.138Z
|
|
1253
|
+
</div>
|
|
1254
|
+
<script src="../../prettify.js"></script>
|
|
1255
|
+
<script>
|
|
1256
|
+
window.onload = function () {
|
|
1257
|
+
prettyPrint();
|
|
1258
|
+
};
|
|
1259
|
+
</script>
|
|
1260
|
+
<script src="../../sorter.js"></script>
|
|
1261
|
+
<script src="../../block-navigation.js"></script>
|
|
1262
|
+
</body>
|
|
1263
|
+
</html>
|
|
1264
|
+
|