sportident.js 1.0.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 (151) hide show
  1. package/.dependency-cruiser.js +233 -0
  2. package/.editorconfig +12 -0
  3. package/.eslintignore +6 -0
  4. package/.github/ISSUE_TEMPLATE/bug_report.md +35 -0
  5. package/.github/ISSUE_TEMPLATE/feature_request.md +17 -0
  6. package/.github/workflows/npm.yml +17 -0
  7. package/LICENSE +21 -0
  8. package/README.md +31 -0
  9. package/babel.config.js +21 -0
  10. package/build-docs.sh +25 -0
  11. package/docs/index.md +9 -0
  12. package/docs/typedoc/index.md +11 -0
  13. package/eslint.base.js +232 -0
  14. package/install.sh +6 -0
  15. package/jest.config.ts +49 -0
  16. package/nx.json +39 -0
  17. package/package.json +51 -0
  18. package/src/SiCard/BaseSiCard.test.ts +187 -0
  19. package/src/SiCard/BaseSiCard.ts +101 -0
  20. package/src/SiCard/IRaceResultData.ts +16 -0
  21. package/src/SiCard/ISiCard.ts +23 -0
  22. package/src/SiCard/ISiCardExamples.ts +4 -0
  23. package/src/SiCard/index.ts +2 -0
  24. package/src/SiCard/raceResultTools.test.ts +260 -0
  25. package/src/SiCard/raceResultTools.ts +150 -0
  26. package/src/SiCard/types/FCard.test.ts +19 -0
  27. package/src/SiCard/types/FCard.ts +14 -0
  28. package/src/SiCard/types/ModernSiCard.test.ts +186 -0
  29. package/src/SiCard/types/ModernSiCard.ts +241 -0
  30. package/src/SiCard/types/PCard.test.ts +19 -0
  31. package/src/SiCard/types/PCard.ts +14 -0
  32. package/src/SiCard/types/SIAC.test.ts +84 -0
  33. package/src/SiCard/types/SIAC.ts +19 -0
  34. package/src/SiCard/types/SiCard10.test.ts +85 -0
  35. package/src/SiCard/types/SiCard10.ts +17 -0
  36. package/src/SiCard/types/SiCard11.test.ts +84 -0
  37. package/src/SiCard/types/SiCard11.ts +19 -0
  38. package/src/SiCard/types/SiCard5.test.ts +149 -0
  39. package/src/SiCard/types/SiCard5.ts +129 -0
  40. package/src/SiCard/types/SiCard6.test.ts +179 -0
  41. package/src/SiCard/types/SiCard6.ts +222 -0
  42. package/src/SiCard/types/SiCard8.test.ts +137 -0
  43. package/src/SiCard/types/SiCard8.ts +129 -0
  44. package/src/SiCard/types/SiCard9.test.ts +132 -0
  45. package/src/SiCard/types/SiCard9.ts +128 -0
  46. package/src/SiCard/types/TCard.test.ts +19 -0
  47. package/src/SiCard/types/TCard.ts +14 -0
  48. package/src/SiCard/types/index.test.ts +26 -0
  49. package/src/SiCard/types/index.ts +15 -0
  50. package/src/SiCard/types/modernSiCardExamples.ts +364 -0
  51. package/src/SiCard/types/siCard5Examples.ts +73 -0
  52. package/src/SiCard/types/siCard6Examples.ts +262 -0
  53. package/src/SiCard/types/siCard8Examples.ts +152 -0
  54. package/src/SiCard/types/siCard9Examples.ts +143 -0
  55. package/src/SiDevice/INavigatorWebSerial.ts +78 -0
  56. package/src/SiDevice/INavigatorWebUsb.ts +62 -0
  57. package/src/SiDevice/ISiDevice.ts +48 -0
  58. package/src/SiDevice/ISiDeviceDriver.ts +35 -0
  59. package/src/SiDevice/README.md +13 -0
  60. package/src/SiDevice/SiDevice.test.ts +354 -0
  61. package/src/SiDevice/SiDevice.ts +132 -0
  62. package/src/SiDevice/WebSerialSiDeviceDriver.ts +146 -0
  63. package/src/SiDevice/WebUsbSiDeviceDriver.ts +343 -0
  64. package/src/SiDevice/index.ts +3 -0
  65. package/src/SiDevice/testUtils/index.ts +2 -0
  66. package/src/SiDevice/testUtils/testISiDeviceDriver.ts +63 -0
  67. package/src/SiDevice/testUtils/testISiDeviceDriverWithAutodetection.ts +72 -0
  68. package/src/SiStation/BaseSiStation.test.ts +221 -0
  69. package/src/SiStation/BaseSiStation.ts +253 -0
  70. package/src/SiStation/CoupledSiStation.test.ts +41 -0
  71. package/src/SiStation/CoupledSiStation.ts +130 -0
  72. package/src/SiStation/ISiMainStation.ts +29 -0
  73. package/src/SiStation/ISiSendTask.ts +9 -0
  74. package/src/SiStation/ISiStation.ts +88 -0
  75. package/src/SiStation/ISiTargetMultiplexer.ts +51 -0
  76. package/src/SiStation/SiMainStation.test.ts +222 -0
  77. package/src/SiStation/SiMainStation.ts +133 -0
  78. package/src/SiStation/SiSendTask.ts +50 -0
  79. package/src/SiStation/SiTargetMultiplexer.targeting.test.ts +112 -0
  80. package/src/SiStation/SiTargetMultiplexer.test.ts +605 -0
  81. package/src/SiStation/SiTargetMultiplexer.ts +241 -0
  82. package/src/SiStation/index.ts +5 -0
  83. package/src/SiStation/siStationExamples.ts +103 -0
  84. package/src/constants.test.ts +17 -0
  85. package/src/constants.ts +92 -0
  86. package/src/fakes/FakeSiCard/BaseFakeSiCard.test.ts +11 -0
  87. package/src/fakes/FakeSiCard/BaseFakeSiCard.ts +10 -0
  88. package/src/fakes/FakeSiCard/IFakeSiCard.ts +6 -0
  89. package/src/fakes/FakeSiCard/index.ts +2 -0
  90. package/src/fakes/FakeSiCard/types/FakeModernSiCard.test.ts +62 -0
  91. package/src/fakes/FakeSiCard/types/FakeModernSiCard.ts +43 -0
  92. package/src/fakes/FakeSiCard/types/FakeSIAC.ts +17 -0
  93. package/src/fakes/FakeSiCard/types/FakeSiCard10.ts +17 -0
  94. package/src/fakes/FakeSiCard/types/FakeSiCard11.ts +17 -0
  95. package/src/fakes/FakeSiCard/types/FakeSiCard5.test.ts +42 -0
  96. package/src/fakes/FakeSiCard/types/FakeSiCard5.ts +40 -0
  97. package/src/fakes/FakeSiCard/types/FakeSiCard6.test.ts +62 -0
  98. package/src/fakes/FakeSiCard/types/FakeSiCard6.ts +44 -0
  99. package/src/fakes/FakeSiCard/types/FakeSiCard8.ts +16 -0
  100. package/src/fakes/FakeSiCard/types/FakeSiCard9.ts +16 -0
  101. package/src/fakes/FakeSiCard/types/index.ts +7 -0
  102. package/src/fakes/FakeSiDeviceDriver.ts +148 -0
  103. package/src/fakes/FakeSiMainStation.test.ts +141 -0
  104. package/src/fakes/FakeSiMainStation.ts +118 -0
  105. package/src/fakes/IFakeSiMainStation.ts +15 -0
  106. package/src/fakes/index.ts +2 -0
  107. package/src/index.ts +24 -0
  108. package/src/siProtocol.test.ts +509 -0
  109. package/src/siProtocol.ts +417 -0
  110. package/src/storage/SiArray.test.ts +103 -0
  111. package/src/storage/SiArray.ts +56 -0
  112. package/src/storage/SiBool.test.ts +81 -0
  113. package/src/storage/SiBool.ts +47 -0
  114. package/src/storage/SiDataType.test.ts +81 -0
  115. package/src/storage/SiDataType.ts +60 -0
  116. package/src/storage/SiDict.test.ts +115 -0
  117. package/src/storage/SiDict.ts +60 -0
  118. package/src/storage/SiEnum.test.ts +77 -0
  119. package/src/storage/SiEnum.ts +48 -0
  120. package/src/storage/SiFieldValue.test.ts +58 -0
  121. package/src/storage/SiFieldValue.ts +23 -0
  122. package/src/storage/SiInt.test.ts +80 -0
  123. package/src/storage/SiInt.ts +84 -0
  124. package/src/storage/SiModified.test.ts +135 -0
  125. package/src/storage/SiModified.ts +59 -0
  126. package/src/storage/SiStorage.test.ts +51 -0
  127. package/src/storage/SiStorage.ts +44 -0
  128. package/src/storage/index.test.ts +222 -0
  129. package/src/storage/index.ts +12 -0
  130. package/src/storage/interfaces.ts +41 -0
  131. package/src/storage/siStringEncoding.ts +1361 -0
  132. package/src/testUtils.test.ts +266 -0
  133. package/src/testUtils.ts +75 -0
  134. package/src/utils/NumberRange.test.ts +66 -0
  135. package/src/utils/NumberRange.ts +46 -0
  136. package/src/utils/NumberRangeRegistry.test.ts +49 -0
  137. package/src/utils/NumberRangeRegistry.ts +43 -0
  138. package/src/utils/bytes.test.ts +126 -0
  139. package/src/utils/bytes.ts +69 -0
  140. package/src/utils/errors.test.ts +29 -0
  141. package/src/utils/errors.ts +20 -0
  142. package/src/utils/events.test.ts +112 -0
  143. package/src/utils/events.ts +68 -0
  144. package/src/utils/general.test.ts +139 -0
  145. package/src/utils/general.ts +69 -0
  146. package/src/utils/index.ts +8 -0
  147. package/src/utils/mixins.test.ts +40 -0
  148. package/src/utils/mixins.ts +13 -0
  149. package/src/utils/typed.ts +3 -0
  150. package/tsconfig.base.json +22 -0
  151. package/tsconfig.json +15 -0
@@ -0,0 +1,152 @@
1
+ import _ from 'lodash';
2
+ import * as utils from '../../utils';
3
+ import type { SiCardSample } from '../ISiCardExamples';
4
+
5
+ const cache = {};
6
+
7
+ const getFullTimesPage = utils.cached(cache, () =>
8
+ utils.unPrettyHex(`
9
+ 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
10
+ 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
11
+ 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
12
+ 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
13
+ 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
14
+ 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
15
+ 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
16
+ 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
17
+ `)
18
+ );
19
+ const getNoTimesPage = utils.cached(cache, () =>
20
+ utils.unPrettyHex(`
21
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
22
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
23
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
24
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
25
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
26
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
27
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
28
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
29
+ `)
30
+ );
31
+
32
+ export const getCardWith16Punches = utils.cached(cache, () => ({
33
+ cardData: {
34
+ uid: 0x772a4299,
35
+ cardNumber: 2345678,
36
+ startTime: {time:8721+43200, weekcounter: 0, weekday: 3},
37
+ finishTime: null,
38
+ checkTime: {time:8735+43200, weekcounter: 3, weekday: 3},
39
+ punchCount: 16,
40
+ punches: [
41
+ { code: 31, time: {time:7967+43200, weekcounter: 1, weekday: 7} },
42
+ { code: 32, time: {time:8224, weekcounter: 2, weekday: 0} },
43
+ { code: 33, time: {time:8481+43200, weekcounter: 2, weekday: 0} },
44
+ { code: 34, time: {time:8738, weekcounter: 2, weekday: 1} },
45
+ { code: 35, time: {time:8995+43200, weekcounter: 2, weekday: 1} },
46
+ { code: 36, time: {time:9252, weekcounter: 2, weekday: 2} },
47
+ { code: 37, time: {time:9509+43200, weekcounter: 2, weekday: 2} },
48
+ { code: 38, time: {time:9766, weekcounter: 2, weekday: 3} },
49
+ { code: 39, time: {time:10023+43200, weekcounter: 2, weekday: 3} },
50
+ { code: 40, time: {time:10280, weekcounter: 2, weekday: 4} },
51
+ { code: 41, time: {time:10537+43200, weekcounter: 2, weekday: 4} },
52
+ { code: 42, time: {time:10794, weekcounter: 2, weekday: 5} },
53
+ { code: 43, time: {time:11051+43200, weekcounter: 2, weekday: 5} },
54
+ { code: 44, time: {time:11308, weekcounter: 2, weekday: 6} },
55
+ { code: 45, time: {time:11565+43200, weekcounter: 2, weekday: 6} },
56
+ { code: 46, time: {time:11822, weekcounter: 2, weekday: 7} }
57
+ ],
58
+ cardHolder: {
59
+ firstName: 'a',
60
+ lastName: 'b',
61
+ isComplete: true
62
+ }
63
+ },
64
+ storageData: [
65
+ ...utils.unPrettyHex(`
66
+ 77 2A 42 99 EA EA EA EA 37 02 22 1F 07 03 22 11
67
+ EE EE EE EE 0F 7F 10 09 0F 23 CA CE 06 0F 61 53
68
+ 61 3B 62 3B EE EE EE EE EE EE EE EE EE EE EE EE
69
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
70
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
71
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
72
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
73
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
74
+ `),
75
+ ...utils.unPrettyHex(`
76
+ 20 20 20 20 20 20 20 20 1F 1F 1F 1F 20 20 20 20
77
+ 21 21 21 21 22 22 22 22 23 23 23 23 24 24 24 24
78
+ 25 25 25 25 26 26 26 26 27 27 27 27 28 28 28 28
79
+ 29 29 29 29 2A 2A 2A 2A 2B 2B 2B 2B 2C 2C 2C 2C
80
+ 2D 2D 2D 2D 2E 2E 2E 2E EE EE EE EE EE EE EE EE
81
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
82
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
83
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
84
+ `)
85
+ ]
86
+ }));
87
+
88
+ export const getFullCard = utils.cached(cache, () => ({
89
+ cardData: {
90
+ uid: 0x772a4299,
91
+ cardNumber: 2345678,
92
+ startTime: {time:8721+43200, weekcounter: 0, weekday: 3},
93
+ finishTime: {time:8481+43200, weekcounter: 0, weekday: 3},
94
+ checkTime: {time:8735+43200, weekcounter: 3, weekday: 3},
95
+ punchCount: 30,
96
+ punches: _.range(30).map(() => ({ code: 32, time: {time:8224, weekcounter: 2, weekday: 0} })),
97
+ cardHolder: {
98
+ firstName: 'a',
99
+ lastName: 'b',
100
+ isComplete: true
101
+ }
102
+ },
103
+ storageData: [
104
+ ...utils.unPrettyHex(`
105
+ 77 2A 42 99 EA EA EA EA 37 02 22 1F 07 03 22 11
106
+ 07 04 21 21 0F 7F 1E 09 0F 23 CA CE 06 0F 61 53
107
+ 61 3B 62 3B EE EE EE EE EE EE EE EE EE EE EE EE
108
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
109
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
110
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
111
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
112
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
113
+ `),
114
+ ...getFullTimesPage()
115
+ ]
116
+ }));
117
+
118
+ export const getEmptyCard = utils.cached(cache, () => ({
119
+ cardData: {
120
+ uid: 0x772a4299,
121
+ cardNumber: 2345678,
122
+ startTime: {time:8721+43200, weekcounter: 0, weekday: 3},
123
+ finishTime: null,
124
+ checkTime: {time:8735+43200, weekcounter: 3, weekday: 3},
125
+ punchCount: 0,
126
+ punches: [],
127
+ cardHolder: {
128
+ firstName: undefined,
129
+ lastName: undefined,
130
+ isComplete: false
131
+ }
132
+ },
133
+ storageData: [
134
+ ...utils.unPrettyHex(`
135
+ 77 2A 42 99 EA EA EA EA 37 02 22 1F 07 03 22 11
136
+ EE EE EE EE 0F 7F 00 09 0F 23 CA CE 06 0F 61 53
137
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
138
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
139
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
140
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
141
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
142
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
143
+ `),
144
+ ...getNoTimesPage()
145
+ ]
146
+ }));
147
+
148
+ export const getSiCard8Examples = (): { [name: string]: SiCardSample } => ({
149
+ cardWith16Punches: getCardWith16Punches(),
150
+ fullCard: getFullCard(),
151
+ emptyCard: getEmptyCard()
152
+ });
@@ -0,0 +1,143 @@
1
+ import _ from 'lodash';
2
+ import * as utils from '../../utils';
3
+ import type { SiCardSample } from '../ISiCardExamples';
4
+
5
+ const cache = {};
6
+
7
+ const getFullTimesPage = utils.cached(cache, () =>
8
+ utils.unPrettyHex(`
9
+ 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
10
+ 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
11
+ 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
12
+ 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
13
+ 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
14
+ 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
15
+ 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
16
+ 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
17
+ `)
18
+ );
19
+ const getNoTimesPage = utils.cached(cache, () =>
20
+ utils.unPrettyHex(`
21
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
22
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
23
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
24
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
25
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
26
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
27
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
28
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
29
+ `)
30
+ );
31
+
32
+ export const getCardWith16Punches = utils.cached(cache, () => ({
33
+ cardData: {
34
+ uid: 0x772a4299,
35
+ cardNumber: 1234567,
36
+ startTime: {time:8721+43200, weekcounter: 0, weekday: 3},
37
+ finishTime: null,
38
+ checkTime: {time:8735+43200, weekcounter: 3, weekday: 3},
39
+ punchCount: 16,
40
+ punches: [
41
+ { code: 31, time: {time:7967+43200, weekcounter: 1, weekday: 7} },
42
+ { code: 32, time: {time:8224, weekcounter: 2, weekday: 0} },
43
+ { code: 33, time: {time:8481+43200, weekcounter: 2, weekday: 0} },
44
+ { code: 34, time: {time:8738, weekcounter: 2, weekday: 1} },
45
+ { code: 35, time: {time:8995+43200, weekcounter: 2, weekday: 1} },
46
+ { code: 36, time: {time:9252, weekcounter: 2, weekday: 2} },
47
+ { code: 37, time: {time:9509+43200, weekcounter: 2, weekday: 2} },
48
+ { code: 38, time: {time:9766, weekcounter: 2, weekday: 3} },
49
+ { code: 39, time: {time:10023+43200, weekcounter: 2, weekday: 3} },
50
+ { code: 40, time: {time:10280, weekcounter: 2, weekday: 4} },
51
+ { code: 41, time: {time:10537+43200, weekcounter: 2, weekday: 4} },
52
+ { code: 42, time: {time:10794, weekcounter: 2, weekday: 5} },
53
+ { code: 43, time: {time:11051+43200, weekcounter: 2, weekday: 5} },
54
+ { code: 44, time: {time:11308, weekcounter: 2, weekday: 6} },
55
+ { code: 45, time: {time:11565+43200, weekcounter: 2, weekday: 6} },
56
+ { code: 46, time: {time:11822, weekcounter: 2, weekday: 7} }
57
+ ],
58
+ cardHolder: {
59
+ firstName: 'a',
60
+ lastName: 'b',
61
+ isComplete: true
62
+ }
63
+ },
64
+ storageData: [
65
+ ...utils.unPrettyHex(`
66
+ 77 2A 42 99 EA EA EA EA 37 02 22 1F 07 03 22 11
67
+ EE EE EE EE 0F 7F 10 09 0F 12 D6 87 06 0F 61 53
68
+ 61 3B 62 3B EE EE EE EE EE EE EE EE EE EE EE EE
69
+ EE EE EE EE EE EE EE EE 1F 1F 1F 1F 20 20 20 20
70
+ 21 21 21 21 22 22 22 22 23 23 23 23 24 24 24 24
71
+ 25 25 25 25 26 26 26 26 27 27 27 27 28 28 28 28
72
+ 29 29 29 29 2A 2A 2A 2A 2B 2B 2B 2B 2C 2C 2C 2C
73
+ 2D 2D 2D 2D 2E 2E 2E 2E EE EE EE EE EE EE EE EE
74
+ `),
75
+ ...getNoTimesPage()
76
+ ]
77
+ }));
78
+
79
+ export const getFullCard = utils.cached(cache, () => ({
80
+ cardData: {
81
+ uid: 0x772a4299,
82
+ cardNumber: 1234567,
83
+ startTime: {time:8721+43200, weekcounter: 0, weekday: 3},
84
+ finishTime: {time:8481+43200, weekcounter: 0, weekday: 3},
85
+ checkTime: {time:8735+43200, weekcounter: 3, weekday: 3},
86
+ punchCount: 50,
87
+ punches: _.range(50).map(() => ({ code: 32, time: {time: 8224 , weekcounter: 2, weekday: 0}})),
88
+ cardHolder: {
89
+ firstName: 'aaaaaaaaaaaaaaa',
90
+ lastName: 'bbbbbbb',
91
+ isComplete: true
92
+ }
93
+ },
94
+ storageData: [
95
+ ...utils.unPrettyHex(`
96
+ 77 2A 42 99 EA EA EA EA 37 02 22 1F 07 03 22 11
97
+ 07 04 21 21 0F 7F 32 09 0F 12 D6 87 06 0F 61 53
98
+ 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 3B
99
+ 62 62 62 62 62 62 62 3B 20 20 20 20 20 20 20 20
100
+ 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
101
+ 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
102
+ 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
103
+ 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
104
+ `),
105
+ ...getFullTimesPage()
106
+ ]
107
+ }));
108
+
109
+ export const getEmptyCard = utils.cached(cache, () => ({
110
+ cardData: {
111
+ uid: 0x772a4299,
112
+ cardNumber: 1234567,
113
+ startTime: {time:8721+43200, weekcounter: 0, weekday: 3},
114
+ finishTime: null,
115
+ checkTime: {time:8735+43200, weekcounter: 3, weekday: 3},
116
+ punchCount: 0,
117
+ punches: [],
118
+ cardHolder: {
119
+ firstName: undefined,
120
+ lastName: undefined,
121
+ isComplete: false
122
+ }
123
+ },
124
+ storageData: [
125
+ ...utils.unPrettyHex(`
126
+ 77 2A 42 99 EA EA EA EA 37 02 22 1F 07 03 22 11
127
+ EE EE EE EE 0F 7F 00 09 0F 12 D6 87 06 0F 61 53
128
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
129
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
130
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
131
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
132
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
133
+ EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
134
+ `),
135
+ ...getNoTimesPage()
136
+ ]
137
+ }));
138
+
139
+ export const getSiCard9Examples = (): { [name: string]: SiCardSample } => ({
140
+ cardWith16Punches: getCardWith16Punches(),
141
+ fullCard: getFullCard(),
142
+ emptyCard: getEmptyCard()
143
+ });
@@ -0,0 +1,78 @@
1
+ import type * as utils from '../utils';
2
+
3
+ export interface WebSerialConnectEvent extends utils.IEvent<'connect'> {
4
+ device: WebSerialDevice;
5
+ target: unknown;
6
+ defaultPrevented: boolean;
7
+ }
8
+
9
+ export interface WebSerialDisconnectEvent extends utils.IEvent<'disconnect'> {
10
+ device: WebSerialDevice;
11
+ target: unknown;
12
+ defaultPrevented: boolean;
13
+ }
14
+
15
+ export type WebSerialEvents = {
16
+ connect: WebSerialConnectEvent;
17
+ disconnect: WebSerialDisconnectEvent;
18
+ };
19
+
20
+ interface SerialPortRequestOptions {
21
+ filters: SerialPortFilter[];
22
+ }
23
+ export interface Serial extends EventTarget {
24
+ onconnect: EventHandler | undefined;
25
+ ondisconnect: EventHandler | undefined;
26
+ getPorts(): Promise<WebSerialDevice[]>;
27
+ requestPort(options?: SerialPortRequestOptions): Promise<WebSerialDevice>; // Chromium implementation (spec: SerialOptions)
28
+ }
29
+
30
+ interface Navigator {
31
+ readonly serial: Serial;
32
+ }
33
+
34
+ interface RequestDeviceArgs {
35
+ filters: WebSerialDeviceFilter[];
36
+ }
37
+
38
+ interface WebSerialDeviceFilter {
39
+ usbVendorId?: number;
40
+ usbProductId?: number;
41
+ }
42
+
43
+ export interface WebSerialDevice {
44
+ onconnect: EventHandler;
45
+ ondisconnect: EventHandler;
46
+ readonly readable: ReadableStream; // Chromium implementation (spec: in)
47
+ readonly writable: WritableStream; // Chromium implementation (spec: out)
48
+ open(options: SerialOptions): Promise<void>;
49
+ close(): Promise<void>;
50
+ getInfo(): Partial<SerialPortInfo>;
51
+ forget(): Promise<void>;
52
+ }
53
+ type EventHandler = (event: Event) => void;
54
+ type ParityType = 'none' | 'even' | 'odd' | 'mark' | 'space';
55
+ type FlowControlType = 'none' | 'hardware';
56
+ interface SerialOptions {
57
+ baudRate: number;
58
+ dataBits?: number | undefined;
59
+ stopBits?: number | undefined;
60
+ parity?: ParityType | undefined;
61
+ bufferSize?: number | undefined;
62
+ flowControl?: FlowControlType | undefined;
63
+ }
64
+ interface SerialPortInfo extends SerialPortInfoBase, SerialPortFilter {} // mix spec and Chromium implementation
65
+ interface SerialPortInfoBase {
66
+ serialNumber: string;
67
+ manufacturer: string;
68
+ locationId: string;
69
+ vendorId: string;
70
+ vendor: string;
71
+ productId: string;
72
+ product: string;
73
+ }
74
+
75
+ interface SerialPortFilter {
76
+ usbVendorId: number;
77
+ usbProductId?: number | undefined;
78
+ }
@@ -0,0 +1,62 @@
1
+ import type * as utils from '../utils';
2
+
3
+ export interface WebUsbConnectEvent extends utils.IEvent<'connect'> {
4
+ device: WebUsbDevice;
5
+ target: unknown;
6
+ defaultPrevented: boolean;
7
+ }
8
+
9
+ export interface WebUsbDisconnectEvent extends utils.IEvent<'disconnect'> {
10
+ device: WebUsbDevice;
11
+ target: unknown;
12
+ defaultPrevented: boolean;
13
+ }
14
+
15
+ export type WebUsbEvents = {
16
+ connect: WebUsbConnectEvent;
17
+ disconnect: WebUsbDisconnectEvent;
18
+ };
19
+
20
+ export interface WebUsb extends utils.IEventTarget<WebUsbEvents> {
21
+ getDevices: () => Promise<WebUsbDevice[]>;
22
+ requestDevice: (args: RequestDeviceArgs) => Promise<WebUsbDevice>;
23
+ }
24
+
25
+ interface RequestDeviceArgs {
26
+ filters: WebUsbDeviceFilter[];
27
+ }
28
+
29
+ interface WebUsbDeviceFilter {
30
+ vendorId?: number;
31
+ productId?: number;
32
+ }
33
+
34
+ export interface WebUsbDevice {
35
+ configurations: any[];
36
+ serialNumber: string;
37
+ vendorId: number;
38
+ productId: number;
39
+ opened: boolean;
40
+ open: () => Promise<void>;
41
+ close: () => Promise<void>;
42
+ reset: () => Promise<void>;
43
+ selectConfiguration: (configuration: number) => Promise<void>;
44
+ claimInterface: (interfaceNumber: number) => Promise<void>;
45
+ releaseInterface: (interfaceNumber: number) => Promise<void>;
46
+ selectAlternateInterface: (interfaceNumber: number, alternate: number) => Promise<void>;
47
+ transferIn: (endpoint: number, length: number) => Promise<WebUsbTransferInData>;
48
+ transferOut: (endpoint: number, buffer: ArrayBuffer) => Promise<void>;
49
+ controlTransferOut: (endpoint: WebUsbControlTransferSetup, data?: ArrayBuffer) => Promise<void>;
50
+ }
51
+
52
+ export interface WebUsbTransferInData {
53
+ data?: DataView;
54
+ }
55
+
56
+ interface WebUsbControlTransferSetup {
57
+ recipient: string;
58
+ request: number;
59
+ requestType: string;
60
+ index: number;
61
+ value: number;
62
+ }
@@ -0,0 +1,48 @@
1
+ import type { ISiTargetMultiplexer } from '../SiStation/ISiTargetMultiplexer';
2
+ import * as utils from '../utils';
3
+
4
+ /* eslint-disable no-unused-vars,no-shadow */
5
+ export enum SiDeviceState {
6
+ Closed = 0,
7
+ Opening = 1,
8
+ Opened = 2,
9
+ Closing = 3
10
+ }
11
+ /* eslint-enable no-unused-vars,no-shadow */
12
+
13
+ export interface ISiDeviceDriverData<T> {
14
+ driver: T;
15
+ }
16
+
17
+ export class DeviceClosedError extends utils.SiError {}
18
+
19
+ export class SiDeviceStateChangeEvent extends utils.Event<'stateChange'> {
20
+ constructor(public siDevice: ISiDevice<ISiDeviceDriverData<unknown>>, public state: SiDeviceState) {
21
+ super();
22
+ }
23
+ }
24
+ export class SiDeviceReceiveEvent extends utils.Event<'receive'> {
25
+ constructor(public siDevice: ISiDevice<ISiDeviceDriverData<unknown>>, public uint8Data: number[]) {
26
+ super();
27
+ }
28
+ }
29
+
30
+ export type SiDeviceEvents = {
31
+ stateChange: SiDeviceStateChangeEvent;
32
+ receive: SiDeviceReceiveEvent;
33
+ };
34
+
35
+ export interface ISiDevice<T extends ISiDeviceDriverData<unknown>> extends utils.IEventTarget<SiDeviceEvents> {
36
+ name: string;
37
+ ident: string;
38
+ state: SiDeviceState;
39
+ setState: (newState: SiDeviceState) => void;
40
+ data: T;
41
+ siTargetMultiplexer?: ISiTargetMultiplexer;
42
+ open: () => Promise<ISiDevice<T>>;
43
+ close: () => Promise<ISiDevice<T>>;
44
+ receiveLoop: () => void;
45
+ shouldStopReceivingBecauseOfError: (error: unknown) => boolean;
46
+ receive: () => Promise<number[]>;
47
+ send: (buffer: number[]) => Promise<unknown>;
48
+ }
@@ -0,0 +1,35 @@
1
+ import * as utils from '../utils';
2
+ import type { ISiDevice, ISiDeviceDriverData } from './ISiDevice';
3
+
4
+ export interface ISiDeviceDriver<T extends ISiDeviceDriverData<unknown>> {
5
+ name: string;
6
+ open: (device: ISiDevice<T>) => Promise<unknown>;
7
+ close: (device: ISiDevice<T>) => Promise<unknown>;
8
+ receive: (device: ISiDevice<T>) => Promise<number[]>;
9
+ send: (device: ISiDevice<T>, buffer: number[]) => Promise<unknown>;
10
+ }
11
+
12
+ export interface ISiDeviceDriverWithDetection<T extends ISiDeviceDriverData<unknown>, U extends Array<unknown>> extends ISiDeviceDriver<T> {
13
+ detect: (...args: U) => Promise<ISiDevice<T>>;
14
+ }
15
+
16
+ export class SiDeviceAddEvent<T extends ISiDeviceDriverData<unknown>> extends utils.Event<'add'> {
17
+ constructor(public siDevice: ISiDevice<T>) {
18
+ super();
19
+ }
20
+ }
21
+ export class SiDeviceRemoveEvent<T extends ISiDeviceDriverData<unknown>> extends utils.Event<'remove'> {
22
+ constructor(public siDevice: ISiDevice<T>) {
23
+ super();
24
+ }
25
+ }
26
+
27
+ export type SiDeviceDriverWithAutodetectionEvents<T extends ISiDeviceDriverData<unknown>> = {
28
+ add: SiDeviceAddEvent<T>;
29
+ remove: SiDeviceRemoveEvent<T>;
30
+ };
31
+
32
+ export interface ISiDeviceDriverWithAutodetection<T extends ISiDeviceDriverData<unknown>> extends ISiDeviceDriver<T>, utils.IEventTarget<SiDeviceDriverWithAutodetectionEvents<T>> {
33
+ startAutoDetection: () => Promise<ISiDevice<T>[]>;
34
+ stopAutoDetection: () => Promise<unknown>;
35
+ }
@@ -0,0 +1,13 @@
1
+ # Drivers
2
+
3
+ There are different ways to open a serial data connection to a SportIdent Main Station.
4
+ Some Examples:
5
+
6
+ - [WebUSB](https://wicg.github.io/webusb/)
7
+ - [`chrome.serial`](https://developer.chrome.com/apps/serial)
8
+ - [`chrome.usb`](https://developer.chrome.com/apps/usb)
9
+ - Your custom python script piping the serial port into a WebSocket, which JavaScript then talks to
10
+
11
+ ## Interface
12
+
13
+ see [`ISiDeviceDriver`](ISiDeviceDriver.ts)