@hsuite/native-connect-angular 1.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. package/coverage/coverage-summary.json +49 -49
  2. package/coverage/index.html +122 -122
  3. package/coverage/lcov-report/index.html +122 -122
  4. package/coverage/lcov-report/lib/components/account-selector/account-actions/account-actions.component.ts.html +1 -1
  5. package/coverage/lcov-report/lib/components/account-selector/account-actions/index.html +1 -1
  6. package/coverage/lcov-report/lib/components/account-selector/account-filter/account-filter.component.ts.html +1 -1
  7. package/coverage/lcov-report/lib/components/account-selector/account-filter/index.html +1 -1
  8. package/coverage/lcov-report/lib/components/account-selector/account-formatting.service.ts.html +1 -1
  9. package/coverage/lcov-report/lib/components/account-selector/account-grouping.service.ts.html +1 -1
  10. package/coverage/lcov-report/lib/components/account-selector/account-list/account-list.component.ts.html +1 -1
  11. package/coverage/lcov-report/lib/components/account-selector/account-list/index.html +1 -1
  12. package/coverage/lcov-report/lib/components/account-selector/account-selector.component.ts.html +1 -1
  13. package/coverage/lcov-report/lib/components/account-selector/account-selector.service.ts.html +1 -1
  14. package/coverage/lcov-report/lib/components/account-selector/index.html +1 -1
  15. package/coverage/lcov-report/lib/components/wallet-account-display/index.html +1 -1
  16. package/coverage/lcov-report/lib/components/wallet-account-display/wallet-account-display.component.ts.html +1 -1
  17. package/coverage/lcov-report/lib/components/wallet-connect-button/index.html +21 -21
  18. package/coverage/lcov-report/lib/components/wallet-connect-button/wallet-connect-button.component.ts.html +475 -451
  19. package/coverage/lcov-report/lib/components/wallet-connect-prompt/index.html +1 -1
  20. package/coverage/lcov-report/lib/components/wallet-connect-prompt/wallet-connect-prompt.component.ts.html +1 -1
  21. package/coverage/lcov-report/lib/components/wallet-connected-guard/index.html +1 -1
  22. package/coverage/lcov-report/lib/components/wallet-connected-guard/wallet-connected-guard.component.ts.html +1 -1
  23. package/coverage/lcov-report/lib/components/wallet-connection-modal/connection-method-step/connection-method-step.component.ts.html +148 -148
  24. package/coverage/lcov-report/lib/components/wallet-connection-modal/connection-method-step/index.html +17 -17
  25. package/coverage/lcov-report/lib/components/wallet-connection-modal/index.html +21 -21
  26. package/coverage/lcov-report/lib/components/wallet-connection-modal/qr-pairing-step/index.html +17 -17
  27. package/coverage/lcov-report/lib/components/wallet-connection-modal/qr-pairing-step/qr-pairing-step.component.ts.html +838 -838
  28. package/coverage/lcov-report/lib/components/wallet-connection-modal/wallet-connection-modal.component.ts.html +1182 -987
  29. package/coverage/lcov-report/lib/components/wallet-session-display/index.html +1 -1
  30. package/coverage/lcov-report/lib/components/wallet-session-display/wallet-session-display.component.ts.html +1 -1
  31. package/coverage/lcov-report/lib/components/wallet-transaction-status/index.html +1 -1
  32. package/coverage/lcov-report/lib/components/wallet-transaction-status/wallet-transaction-status.component.ts.html +1 -1
  33. package/coverage/lcov-report/lib/directives/index.html +1 -1
  34. package/coverage/lcov-report/lib/directives/wallet-connected.directive.ts.html +1 -1
  35. package/coverage/lcov-report/lib/directives/wallet-context.directive.ts.html +1 -1
  36. package/coverage/lcov-report/lib/directives/wallet-events.directive.ts.html +1 -1
  37. package/coverage/lcov-report/lib/hsuite-wallet.module.ts.html +1 -1
  38. package/coverage/lcov-report/lib/index.html +1 -1
  39. package/coverage/lcov-report/lib/models/connection-config.model.ts.html +1 -1
  40. package/coverage/lcov-report/lib/models/index.html +1 -1
  41. package/coverage/lcov-report/lib/models/provider-types.ts.html +1 -1
  42. package/coverage/lcov-report/lib/providers/base-wallet-provider.ts.html +20 -20
  43. package/coverage/lcov-report/lib/providers/hsuite-native/channel-client.service.ts.html +637 -637
  44. package/coverage/lcov-report/lib/providers/hsuite-native/index.html +19 -19
  45. package/coverage/lcov-report/lib/providers/hsuite-native-provider.ts.html +1 -1
  46. package/coverage/lcov-report/lib/providers/index.html +18 -18
  47. package/coverage/lcov-report/lib/providers/p2p-native/index.html +20 -20
  48. package/coverage/lcov-report/lib/providers/p2p-native/p2p-native.provider.ts.html +993 -993
  49. package/coverage/lcov-report/lib/providers/p2p-native/p2p-session-manager.ts.html +1 -1
  50. package/coverage/lcov-report/lib/providers/wallet-error-handler.ts.html +1 -1
  51. package/coverage/lcov-report/lib/providers/walletconnect/core/index.html +65 -65
  52. package/coverage/lcov-report/lib/providers/walletconnect/core/session-health.ts.html +240 -240
  53. package/coverage/lcov-report/lib/providers/walletconnect/core/walletconnect-client-manager.ts.html +559 -559
  54. package/coverage/lcov-report/lib/providers/walletconnect/core/walletconnect-provider.ts.html +1104 -1104
  55. package/coverage/lcov-report/lib/providers/walletconnect/core/walletconnect-session-store.ts.html +493 -493
  56. package/coverage/lcov-report/lib/providers/walletconnect/core/walletconnect-signing-orchestrator.ts.html +366 -366
  57. package/coverage/lcov-report/lib/providers/walletconnect/signers/hedera-signer.ts.html +730 -730
  58. package/coverage/lcov-report/lib/providers/walletconnect/signers/index.html +43 -43
  59. package/coverage/lcov-report/lib/providers/walletconnect/signers/signer-factory.ts.html +234 -234
  60. package/coverage/lcov-report/lib/providers/walletconnect/signers/xrpl-signer.ts.html +650 -650
  61. package/coverage/lcov-report/lib/services/index.html +31 -31
  62. package/coverage/lcov-report/lib/services/logger.service.ts.html +4 -4
  63. package/coverage/lcov-report/lib/services/transaction-builders/base-transaction-builder.service.ts.html +1 -1
  64. package/coverage/lcov-report/lib/services/transaction-builders/hedera-amount-utils.ts.html +155 -155
  65. package/coverage/lcov-report/lib/services/transaction-builders/hedera-transaction-builder.service.ts.html +2156 -2156
  66. package/coverage/lcov-report/lib/services/transaction-builders/index.html +43 -43
  67. package/coverage/lcov-report/lib/services/transaction-builders/xrpl-transaction-builder.service.ts.html +1674 -1674
  68. package/coverage/lcov-report/lib/services/transaction.service.ts.html +4 -7
  69. package/coverage/lcov-report/lib/services/unified-wallet.service.ts.html +7 -10
  70. package/coverage/lcov-report/lib/services/wallet-context.service.ts.html +1 -1
  71. package/coverage/lcov-report/lib/services/wallet-event-bus.service.ts.html +249 -249
  72. package/coverage/lcov-report/lib/services/wallet-providers.service.ts.html +4 -7
  73. package/coverage/lcov-report/lib/transports/chrome-extension-transport.ts.html +1 -1
  74. package/coverage/lcov-report/lib/transports/index.html +1 -1
  75. package/coverage/lcov-report/lib/utils/index.html +1 -1
  76. package/coverage/lcov-report/lib/utils/ledger-icons.util.ts.html +1 -1
  77. package/coverage/lcov.info +14420 -14977
  78. package/coverage/lib/components/account-selector/account-actions/account-actions.component.ts.html +1 -1
  79. package/coverage/lib/components/account-selector/account-actions/index.html +1 -1
  80. package/coverage/lib/components/account-selector/account-filter/account-filter.component.ts.html +1 -1
  81. package/coverage/lib/components/account-selector/account-filter/index.html +1 -1
  82. package/coverage/lib/components/account-selector/account-formatting.service.ts.html +1 -1
  83. package/coverage/lib/components/account-selector/account-grouping.service.ts.html +1 -1
  84. package/coverage/lib/components/account-selector/account-list/account-list.component.ts.html +1 -1
  85. package/coverage/lib/components/account-selector/account-list/index.html +1 -1
  86. package/coverage/lib/components/account-selector/account-selector.component.ts.html +1 -1
  87. package/coverage/lib/components/account-selector/account-selector.service.ts.html +1 -1
  88. package/coverage/lib/components/account-selector/index.html +1 -1
  89. package/coverage/lib/components/wallet-account-display/index.html +1 -1
  90. package/coverage/lib/components/wallet-account-display/wallet-account-display.component.ts.html +1 -1
  91. package/coverage/lib/components/wallet-connect-button/index.html +21 -21
  92. package/coverage/lib/components/wallet-connect-button/wallet-connect-button.component.ts.html +475 -451
  93. package/coverage/lib/components/wallet-connect-prompt/index.html +1 -1
  94. package/coverage/lib/components/wallet-connect-prompt/wallet-connect-prompt.component.ts.html +1 -1
  95. package/coverage/lib/components/wallet-connected-guard/index.html +1 -1
  96. package/coverage/lib/components/wallet-connected-guard/wallet-connected-guard.component.ts.html +1 -1
  97. package/coverage/lib/components/wallet-connection-modal/connection-method-step/connection-method-step.component.ts.html +148 -148
  98. package/coverage/lib/components/wallet-connection-modal/connection-method-step/index.html +17 -17
  99. package/coverage/lib/components/wallet-connection-modal/index.html +21 -21
  100. package/coverage/lib/components/wallet-connection-modal/qr-pairing-step/index.html +17 -17
  101. package/coverage/lib/components/wallet-connection-modal/qr-pairing-step/qr-pairing-step.component.ts.html +838 -838
  102. package/coverage/lib/components/wallet-connection-modal/wallet-connection-modal.component.ts.html +1182 -987
  103. package/coverage/lib/components/wallet-session-display/index.html +1 -1
  104. package/coverage/lib/components/wallet-session-display/wallet-session-display.component.ts.html +1 -1
  105. package/coverage/lib/components/wallet-transaction-status/index.html +1 -1
  106. package/coverage/lib/components/wallet-transaction-status/wallet-transaction-status.component.ts.html +1 -1
  107. package/coverage/lib/directives/index.html +1 -1
  108. package/coverage/lib/directives/wallet-connected.directive.ts.html +1 -1
  109. package/coverage/lib/directives/wallet-context.directive.ts.html +1 -1
  110. package/coverage/lib/directives/wallet-events.directive.ts.html +1 -1
  111. package/coverage/lib/hsuite-wallet.module.ts.html +1 -1
  112. package/coverage/lib/index.html +1 -1
  113. package/coverage/lib/models/connection-config.model.ts.html +1 -1
  114. package/coverage/lib/models/index.html +1 -1
  115. package/coverage/lib/models/provider-types.ts.html +1 -1
  116. package/coverage/lib/providers/base-wallet-provider.ts.html +20 -20
  117. package/coverage/lib/providers/hsuite-native/channel-client.service.ts.html +637 -637
  118. package/coverage/lib/providers/hsuite-native/index.html +19 -19
  119. package/coverage/lib/providers/hsuite-native-provider.ts.html +1 -1
  120. package/coverage/lib/providers/index.html +18 -18
  121. package/coverage/lib/providers/p2p-native/index.html +20 -20
  122. package/coverage/lib/providers/p2p-native/p2p-native.provider.ts.html +993 -993
  123. package/coverage/lib/providers/p2p-native/p2p-session-manager.ts.html +1 -1
  124. package/coverage/lib/providers/wallet-error-handler.ts.html +1 -1
  125. package/coverage/lib/providers/walletconnect/core/index.html +65 -65
  126. package/coverage/lib/providers/walletconnect/core/session-health.ts.html +240 -240
  127. package/coverage/lib/providers/walletconnect/core/walletconnect-client-manager.ts.html +559 -559
  128. package/coverage/lib/providers/walletconnect/core/walletconnect-provider.ts.html +1104 -1104
  129. package/coverage/lib/providers/walletconnect/core/walletconnect-session-store.ts.html +493 -493
  130. package/coverage/lib/providers/walletconnect/core/walletconnect-signing-orchestrator.ts.html +366 -366
  131. package/coverage/lib/providers/walletconnect/signers/hedera-signer.ts.html +730 -730
  132. package/coverage/lib/providers/walletconnect/signers/index.html +43 -43
  133. package/coverage/lib/providers/walletconnect/signers/signer-factory.ts.html +234 -234
  134. package/coverage/lib/providers/walletconnect/signers/xrpl-signer.ts.html +650 -650
  135. package/coverage/lib/services/index.html +31 -31
  136. package/coverage/lib/services/logger.service.ts.html +4 -4
  137. package/coverage/lib/services/transaction-builders/base-transaction-builder.service.ts.html +1 -1
  138. package/coverage/lib/services/transaction-builders/hedera-amount-utils.ts.html +155 -155
  139. package/coverage/lib/services/transaction-builders/hedera-transaction-builder.service.ts.html +2156 -2156
  140. package/coverage/lib/services/transaction-builders/index.html +43 -43
  141. package/coverage/lib/services/transaction-builders/xrpl-transaction-builder.service.ts.html +1674 -1674
  142. package/coverage/lib/services/transaction.service.ts.html +4 -7
  143. package/coverage/lib/services/unified-wallet.service.ts.html +7 -10
  144. package/coverage/lib/services/wallet-context.service.ts.html +1 -1
  145. package/coverage/lib/services/wallet-event-bus.service.ts.html +249 -249
  146. package/coverage/lib/services/wallet-providers.service.ts.html +4 -7
  147. package/coverage/lib/transports/chrome-extension-transport.ts.html +1 -1
  148. package/coverage/lib/transports/index.html +1 -1
  149. package/coverage/lib/utils/index.html +1 -1
  150. package/coverage/lib/utils/ledger-icons.util.ts.html +1 -1
  151. package/dist/fesm2022/hsuite-native-connect-angular.mjs +85 -20
  152. package/dist/fesm2022/hsuite-native-connect-angular.mjs.map +1 -1
  153. package/dist/index.d.ts +33 -3
  154. package/package.json +4 -4
  155. package/src/lib/components/wallet-connect-button/wallet-connect-button.component.spec.ts +89 -0
  156. package/src/lib/components/wallet-connect-button/wallet-connect-button.component.ts +8 -0
  157. package/src/lib/components/wallet-connection-modal/wallet-connection-modal.component.html +1 -6
  158. package/src/lib/components/wallet-connection-modal/wallet-connection-modal.component.spec.ts +173 -0
  159. package/src/lib/components/wallet-connection-modal/wallet-connection-modal.component.ts +84 -19
  160. package/src/lib/services/transaction.service.ts +0 -1
  161. package/src/lib/services/unified-wallet.service.ts +0 -1
  162. package/src/lib/services/wallet-providers.service.ts +0 -1
@@ -23,30 +23,30 @@
23
23
  <div class='clearfix'>
24
24
 
25
25
  <div class='fl pad1y space-right2'>
26
- <span class="strong">86.58% </span>
26
+ <span class="strong">19.91% </span>
27
27
  <span class="quiet">Statements</span>
28
- <span class='fraction'>626/723</span>
28
+ <span class='fraction'>144/723</span>
29
29
  </div>
30
30
 
31
31
 
32
32
  <div class='fl pad1y space-right2'>
33
- <span class="strong">69.81% </span>
33
+ <span class="strong">0% </span>
34
34
  <span class="quiet">Branches</span>
35
- <span class='fraction'>37/53</span>
35
+ <span class='fraction'>0/1</span>
36
36
  </div>
37
37
 
38
38
 
39
39
  <div class='fl pad1y space-right2'>
40
- <span class="strong">80% </span>
40
+ <span class="strong">0% </span>
41
41
  <span class="quiet">Functions</span>
42
- <span class='fraction'>16/20</span>
42
+ <span class='fraction'>0/5</span>
43
43
  </div>
44
44
 
45
45
 
46
46
  <div class='fl pad1y space-right2'>
47
- <span class="strong">86.58% </span>
47
+ <span class="strong">19.91% </span>
48
48
  <span class="quiet">Lines</span>
49
- <span class='fraction'>626/723</span>
49
+ <span class='fraction'>144/723</span>
50
50
  </div>
51
51
 
52
52
 
@@ -61,7 +61,7 @@
61
61
  </div>
62
62
  </template>
63
63
  </div>
64
- <div class='status-line high'></div>
64
+ <div class='status-line low'></div>
65
65
  <pre><table class="coverage">
66
66
  <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
67
67
  <a name='L2'></a><a href='#L2'>2</a>
@@ -855,29 +855,9 @@
855
855
  <span class="cline-any cline-yes">1x</span>
856
856
  <span class="cline-any cline-yes">1x</span>
857
857
  <span class="cline-any cline-yes">1x</span>
858
- <span class="cline-any cline-yes">10x</span>
859
- <span class="cline-any cline-yes">10x</span>
860
- <span class="cline-any cline-yes">10x</span>
861
- <span class="cline-any cline-yes">10x</span>
862
- <span class="cline-any cline-yes">10x</span>
863
- <span class="cline-any cline-yes">10x</span>
864
- <span class="cline-any cline-yes">10x</span>
865
- <span class="cline-any cline-yes">10x</span>
866
- <span class="cline-any cline-yes">10x</span>
867
858
  <span class="cline-any cline-no">&nbsp;</span>
868
859
  <span class="cline-any cline-no">&nbsp;</span>
869
- <span class="cline-any cline-yes">10x</span>
870
- <span class="cline-any cline-yes">1x</span>
871
- <span class="cline-any cline-yes">1x</span>
872
- <span class="cline-any cline-yes">1x</span>
873
- <span class="cline-any cline-yes">1x</span>
874
- <span class="cline-any cline-yes">1x</span>
875
- <span class="cline-any cline-yes">27x</span>
876
- <span class="cline-any cline-yes">27x</span>
877
- <span class="cline-any cline-yes">27x</span>
878
- <span class="cline-any cline-yes">27x</span>
879
860
  <span class="cline-any cline-no">&nbsp;</span>
880
- <span class="cline-any cline-yes">27x</span>
881
861
  <span class="cline-any cline-no">&nbsp;</span>
882
862
  <span class="cline-any cline-no">&nbsp;</span>
883
863
  <span class="cline-any cline-no">&nbsp;</span>
@@ -887,25 +867,20 @@
887
867
  <span class="cline-any cline-no">&nbsp;</span>
888
868
  <span class="cline-any cline-no">&nbsp;</span>
889
869
  <span class="cline-any cline-no">&nbsp;</span>
890
- <span class="cline-any cline-yes">27x</span>
891
870
  <span class="cline-any cline-yes">1x</span>
892
871
  <span class="cline-any cline-yes">1x</span>
893
872
  <span class="cline-any cline-yes">1x</span>
894
873
  <span class="cline-any cline-yes">1x</span>
895
874
  <span class="cline-any cline-yes">1x</span>
896
- <span class="cline-any cline-yes">3x</span>
897
- <span class="cline-any cline-yes">3x</span>
898
- <span class="cline-any cline-yes">3x</span>
899
- <span class="cline-any cline-yes">3x</span>
900
- <span class="cline-any cline-yes">3x</span>
901
875
  <span class="cline-any cline-no">&nbsp;</span>
902
876
  <span class="cline-any cline-no">&nbsp;</span>
903
- <span class="cline-any cline-yes">3x</span>
904
- <span class="cline-any cline-yes">1x</span>
905
- <span class="cline-any cline-yes">1x</span>
906
- <span class="cline-any cline-yes">1x</span>
907
- <span class="cline-any cline-yes">1x</span>
908
- <span class="cline-any cline-yes">1x</span>
877
+ <span class="cline-any cline-no">&nbsp;</span>
878
+ <span class="cline-any cline-no">&nbsp;</span>
879
+ <span class="cline-any cline-no">&nbsp;</span>
880
+ <span class="cline-any cline-no">&nbsp;</span>
881
+ <span class="cline-any cline-no">&nbsp;</span>
882
+ <span class="cline-any cline-no">&nbsp;</span>
883
+ <span class="cline-any cline-no">&nbsp;</span>
909
884
  <span class="cline-any cline-no">&nbsp;</span>
910
885
  <span class="cline-any cline-no">&nbsp;</span>
911
886
  <span class="cline-any cline-no">&nbsp;</span>
@@ -918,11 +893,26 @@
918
893
  <span class="cline-any cline-yes">1x</span>
919
894
  <span class="cline-any cline-yes">1x</span>
920
895
  <span class="cline-any cline-yes">1x</span>
896
+ <span class="cline-any cline-no">&nbsp;</span>
897
+ <span class="cline-any cline-no">&nbsp;</span>
898
+ <span class="cline-any cline-no">&nbsp;</span>
899
+ <span class="cline-any cline-no">&nbsp;</span>
900
+ <span class="cline-any cline-no">&nbsp;</span>
901
+ <span class="cline-any cline-no">&nbsp;</span>
902
+ <span class="cline-any cline-no">&nbsp;</span>
903
+ <span class="cline-any cline-no">&nbsp;</span>
921
904
  <span class="cline-any cline-yes">1x</span>
922
905
  <span class="cline-any cline-yes">1x</span>
923
906
  <span class="cline-any cline-yes">1x</span>
924
907
  <span class="cline-any cline-yes">1x</span>
925
908
  <span class="cline-any cline-yes">1x</span>
909
+ <span class="cline-any cline-no">&nbsp;</span>
910
+ <span class="cline-any cline-no">&nbsp;</span>
911
+ <span class="cline-any cline-no">&nbsp;</span>
912
+ <span class="cline-any cline-no">&nbsp;</span>
913
+ <span class="cline-any cline-no">&nbsp;</span>
914
+ <span class="cline-any cline-no">&nbsp;</span>
915
+ <span class="cline-any cline-no">&nbsp;</span>
926
916
  <span class="cline-any cline-yes">1x</span>
927
917
  <span class="cline-any cline-yes">1x</span>
928
918
  <span class="cline-any cline-yes">1x</span>
@@ -973,224 +963,16 @@
973
963
  <span class="cline-any cline-yes">1x</span>
974
964
  <span class="cline-any cline-yes">1x</span>
975
965
  <span class="cline-any cline-yes">1x</span>
976
- <span class="cline-any cline-yes">27x</span>
977
- <span class="cline-any cline-yes">27x</span>
978
- <span class="cline-any cline-yes">27x</span>
979
- <span class="cline-any cline-yes">27x</span>
980
- <span class="cline-any cline-yes">27x</span>
981
- <span class="cline-any cline-yes">27x</span>
982
- <span class="cline-any cline-yes">27x</span>
983
- <span class="cline-any cline-yes">27x</span>
984
- <span class="cline-any cline-yes">27x</span>
985
- <span class="cline-any cline-yes">27x</span>
986
- <span class="cline-any cline-yes">27x</span>
987
- <span class="cline-any cline-yes">27x</span>
988
- <span class="cline-any cline-yes">27x</span>
989
- <span class="cline-any cline-yes">27x</span>
990
- <span class="cline-any cline-yes">27x</span>
991
- <span class="cline-any cline-yes">27x</span>
992
- <span class="cline-any cline-yes">27x</span>
993
- <span class="cline-any cline-yes">27x</span>
994
- <span class="cline-any cline-yes">27x</span>
995
- <span class="cline-any cline-yes">27x</span>
996
- <span class="cline-any cline-yes">27x</span>
997
- <span class="cline-any cline-yes">27x</span>
998
- <span class="cline-any cline-yes">27x</span>
999
- <span class="cline-any cline-yes">27x</span>
1000
- <span class="cline-any cline-yes">27x</span>
1001
- <span class="cline-any cline-yes">27x</span>
1002
- <span class="cline-any cline-yes">27x</span>
1003
- <span class="cline-any cline-yes">27x</span>
1004
- <span class="cline-any cline-yes">27x</span>
1005
- <span class="cline-any cline-yes">27x</span>
1006
- <span class="cline-any cline-yes">27x</span>
1007
- <span class="cline-any cline-yes">27x</span>
1008
- <span class="cline-any cline-yes">27x</span>
1009
- <span class="cline-any cline-yes">27x</span>
1010
- <span class="cline-any cline-yes">27x</span>
1011
- <span class="cline-any cline-yes">27x</span>
1012
- <span class="cline-any cline-yes">27x</span>
1013
- <span class="cline-any cline-yes">27x</span>
1014
- <span class="cline-any cline-yes">27x</span>
1015
- <span class="cline-any cline-yes">27x</span>
1016
- <span class="cline-any cline-yes">27x</span>
1017
- <span class="cline-any cline-yes">27x</span>
1018
- <span class="cline-any cline-yes">27x</span>
1019
- <span class="cline-any cline-yes">27x</span>
1020
- <span class="cline-any cline-yes">27x</span>
1021
- <span class="cline-any cline-yes">27x</span>
1022
- <span class="cline-any cline-yes">27x</span>
1023
- <span class="cline-any cline-yes">27x</span>
1024
- <span class="cline-any cline-yes">27x</span>
1025
- <span class="cline-any cline-yes">27x</span>
1026
- <span class="cline-any cline-yes">27x</span>
1027
- <span class="cline-any cline-yes">27x</span>
1028
- <span class="cline-any cline-yes">27x</span>
1029
- <span class="cline-any cline-yes">27x</span>
1030
- <span class="cline-any cline-yes">27x</span>
1031
- <span class="cline-any cline-yes">27x</span>
1032
- <span class="cline-any cline-yes">27x</span>
1033
- <span class="cline-any cline-yes">27x</span>
1034
- <span class="cline-any cline-yes">27x</span>
1035
- <span class="cline-any cline-yes">27x</span>
1036
- <span class="cline-any cline-yes">27x</span>
1037
- <span class="cline-any cline-yes">27x</span>
1038
- <span class="cline-any cline-yes">27x</span>
1039
- <span class="cline-any cline-yes">27x</span>
1040
- <span class="cline-any cline-yes">27x</span>
1041
- <span class="cline-any cline-yes">27x</span>
1042
- <span class="cline-any cline-yes">27x</span>
1043
- <span class="cline-any cline-yes">27x</span>
1044
- <span class="cline-any cline-yes">27x</span>
1045
- <span class="cline-any cline-yes">27x</span>
1046
- <span class="cline-any cline-yes">27x</span>
1047
- <span class="cline-any cline-yes">27x</span>
1048
- <span class="cline-any cline-yes">27x</span>
1049
- <span class="cline-any cline-yes">27x</span>
1050
- <span class="cline-any cline-yes">27x</span>
1051
- <span class="cline-any cline-yes">27x</span>
1052
- <span class="cline-any cline-yes">27x</span>
1053
- <span class="cline-any cline-yes">27x</span>
1054
- <span class="cline-any cline-yes">27x</span>
1055
- <span class="cline-any cline-yes">27x</span>
1056
- <span class="cline-any cline-yes">27x</span>
1057
- <span class="cline-any cline-yes">27x</span>
1058
- <span class="cline-any cline-yes">27x</span>
1059
- <span class="cline-any cline-yes">27x</span>
1060
- <span class="cline-any cline-yes">27x</span>
1061
- <span class="cline-any cline-yes">27x</span>
1062
- <span class="cline-any cline-yes">27x</span>
1063
- <span class="cline-any cline-yes">27x</span>
1064
- <span class="cline-any cline-yes">27x</span>
1065
- <span class="cline-any cline-yes">27x</span>
1066
- <span class="cline-any cline-no">&nbsp;</span>
1067
- <span class="cline-any cline-no">&nbsp;</span>
1068
- <span class="cline-any cline-no">&nbsp;</span>
1069
- <span class="cline-any cline-no">&nbsp;</span>
1070
- <span class="cline-any cline-no">&nbsp;</span>
1071
- <span class="cline-any cline-no">&nbsp;</span>
1072
- <span class="cline-any cline-no">&nbsp;</span>
1073
- <span class="cline-any cline-no">&nbsp;</span>
1074
- <span class="cline-any cline-no">&nbsp;</span>
1075
- <span class="cline-any cline-no">&nbsp;</span>
1076
- <span class="cline-any cline-no">&nbsp;</span>
1077
- <span class="cline-any cline-no">&nbsp;</span>
1078
- <span class="cline-any cline-no">&nbsp;</span>
1079
- <span class="cline-any cline-no">&nbsp;</span>
1080
- <span class="cline-any cline-no">&nbsp;</span>
1081
- <span class="cline-any cline-yes">27x</span>
1082
- <span class="cline-any cline-yes">27x</span>
1083
- <span class="cline-any cline-yes">27x</span>
1084
- <span class="cline-any cline-yes">27x</span>
1085
- <span class="cline-any cline-yes">27x</span>
1086
- <span class="cline-any cline-yes">27x</span>
1087
- <span class="cline-any cline-yes">27x</span>
1088
- <span class="cline-any cline-yes">27x</span>
1089
- <span class="cline-any cline-yes">27x</span>
1090
- <span class="cline-any cline-yes">27x</span>
1091
- <span class="cline-any cline-yes">27x</span>
1092
- <span class="cline-any cline-yes">27x</span>
1093
- <span class="cline-any cline-yes">27x</span>
1094
- <span class="cline-any cline-yes">27x</span>
1095
- <span class="cline-any cline-yes">27x</span>
1096
- <span class="cline-any cline-yes">27x</span>
1097
- <span class="cline-any cline-yes">27x</span>
1098
- <span class="cline-any cline-yes">27x</span>
1099
- <span class="cline-any cline-yes">27x</span>
1100
- <span class="cline-any cline-yes">27x</span>
1101
- <span class="cline-any cline-yes">27x</span>
1102
- <span class="cline-any cline-yes">27x</span>
1103
- <span class="cline-any cline-yes">8x</span>
1104
- <span class="cline-any cline-yes">8x</span>
1105
- <span class="cline-any cline-yes">8x</span>
1106
- <span class="cline-any cline-yes">8x</span>
1107
- <span class="cline-any cline-yes">8x</span>
1108
- <span class="cline-any cline-yes">8x</span>
1109
- <span class="cline-any cline-yes">8x</span>
1110
- <span class="cline-any cline-yes">8x</span>
1111
- <span class="cline-any cline-yes">8x</span>
1112
- <span class="cline-any cline-yes">8x</span>
1113
- <span class="cline-any cline-yes">8x</span>
1114
- <span class="cline-any cline-yes">8x</span>
1115
- <span class="cline-any cline-yes">8x</span>
1116
- <span class="cline-any cline-yes">8x</span>
1117
- <span class="cline-any cline-yes">8x</span>
1118
- <span class="cline-any cline-yes">8x</span>
1119
- <span class="cline-any cline-yes">8x</span>
1120
- <span class="cline-any cline-yes">8x</span>
1121
- <span class="cline-any cline-yes">7x</span>
1122
- <span class="cline-any cline-yes">7x</span>
1123
- <span class="cline-any cline-yes">7x</span>
1124
- <span class="cline-any cline-yes">7x</span>
1125
- <span class="cline-any cline-yes">7x</span>
1126
- <span class="cline-any cline-yes">7x</span>
1127
- <span class="cline-any cline-yes">7x</span>
1128
- <span class="cline-any cline-yes">7x</span>
1129
- <span class="cline-any cline-yes">7x</span>
1130
- <span class="cline-any cline-yes">7x</span>
1131
- <span class="cline-any cline-yes">7x</span>
1132
- <span class="cline-any cline-yes">7x</span>
1133
- <span class="cline-any cline-yes">7x</span>
1134
- <span class="cline-any cline-yes">7x</span>
1135
- <span class="cline-any cline-yes">7x</span>
1136
- <span class="cline-any cline-yes">7x</span>
1137
- <span class="cline-any cline-yes">7x</span>
1138
- <span class="cline-any cline-yes">8x</span>
1139
- <span class="cline-any cline-yes">1x</span>
1140
- <span class="cline-any cline-yes">1x</span>
1141
- <span class="cline-any cline-yes">1x</span>
1142
- <span class="cline-any cline-yes">1x</span>
1143
- <span class="cline-any cline-yes">1x</span>
1144
- <span class="cline-any cline-yes">1x</span>
1145
- <span class="cline-any cline-yes">8x</span>
1146
- <span class="cline-any cline-yes">27x</span>
1147
- <span class="cline-any cline-yes">27x</span>
1148
- <span class="cline-any cline-yes">27x</span>
1149
- <span class="cline-any cline-yes">27x</span>
1150
- <span class="cline-any cline-yes">27x</span>
1151
- <span class="cline-any cline-yes">27x</span>
1152
- <span class="cline-any cline-yes">27x</span>
1153
- <span class="cline-any cline-yes">27x</span>
1154
- <span class="cline-any cline-yes">1x</span>
1155
966
  <span class="cline-any cline-yes">1x</span>
1156
967
  <span class="cline-any cline-yes">1x</span>
1157
968
  <span class="cline-any cline-yes">1x</span>
1158
969
  <span class="cline-any cline-yes">1x</span>
1159
970
  <span class="cline-any cline-yes">1x</span>
1160
971
  <span class="cline-any cline-yes">1x</span>
1161
- <span class="cline-any cline-yes">27x</span>
1162
- <span class="cline-any cline-yes">27x</span>
1163
- <span class="cline-any cline-yes">27x</span>
1164
- <span class="cline-any cline-yes">27x</span>
1165
- <span class="cline-any cline-yes">27x</span>
1166
- <span class="cline-any cline-yes">27x</span>
1167
- <span class="cline-any cline-yes">27x</span>
1168
972
  <span class="cline-any cline-yes">1x</span>
1169
973
  <span class="cline-any cline-yes">1x</span>
1170
974
  <span class="cline-any cline-yes">1x</span>
1171
975
  <span class="cline-any cline-yes">1x</span>
1172
- <span class="cline-any cline-yes">27x</span>
1173
- <span class="cline-any cline-yes">27x</span>
1174
- <span class="cline-any cline-yes">27x</span>
1175
- <span class="cline-any cline-yes">27x</span>
1176
- <span class="cline-any cline-yes">27x</span>
1177
- <span class="cline-any cline-yes">27x</span>
1178
- <span class="cline-any cline-yes">27x</span>
1179
- <span class="cline-any cline-yes">27x</span>
1180
- <span class="cline-any cline-yes">27x</span>
1181
- <span class="cline-any cline-yes">27x</span>
1182
- <span class="cline-any cline-yes">27x</span>
1183
- <span class="cline-any cline-yes">27x</span>
1184
- <span class="cline-any cline-yes">27x</span>
1185
- <span class="cline-any cline-yes">27x</span>
1186
- <span class="cline-any cline-yes">27x</span>
1187
- <span class="cline-any cline-yes">27x</span>
1188
- <span class="cline-any cline-yes">27x</span>
1189
- <span class="cline-any cline-yes">27x</span>
1190
- <span class="cline-any cline-yes">27x</span>
1191
- <span class="cline-any cline-yes">27x</span>
1192
- <span class="cline-any cline-yes">27x</span>
1193
- <span class="cline-any cline-yes">27x</span>
1194
976
  <span class="cline-any cline-no">&nbsp;</span>
1195
977
  <span class="cline-any cline-no">&nbsp;</span>
1196
978
  <span class="cline-any cline-no">&nbsp;</span>
@@ -1218,28 +1000,6 @@
1218
1000
  <span class="cline-any cline-no">&nbsp;</span>
1219
1001
  <span class="cline-any cline-no">&nbsp;</span>
1220
1002
  <span class="cline-any cline-no">&nbsp;</span>
1221
- <span class="cline-any cline-yes">27x</span>
1222
- <span class="cline-any cline-yes">27x</span>
1223
- <span class="cline-any cline-yes">27x</span>
1224
- <span class="cline-any cline-yes">27x</span>
1225
- <span class="cline-any cline-yes">27x</span>
1226
- <span class="cline-any cline-yes">27x</span>
1227
- <span class="cline-any cline-yes">27x</span>
1228
- <span class="cline-any cline-yes">27x</span>
1229
- <span class="cline-any cline-yes">27x</span>
1230
- <span class="cline-any cline-yes">27x</span>
1231
- <span class="cline-any cline-yes">27x</span>
1232
- <span class="cline-any cline-yes">27x</span>
1233
- <span class="cline-any cline-yes">27x</span>
1234
- <span class="cline-any cline-yes">27x</span>
1235
- <span class="cline-any cline-yes">27x</span>
1236
- <span class="cline-any cline-yes">27x</span>
1237
- <span class="cline-any cline-yes">27x</span>
1238
- <span class="cline-any cline-yes">27x</span>
1239
- <span class="cline-any cline-yes">27x</span>
1240
- <span class="cline-any cline-yes">27x</span>
1241
- <span class="cline-any cline-yes">27x</span>
1242
- <span class="cline-any cline-yes">27x</span>
1243
1003
  <span class="cline-any cline-no">&nbsp;</span>
1244
1004
  <span class="cline-any cline-no">&nbsp;</span>
1245
1005
  <span class="cline-any cline-no">&nbsp;</span>
@@ -1268,247 +1028,487 @@
1268
1028
  <span class="cline-any cline-no">&nbsp;</span>
1269
1029
  <span class="cline-any cline-no">&nbsp;</span>
1270
1030
  <span class="cline-any cline-no">&nbsp;</span>
1271
- <span class="cline-any cline-yes">27x</span>
1272
- <span class="cline-any cline-yes">27x</span>
1273
- <span class="cline-any cline-yes">27x</span>
1274
- <span class="cline-any cline-yes">27x</span>
1275
- <span class="cline-any cline-yes">27x</span>
1276
- <span class="cline-any cline-yes">27x</span>
1277
- <span class="cline-any cline-yes">27x</span>
1278
- <span class="cline-any cline-yes">27x</span>
1279
- <span class="cline-any cline-yes">27x</span>
1280
- <span class="cline-any cline-yes">1x</span>
1281
- <span class="cline-any cline-yes">1x</span>
1282
- <span class="cline-any cline-yes">1x</span>
1283
- <span class="cline-any cline-yes">1x</span>
1284
- <span class="cline-any cline-yes">1x</span>
1285
- <span class="cline-any cline-yes">1x</span>
1286
- <span class="cline-any cline-yes">1x</span>
1287
- <span class="cline-any cline-yes">1x</span>
1288
- <span class="cline-any cline-yes">1x</span>
1289
- <span class="cline-any cline-yes">1x</span>
1290
- <span class="cline-any cline-yes">1x</span>
1291
- <span class="cline-any cline-yes">1x</span>
1292
- <span class="cline-any cline-yes">1x</span>
1293
- <span class="cline-any cline-yes">1x</span>
1294
- <span class="cline-any cline-yes">1x</span>
1295
- <span class="cline-any cline-yes">27x</span>
1296
- <span class="cline-any cline-yes">27x</span>
1297
- <span class="cline-any cline-yes">27x</span>
1298
- <span class="cline-any cline-yes">27x</span>
1299
- <span class="cline-any cline-yes">27x</span>
1300
- <span class="cline-any cline-yes">27x</span>
1301
- <span class="cline-any cline-yes">27x</span>
1302
- <span class="cline-any cline-yes">27x</span>
1303
- <span class="cline-any cline-yes">27x</span>
1304
- <span class="cline-any cline-yes">27x</span>
1305
- <span class="cline-any cline-yes">27x</span>
1306
- <span class="cline-any cline-yes">27x</span>
1307
- <span class="cline-any cline-yes">27x</span>
1308
- <span class="cline-any cline-yes">27x</span>
1309
- <span class="cline-any cline-yes">27x</span>
1310
- <span class="cline-any cline-yes">27x</span>
1311
- <span class="cline-any cline-yes">2x</span>
1312
- <span class="cline-any cline-yes">1x</span>
1313
- <span class="cline-any cline-yes">1x</span>
1314
- <span class="cline-any cline-yes">1x</span>
1315
- <span class="cline-any cline-yes">1x</span>
1316
- <span class="cline-any cline-yes">1x</span>
1317
- <span class="cline-any cline-yes">1x</span>
1318
- <span class="cline-any cline-yes">1x</span>
1319
- <span class="cline-any cline-yes">1x</span>
1320
- <span class="cline-any cline-yes">1x</span>
1321
- <span class="cline-any cline-yes">1x</span>
1322
- <span class="cline-any cline-yes">1x</span>
1323
- <span class="cline-any cline-yes">1x</span>
1324
- <span class="cline-any cline-yes">1x</span>
1325
- <span class="cline-any cline-yes">1x</span>
1326
- <span class="cline-any cline-yes">1x</span>
1327
- <span class="cline-any cline-yes">1x</span>
1328
- <span class="cline-any cline-yes">1x</span>
1329
- <span class="cline-any cline-yes">2x</span>
1330
- <span class="cline-any cline-yes">27x</span>
1331
- <span class="cline-any cline-yes">27x</span>
1332
- <span class="cline-any cline-yes">27x</span>
1333
- <span class="cline-any cline-yes">27x</span>
1334
- <span class="cline-any cline-yes">27x</span>
1335
- <span class="cline-any cline-yes">27x</span>
1336
- <span class="cline-any cline-yes">27x</span>
1337
- <span class="cline-any cline-yes">27x</span>
1338
- <span class="cline-any cline-yes">27x</span>
1339
- <span class="cline-any cline-yes">27x</span>
1340
- <span class="cline-any cline-yes">27x</span>
1341
- <span class="cline-any cline-yes">27x</span>
1342
- <span class="cline-any cline-yes">27x</span>
1343
- <span class="cline-any cline-yes">27x</span>
1344
- <span class="cline-any cline-yes">27x</span>
1345
- <span class="cline-any cline-yes">27x</span>
1346
- <span class="cline-any cline-yes">1x</span>
1347
1031
  <span class="cline-any cline-no">&nbsp;</span>
1348
1032
  <span class="cline-any cline-no">&nbsp;</span>
1349
- <span class="cline-any cline-yes">1x</span>
1350
- <span class="cline-any cline-yes">1x</span>
1351
- <span class="cline-any cline-yes">1x</span>
1352
- <span class="cline-any cline-yes">1x</span>
1353
- <span class="cline-any cline-yes">1x</span>
1354
- <span class="cline-any cline-yes">1x</span>
1355
- <span class="cline-any cline-yes">1x</span>
1356
- <span class="cline-any cline-yes">1x</span>
1357
- <span class="cline-any cline-yes">1x</span>
1358
- <span class="cline-any cline-yes">1x</span>
1359
- <span class="cline-any cline-yes">1x</span>
1360
- <span class="cline-any cline-yes">1x</span>
1361
- <span class="cline-any cline-yes">1x</span>
1362
- <span class="cline-any cline-yes">1x</span>
1363
- <span class="cline-any cline-yes">1x</span>
1364
- <span class="cline-any cline-yes">1x</span>
1365
- <span class="cline-any cline-yes">1x</span>
1366
- <span class="cline-any cline-yes">1x</span>
1367
- <span class="cline-any cline-yes">1x</span>
1368
- <span class="cline-any cline-yes">27x</span>
1369
- <span class="cline-any cline-yes">27x</span>
1370
- <span class="cline-any cline-yes">27x</span>
1371
- <span class="cline-any cline-yes">27x</span>
1372
- <span class="cline-any cline-yes">27x</span>
1373
- <span class="cline-any cline-yes">27x</span>
1374
- <span class="cline-any cline-yes">27x</span>
1375
- <span class="cline-any cline-yes">27x</span>
1376
- <span class="cline-any cline-yes">27x</span>
1377
- <span class="cline-any cline-yes">27x</span>
1378
- <span class="cline-any cline-yes">27x</span>
1379
- <span class="cline-any cline-yes">27x</span>
1380
- <span class="cline-any cline-yes">27x</span>
1381
- <span class="cline-any cline-yes">27x</span>
1382
- <span class="cline-any cline-yes">27x</span>
1383
- <span class="cline-any cline-yes">27x</span>
1384
- <span class="cline-any cline-yes">27x</span>
1385
1033
  <span class="cline-any cline-no">&nbsp;</span>
1386
1034
  <span class="cline-any cline-no">&nbsp;</span>
1387
- <span class="cline-any cline-yes">27x</span>
1388
- <span class="cline-any cline-yes">27x</span>
1389
- <span class="cline-any cline-yes">27x</span>
1390
- <span class="cline-any cline-yes">27x</span>
1391
- <span class="cline-any cline-yes">27x</span>
1392
- <span class="cline-any cline-yes">27x</span>
1393
- <span class="cline-any cline-yes">27x</span>
1394
- <span class="cline-any cline-yes">27x</span>
1395
- <span class="cline-any cline-yes">27x</span>
1396
- <span class="cline-any cline-yes">27x</span>
1397
- <span class="cline-any cline-yes">27x</span>
1398
- <span class="cline-any cline-yes">27x</span>
1399
- <span class="cline-any cline-yes">27x</span>
1400
- <span class="cline-any cline-yes">27x</span>
1401
- <span class="cline-any cline-yes">27x</span>
1402
- <span class="cline-any cline-yes">27x</span>
1403
- <span class="cline-any cline-yes">1x</span>
1404
1035
  <span class="cline-any cline-no">&nbsp;</span>
1405
1036
  <span class="cline-any cline-no">&nbsp;</span>
1406
- <span class="cline-any cline-yes">1x</span>
1407
- <span class="cline-any cline-yes">1x</span>
1408
- <span class="cline-any cline-yes">1x</span>
1409
- <span class="cline-any cline-yes">1x</span>
1410
- <span class="cline-any cline-yes">1x</span>
1411
- <span class="cline-any cline-yes">1x</span>
1412
- <span class="cline-any cline-yes">1x</span>
1413
- <span class="cline-any cline-yes">1x</span>
1414
- <span class="cline-any cline-yes">1x</span>
1415
- <span class="cline-any cline-yes">1x</span>
1416
- <span class="cline-any cline-yes">1x</span>
1417
- <span class="cline-any cline-yes">1x</span>
1418
- <span class="cline-any cline-yes">1x</span>
1419
- <span class="cline-any cline-yes">1x</span>
1420
- <span class="cline-any cline-yes">1x</span>
1421
- <span class="cline-any cline-yes">1x</span>
1422
- <span class="cline-any cline-yes">1x</span>
1423
- <span class="cline-any cline-yes">27x</span>
1424
- <span class="cline-any cline-yes">27x</span>
1425
- <span class="cline-any cline-yes">27x</span>
1426
- <span class="cline-any cline-yes">27x</span>
1427
- <span class="cline-any cline-yes">27x</span>
1428
- <span class="cline-any cline-yes">27x</span>
1429
- <span class="cline-any cline-yes">27x</span>
1430
- <span class="cline-any cline-yes">27x</span>
1431
- <span class="cline-any cline-yes">27x</span>
1432
- <span class="cline-any cline-yes">27x</span>
1433
- <span class="cline-any cline-yes">27x</span>
1434
- <span class="cline-any cline-yes">2x</span>
1435
- <span class="cline-any cline-yes">2x</span>
1436
- <span class="cline-any cline-yes">2x</span>
1437
- <span class="cline-any cline-yes">27x</span>
1438
- <span class="cline-any cline-yes">27x</span>
1439
- <span class="cline-any cline-yes">27x</span>
1440
- <span class="cline-any cline-yes">27x</span>
1441
- <span class="cline-any cline-yes">27x</span>
1442
- <span class="cline-any cline-yes">27x</span>
1443
- <span class="cline-any cline-yes">27x</span>
1444
- <span class="cline-any cline-yes">27x</span>
1445
- <span class="cline-any cline-yes">27x</span>
1446
- <span class="cline-any cline-yes">27x</span>
1447
- <span class="cline-any cline-yes">10x</span>
1448
- <span class="cline-any cline-yes">10x</span>
1449
- <span class="cline-any cline-yes">10x</span>
1450
- <span class="cline-any cline-yes">10x</span>
1451
- <span class="cline-any cline-yes">10x</span>
1452
- <span class="cline-any cline-yes">10x</span>
1453
- <span class="cline-any cline-yes">10x</span>
1454
- <span class="cline-any cline-yes">10x</span>
1455
- <span class="cline-any cline-yes">10x</span>
1456
- <span class="cline-any cline-yes">10x</span>
1457
- <span class="cline-any cline-yes">10x</span>
1458
- <span class="cline-any cline-yes">10x</span>
1459
- <span class="cline-any cline-yes">10x</span>
1460
- <span class="cline-any cline-yes">10x</span>
1461
- <span class="cline-any cline-yes">10x</span>
1462
- <span class="cline-any cline-yes">10x</span>
1463
- <span class="cline-any cline-yes">10x</span>
1464
- <span class="cline-any cline-yes">27x</span>
1465
- <span class="cline-any cline-yes">27x</span>
1466
- <span class="cline-any cline-yes">27x</span>
1467
- <span class="cline-any cline-yes">27x</span>
1468
- <span class="cline-any cline-yes">2x</span>
1469
- <span class="cline-any cline-yes">2x</span>
1470
- <span class="cline-any cline-yes">2x</span>
1471
- <span class="cline-any cline-yes">2x</span>
1472
- <span class="cline-any cline-yes">2x</span>
1473
- <span class="cline-any cline-yes">2x</span>
1474
- <span class="cline-any cline-yes">2x</span>
1475
- <span class="cline-any cline-yes">2x</span>
1476
- <span class="cline-any cline-yes">2x</span>
1477
- <span class="cline-any cline-yes">27x</span>
1478
- <span class="cline-any cline-yes">27x</span>
1479
- <span class="cline-any cline-yes">27x</span>
1480
- <span class="cline-any cline-yes">27x</span>
1481
- <span class="cline-any cline-yes">1x</span>
1482
- <span class="cline-any cline-yes">1x</span>
1483
- <span class="cline-any cline-yes">1x</span>
1484
- <span class="cline-any cline-yes">1x</span>
1485
- <span class="cline-any cline-yes">1x</span>
1486
- <span class="cline-any cline-yes">1x</span>
1487
- <span class="cline-any cline-yes">27x</span>
1488
- <span class="cline-any cline-yes">27x</span>
1489
- <span class="cline-any cline-yes">27x</span>
1490
- <span class="cline-any cline-yes">27x</span>
1491
- <span class="cline-any cline-yes">1x</span>
1492
- <span class="cline-any cline-yes">1x</span>
1493
- <span class="cline-any cline-yes">1x</span>
1494
- <span class="cline-any cline-yes">1x</span>
1495
- <span class="cline-any cline-yes">1x</span>
1496
- <span class="cline-any cline-yes">27x</span>
1497
- <span class="cline-any cline-yes">27x</span>
1498
- <span class="cline-any cline-yes">27x</span>
1499
- <span class="cline-any cline-yes">27x</span>
1500
- <span class="cline-any cline-yes">27x</span>
1501
- <span class="cline-any cline-yes">27x</span>
1502
- <span class="cline-any cline-yes">27x</span>
1503
- <span class="cline-any cline-yes">27x</span>
1504
- <span class="cline-any cline-yes">11x</span>
1505
- <span class="cline-any cline-yes">10x</span>
1506
- <span class="cline-any cline-yes">10x</span>
1507
- <span class="cline-any cline-yes">10x</span>
1508
- <span class="cline-any cline-yes">10x</span>
1509
- <span class="cline-any cline-yes">11x</span>
1510
- <span class="cline-any cline-yes">11x</span>
1511
- <span class="cline-any cline-yes">27x</span>
1037
+ <span class="cline-any cline-no">&nbsp;</span>
1038
+ <span class="cline-any cline-no">&nbsp;</span>
1039
+ <span class="cline-any cline-no">&nbsp;</span>
1040
+ <span class="cline-any cline-no">&nbsp;</span>
1041
+ <span class="cline-any cline-no">&nbsp;</span>
1042
+ <span class="cline-any cline-no">&nbsp;</span>
1043
+ <span class="cline-any cline-no">&nbsp;</span>
1044
+ <span class="cline-any cline-no">&nbsp;</span>
1045
+ <span class="cline-any cline-no">&nbsp;</span>
1046
+ <span class="cline-any cline-no">&nbsp;</span>
1047
+ <span class="cline-any cline-no">&nbsp;</span>
1048
+ <span class="cline-any cline-no">&nbsp;</span>
1049
+ <span class="cline-any cline-no">&nbsp;</span>
1050
+ <span class="cline-any cline-no">&nbsp;</span>
1051
+ <span class="cline-any cline-no">&nbsp;</span>
1052
+ <span class="cline-any cline-no">&nbsp;</span>
1053
+ <span class="cline-any cline-no">&nbsp;</span>
1054
+ <span class="cline-any cline-no">&nbsp;</span>
1055
+ <span class="cline-any cline-no">&nbsp;</span>
1056
+ <span class="cline-any cline-no">&nbsp;</span>
1057
+ <span class="cline-any cline-no">&nbsp;</span>
1058
+ <span class="cline-any cline-no">&nbsp;</span>
1059
+ <span class="cline-any cline-no">&nbsp;</span>
1060
+ <span class="cline-any cline-no">&nbsp;</span>
1061
+ <span class="cline-any cline-no">&nbsp;</span>
1062
+ <span class="cline-any cline-no">&nbsp;</span>
1063
+ <span class="cline-any cline-no">&nbsp;</span>
1064
+ <span class="cline-any cline-no">&nbsp;</span>
1065
+ <span class="cline-any cline-no">&nbsp;</span>
1066
+ <span class="cline-any cline-no">&nbsp;</span>
1067
+ <span class="cline-any cline-no">&nbsp;</span>
1068
+ <span class="cline-any cline-no">&nbsp;</span>
1069
+ <span class="cline-any cline-no">&nbsp;</span>
1070
+ <span class="cline-any cline-no">&nbsp;</span>
1071
+ <span class="cline-any cline-no">&nbsp;</span>
1072
+ <span class="cline-any cline-no">&nbsp;</span>
1073
+ <span class="cline-any cline-no">&nbsp;</span>
1074
+ <span class="cline-any cline-no">&nbsp;</span>
1075
+ <span class="cline-any cline-no">&nbsp;</span>
1076
+ <span class="cline-any cline-no">&nbsp;</span>
1077
+ <span class="cline-any cline-no">&nbsp;</span>
1078
+ <span class="cline-any cline-no">&nbsp;</span>
1079
+ <span class="cline-any cline-no">&nbsp;</span>
1080
+ <span class="cline-any cline-no">&nbsp;</span>
1081
+ <span class="cline-any cline-no">&nbsp;</span>
1082
+ <span class="cline-any cline-no">&nbsp;</span>
1083
+ <span class="cline-any cline-no">&nbsp;</span>
1084
+ <span class="cline-any cline-no">&nbsp;</span>
1085
+ <span class="cline-any cline-no">&nbsp;</span>
1086
+ <span class="cline-any cline-no">&nbsp;</span>
1087
+ <span class="cline-any cline-no">&nbsp;</span>
1088
+ <span class="cline-any cline-no">&nbsp;</span>
1089
+ <span class="cline-any cline-no">&nbsp;</span>
1090
+ <span class="cline-any cline-no">&nbsp;</span>
1091
+ <span class="cline-any cline-no">&nbsp;</span>
1092
+ <span class="cline-any cline-no">&nbsp;</span>
1093
+ <span class="cline-any cline-no">&nbsp;</span>
1094
+ <span class="cline-any cline-no">&nbsp;</span>
1095
+ <span class="cline-any cline-no">&nbsp;</span>
1096
+ <span class="cline-any cline-no">&nbsp;</span>
1097
+ <span class="cline-any cline-no">&nbsp;</span>
1098
+ <span class="cline-any cline-no">&nbsp;</span>
1099
+ <span class="cline-any cline-no">&nbsp;</span>
1100
+ <span class="cline-any cline-no">&nbsp;</span>
1101
+ <span class="cline-any cline-no">&nbsp;</span>
1102
+ <span class="cline-any cline-no">&nbsp;</span>
1103
+ <span class="cline-any cline-no">&nbsp;</span>
1104
+ <span class="cline-any cline-no">&nbsp;</span>
1105
+ <span class="cline-any cline-no">&nbsp;</span>
1106
+ <span class="cline-any cline-no">&nbsp;</span>
1107
+ <span class="cline-any cline-no">&nbsp;</span>
1108
+ <span class="cline-any cline-no">&nbsp;</span>
1109
+ <span class="cline-any cline-no">&nbsp;</span>
1110
+ <span class="cline-any cline-no">&nbsp;</span>
1111
+ <span class="cline-any cline-no">&nbsp;</span>
1112
+ <span class="cline-any cline-no">&nbsp;</span>
1113
+ <span class="cline-any cline-no">&nbsp;</span>
1114
+ <span class="cline-any cline-no">&nbsp;</span>
1115
+ <span class="cline-any cline-no">&nbsp;</span>
1116
+ <span class="cline-any cline-no">&nbsp;</span>
1117
+ <span class="cline-any cline-no">&nbsp;</span>
1118
+ <span class="cline-any cline-no">&nbsp;</span>
1119
+ <span class="cline-any cline-no">&nbsp;</span>
1120
+ <span class="cline-any cline-no">&nbsp;</span>
1121
+ <span class="cline-any cline-no">&nbsp;</span>
1122
+ <span class="cline-any cline-no">&nbsp;</span>
1123
+ <span class="cline-any cline-no">&nbsp;</span>
1124
+ <span class="cline-any cline-no">&nbsp;</span>
1125
+ <span class="cline-any cline-no">&nbsp;</span>
1126
+ <span class="cline-any cline-no">&nbsp;</span>
1127
+ <span class="cline-any cline-no">&nbsp;</span>
1128
+ <span class="cline-any cline-no">&nbsp;</span>
1129
+ <span class="cline-any cline-no">&nbsp;</span>
1130
+ <span class="cline-any cline-no">&nbsp;</span>
1131
+ <span class="cline-any cline-no">&nbsp;</span>
1132
+ <span class="cline-any cline-no">&nbsp;</span>
1133
+ <span class="cline-any cline-no">&nbsp;</span>
1134
+ <span class="cline-any cline-no">&nbsp;</span>
1135
+ <span class="cline-any cline-no">&nbsp;</span>
1136
+ <span class="cline-any cline-no">&nbsp;</span>
1137
+ <span class="cline-any cline-no">&nbsp;</span>
1138
+ <span class="cline-any cline-no">&nbsp;</span>
1139
+ <span class="cline-any cline-no">&nbsp;</span>
1140
+ <span class="cline-any cline-no">&nbsp;</span>
1141
+ <span class="cline-any cline-no">&nbsp;</span>
1142
+ <span class="cline-any cline-no">&nbsp;</span>
1143
+ <span class="cline-any cline-no">&nbsp;</span>
1144
+ <span class="cline-any cline-no">&nbsp;</span>
1145
+ <span class="cline-any cline-no">&nbsp;</span>
1146
+ <span class="cline-any cline-no">&nbsp;</span>
1147
+ <span class="cline-any cline-no">&nbsp;</span>
1148
+ <span class="cline-any cline-no">&nbsp;</span>
1149
+ <span class="cline-any cline-no">&nbsp;</span>
1150
+ <span class="cline-any cline-no">&nbsp;</span>
1151
+ <span class="cline-any cline-no">&nbsp;</span>
1152
+ <span class="cline-any cline-no">&nbsp;</span>
1153
+ <span class="cline-any cline-no">&nbsp;</span>
1154
+ <span class="cline-any cline-no">&nbsp;</span>
1155
+ <span class="cline-any cline-no">&nbsp;</span>
1156
+ <span class="cline-any cline-no">&nbsp;</span>
1157
+ <span class="cline-any cline-no">&nbsp;</span>
1158
+ <span class="cline-any cline-no">&nbsp;</span>
1159
+ <span class="cline-any cline-no">&nbsp;</span>
1160
+ <span class="cline-any cline-no">&nbsp;</span>
1161
+ <span class="cline-any cline-no">&nbsp;</span>
1162
+ <span class="cline-any cline-no">&nbsp;</span>
1163
+ <span class="cline-any cline-no">&nbsp;</span>
1164
+ <span class="cline-any cline-no">&nbsp;</span>
1165
+ <span class="cline-any cline-no">&nbsp;</span>
1166
+ <span class="cline-any cline-no">&nbsp;</span>
1167
+ <span class="cline-any cline-no">&nbsp;</span>
1168
+ <span class="cline-any cline-no">&nbsp;</span>
1169
+ <span class="cline-any cline-no">&nbsp;</span>
1170
+ <span class="cline-any cline-no">&nbsp;</span>
1171
+ <span class="cline-any cline-no">&nbsp;</span>
1172
+ <span class="cline-any cline-no">&nbsp;</span>
1173
+ <span class="cline-any cline-no">&nbsp;</span>
1174
+ <span class="cline-any cline-no">&nbsp;</span>
1175
+ <span class="cline-any cline-no">&nbsp;</span>
1176
+ <span class="cline-any cline-no">&nbsp;</span>
1177
+ <span class="cline-any cline-no">&nbsp;</span>
1178
+ <span class="cline-any cline-no">&nbsp;</span>
1179
+ <span class="cline-any cline-no">&nbsp;</span>
1180
+ <span class="cline-any cline-no">&nbsp;</span>
1181
+ <span class="cline-any cline-no">&nbsp;</span>
1182
+ <span class="cline-any cline-no">&nbsp;</span>
1183
+ <span class="cline-any cline-no">&nbsp;</span>
1184
+ <span class="cline-any cline-no">&nbsp;</span>
1185
+ <span class="cline-any cline-no">&nbsp;</span>
1186
+ <span class="cline-any cline-no">&nbsp;</span>
1187
+ <span class="cline-any cline-no">&nbsp;</span>
1188
+ <span class="cline-any cline-no">&nbsp;</span>
1189
+ <span class="cline-any cline-no">&nbsp;</span>
1190
+ <span class="cline-any cline-no">&nbsp;</span>
1191
+ <span class="cline-any cline-no">&nbsp;</span>
1192
+ <span class="cline-any cline-no">&nbsp;</span>
1193
+ <span class="cline-any cline-no">&nbsp;</span>
1194
+ <span class="cline-any cline-no">&nbsp;</span>
1195
+ <span class="cline-any cline-no">&nbsp;</span>
1196
+ <span class="cline-any cline-no">&nbsp;</span>
1197
+ <span class="cline-any cline-no">&nbsp;</span>
1198
+ <span class="cline-any cline-no">&nbsp;</span>
1199
+ <span class="cline-any cline-no">&nbsp;</span>
1200
+ <span class="cline-any cline-no">&nbsp;</span>
1201
+ <span class="cline-any cline-no">&nbsp;</span>
1202
+ <span class="cline-any cline-no">&nbsp;</span>
1203
+ <span class="cline-any cline-no">&nbsp;</span>
1204
+ <span class="cline-any cline-no">&nbsp;</span>
1205
+ <span class="cline-any cline-no">&nbsp;</span>
1206
+ <span class="cline-any cline-no">&nbsp;</span>
1207
+ <span class="cline-any cline-no">&nbsp;</span>
1208
+ <span class="cline-any cline-no">&nbsp;</span>
1209
+ <span class="cline-any cline-no">&nbsp;</span>
1210
+ <span class="cline-any cline-no">&nbsp;</span>
1211
+ <span class="cline-any cline-no">&nbsp;</span>
1212
+ <span class="cline-any cline-no">&nbsp;</span>
1213
+ <span class="cline-any cline-no">&nbsp;</span>
1214
+ <span class="cline-any cline-no">&nbsp;</span>
1215
+ <span class="cline-any cline-no">&nbsp;</span>
1216
+ <span class="cline-any cline-no">&nbsp;</span>
1217
+ <span class="cline-any cline-no">&nbsp;</span>
1218
+ <span class="cline-any cline-no">&nbsp;</span>
1219
+ <span class="cline-any cline-no">&nbsp;</span>
1220
+ <span class="cline-any cline-no">&nbsp;</span>
1221
+ <span class="cline-any cline-no">&nbsp;</span>
1222
+ <span class="cline-any cline-no">&nbsp;</span>
1223
+ <span class="cline-any cline-no">&nbsp;</span>
1224
+ <span class="cline-any cline-no">&nbsp;</span>
1225
+ <span class="cline-any cline-no">&nbsp;</span>
1226
+ <span class="cline-any cline-no">&nbsp;</span>
1227
+ <span class="cline-any cline-no">&nbsp;</span>
1228
+ <span class="cline-any cline-no">&nbsp;</span>
1229
+ <span class="cline-any cline-no">&nbsp;</span>
1230
+ <span class="cline-any cline-no">&nbsp;</span>
1231
+ <span class="cline-any cline-no">&nbsp;</span>
1232
+ <span class="cline-any cline-no">&nbsp;</span>
1233
+ <span class="cline-any cline-no">&nbsp;</span>
1234
+ <span class="cline-any cline-no">&nbsp;</span>
1235
+ <span class="cline-any cline-no">&nbsp;</span>
1236
+ <span class="cline-any cline-no">&nbsp;</span>
1237
+ <span class="cline-any cline-no">&nbsp;</span>
1238
+ <span class="cline-any cline-no">&nbsp;</span>
1239
+ <span class="cline-any cline-no">&nbsp;</span>
1240
+ <span class="cline-any cline-no">&nbsp;</span>
1241
+ <span class="cline-any cline-no">&nbsp;</span>
1242
+ <span class="cline-any cline-no">&nbsp;</span>
1243
+ <span class="cline-any cline-no">&nbsp;</span>
1244
+ <span class="cline-any cline-no">&nbsp;</span>
1245
+ <span class="cline-any cline-no">&nbsp;</span>
1246
+ <span class="cline-any cline-no">&nbsp;</span>
1247
+ <span class="cline-any cline-no">&nbsp;</span>
1248
+ <span class="cline-any cline-no">&nbsp;</span>
1249
+ <span class="cline-any cline-no">&nbsp;</span>
1250
+ <span class="cline-any cline-no">&nbsp;</span>
1251
+ <span class="cline-any cline-no">&nbsp;</span>
1252
+ <span class="cline-any cline-no">&nbsp;</span>
1253
+ <span class="cline-any cline-no">&nbsp;</span>
1254
+ <span class="cline-any cline-no">&nbsp;</span>
1255
+ <span class="cline-any cline-no">&nbsp;</span>
1256
+ <span class="cline-any cline-no">&nbsp;</span>
1257
+ <span class="cline-any cline-no">&nbsp;</span>
1258
+ <span class="cline-any cline-no">&nbsp;</span>
1259
+ <span class="cline-any cline-no">&nbsp;</span>
1260
+ <span class="cline-any cline-no">&nbsp;</span>
1261
+ <span class="cline-any cline-no">&nbsp;</span>
1262
+ <span class="cline-any cline-no">&nbsp;</span>
1263
+ <span class="cline-any cline-no">&nbsp;</span>
1264
+ <span class="cline-any cline-no">&nbsp;</span>
1265
+ <span class="cline-any cline-no">&nbsp;</span>
1266
+ <span class="cline-any cline-no">&nbsp;</span>
1267
+ <span class="cline-any cline-no">&nbsp;</span>
1268
+ <span class="cline-any cline-no">&nbsp;</span>
1269
+ <span class="cline-any cline-no">&nbsp;</span>
1270
+ <span class="cline-any cline-no">&nbsp;</span>
1271
+ <span class="cline-any cline-no">&nbsp;</span>
1272
+ <span class="cline-any cline-no">&nbsp;</span>
1273
+ <span class="cline-any cline-no">&nbsp;</span>
1274
+ <span class="cline-any cline-no">&nbsp;</span>
1275
+ <span class="cline-any cline-no">&nbsp;</span>
1276
+ <span class="cline-any cline-no">&nbsp;</span>
1277
+ <span class="cline-any cline-no">&nbsp;</span>
1278
+ <span class="cline-any cline-no">&nbsp;</span>
1279
+ <span class="cline-any cline-no">&nbsp;</span>
1280
+ <span class="cline-any cline-no">&nbsp;</span>
1281
+ <span class="cline-any cline-no">&nbsp;</span>
1282
+ <span class="cline-any cline-no">&nbsp;</span>
1283
+ <span class="cline-any cline-no">&nbsp;</span>
1284
+ <span class="cline-any cline-no">&nbsp;</span>
1285
+ <span class="cline-any cline-no">&nbsp;</span>
1286
+ <span class="cline-any cline-no">&nbsp;</span>
1287
+ <span class="cline-any cline-no">&nbsp;</span>
1288
+ <span class="cline-any cline-no">&nbsp;</span>
1289
+ <span class="cline-any cline-no">&nbsp;</span>
1290
+ <span class="cline-any cline-no">&nbsp;</span>
1291
+ <span class="cline-any cline-no">&nbsp;</span>
1292
+ <span class="cline-any cline-no">&nbsp;</span>
1293
+ <span class="cline-any cline-no">&nbsp;</span>
1294
+ <span class="cline-any cline-no">&nbsp;</span>
1295
+ <span class="cline-any cline-no">&nbsp;</span>
1296
+ <span class="cline-any cline-no">&nbsp;</span>
1297
+ <span class="cline-any cline-no">&nbsp;</span>
1298
+ <span class="cline-any cline-no">&nbsp;</span>
1299
+ <span class="cline-any cline-no">&nbsp;</span>
1300
+ <span class="cline-any cline-no">&nbsp;</span>
1301
+ <span class="cline-any cline-no">&nbsp;</span>
1302
+ <span class="cline-any cline-no">&nbsp;</span>
1303
+ <span class="cline-any cline-no">&nbsp;</span>
1304
+ <span class="cline-any cline-no">&nbsp;</span>
1305
+ <span class="cline-any cline-no">&nbsp;</span>
1306
+ <span class="cline-any cline-no">&nbsp;</span>
1307
+ <span class="cline-any cline-no">&nbsp;</span>
1308
+ <span class="cline-any cline-no">&nbsp;</span>
1309
+ <span class="cline-any cline-no">&nbsp;</span>
1310
+ <span class="cline-any cline-no">&nbsp;</span>
1311
+ <span class="cline-any cline-no">&nbsp;</span>
1312
+ <span class="cline-any cline-no">&nbsp;</span>
1313
+ <span class="cline-any cline-no">&nbsp;</span>
1314
+ <span class="cline-any cline-no">&nbsp;</span>
1315
+ <span class="cline-any cline-no">&nbsp;</span>
1316
+ <span class="cline-any cline-no">&nbsp;</span>
1317
+ <span class="cline-any cline-no">&nbsp;</span>
1318
+ <span class="cline-any cline-no">&nbsp;</span>
1319
+ <span class="cline-any cline-no">&nbsp;</span>
1320
+ <span class="cline-any cline-no">&nbsp;</span>
1321
+ <span class="cline-any cline-no">&nbsp;</span>
1322
+ <span class="cline-any cline-no">&nbsp;</span>
1323
+ <span class="cline-any cline-no">&nbsp;</span>
1324
+ <span class="cline-any cline-no">&nbsp;</span>
1325
+ <span class="cline-any cline-no">&nbsp;</span>
1326
+ <span class="cline-any cline-no">&nbsp;</span>
1327
+ <span class="cline-any cline-no">&nbsp;</span>
1328
+ <span class="cline-any cline-no">&nbsp;</span>
1329
+ <span class="cline-any cline-no">&nbsp;</span>
1330
+ <span class="cline-any cline-no">&nbsp;</span>
1331
+ <span class="cline-any cline-no">&nbsp;</span>
1332
+ <span class="cline-any cline-no">&nbsp;</span>
1333
+ <span class="cline-any cline-no">&nbsp;</span>
1334
+ <span class="cline-any cline-no">&nbsp;</span>
1335
+ <span class="cline-any cline-no">&nbsp;</span>
1336
+ <span class="cline-any cline-no">&nbsp;</span>
1337
+ <span class="cline-any cline-no">&nbsp;</span>
1338
+ <span class="cline-any cline-no">&nbsp;</span>
1339
+ <span class="cline-any cline-no">&nbsp;</span>
1340
+ <span class="cline-any cline-no">&nbsp;</span>
1341
+ <span class="cline-any cline-no">&nbsp;</span>
1342
+ <span class="cline-any cline-no">&nbsp;</span>
1343
+ <span class="cline-any cline-no">&nbsp;</span>
1344
+ <span class="cline-any cline-no">&nbsp;</span>
1345
+ <span class="cline-any cline-no">&nbsp;</span>
1346
+ <span class="cline-any cline-no">&nbsp;</span>
1347
+ <span class="cline-any cline-no">&nbsp;</span>
1348
+ <span class="cline-any cline-no">&nbsp;</span>
1349
+ <span class="cline-any cline-no">&nbsp;</span>
1350
+ <span class="cline-any cline-no">&nbsp;</span>
1351
+ <span class="cline-any cline-no">&nbsp;</span>
1352
+ <span class="cline-any cline-no">&nbsp;</span>
1353
+ <span class="cline-any cline-no">&nbsp;</span>
1354
+ <span class="cline-any cline-no">&nbsp;</span>
1355
+ <span class="cline-any cline-no">&nbsp;</span>
1356
+ <span class="cline-any cline-no">&nbsp;</span>
1357
+ <span class="cline-any cline-no">&nbsp;</span>
1358
+ <span class="cline-any cline-no">&nbsp;</span>
1359
+ <span class="cline-any cline-no">&nbsp;</span>
1360
+ <span class="cline-any cline-no">&nbsp;</span>
1361
+ <span class="cline-any cline-no">&nbsp;</span>
1362
+ <span class="cline-any cline-no">&nbsp;</span>
1363
+ <span class="cline-any cline-no">&nbsp;</span>
1364
+ <span class="cline-any cline-no">&nbsp;</span>
1365
+ <span class="cline-any cline-no">&nbsp;</span>
1366
+ <span class="cline-any cline-no">&nbsp;</span>
1367
+ <span class="cline-any cline-no">&nbsp;</span>
1368
+ <span class="cline-any cline-no">&nbsp;</span>
1369
+ <span class="cline-any cline-no">&nbsp;</span>
1370
+ <span class="cline-any cline-no">&nbsp;</span>
1371
+ <span class="cline-any cline-no">&nbsp;</span>
1372
+ <span class="cline-any cline-no">&nbsp;</span>
1373
+ <span class="cline-any cline-no">&nbsp;</span>
1374
+ <span class="cline-any cline-no">&nbsp;</span>
1375
+ <span class="cline-any cline-no">&nbsp;</span>
1376
+ <span class="cline-any cline-no">&nbsp;</span>
1377
+ <span class="cline-any cline-no">&nbsp;</span>
1378
+ <span class="cline-any cline-no">&nbsp;</span>
1379
+ <span class="cline-any cline-no">&nbsp;</span>
1380
+ <span class="cline-any cline-no">&nbsp;</span>
1381
+ <span class="cline-any cline-no">&nbsp;</span>
1382
+ <span class="cline-any cline-no">&nbsp;</span>
1383
+ <span class="cline-any cline-no">&nbsp;</span>
1384
+ <span class="cline-any cline-no">&nbsp;</span>
1385
+ <span class="cline-any cline-no">&nbsp;</span>
1386
+ <span class="cline-any cline-no">&nbsp;</span>
1387
+ <span class="cline-any cline-no">&nbsp;</span>
1388
+ <span class="cline-any cline-no">&nbsp;</span>
1389
+ <span class="cline-any cline-no">&nbsp;</span>
1390
+ <span class="cline-any cline-no">&nbsp;</span>
1391
+ <span class="cline-any cline-no">&nbsp;</span>
1392
+ <span class="cline-any cline-no">&nbsp;</span>
1393
+ <span class="cline-any cline-no">&nbsp;</span>
1394
+ <span class="cline-any cline-no">&nbsp;</span>
1395
+ <span class="cline-any cline-no">&nbsp;</span>
1396
+ <span class="cline-any cline-no">&nbsp;</span>
1397
+ <span class="cline-any cline-no">&nbsp;</span>
1398
+ <span class="cline-any cline-no">&nbsp;</span>
1399
+ <span class="cline-any cline-no">&nbsp;</span>
1400
+ <span class="cline-any cline-no">&nbsp;</span>
1401
+ <span class="cline-any cline-no">&nbsp;</span>
1402
+ <span class="cline-any cline-no">&nbsp;</span>
1403
+ <span class="cline-any cline-no">&nbsp;</span>
1404
+ <span class="cline-any cline-no">&nbsp;</span>
1405
+ <span class="cline-any cline-no">&nbsp;</span>
1406
+ <span class="cline-any cline-no">&nbsp;</span>
1407
+ <span class="cline-any cline-no">&nbsp;</span>
1408
+ <span class="cline-any cline-no">&nbsp;</span>
1409
+ <span class="cline-any cline-no">&nbsp;</span>
1410
+ <span class="cline-any cline-no">&nbsp;</span>
1411
+ <span class="cline-any cline-no">&nbsp;</span>
1412
+ <span class="cline-any cline-no">&nbsp;</span>
1413
+ <span class="cline-any cline-no">&nbsp;</span>
1414
+ <span class="cline-any cline-no">&nbsp;</span>
1415
+ <span class="cline-any cline-no">&nbsp;</span>
1416
+ <span class="cline-any cline-no">&nbsp;</span>
1417
+ <span class="cline-any cline-no">&nbsp;</span>
1418
+ <span class="cline-any cline-no">&nbsp;</span>
1419
+ <span class="cline-any cline-no">&nbsp;</span>
1420
+ <span class="cline-any cline-no">&nbsp;</span>
1421
+ <span class="cline-any cline-no">&nbsp;</span>
1422
+ <span class="cline-any cline-no">&nbsp;</span>
1423
+ <span class="cline-any cline-no">&nbsp;</span>
1424
+ <span class="cline-any cline-no">&nbsp;</span>
1425
+ <span class="cline-any cline-no">&nbsp;</span>
1426
+ <span class="cline-any cline-no">&nbsp;</span>
1427
+ <span class="cline-any cline-no">&nbsp;</span>
1428
+ <span class="cline-any cline-no">&nbsp;</span>
1429
+ <span class="cline-any cline-no">&nbsp;</span>
1430
+ <span class="cline-any cline-no">&nbsp;</span>
1431
+ <span class="cline-any cline-no">&nbsp;</span>
1432
+ <span class="cline-any cline-no">&nbsp;</span>
1433
+ <span class="cline-any cline-no">&nbsp;</span>
1434
+ <span class="cline-any cline-no">&nbsp;</span>
1435
+ <span class="cline-any cline-no">&nbsp;</span>
1436
+ <span class="cline-any cline-no">&nbsp;</span>
1437
+ <span class="cline-any cline-no">&nbsp;</span>
1438
+ <span class="cline-any cline-no">&nbsp;</span>
1439
+ <span class="cline-any cline-no">&nbsp;</span>
1440
+ <span class="cline-any cline-no">&nbsp;</span>
1441
+ <span class="cline-any cline-no">&nbsp;</span>
1442
+ <span class="cline-any cline-no">&nbsp;</span>
1443
+ <span class="cline-any cline-no">&nbsp;</span>
1444
+ <span class="cline-any cline-no">&nbsp;</span>
1445
+ <span class="cline-any cline-no">&nbsp;</span>
1446
+ <span class="cline-any cline-no">&nbsp;</span>
1447
+ <span class="cline-any cline-no">&nbsp;</span>
1448
+ <span class="cline-any cline-no">&nbsp;</span>
1449
+ <span class="cline-any cline-no">&nbsp;</span>
1450
+ <span class="cline-any cline-no">&nbsp;</span>
1451
+ <span class="cline-any cline-no">&nbsp;</span>
1452
+ <span class="cline-any cline-no">&nbsp;</span>
1453
+ <span class="cline-any cline-no">&nbsp;</span>
1454
+ <span class="cline-any cline-no">&nbsp;</span>
1455
+ <span class="cline-any cline-no">&nbsp;</span>
1456
+ <span class="cline-any cline-no">&nbsp;</span>
1457
+ <span class="cline-any cline-no">&nbsp;</span>
1458
+ <span class="cline-any cline-no">&nbsp;</span>
1459
+ <span class="cline-any cline-no">&nbsp;</span>
1460
+ <span class="cline-any cline-no">&nbsp;</span>
1461
+ <span class="cline-any cline-no">&nbsp;</span>
1462
+ <span class="cline-any cline-no">&nbsp;</span>
1463
+ <span class="cline-any cline-no">&nbsp;</span>
1464
+ <span class="cline-any cline-no">&nbsp;</span>
1465
+ <span class="cline-any cline-no">&nbsp;</span>
1466
+ <span class="cline-any cline-no">&nbsp;</span>
1467
+ <span class="cline-any cline-no">&nbsp;</span>
1468
+ <span class="cline-any cline-no">&nbsp;</span>
1469
+ <span class="cline-any cline-no">&nbsp;</span>
1470
+ <span class="cline-any cline-no">&nbsp;</span>
1471
+ <span class="cline-any cline-no">&nbsp;</span>
1472
+ <span class="cline-any cline-no">&nbsp;</span>
1473
+ <span class="cline-any cline-no">&nbsp;</span>
1474
+ <span class="cline-any cline-no">&nbsp;</span>
1475
+ <span class="cline-any cline-no">&nbsp;</span>
1476
+ <span class="cline-any cline-no">&nbsp;</span>
1477
+ <span class="cline-any cline-no">&nbsp;</span>
1478
+ <span class="cline-any cline-no">&nbsp;</span>
1479
+ <span class="cline-any cline-no">&nbsp;</span>
1480
+ <span class="cline-any cline-no">&nbsp;</span>
1481
+ <span class="cline-any cline-no">&nbsp;</span>
1482
+ <span class="cline-any cline-no">&nbsp;</span>
1483
+ <span class="cline-any cline-no">&nbsp;</span>
1484
+ <span class="cline-any cline-no">&nbsp;</span>
1485
+ <span class="cline-any cline-no">&nbsp;</span>
1486
+ <span class="cline-any cline-no">&nbsp;</span>
1487
+ <span class="cline-any cline-no">&nbsp;</span>
1488
+ <span class="cline-any cline-no">&nbsp;</span>
1489
+ <span class="cline-any cline-no">&nbsp;</span>
1490
+ <span class="cline-any cline-no">&nbsp;</span>
1491
+ <span class="cline-any cline-no">&nbsp;</span>
1492
+ <span class="cline-any cline-no">&nbsp;</span>
1493
+ <span class="cline-any cline-no">&nbsp;</span>
1494
+ <span class="cline-any cline-no">&nbsp;</span>
1495
+ <span class="cline-any cline-no">&nbsp;</span>
1496
+ <span class="cline-any cline-no">&nbsp;</span>
1497
+ <span class="cline-any cline-no">&nbsp;</span>
1498
+ <span class="cline-any cline-no">&nbsp;</span>
1499
+ <span class="cline-any cline-no">&nbsp;</span>
1500
+ <span class="cline-any cline-no">&nbsp;</span>
1501
+ <span class="cline-any cline-no">&nbsp;</span>
1502
+ <span class="cline-any cline-no">&nbsp;</span>
1503
+ <span class="cline-any cline-no">&nbsp;</span>
1504
+ <span class="cline-any cline-no">&nbsp;</span>
1505
+ <span class="cline-any cline-no">&nbsp;</span>
1506
+ <span class="cline-any cline-no">&nbsp;</span>
1507
+ <span class="cline-any cline-no">&nbsp;</span>
1508
+ <span class="cline-any cline-no">&nbsp;</span>
1509
+ <span class="cline-any cline-no">&nbsp;</span>
1510
+ <span class="cline-any cline-no">&nbsp;</span>
1511
+ <span class="cline-any cline-no">&nbsp;</span>
1512
1512
  <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">/**
1513
1513
  * HSuite Native Connect
1514
1514
  * Copyright 2024-2025 HSuite (https://hsuite.finance)
@@ -1577,30 +1577,30 @@ class P2PSessionPersistence {
1577
1577
  * @param session
1578
1578
  * Persist mobile session to localStorage.
1579
1579
  */
1580
- save(session: P2PSession): void {
1581
- try {
1582
- if (typeof window === 'undefined') <span class="branch-0 cbranch-no" title="branch not covered" >return;</span>
1583
- const payload = {
1584
- ...session,
1585
- timestamp: Date.now(),
1586
- };
1587
- window.localStorage.setItem(P2P_SESSION_STORAGE_KEY, JSON.stringify(payload));
1588
- logger.debug('Mobile session persisted', { sessionId: session.sessionId });
1589
- <span class="branch-0 cbranch-no" title="branch not covered" > } catch (error) {</span>
1580
+ <span class="fstat-no" title="function not covered" > save(session: P2PSession): void {</span>
1581
+ <span class="cstat-no" title="statement not covered" > try {</span>
1582
+ <span class="cstat-no" title="statement not covered" > if (typeof window === 'undefined') return;</span>
1583
+ <span class="cstat-no" title="statement not covered" > const payload = {</span>
1584
+ <span class="cstat-no" title="statement not covered" > ...session,</span>
1585
+ <span class="cstat-no" title="statement not covered" > timestamp: Date.now(),</span>
1586
+ <span class="cstat-no" title="statement not covered" > };</span>
1587
+ <span class="cstat-no" title="statement not covered" > window.localStorage.setItem(P2P_SESSION_STORAGE_KEY, JSON.stringify(payload));</span>
1588
+ <span class="cstat-no" title="statement not covered" > logger.debug('Mobile session persisted', { sessionId: session.sessionId });</span>
1589
+ <span class="cstat-no" title="statement not covered" > } catch (error) {</span>
1590
1590
  <span class="cstat-no" title="statement not covered" > logger.warn('Failed to persist mobile session', { error });</span>
1591
1591
  <span class="cstat-no" title="statement not covered" > }</span>
1592
- }
1592
+ <span class="cstat-no" title="statement not covered" > }</span>
1593
1593
  &nbsp;
1594
1594
  /**
1595
1595
  * Restore mobile session from localStorage.
1596
1596
  */
1597
- restore(): (P2PSession &amp; { timestamp: number }) | null {
1598
- try {
1599
- if (typeof window === 'undefined') <span class="branch-0 cbranch-no" title="branch not covered" >return null;</span>
1600
- const raw = window.localStorage.getItem(P2P_SESSION_STORAGE_KEY);
1601
- if (!raw) return <span class="branch-0 cbranch-no" title="branch not covered" >null;</span>
1597
+ <span class="fstat-no" title="function not covered" > restore(): (P2PSession &amp; { timestamp: number }) | null {</span>
1598
+ <span class="cstat-no" title="statement not covered" > try {</span>
1599
+ <span class="cstat-no" title="statement not covered" > if (typeof window === 'undefined') return null;</span>
1600
+ <span class="cstat-no" title="statement not covered" > const raw = window.localStorage.getItem(P2P_SESSION_STORAGE_KEY);</span>
1601
+ <span class="cstat-no" title="statement not covered" > if (!raw) return null;</span>
1602
1602
  <span class="cstat-no" title="statement not covered" > const stored = JSON.parse(raw) as P2PSession &amp; { timestamp: number };</span>
1603
- if (!stored?.sessionId) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
1603
+ <span class="cstat-no" title="statement not covered" > if (!stored?.sessionId) {</span>
1604
1604
  <span class="cstat-no" title="statement not covered" > this.clear();</span>
1605
1605
  <span class="cstat-no" title="statement not covered" > return null;</span>
1606
1606
  <span class="cstat-no" title="statement not covered" > }</span>
@@ -1610,20 +1610,20 @@ class P2PSessionPersistence {
1610
1610
  <span class="cstat-no" title="statement not covered" > logger.warn('Failed to restore mobile session', { error });</span>
1611
1611
  <span class="cstat-no" title="statement not covered" > return null;</span>
1612
1612
  <span class="cstat-no" title="statement not covered" > }</span>
1613
- }
1613
+ <span class="cstat-no" title="statement not covered" > }</span>
1614
1614
  &nbsp;
1615
1615
  /**
1616
1616
  * Clear persisted mobile session.
1617
1617
  */
1618
- clear(): void {
1619
- try {
1620
- if (typeof window === 'undefined') <span class="branch-0 cbranch-no" title="branch not covered" >return;</span>
1621
- window.localStorage.removeItem(P2P_SESSION_STORAGE_KEY);
1622
- logger.debug('Mobile session cleared');
1623
- <span class="branch-0 cbranch-no" title="branch not covered" > } catch (error) {</span>
1618
+ <span class="fstat-no" title="function not covered" > clear(): void {</span>
1619
+ <span class="cstat-no" title="statement not covered" > try {</span>
1620
+ <span class="cstat-no" title="statement not covered" > if (typeof window === 'undefined') return;</span>
1621
+ <span class="cstat-no" title="statement not covered" > window.localStorage.removeItem(P2P_SESSION_STORAGE_KEY);</span>
1622
+ <span class="cstat-no" title="statement not covered" > logger.debug('Mobile session cleared');</span>
1623
+ <span class="cstat-no" title="statement not covered" > } catch (error) {</span>
1624
1624
  <span class="cstat-no" title="statement not covered" > logger.warn('Failed to clear mobile session', { error });</span>
1625
1625
  <span class="cstat-no" title="statement not covered" > }</span>
1626
- }
1626
+ <span class="cstat-no" title="statement not covered" > }</span>
1627
1627
  &nbsp;
1628
1628
  /**
1629
1629
  * Check if a mobile session is stored.
@@ -1695,97 +1695,97 @@ export interface PairingOfferResult {
1695
1695
  * @publicApi
1696
1696
  */
1697
1697
  @Injectable({ providedIn: 'root' })
1698
- export class P2PNativeProvider extends BaseWalletProvider {
1699
- readonly id = 'mobile-native';
1700
- &nbsp;
1701
- readonly metadata: ProviderMetadata = {
1702
- name: 'HSuite Mobile',
1703
- type: 'mobile-native' as ProviderType,
1704
- icon: 'phone-portrait-outline',
1705
- description: 'Connect via QR code (P2P)',
1706
- features: [
1707
- 'Direct P2P connection',
1708
- 'End-to-end encrypted',
1709
- 'No server required',
1710
- 'Works on any network',
1711
- ],
1712
- };
1713
- &nbsp;
1714
- // Internal state signals
1715
- private readonly _status = signal&lt;ConnectionStatus&gt;('disconnected');
1716
- private readonly _accounts = signal&lt;UnifiedAccount[]&gt;([]);
1717
- private readonly _error = signal&lt;string | null&gt;(null);
1718
- private readonly _connectionState = signal&lt;P2PNativeConnectionState&gt;('disconnected');
1719
- private readonly _pairingOffer = signal&lt;PairingOfferResult | null&gt;(null);
1720
- &nbsp;
1721
- /** Session persistence for page reload recovery */
1722
- private readonly sessionPersistence = new P2PSessionPersistence();
1723
- &nbsp;
1724
- // Public readonly signals
1725
- readonly status: Signal&lt;ConnectionStatus&gt; = this._status.asReadonly();
1726
- readonly accounts: Signal&lt;UnifiedAccount[]&gt; = this._accounts.asReadonly();
1727
- readonly error: Signal&lt;string | null&gt; = this._error.asReadonly();
1728
- &nbsp;
1729
- /**
1730
- * Current detailed connection state
1731
- */
1732
- readonly connectionState: Signal&lt;P2PNativeConnectionState&gt; = this._connectionState.asReadonly();
1733
- &nbsp;
1734
- /**
1735
- * Current pairing offer (if awaiting scan)
1736
- */
1737
- readonly pairingOffer: Signal&lt;PairingOfferResult | null&gt; = this._pairingOffer.asReadonly();
1738
- &nbsp;
1739
- /**
1740
- * Whether currently awaiting wallet to scan QR
1741
- */
1742
- readonly isAwaitingScan = computed(() =&gt; this._connectionState() === 'awaiting_scan');
1743
- &nbsp;
1744
- /**
1745
- * Whether a pairing offer is available
1746
- */
1747
- readonly hasPairingOffer = computed(() =&gt; this._pairingOffer() !== null);
1748
- &nbsp;
1749
- /**
1750
- * Whether a persisted session exists
1751
- */
1752
- readonly hasPersistedSession = computed(() =&gt; this.sessionPersistence.hasStoredSession());
1753
- &nbsp;
1754
- /**
1755
- * Transport state for the P2P connection.
1756
- * Values: 'nostr-only' | 'upgrading' | 'p2p-connected' | 'p2p-failed'
1757
- *
1758
- * This allows the UI to show the current transport layer being used.
1759
- */
1760
- readonly transportState = computed(() =&gt; this.sessionManager.p2pState());
1761
- &nbsp;
1762
- /**
1763
- * @param sessionManager
1764
- * @param ngZone
1765
- */
1766
- constructor(
1767
- private readonly sessionManager: P2PSessionManager,
1768
- private readonly ngZone: NgZone,
1769
- ) {
1770
- super();
1771
- // CRITICAL: Pass NgZone to session manager so signal updates from
1772
- // Nostr/WebSocket callbacks (which fire outside Angular zone) trigger
1773
- // Angular change detection. Without this, walletContext.activeAccount
1774
- // stays null after session approval.
1775
- this.sessionManager.setNgZone(this.ngZone);
1776
- this.setupSessionManagerListeners();
1777
- this.restorePersistedSession();
1778
- }
1779
- &nbsp;
1780
- /**
1781
- * Restore session from localStorage on page load.
1782
- * Sets accounts and status from persisted data.
1783
- * Note: This only restores metadata - the actual WebRTC connection
1784
- * will need to be re-established via QR pairing.
1785
- */
1786
- private restorePersistedSession(): void {
1787
- const stored = this.sessionPersistence.restore();
1788
- if (stored) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
1698
+ export class P2PNativeProvider extends BaseWalletProvider <span class="fstat-no" title="function not covered" >{</span>
1699
+ <span class="cstat-no" title="statement not covered" > readonly id = 'mobile-native';</span>
1700
+ <span class="cstat-no" title="statement not covered" ></span>
1701
+ <span class="cstat-no" title="statement not covered" > readonly metadata: ProviderMetadata = {</span>
1702
+ <span class="cstat-no" title="statement not covered" > name: 'HSuite Mobile',</span>
1703
+ <span class="cstat-no" title="statement not covered" > type: 'mobile-native' as ProviderType,</span>
1704
+ <span class="cstat-no" title="statement not covered" > icon: 'phone-portrait-outline',</span>
1705
+ <span class="cstat-no" title="statement not covered" > description: 'Connect via QR code (P2P)',</span>
1706
+ <span class="cstat-no" title="statement not covered" > features: [</span>
1707
+ <span class="cstat-no" title="statement not covered" > 'Direct P2P connection',</span>
1708
+ <span class="cstat-no" title="statement not covered" > 'End-to-end encrypted',</span>
1709
+ <span class="cstat-no" title="statement not covered" > 'No server required',</span>
1710
+ <span class="cstat-no" title="statement not covered" > 'Works on any network',</span>
1711
+ <span class="cstat-no" title="statement not covered" > ],</span>
1712
+ <span class="cstat-no" title="statement not covered" > };</span>
1713
+ <span class="cstat-no" title="statement not covered" ></span>
1714
+ <span class="cstat-no" title="statement not covered" > // Internal state signals</span>
1715
+ <span class="cstat-no" title="statement not covered" > private readonly _status = signal&lt;ConnectionStatus&gt;('disconnected');</span>
1716
+ <span class="cstat-no" title="statement not covered" > private readonly _accounts = signal&lt;UnifiedAccount[]&gt;([]);</span>
1717
+ <span class="cstat-no" title="statement not covered" > private readonly _error = signal&lt;string | null&gt;(null);</span>
1718
+ <span class="cstat-no" title="statement not covered" > private readonly _connectionState = signal&lt;P2PNativeConnectionState&gt;('disconnected');</span>
1719
+ <span class="cstat-no" title="statement not covered" > private readonly _pairingOffer = signal&lt;PairingOfferResult | null&gt;(null);</span>
1720
+ <span class="cstat-no" title="statement not covered" ></span>
1721
+ <span class="cstat-no" title="statement not covered" > /** Session persistence for page reload recovery */</span>
1722
+ <span class="cstat-no" title="statement not covered" > private readonly sessionPersistence = new P2PSessionPersistence();</span>
1723
+ <span class="cstat-no" title="statement not covered" ></span>
1724
+ <span class="cstat-no" title="statement not covered" > // Public readonly signals</span>
1725
+ <span class="cstat-no" title="statement not covered" > readonly status: Signal&lt;ConnectionStatus&gt; = this._status.asReadonly();</span>
1726
+ <span class="cstat-no" title="statement not covered" > readonly accounts: Signal&lt;UnifiedAccount[]&gt; = this._accounts.asReadonly();</span>
1727
+ <span class="cstat-no" title="statement not covered" > readonly error: Signal&lt;string | null&gt; = this._error.asReadonly();</span>
1728
+ <span class="cstat-no" title="statement not covered" ></span>
1729
+ <span class="cstat-no" title="statement not covered" > /**</span>
1730
+ <span class="cstat-no" title="statement not covered" > * Current detailed connection state</span>
1731
+ <span class="cstat-no" title="statement not covered" > */</span>
1732
+ <span class="cstat-no" title="statement not covered" > readonly connectionState: Signal&lt;P2PNativeConnectionState&gt; = this._connectionState.asReadonly();</span>
1733
+ <span class="cstat-no" title="statement not covered" ></span>
1734
+ <span class="cstat-no" title="statement not covered" > /**</span>
1735
+ <span class="cstat-no" title="statement not covered" > * Current pairing offer (if awaiting scan)</span>
1736
+ <span class="cstat-no" title="statement not covered" > */</span>
1737
+ <span class="cstat-no" title="statement not covered" > readonly pairingOffer: Signal&lt;PairingOfferResult | null&gt; = this._pairingOffer.asReadonly();</span>
1738
+ <span class="cstat-no" title="statement not covered" ></span>
1739
+ <span class="cstat-no" title="statement not covered" > /**</span>
1740
+ <span class="cstat-no" title="statement not covered" > * Whether currently awaiting wallet to scan QR</span>
1741
+ <span class="cstat-no" title="statement not covered" > */</span>
1742
+ <span class="cstat-no" title="statement not covered" > readonly isAwaitingScan = computed(() =&gt; this._connectionState() === 'awaiting_scan');</span>
1743
+ <span class="cstat-no" title="statement not covered" ></span>
1744
+ <span class="cstat-no" title="statement not covered" > /**</span>
1745
+ <span class="cstat-no" title="statement not covered" > * Whether a pairing offer is available</span>
1746
+ <span class="cstat-no" title="statement not covered" > */</span>
1747
+ <span class="cstat-no" title="statement not covered" > readonly hasPairingOffer = computed(() =&gt; this._pairingOffer() !== null);</span>
1748
+ <span class="cstat-no" title="statement not covered" ></span>
1749
+ <span class="cstat-no" title="statement not covered" > /**</span>
1750
+ <span class="cstat-no" title="statement not covered" > * Whether a persisted session exists</span>
1751
+ <span class="cstat-no" title="statement not covered" > */</span>
1752
+ <span class="cstat-no" title="statement not covered" > readonly hasPersistedSession = computed(() =&gt; this.sessionPersistence.hasStoredSession());</span>
1753
+ <span class="cstat-no" title="statement not covered" ></span>
1754
+ <span class="cstat-no" title="statement not covered" > /**</span>
1755
+ <span class="cstat-no" title="statement not covered" > * Transport state for the P2P connection.</span>
1756
+ <span class="cstat-no" title="statement not covered" > * Values: 'nostr-only' | 'upgrading' | 'p2p-connected' | 'p2p-failed'</span>
1757
+ <span class="cstat-no" title="statement not covered" > *</span>
1758
+ <span class="cstat-no" title="statement not covered" > * This allows the UI to show the current transport layer being used.</span>
1759
+ <span class="cstat-no" title="statement not covered" > */</span>
1760
+ <span class="cstat-no" title="statement not covered" > readonly transportState = computed(() =&gt; this.sessionManager.p2pState());</span>
1761
+ <span class="cstat-no" title="statement not covered" ></span>
1762
+ <span class="cstat-no" title="statement not covered" > /**</span>
1763
+ <span class="cstat-no" title="statement not covered" > * @param sessionManager</span>
1764
+ <span class="cstat-no" title="statement not covered" > * @param ngZone</span>
1765
+ <span class="cstat-no" title="statement not covered" > */</span>
1766
+ <span class="cstat-no" title="statement not covered" > constructor(</span>
1767
+ <span class="cstat-no" title="statement not covered" > private readonly sessionManager: P2PSessionManager,</span>
1768
+ <span class="cstat-no" title="statement not covered" > private readonly ngZone: NgZone,</span>
1769
+ <span class="cstat-no" title="statement not covered" > ) {</span>
1770
+ <span class="cstat-no" title="statement not covered" > super();</span>
1771
+ <span class="cstat-no" title="statement not covered" > // CRITICAL: Pass NgZone to session manager so signal updates from</span>
1772
+ <span class="cstat-no" title="statement not covered" > // Nostr/WebSocket callbacks (which fire outside Angular zone) trigger</span>
1773
+ <span class="cstat-no" title="statement not covered" > // Angular change detection. Without this, walletContext.activeAccount</span>
1774
+ <span class="cstat-no" title="statement not covered" > // stays null after session approval.</span>
1775
+ <span class="cstat-no" title="statement not covered" > this.sessionManager.setNgZone(this.ngZone);</span>
1776
+ <span class="cstat-no" title="statement not covered" > this.setupSessionManagerListeners();</span>
1777
+ <span class="cstat-no" title="statement not covered" > this.restorePersistedSession();</span>
1778
+ <span class="cstat-no" title="statement not covered" > }</span>
1779
+ <span class="cstat-no" title="statement not covered" ></span>
1780
+ <span class="cstat-no" title="statement not covered" > /**</span>
1781
+ <span class="cstat-no" title="statement not covered" > * Restore session from localStorage on page load.</span>
1782
+ <span class="cstat-no" title="statement not covered" > * Sets accounts and status from persisted data.</span>
1783
+ <span class="cstat-no" title="statement not covered" > * Note: This only restores metadata - the actual WebRTC connection</span>
1784
+ <span class="cstat-no" title="statement not covered" > * will need to be re-established via QR pairing.</span>
1785
+ <span class="cstat-no" title="statement not covered" > */</span>
1786
+ <span class="cstat-no" title="statement not covered" > private restorePersistedSession(): void {</span>
1787
+ <span class="cstat-no" title="statement not covered" > const stored = this.sessionPersistence.restore();</span>
1788
+ <span class="cstat-no" title="statement not covered" > if (stored) {</span>
1789
1789
  <span class="cstat-no" title="statement not covered" > logger.info('Restoring persisted mobile session', {</span>
1790
1790
  <span class="cstat-no" title="statement not covered" > sessionId: stored.sessionId,</span>
1791
1791
  <span class="cstat-no" title="statement not covered" > accountCount: stored.accounts?.length ?? 0,</span>
@@ -1801,119 +1801,119 @@ export class P2PNativeProvider extends BaseWalletProvider {
1801
1801
  <span class="cstat-no" title="statement not covered" > // The persisted data is for account info only</span>
1802
1802
  <span class="cstat-no" title="statement not covered" > logger.debug('Mobile session metadata restored (requires re-pairing for connection)');</span>
1803
1803
  <span class="cstat-no" title="statement not covered" > }</span>
1804
- }
1805
- &nbsp;
1806
- /**
1807
- * Creates a pairing offer for QR code display.
1808
- *
1809
- * @description
1810
- * Generates a channel invite encoded for QR display. The mobile wallet
1811
- * scans this QR code to establish a connection via Nostr relays with
1812
- * automatic P2P upgrade.
1813
- *
1814
- * The returned `qrData` is a compact `hsc:connect?i=...` URL that contains:
1815
- * - Channel ID and encryption keys
1816
- * - App metadata (name, ID)
1817
- * - Relay endpoints for communication
1818
- *
1819
- * @param config - Connection configuration specifying ledger and network
1820
- *
1821
- * @returns Promise resolving to pairing offer containing QR data and expiry
1822
- *
1823
- * @throws {Error} If offer generation fails
1824
- */
1825
- async createPairingOffer(config: ConnectionConfig): Promise&lt;PairingOfferResult&gt; {
1826
- logger.info('Creating pairing offer', { config });
1827
- &nbsp;
1828
- try {
1829
- this._connectionState.set('generating_offer');
1830
- this._error.set(null);
1831
- &nbsp;
1832
- // Extract common properties based on config type
1833
- const appId = 'appId' in config ? (config.<span class="branch-0 cbranch-no" title="branch not covered" >appId ?? 'hsuite-dapp') : '</span>hsuite-dapp';
1834
- const appName = 'appName' in config ? (config.<span class="branch-0 cbranch-no" title="branch not covered" >appName ?? 'HSuite dApp') : '</span>HSuite dApp';
1835
- const ledgerId = 'ledgerId' in config ? (config.<span class="branch-0 cbranch-no" title="branch not covered" >ledgerId ?? 'hedera') : '</span>hedera';
1836
- const networkId = config.<span class="branch-0 cbranch-no" title="branch not covered" >networkId ?? 'testnet';</span>
1837
- &nbsp;
1838
- const result = await this.sessionManager.createPairingOffer({
1839
- appId,
1840
- appName,
1841
- ledgerId,
1842
- networkId,
1843
- });
1844
- &nbsp;
1845
- const offerResult: PairingOfferResult = {
1846
- qrData: result.qrData,
1847
- sessionId: result.sessionId,
1848
- expiresAt: Date.now() + 120 * 1000, // 2 minutes
1849
- };
1850
- &nbsp;
1851
- this._pairingOffer.set(offerResult);
1852
- this._connectionState.set('awaiting_scan');
1853
- this._status.set('connecting');
1854
- &nbsp;
1855
- logger.info('Pairing offer created', {
1856
- qrDataLength: result.qrData.length,
1857
- expiresAt: offerResult.expiresAt,
1858
- });
1859
- &nbsp;
1860
- return offerResult;
1861
- } catch (error) {
1862
- logger.error('Failed to create pairing offer', { error });
1863
- this._connectionState.set('error');
1864
- this._status.set('error');
1865
- this._error.set(error instanceof Error ? error.<span class="branch-0 cbranch-no" title="branch not covered" >message : 'Failed to create pairing offer')</span>;
1866
- throw error;
1867
- }
1868
- }
1869
- &nbsp;
1870
- /**
1871
- * Refresh the pairing offer (e.g., when expired).
1872
- *
1873
- * @param config - Connection configuration
1874
- * @returns Promise resolving to new pairing offer
1875
- */
1876
- async refreshPairingOffer(config: ConnectionConfig): Promise&lt;PairingOfferResult&gt; {
1877
- logger.debug('Refreshing pairing offer');
1878
- &nbsp;
1879
- // Cancel any existing offer
1880
- await this.sessionManager.cancelPairingOffer();
1881
- &nbsp;
1882
- return this.createPairingOffer(config);
1883
- }
1884
- &nbsp;
1885
- /**
1886
- * Register callback for when peer connects.
1887
- *
1888
- * @param callback - Function to call when connection is established
1889
- */
1890
- onPeerConnected(callback: () =&gt; void): void {
1891
- this.sessionManager.onConnected(() =&gt; {
1892
- callback();
1893
- });
1894
- }
1895
- &nbsp;
1896
- /**
1897
- * Waits for the wallet to connect and approve the session.
1898
- *
1899
- * @description
1900
- * Call this after {@link createPairingOffer} to block until the wallet user
1901
- * completes the connection flow. This is the single-QR flow - no answer
1902
- * scanning is required.
1903
- *
1904
- * The method resolves when all of the following occur:
1905
- * 1. Wallet scans the QR code
1906
- * 2. Wallet connects via Nostr relay
1907
- * 3. User approves the session in the wallet
1908
- *
1909
- * Upon success, the session is automatically persisted for reconnection.
1910
- *
1911
- * @returns Promise resolving to the approved session with account information
1912
- *
1913
- * @throws {Error} If connection fails or is rejected
1914
- * @throws {Error} If no pairing offer was created
1915
- */
1916
- <span class="fstat-no" title="function not covered" > async waitForSessionApproval(): Promise&lt;P2PSession&gt; {</span>
1804
+ <span class="cstat-no" title="statement not covered" > }</span>
1805
+ <span class="cstat-no" title="statement not covered" ></span>
1806
+ <span class="cstat-no" title="statement not covered" > /**</span>
1807
+ <span class="cstat-no" title="statement not covered" > * Creates a pairing offer for QR code display.</span>
1808
+ <span class="cstat-no" title="statement not covered" > *</span>
1809
+ <span class="cstat-no" title="statement not covered" > * @description</span>
1810
+ <span class="cstat-no" title="statement not covered" > * Generates a channel invite encoded for QR display. The mobile wallet</span>
1811
+ <span class="cstat-no" title="statement not covered" > * scans this QR code to establish a connection via Nostr relays with</span>
1812
+ <span class="cstat-no" title="statement not covered" > * automatic P2P upgrade.</span>
1813
+ <span class="cstat-no" title="statement not covered" > *</span>
1814
+ <span class="cstat-no" title="statement not covered" > * The returned `qrData` is a compact `hsc:connect?i=...` URL that contains:</span>
1815
+ <span class="cstat-no" title="statement not covered" > * - Channel ID and encryption keys</span>
1816
+ <span class="cstat-no" title="statement not covered" > * - App metadata (name, ID)</span>
1817
+ <span class="cstat-no" title="statement not covered" > * - Relay endpoints for communication</span>
1818
+ <span class="cstat-no" title="statement not covered" > *</span>
1819
+ <span class="cstat-no" title="statement not covered" > * @param config - Connection configuration specifying ledger and network</span>
1820
+ <span class="cstat-no" title="statement not covered" > *</span>
1821
+ <span class="cstat-no" title="statement not covered" > * @returns Promise resolving to pairing offer containing QR data and expiry</span>
1822
+ <span class="cstat-no" title="statement not covered" > *</span>
1823
+ <span class="cstat-no" title="statement not covered" > * @throws {Error} If offer generation fails</span>
1824
+ <span class="cstat-no" title="statement not covered" > */</span>
1825
+ <span class="cstat-no" title="statement not covered" > async createPairingOffer(config: ConnectionConfig): Promise&lt;PairingOfferResult&gt; {</span>
1826
+ <span class="cstat-no" title="statement not covered" > logger.info('Creating pairing offer', { config });</span>
1827
+ <span class="cstat-no" title="statement not covered" ></span>
1828
+ <span class="cstat-no" title="statement not covered" > try {</span>
1829
+ <span class="cstat-no" title="statement not covered" > this._connectionState.set('generating_offer');</span>
1830
+ <span class="cstat-no" title="statement not covered" > this._error.set(null);</span>
1831
+ <span class="cstat-no" title="statement not covered" ></span>
1832
+ <span class="cstat-no" title="statement not covered" > // Extract common properties based on config type</span>
1833
+ <span class="cstat-no" title="statement not covered" > const appId = 'appId' in config ? (config.appId ?? 'hsuite-dapp') : 'hsuite-dapp';</span>
1834
+ <span class="cstat-no" title="statement not covered" > const appName = 'appName' in config ? (config.appName ?? 'HSuite dApp') : 'HSuite dApp';</span>
1835
+ <span class="cstat-no" title="statement not covered" > const ledgerId = 'ledgerId' in config ? (config.ledgerId ?? 'hedera') : 'hedera';</span>
1836
+ <span class="cstat-no" title="statement not covered" > const networkId = config.networkId ?? 'testnet';</span>
1837
+ <span class="cstat-no" title="statement not covered" ></span>
1838
+ <span class="cstat-no" title="statement not covered" > const result = await this.sessionManager.createPairingOffer({</span>
1839
+ <span class="cstat-no" title="statement not covered" > appId,</span>
1840
+ <span class="cstat-no" title="statement not covered" > appName,</span>
1841
+ <span class="cstat-no" title="statement not covered" > ledgerId,</span>
1842
+ <span class="cstat-no" title="statement not covered" > networkId,</span>
1843
+ <span class="cstat-no" title="statement not covered" > });</span>
1844
+ <span class="cstat-no" title="statement not covered" ></span>
1845
+ <span class="cstat-no" title="statement not covered" > const offerResult: PairingOfferResult = {</span>
1846
+ <span class="cstat-no" title="statement not covered" > qrData: result.qrData,</span>
1847
+ <span class="cstat-no" title="statement not covered" > sessionId: result.sessionId,</span>
1848
+ <span class="cstat-no" title="statement not covered" > expiresAt: Date.now() + 120 * 1000, // 2 minutes</span>
1849
+ <span class="cstat-no" title="statement not covered" > };</span>
1850
+ <span class="cstat-no" title="statement not covered" ></span>
1851
+ <span class="cstat-no" title="statement not covered" > this._pairingOffer.set(offerResult);</span>
1852
+ <span class="cstat-no" title="statement not covered" > this._connectionState.set('awaiting_scan');</span>
1853
+ <span class="cstat-no" title="statement not covered" > this._status.set('connecting');</span>
1854
+ <span class="cstat-no" title="statement not covered" ></span>
1855
+ <span class="cstat-no" title="statement not covered" > logger.info('Pairing offer created', {</span>
1856
+ <span class="cstat-no" title="statement not covered" > qrDataLength: result.qrData.length,</span>
1857
+ <span class="cstat-no" title="statement not covered" > expiresAt: offerResult.expiresAt,</span>
1858
+ <span class="cstat-no" title="statement not covered" > });</span>
1859
+ <span class="cstat-no" title="statement not covered" ></span>
1860
+ <span class="cstat-no" title="statement not covered" > return offerResult;</span>
1861
+ <span class="cstat-no" title="statement not covered" > } catch (error) {</span>
1862
+ <span class="cstat-no" title="statement not covered" > logger.error('Failed to create pairing offer', { error });</span>
1863
+ <span class="cstat-no" title="statement not covered" > this._connectionState.set('error');</span>
1864
+ <span class="cstat-no" title="statement not covered" > this._status.set('error');</span>
1865
+ <span class="cstat-no" title="statement not covered" > this._error.set(error instanceof Error ? error.message : 'Failed to create pairing offer');</span>
1866
+ <span class="cstat-no" title="statement not covered" > throw error;</span>
1867
+ <span class="cstat-no" title="statement not covered" > }</span>
1868
+ <span class="cstat-no" title="statement not covered" > }</span>
1869
+ <span class="cstat-no" title="statement not covered" ></span>
1870
+ <span class="cstat-no" title="statement not covered" > /**</span>
1871
+ <span class="cstat-no" title="statement not covered" > * Refresh the pairing offer (e.g., when expired).</span>
1872
+ <span class="cstat-no" title="statement not covered" > *</span>
1873
+ <span class="cstat-no" title="statement not covered" > * @param config - Connection configuration</span>
1874
+ <span class="cstat-no" title="statement not covered" > * @returns Promise resolving to new pairing offer</span>
1875
+ <span class="cstat-no" title="statement not covered" > */</span>
1876
+ <span class="cstat-no" title="statement not covered" > async refreshPairingOffer(config: ConnectionConfig): Promise&lt;PairingOfferResult&gt; {</span>
1877
+ <span class="cstat-no" title="statement not covered" > logger.debug('Refreshing pairing offer');</span>
1878
+ <span class="cstat-no" title="statement not covered" ></span>
1879
+ <span class="cstat-no" title="statement not covered" > // Cancel any existing offer</span>
1880
+ <span class="cstat-no" title="statement not covered" > await this.sessionManager.cancelPairingOffer();</span>
1881
+ <span class="cstat-no" title="statement not covered" ></span>
1882
+ <span class="cstat-no" title="statement not covered" > return this.createPairingOffer(config);</span>
1883
+ <span class="cstat-no" title="statement not covered" > }</span>
1884
+ <span class="cstat-no" title="statement not covered" ></span>
1885
+ <span class="cstat-no" title="statement not covered" > /**</span>
1886
+ <span class="cstat-no" title="statement not covered" > * Register callback for when peer connects.</span>
1887
+ <span class="cstat-no" title="statement not covered" > *</span>
1888
+ <span class="cstat-no" title="statement not covered" > * @param callback - Function to call when connection is established</span>
1889
+ <span class="cstat-no" title="statement not covered" > */</span>
1890
+ <span class="cstat-no" title="statement not covered" > onPeerConnected(callback: () =&gt; void): void {</span>
1891
+ <span class="cstat-no" title="statement not covered" > this.sessionManager.onConnected(() =&gt; {</span>
1892
+ <span class="cstat-no" title="statement not covered" > callback();</span>
1893
+ <span class="cstat-no" title="statement not covered" > });</span>
1894
+ <span class="cstat-no" title="statement not covered" > }</span>
1895
+ <span class="cstat-no" title="statement not covered" ></span>
1896
+ <span class="cstat-no" title="statement not covered" > /**</span>
1897
+ <span class="cstat-no" title="statement not covered" > * Waits for the wallet to connect and approve the session.</span>
1898
+ <span class="cstat-no" title="statement not covered" > *</span>
1899
+ <span class="cstat-no" title="statement not covered" > * @description</span>
1900
+ <span class="cstat-no" title="statement not covered" > * Call this after {@link createPairingOffer} to block until the wallet user</span>
1901
+ <span class="cstat-no" title="statement not covered" > * completes the connection flow. This is the single-QR flow - no answer</span>
1902
+ <span class="cstat-no" title="statement not covered" > * scanning is required.</span>
1903
+ <span class="cstat-no" title="statement not covered" > *</span>
1904
+ <span class="cstat-no" title="statement not covered" > * The method resolves when all of the following occur:</span>
1905
+ <span class="cstat-no" title="statement not covered" > * 1. Wallet scans the QR code</span>
1906
+ <span class="cstat-no" title="statement not covered" > * 2. Wallet connects via Nostr relay</span>
1907
+ <span class="cstat-no" title="statement not covered" > * 3. User approves the session in the wallet</span>
1908
+ <span class="cstat-no" title="statement not covered" > *</span>
1909
+ <span class="cstat-no" title="statement not covered" > * Upon success, the session is automatically persisted for reconnection.</span>
1910
+ <span class="cstat-no" title="statement not covered" > *</span>
1911
+ <span class="cstat-no" title="statement not covered" > * @returns Promise resolving to the approved session with account information</span>
1912
+ <span class="cstat-no" title="statement not covered" > *</span>
1913
+ <span class="cstat-no" title="statement not covered" > * @throws {Error} If connection fails or is rejected</span>
1914
+ <span class="cstat-no" title="statement not covered" > * @throws {Error} If no pairing offer was created</span>
1915
+ <span class="cstat-no" title="statement not covered" > */</span>
1916
+ <span class="cstat-no" title="statement not covered" > async waitForSessionApproval(): Promise&lt;P2PSession&gt; {</span>
1917
1917
  <span class="cstat-no" title="statement not covered" > logger.info('Waiting for wallet to connect and approve session');</span>
1918
1918
  <span class="cstat-no" title="statement not covered" > this._connectionState.set('pending_approval');</span>
1919
1919
  <span class="cstat-no" title="statement not covered" ></span>
@@ -1941,28 +1941,28 @@ export class P2PNativeProvider extends BaseWalletProvider {
1941
1941
  <span class="cstat-no" title="statement not covered" > throw error;</span>
1942
1942
  <span class="cstat-no" title="statement not covered" > }</span>
1943
1943
  <span class="cstat-no" title="statement not covered" > }</span>
1944
- &nbsp;
1945
- // ========== BaseWalletProvider Implementation ==========
1946
- &nbsp;
1947
- /**
1948
- * Connects to a wallet via the P2P pairing flow.
1949
- *
1950
- * @description
1951
- * Initiates the pairing offer flow and waits for connection. For more
1952
- * control over QR display timing, use {@link createPairingOffer} and
1953
- * {@link waitForSessionApproval} separately.
1954
- *
1955
- * This method:
1956
- * 1. Creates a pairing offer
1957
- * 2. Updates `pairingOffer` signal with QR data
1958
- * 3. Waits up to 2 minutes for wallet to connect
1959
- *
1960
- * @param config - Connection configuration
1961
- *
1962
- * @throws {Error} If already connected (no-op)
1963
- * @throws {Error} If connection times out (2 minutes)
1964
- */
1965
- <span class="fstat-no" title="function not covered" > async connect(config: ConnectionConfig): Promise&lt;void&gt; {</span>
1944
+ <span class="cstat-no" title="statement not covered" ></span>
1945
+ <span class="cstat-no" title="statement not covered" > // ========== BaseWalletProvider Implementation ==========</span>
1946
+ <span class="cstat-no" title="statement not covered" ></span>
1947
+ <span class="cstat-no" title="statement not covered" > /**</span>
1948
+ <span class="cstat-no" title="statement not covered" > * Connects to a wallet via the P2P pairing flow.</span>
1949
+ <span class="cstat-no" title="statement not covered" > *</span>
1950
+ <span class="cstat-no" title="statement not covered" > * @description</span>
1951
+ <span class="cstat-no" title="statement not covered" > * Initiates the pairing offer flow and waits for connection. For more</span>
1952
+ <span class="cstat-no" title="statement not covered" > * control over QR display timing, use {@link createPairingOffer} and</span>
1953
+ <span class="cstat-no" title="statement not covered" > * {@link waitForSessionApproval} separately.</span>
1954
+ <span class="cstat-no" title="statement not covered" > *</span>
1955
+ <span class="cstat-no" title="statement not covered" > * This method:</span>
1956
+ <span class="cstat-no" title="statement not covered" > * 1. Creates a pairing offer</span>
1957
+ <span class="cstat-no" title="statement not covered" > * 2. Updates `pairingOffer` signal with QR data</span>
1958
+ <span class="cstat-no" title="statement not covered" > * 3. Waits up to 2 minutes for wallet to connect</span>
1959
+ <span class="cstat-no" title="statement not covered" > *</span>
1960
+ <span class="cstat-no" title="statement not covered" > * @param config - Connection configuration</span>
1961
+ <span class="cstat-no" title="statement not covered" > *</span>
1962
+ <span class="cstat-no" title="statement not covered" > * @throws {Error} If already connected (no-op)</span>
1963
+ <span class="cstat-no" title="statement not covered" > * @throws {Error} If connection times out (2 minutes)</span>
1964
+ <span class="cstat-no" title="statement not covered" > */</span>
1965
+ <span class="cstat-no" title="statement not covered" > async connect(config: ConnectionConfig): Promise&lt;void&gt; {</span>
1966
1966
  <span class="cstat-no" title="statement not covered" > logger.info('Connect called', { config });</span>
1967
1967
  <span class="cstat-no" title="statement not covered" ></span>
1968
1968
  <span class="cstat-no" title="statement not covered" > // If already connected, no-op</span>
@@ -1991,247 +1991,247 @@ export class P2PNativeProvider extends BaseWalletProvider {
1991
1991
  <span class="cstat-no" title="statement not covered" > });</span>
1992
1992
  <span class="cstat-no" title="statement not covered" > });</span>
1993
1993
  <span class="cstat-no" title="statement not covered" > }</span>
1994
- &nbsp;
1995
- /**
1996
- * Disconnects from the wallet and clears session.
1997
- *
1998
- * @description
1999
- * Terminates the P2P session, clears all state signals, and removes
2000
- * persisted session data. The wallet is notified of the disconnection.
2001
- */
2002
- async disconnect(): Promise&lt;void&gt; {
2003
- logger.info('Disconnecting');
2004
- &nbsp;
2005
- try {
2006
- await this.sessionManager.terminateSession();
2007
- } finally {
2008
- this._status.set('disconnected');
2009
- this._connectionState.set('disconnected');
2010
- this._accounts.set([]);
2011
- this._pairingOffer.set(null);
2012
- this._error.set(null);
2013
- &nbsp;
2014
- // Clear persisted session
2015
- this.sessionPersistence.clear();
2016
- }
2017
- }
2018
- &nbsp;
2019
- /**
2020
- * Signs a transaction without submitting it.
2021
- *
2022
- * @description
2023
- * Sends the transaction to the connected wallet for signing. The wallet
2024
- * displays transaction details and prompts the user for approval.
2025
- *
2026
- * @param options - Transaction signing options
2027
- *
2028
- * @returns Promise resolving to signed payload and signature
2029
- *
2030
- * @throws {Error} If not connected to wallet
2031
- * @throws {Error} If user rejects signing
2032
- */
2033
- async signTransaction(options: SignTransactionOptions): Promise&lt;SignResult&gt; {
2034
- if (this._status() !== 'connected') {
2035
- throw new Error('Not connected to wallet');
2036
- }
2037
- &nbsp;
2038
- logger.info('Signing transaction', { account: options.accountAddress });
2039
- &nbsp;
2040
- const result = await this.sessionManager.signTransaction({
2041
- accountAddress: options.accountAddress,
2042
- payload: options.payload,
2043
- ledgerId: options.ledgerId,
2044
- networkId: options.networkId,
2045
- });
2046
- &nbsp;
2047
- return {
2048
- signedPayload: result.signedPayload,
2049
- signature: result.signature,
2050
- metadata: result.metadata,
2051
- };
2052
- }
2053
- &nbsp;
2054
- /**
2055
- * Signs and submits a transaction to the blockchain.
2056
- *
2057
- * @description
2058
- * Performs atomic sign and submit in a single operation. Supports batch
2059
- * transactions when isBatch is true.
2060
- *
2061
- * @param options - Transaction submission options
2062
- *
2063
- * @returns Promise resolving to transaction ID and hash
2064
- *
2065
- * @throws {Error} If not connected to wallet
2066
- * @throws {Error} If user rejects or transaction fails
2067
- */
2068
- async submitTransaction(options: SubmitTransactionOptions): Promise&lt;SubmitResult&gt; {
2069
- if (this._status() !== 'connected') <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
1994
+ <span class="cstat-no" title="statement not covered" ></span>
1995
+ <span class="cstat-no" title="statement not covered" > /**</span>
1996
+ <span class="cstat-no" title="statement not covered" > * Disconnects from the wallet and clears session.</span>
1997
+ <span class="cstat-no" title="statement not covered" > *</span>
1998
+ <span class="cstat-no" title="statement not covered" > * @description</span>
1999
+ <span class="cstat-no" title="statement not covered" > * Terminates the P2P session, clears all state signals, and removes</span>
2000
+ <span class="cstat-no" title="statement not covered" > * persisted session data. The wallet is notified of the disconnection.</span>
2001
+ <span class="cstat-no" title="statement not covered" > */</span>
2002
+ <span class="cstat-no" title="statement not covered" > async disconnect(): Promise&lt;void&gt; {</span>
2003
+ <span class="cstat-no" title="statement not covered" > logger.info('Disconnecting');</span>
2004
+ <span class="cstat-no" title="statement not covered" ></span>
2005
+ <span class="cstat-no" title="statement not covered" > try {</span>
2006
+ <span class="cstat-no" title="statement not covered" > await this.sessionManager.terminateSession();</span>
2007
+ <span class="cstat-no" title="statement not covered" > } finally {</span>
2008
+ <span class="cstat-no" title="statement not covered" > this._status.set('disconnected');</span>
2009
+ <span class="cstat-no" title="statement not covered" > this._connectionState.set('disconnected');</span>
2010
+ <span class="cstat-no" title="statement not covered" > this._accounts.set([]);</span>
2011
+ <span class="cstat-no" title="statement not covered" > this._pairingOffer.set(null);</span>
2012
+ <span class="cstat-no" title="statement not covered" > this._error.set(null);</span>
2013
+ <span class="cstat-no" title="statement not covered" ></span>
2014
+ <span class="cstat-no" title="statement not covered" > // Clear persisted session</span>
2015
+ <span class="cstat-no" title="statement not covered" > this.sessionPersistence.clear();</span>
2016
+ <span class="cstat-no" title="statement not covered" > }</span>
2017
+ <span class="cstat-no" title="statement not covered" > }</span>
2018
+ <span class="cstat-no" title="statement not covered" ></span>
2019
+ <span class="cstat-no" title="statement not covered" > /**</span>
2020
+ <span class="cstat-no" title="statement not covered" > * Signs a transaction without submitting it.</span>
2021
+ <span class="cstat-no" title="statement not covered" > *</span>
2022
+ <span class="cstat-no" title="statement not covered" > * @description</span>
2023
+ <span class="cstat-no" title="statement not covered" > * Sends the transaction to the connected wallet for signing. The wallet</span>
2024
+ <span class="cstat-no" title="statement not covered" > * displays transaction details and prompts the user for approval.</span>
2025
+ <span class="cstat-no" title="statement not covered" > *</span>
2026
+ <span class="cstat-no" title="statement not covered" > * @param options - Transaction signing options</span>
2027
+ <span class="cstat-no" title="statement not covered" > *</span>
2028
+ <span class="cstat-no" title="statement not covered" > * @returns Promise resolving to signed payload and signature</span>
2029
+ <span class="cstat-no" title="statement not covered" > *</span>
2030
+ <span class="cstat-no" title="statement not covered" > * @throws {Error} If not connected to wallet</span>
2031
+ <span class="cstat-no" title="statement not covered" > * @throws {Error} If user rejects signing</span>
2032
+ <span class="cstat-no" title="statement not covered" > */</span>
2033
+ <span class="cstat-no" title="statement not covered" > async signTransaction(options: SignTransactionOptions): Promise&lt;SignResult&gt; {</span>
2034
+ <span class="cstat-no" title="statement not covered" > if (this._status() !== 'connected') {</span>
2070
2035
  <span class="cstat-no" title="statement not covered" > throw new Error('Not connected to wallet');</span>
2071
2036
  <span class="cstat-no" title="statement not covered" > }</span>
2072
- &nbsp;
2073
- logger.info('Submitting transaction', { account: options.accountAddress });
2074
- &nbsp;
2075
- const result = await this.sessionManager.submitTransaction({
2076
- accountAddress: options.accountAddress,
2077
- payload: options.payload,
2078
- ledgerId: options.ledgerId,
2079
- networkId: options.networkId,
2080
- isBatch: options.isBatch,
2081
- batchKey: options.batchKey,
2082
- innerTransactions: options.innerTransactions,
2083
- });
2084
- &nbsp;
2085
- return {
2086
- transactionId: result.transactionId,
2087
- transactionHash: result.transactionHash,
2088
- metadata: result.metadata,
2089
- };
2090
- }
2091
- &nbsp;
2092
- /**
2093
- * Signs and executes a transaction atomically in a single prompt.
2094
- *
2095
- * @description
2096
- * Delegates to {@link submitTransaction}. This method exists so that
2097
- * {@link UnifiedWalletService.signAndExecuteTransaction} can detect native
2098
- * atomic sign+submit support on the provider (via duck-typing) and avoid
2099
- * its fallback path that chains separate signTransaction + submitTransaction
2100
- * calls. Mirrors the pattern used by HsuiteNativeProvider and the
2101
- * WalletConnect signers.
2102
- *
2103
- * @param options - Transaction submission options
2104
- *
2105
- * @returns Promise resolving to submission result with transaction ID
2106
- */
2107
- <span class="fstat-no" title="function not covered" > async signAndExecuteTransaction(options: SubmitTransactionOptions): Promise&lt;SubmitResult&gt; {</span>
2037
+ <span class="cstat-no" title="statement not covered" ></span>
2038
+ <span class="cstat-no" title="statement not covered" > logger.info('Signing transaction', { account: options.accountAddress });</span>
2039
+ <span class="cstat-no" title="statement not covered" ></span>
2040
+ <span class="cstat-no" title="statement not covered" > const result = await this.sessionManager.signTransaction({</span>
2041
+ <span class="cstat-no" title="statement not covered" > accountAddress: options.accountAddress,</span>
2042
+ <span class="cstat-no" title="statement not covered" > payload: options.payload,</span>
2043
+ <span class="cstat-no" title="statement not covered" > ledgerId: options.ledgerId,</span>
2044
+ <span class="cstat-no" title="statement not covered" > networkId: options.networkId,</span>
2045
+ <span class="cstat-no" title="statement not covered" > });</span>
2046
+ <span class="cstat-no" title="statement not covered" ></span>
2047
+ <span class="cstat-no" title="statement not covered" > return {</span>
2048
+ <span class="cstat-no" title="statement not covered" > signedPayload: result.signedPayload,</span>
2049
+ <span class="cstat-no" title="statement not covered" > signature: result.signature,</span>
2050
+ <span class="cstat-no" title="statement not covered" > metadata: result.metadata,</span>
2051
+ <span class="cstat-no" title="statement not covered" > };</span>
2052
+ <span class="cstat-no" title="statement not covered" > }</span>
2053
+ <span class="cstat-no" title="statement not covered" ></span>
2054
+ <span class="cstat-no" title="statement not covered" > /**</span>
2055
+ <span class="cstat-no" title="statement not covered" > * Signs and submits a transaction to the blockchain.</span>
2056
+ <span class="cstat-no" title="statement not covered" > *</span>
2057
+ <span class="cstat-no" title="statement not covered" > * @description</span>
2058
+ <span class="cstat-no" title="statement not covered" > * Performs atomic sign and submit in a single operation. Supports batch</span>
2059
+ <span class="cstat-no" title="statement not covered" > * transactions when isBatch is true.</span>
2060
+ <span class="cstat-no" title="statement not covered" > *</span>
2061
+ <span class="cstat-no" title="statement not covered" > * @param options - Transaction submission options</span>
2062
+ <span class="cstat-no" title="statement not covered" > *</span>
2063
+ <span class="cstat-no" title="statement not covered" > * @returns Promise resolving to transaction ID and hash</span>
2064
+ <span class="cstat-no" title="statement not covered" > *</span>
2065
+ <span class="cstat-no" title="statement not covered" > * @throws {Error} If not connected to wallet</span>
2066
+ <span class="cstat-no" title="statement not covered" > * @throws {Error} If user rejects or transaction fails</span>
2067
+ <span class="cstat-no" title="statement not covered" > */</span>
2068
+ <span class="cstat-no" title="statement not covered" > async submitTransaction(options: SubmitTransactionOptions): Promise&lt;SubmitResult&gt; {</span>
2069
+ <span class="cstat-no" title="statement not covered" > if (this._status() !== 'connected') {</span>
2070
+ <span class="cstat-no" title="statement not covered" > throw new Error('Not connected to wallet');</span>
2071
+ <span class="cstat-no" title="statement not covered" > }</span>
2072
+ <span class="cstat-no" title="statement not covered" ></span>
2073
+ <span class="cstat-no" title="statement not covered" > logger.info('Submitting transaction', { account: options.accountAddress });</span>
2074
+ <span class="cstat-no" title="statement not covered" ></span>
2075
+ <span class="cstat-no" title="statement not covered" > const result = await this.sessionManager.submitTransaction({</span>
2076
+ <span class="cstat-no" title="statement not covered" > accountAddress: options.accountAddress,</span>
2077
+ <span class="cstat-no" title="statement not covered" > payload: options.payload,</span>
2078
+ <span class="cstat-no" title="statement not covered" > ledgerId: options.ledgerId,</span>
2079
+ <span class="cstat-no" title="statement not covered" > networkId: options.networkId,</span>
2080
+ <span class="cstat-no" title="statement not covered" > isBatch: options.isBatch,</span>
2081
+ <span class="cstat-no" title="statement not covered" > batchKey: options.batchKey,</span>
2082
+ <span class="cstat-no" title="statement not covered" > innerTransactions: options.innerTransactions,</span>
2083
+ <span class="cstat-no" title="statement not covered" > });</span>
2084
+ <span class="cstat-no" title="statement not covered" ></span>
2085
+ <span class="cstat-no" title="statement not covered" > return {</span>
2086
+ <span class="cstat-no" title="statement not covered" > transactionId: result.transactionId,</span>
2087
+ <span class="cstat-no" title="statement not covered" > transactionHash: result.transactionHash,</span>
2088
+ <span class="cstat-no" title="statement not covered" > metadata: result.metadata,</span>
2089
+ <span class="cstat-no" title="statement not covered" > };</span>
2090
+ <span class="cstat-no" title="statement not covered" > }</span>
2091
+ <span class="cstat-no" title="statement not covered" ></span>
2092
+ <span class="cstat-no" title="statement not covered" > /**</span>
2093
+ <span class="cstat-no" title="statement not covered" > * Signs and executes a transaction atomically in a single prompt.</span>
2094
+ <span class="cstat-no" title="statement not covered" > *</span>
2095
+ <span class="cstat-no" title="statement not covered" > * @description</span>
2096
+ <span class="cstat-no" title="statement not covered" > * Delegates to {@link submitTransaction}. This method exists so that</span>
2097
+ <span class="cstat-no" title="statement not covered" > * {@link UnifiedWalletService.signAndExecuteTransaction} can detect native</span>
2098
+ <span class="cstat-no" title="statement not covered" > * atomic sign+submit support on the provider (via duck-typing) and avoid</span>
2099
+ <span class="cstat-no" title="statement not covered" > * its fallback path that chains separate signTransaction + submitTransaction</span>
2100
+ <span class="cstat-no" title="statement not covered" > * calls. Mirrors the pattern used by HsuiteNativeProvider and the</span>
2101
+ <span class="cstat-no" title="statement not covered" > * WalletConnect signers.</span>
2102
+ <span class="cstat-no" title="statement not covered" > *</span>
2103
+ <span class="cstat-no" title="statement not covered" > * @param options - Transaction submission options</span>
2104
+ <span class="cstat-no" title="statement not covered" > *</span>
2105
+ <span class="cstat-no" title="statement not covered" > * @returns Promise resolving to submission result with transaction ID</span>
2106
+ <span class="cstat-no" title="statement not covered" > */</span>
2107
+ <span class="cstat-no" title="statement not covered" > async signAndExecuteTransaction(options: SubmitTransactionOptions): Promise&lt;SubmitResult&gt; {</span>
2108
2108
  <span class="cstat-no" title="statement not covered" > return this.submitTransaction(options);</span>
2109
2109
  <span class="cstat-no" title="statement not covered" > }</span>
2110
- &nbsp;
2111
- /**
2112
- * Signs an arbitrary message for authentication or verification.
2113
- *
2114
- * @description
2115
- * Requests the wallet to sign a non-transaction message. Used for
2116
- * authentication challenges, DAO voting, or off-chain signatures.
2117
- *
2118
- * @param options - Message signing options
2119
- *
2120
- * @returns Promise resolving to signature and public key
2121
- *
2122
- * @throws {Error} If not connected to wallet
2123
- * @throws {Error} If user rejects signing
2124
- */
2125
- async signMessage(options: SignMessageOptions): Promise&lt;SignMessageResult&gt; {
2126
- if (this._status() !== 'connected') <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
2110
+ <span class="cstat-no" title="statement not covered" ></span>
2111
+ <span class="cstat-no" title="statement not covered" > /**</span>
2112
+ <span class="cstat-no" title="statement not covered" > * Signs an arbitrary message for authentication or verification.</span>
2113
+ <span class="cstat-no" title="statement not covered" > *</span>
2114
+ <span class="cstat-no" title="statement not covered" > * @description</span>
2115
+ <span class="cstat-no" title="statement not covered" > * Requests the wallet to sign a non-transaction message. Used for</span>
2116
+ <span class="cstat-no" title="statement not covered" > * authentication challenges, DAO voting, or off-chain signatures.</span>
2117
+ <span class="cstat-no" title="statement not covered" > *</span>
2118
+ <span class="cstat-no" title="statement not covered" > * @param options - Message signing options</span>
2119
+ <span class="cstat-no" title="statement not covered" > *</span>
2120
+ <span class="cstat-no" title="statement not covered" > * @returns Promise resolving to signature and public key</span>
2121
+ <span class="cstat-no" title="statement not covered" > *</span>
2122
+ <span class="cstat-no" title="statement not covered" > * @throws {Error} If not connected to wallet</span>
2123
+ <span class="cstat-no" title="statement not covered" > * @throws {Error} If user rejects signing</span>
2124
+ <span class="cstat-no" title="statement not covered" > */</span>
2125
+ <span class="cstat-no" title="statement not covered" > async signMessage(options: SignMessageOptions): Promise&lt;SignMessageResult&gt; {</span>
2126
+ <span class="cstat-no" title="statement not covered" > if (this._status() !== 'connected') {</span>
2127
2127
  <span class="cstat-no" title="statement not covered" > throw new Error('Not connected to wallet');</span>
2128
2128
  <span class="cstat-no" title="statement not covered" > }</span>
2129
- &nbsp;
2130
- logger.info('Signing message', { account: options.accountAddress });
2131
- &nbsp;
2132
- const result = await this.sessionManager.signMessage({
2133
- accountAddress: options.accountAddress,
2134
- message: options.message,
2135
- encoding: options.encoding,
2136
- ledgerId: options.ledgerId,
2137
- networkId: options.networkId,
2138
- });
2139
- &nbsp;
2140
- return {
2141
- signature: result.signature,
2142
- publicKey: result.publicKey,
2143
- metadata: result.metadata,
2144
- };
2145
- }
2146
- &nbsp;
2147
- /**
2148
- * Checks if P2P provider is available in the current environment.
2149
- *
2150
- * @description
2151
- * P2P Native requires WebRTC support (RTCPeerConnection). This is available
2152
- * in all modern browsers and most mobile WebViews.
2153
- *
2154
- * @returns Promise resolving to true if WebRTC is available
2155
- */
2156
- async isAvailable(): Promise&lt;boolean&gt; {
2157
- // Check for WebRTC support
2158
- return typeof RTCPeerConnection !== 'undefined';
2159
- }
2160
- &nbsp;
2161
- // ========== Private Methods ==========
2162
- &nbsp;
2163
- /**
2164
- * Set up listeners for session manager events
2165
- */
2166
- private setupSessionManagerListeners(): void {
2167
- // Connection established — wrap in NgZone to ensure Angular change
2168
- // detection picks up signal updates from Nostr/WebSocket callbacks
2169
- this.sessionManager.onConnected((session) =&gt; {
2170
- logger.info('Session connected', { sessionId: session?.id });
2171
- this.ngZone.run(() =&gt; {
2172
- this._connectionState.set('connected');
2173
- this._status.set('connected');
2174
- this._pairingOffer.set(null);
2175
- &nbsp;
2176
- // Update accounts from session - ensure providerId is set
2177
- if (session?.accounts) {
2178
- const accountsWithProvider = this.ensureProviderIdOnAccounts(session.accounts);
2179
- this._accounts.set(accountsWithProvider);
2180
- }
2181
- });
2182
- &nbsp;
2183
- // Persist session for page reload recovery
2184
- if (session) {
2185
- this.sessionPersistence.save(session);
2186
- }
2187
- });
2188
- &nbsp;
2189
- // Session terminated
2190
- this.sessionManager.onDisconnected(() =&gt; {
2191
- logger.info('Session disconnected');
2192
- this.ngZone.run(() =&gt; {
2193
- this._connectionState.set('disconnected');
2194
- this._status.set('disconnected');
2195
- this._accounts.set([]);
2196
- });
2197
- &nbsp;
2198
- // Clear persisted session
2199
- this.sessionPersistence.clear();
2200
- });
2201
- &nbsp;
2202
- // Error occurred
2203
- this.sessionManager.onError((error: Error) =&gt; {
2204
- logger.error('Session error', { error });
2205
- this.ngZone.run(() =&gt; {
2206
- this._connectionState.set('error');
2207
- this._status.set('error');
2208
- this._error.set(error.message);
2209
- });
2210
- });
2211
- &nbsp;
2212
- // Accounts updated
2213
- this.sessionManager.onAccountsChanged((accounts) =&gt; {
2214
- logger.debug('Accounts updated', { count: accounts.length });
2215
- this.ngZone.run(() =&gt; {
2216
- const accountsWithProvider = this.ensureProviderIdOnAccounts(accounts);
2217
- this._accounts.set(accountsWithProvider);
2218
- });
2219
- });
2220
- }
2221
- &nbsp;
2222
- /**
2223
- * Ensure all accounts have providerId and providerType set correctly
2224
- * @param accounts
2225
- */
2226
- private ensureProviderIdOnAccounts(accounts: UnifiedAccount[]): UnifiedAccount[] {
2227
- return accounts.map((account) =&gt; ({
2228
- ...account,
2229
- id: account.id || `${this.id}-${account.address}`,
2230
- providerId: this.id,
2231
- providerType: this.metadata.type,
2232
- }));
2233
- }
2234
- }
2129
+ <span class="cstat-no" title="statement not covered" ></span>
2130
+ <span class="cstat-no" title="statement not covered" > logger.info('Signing message', { account: options.accountAddress });</span>
2131
+ <span class="cstat-no" title="statement not covered" ></span>
2132
+ <span class="cstat-no" title="statement not covered" > const result = await this.sessionManager.signMessage({</span>
2133
+ <span class="cstat-no" title="statement not covered" > accountAddress: options.accountAddress,</span>
2134
+ <span class="cstat-no" title="statement not covered" > message: options.message,</span>
2135
+ <span class="cstat-no" title="statement not covered" > encoding: options.encoding,</span>
2136
+ <span class="cstat-no" title="statement not covered" > ledgerId: options.ledgerId,</span>
2137
+ <span class="cstat-no" title="statement not covered" > networkId: options.networkId,</span>
2138
+ <span class="cstat-no" title="statement not covered" > });</span>
2139
+ <span class="cstat-no" title="statement not covered" ></span>
2140
+ <span class="cstat-no" title="statement not covered" > return {</span>
2141
+ <span class="cstat-no" title="statement not covered" > signature: result.signature,</span>
2142
+ <span class="cstat-no" title="statement not covered" > publicKey: result.publicKey,</span>
2143
+ <span class="cstat-no" title="statement not covered" > metadata: result.metadata,</span>
2144
+ <span class="cstat-no" title="statement not covered" > };</span>
2145
+ <span class="cstat-no" title="statement not covered" > }</span>
2146
+ <span class="cstat-no" title="statement not covered" ></span>
2147
+ <span class="cstat-no" title="statement not covered" > /**</span>
2148
+ <span class="cstat-no" title="statement not covered" > * Checks if P2P provider is available in the current environment.</span>
2149
+ <span class="cstat-no" title="statement not covered" > *</span>
2150
+ <span class="cstat-no" title="statement not covered" > * @description</span>
2151
+ <span class="cstat-no" title="statement not covered" > * P2P Native requires WebRTC support (RTCPeerConnection). This is available</span>
2152
+ <span class="cstat-no" title="statement not covered" > * in all modern browsers and most mobile WebViews.</span>
2153
+ <span class="cstat-no" title="statement not covered" > *</span>
2154
+ <span class="cstat-no" title="statement not covered" > * @returns Promise resolving to true if WebRTC is available</span>
2155
+ <span class="cstat-no" title="statement not covered" > */</span>
2156
+ <span class="cstat-no" title="statement not covered" > async isAvailable(): Promise&lt;boolean&gt; {</span>
2157
+ <span class="cstat-no" title="statement not covered" > // Check for WebRTC support</span>
2158
+ <span class="cstat-no" title="statement not covered" > return typeof RTCPeerConnection !== 'undefined';</span>
2159
+ <span class="cstat-no" title="statement not covered" > }</span>
2160
+ <span class="cstat-no" title="statement not covered" ></span>
2161
+ <span class="cstat-no" title="statement not covered" > // ========== Private Methods ==========</span>
2162
+ <span class="cstat-no" title="statement not covered" ></span>
2163
+ <span class="cstat-no" title="statement not covered" > /**</span>
2164
+ <span class="cstat-no" title="statement not covered" > * Set up listeners for session manager events</span>
2165
+ <span class="cstat-no" title="statement not covered" > */</span>
2166
+ <span class="cstat-no" title="statement not covered" > private setupSessionManagerListeners(): void {</span>
2167
+ <span class="cstat-no" title="statement not covered" > // Connection established — wrap in NgZone to ensure Angular change</span>
2168
+ <span class="cstat-no" title="statement not covered" > // detection picks up signal updates from Nostr/WebSocket callbacks</span>
2169
+ <span class="cstat-no" title="statement not covered" > this.sessionManager.onConnected((session) =&gt; {</span>
2170
+ <span class="cstat-no" title="statement not covered" > logger.info('Session connected', { sessionId: session?.id });</span>
2171
+ <span class="cstat-no" title="statement not covered" > this.ngZone.run(() =&gt; {</span>
2172
+ <span class="cstat-no" title="statement not covered" > this._connectionState.set('connected');</span>
2173
+ <span class="cstat-no" title="statement not covered" > this._status.set('connected');</span>
2174
+ <span class="cstat-no" title="statement not covered" > this._pairingOffer.set(null);</span>
2175
+ <span class="cstat-no" title="statement not covered" ></span>
2176
+ <span class="cstat-no" title="statement not covered" > // Update accounts from session - ensure providerId is set</span>
2177
+ <span class="cstat-no" title="statement not covered" > if (session?.accounts) {</span>
2178
+ <span class="cstat-no" title="statement not covered" > const accountsWithProvider = this.ensureProviderIdOnAccounts(session.accounts);</span>
2179
+ <span class="cstat-no" title="statement not covered" > this._accounts.set(accountsWithProvider);</span>
2180
+ <span class="cstat-no" title="statement not covered" > }</span>
2181
+ <span class="cstat-no" title="statement not covered" > });</span>
2182
+ <span class="cstat-no" title="statement not covered" ></span>
2183
+ <span class="cstat-no" title="statement not covered" > // Persist session for page reload recovery</span>
2184
+ <span class="cstat-no" title="statement not covered" > if (session) {</span>
2185
+ <span class="cstat-no" title="statement not covered" > this.sessionPersistence.save(session);</span>
2186
+ <span class="cstat-no" title="statement not covered" > }</span>
2187
+ <span class="cstat-no" title="statement not covered" > });</span>
2188
+ <span class="cstat-no" title="statement not covered" ></span>
2189
+ <span class="cstat-no" title="statement not covered" > // Session terminated</span>
2190
+ <span class="cstat-no" title="statement not covered" > this.sessionManager.onDisconnected(() =&gt; {</span>
2191
+ <span class="cstat-no" title="statement not covered" > logger.info('Session disconnected');</span>
2192
+ <span class="cstat-no" title="statement not covered" > this.ngZone.run(() =&gt; {</span>
2193
+ <span class="cstat-no" title="statement not covered" > this._connectionState.set('disconnected');</span>
2194
+ <span class="cstat-no" title="statement not covered" > this._status.set('disconnected');</span>
2195
+ <span class="cstat-no" title="statement not covered" > this._accounts.set([]);</span>
2196
+ <span class="cstat-no" title="statement not covered" > });</span>
2197
+ <span class="cstat-no" title="statement not covered" ></span>
2198
+ <span class="cstat-no" title="statement not covered" > // Clear persisted session</span>
2199
+ <span class="cstat-no" title="statement not covered" > this.sessionPersistence.clear();</span>
2200
+ <span class="cstat-no" title="statement not covered" > });</span>
2201
+ <span class="cstat-no" title="statement not covered" ></span>
2202
+ <span class="cstat-no" title="statement not covered" > // Error occurred</span>
2203
+ <span class="cstat-no" title="statement not covered" > this.sessionManager.onError((error: Error) =&gt; {</span>
2204
+ <span class="cstat-no" title="statement not covered" > logger.error('Session error', { error });</span>
2205
+ <span class="cstat-no" title="statement not covered" > this.ngZone.run(() =&gt; {</span>
2206
+ <span class="cstat-no" title="statement not covered" > this._connectionState.set('error');</span>
2207
+ <span class="cstat-no" title="statement not covered" > this._status.set('error');</span>
2208
+ <span class="cstat-no" title="statement not covered" > this._error.set(error.message);</span>
2209
+ <span class="cstat-no" title="statement not covered" > });</span>
2210
+ <span class="cstat-no" title="statement not covered" > });</span>
2211
+ <span class="cstat-no" title="statement not covered" ></span>
2212
+ <span class="cstat-no" title="statement not covered" > // Accounts updated</span>
2213
+ <span class="cstat-no" title="statement not covered" > this.sessionManager.onAccountsChanged((accounts) =&gt; {</span>
2214
+ <span class="cstat-no" title="statement not covered" > logger.debug('Accounts updated', { count: accounts.length });</span>
2215
+ <span class="cstat-no" title="statement not covered" > this.ngZone.run(() =&gt; {</span>
2216
+ <span class="cstat-no" title="statement not covered" > const accountsWithProvider = this.ensureProviderIdOnAccounts(accounts);</span>
2217
+ <span class="cstat-no" title="statement not covered" > this._accounts.set(accountsWithProvider);</span>
2218
+ <span class="cstat-no" title="statement not covered" > });</span>
2219
+ <span class="cstat-no" title="statement not covered" > });</span>
2220
+ <span class="cstat-no" title="statement not covered" > }</span>
2221
+ <span class="cstat-no" title="statement not covered" ></span>
2222
+ <span class="cstat-no" title="statement not covered" > /**</span>
2223
+ <span class="cstat-no" title="statement not covered" > * Ensure all accounts have providerId and providerType set correctly</span>
2224
+ <span class="cstat-no" title="statement not covered" > * @param accounts</span>
2225
+ <span class="cstat-no" title="statement not covered" > */</span>
2226
+ <span class="cstat-no" title="statement not covered" > private ensureProviderIdOnAccounts(accounts: UnifiedAccount[]): UnifiedAccount[] {</span>
2227
+ <span class="cstat-no" title="statement not covered" > return accounts.map((account) =&gt; ({</span>
2228
+ <span class="cstat-no" title="statement not covered" > ...account,</span>
2229
+ <span class="cstat-no" title="statement not covered" > id: account.id || `${this.id}-${account.address}`,</span>
2230
+ <span class="cstat-no" title="statement not covered" > providerId: this.id,</span>
2231
+ <span class="cstat-no" title="statement not covered" > providerType: this.metadata.type,</span>
2232
+ <span class="cstat-no" title="statement not covered" > }));</span>
2233
+ <span class="cstat-no" title="statement not covered" > }</span>
2234
+ <span class="cstat-no" title="statement not covered" >}</span>
2235
2235
  &nbsp;</pre></td></tr></table></pre>
2236
2236
 
2237
2237
  <div class='push'></div><!-- for sticky footer -->
@@ -2239,7 +2239,7 @@ export class P2PNativeProvider extends BaseWalletProvider {
2239
2239
  <div class='footer quiet pad2 space-top1 center small'>
2240
2240
  Code coverage generated by
2241
2241
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
2242
- at 2026-06-02T14:30:38.257Z
2242
+ at 2026-06-10T09:00:36.727Z
2243
2243
  </div>
2244
2244
  <script src="../../../prettify.js"></script>
2245
2245
  <script>