Initial Revision
This commit is contained in:
commit
9bd618202d
5 changed files with 1003 additions and 0 deletions
122
README.md
Normal file
122
README.md
Normal file
|
@ -0,0 +1,122 @@
|
|||
# The Plover HID protocol
|
||||
|
||||
## Background
|
||||
|
||||
Currently most hobbyist steno machines use either the TXBolt protocol or the
|
||||
GeminiPR protocol, which are serial protocols running over USB CDC. The main
|
||||
reason why many end users want to use the steno protocols instead of just
|
||||
having their machines act like keyboards is that they don't want to
|
||||
enable/disable plover all the time to be able to use their keyboards.
|
||||
|
||||
However there are certain issues with those protocols:
|
||||
|
||||
1. There is no serial profile for BLE, so any bluetooth low energy device would
|
||||
need a custom protocol (GATT Service).
|
||||
2. GeminiPR and TXBolt only send complete chords to the host, this makes us
|
||||
lose information that could be used on the plover side to easily implement
|
||||
features such as first-up chord send or auto-repeat of chords.
|
||||
3. TXBolt and GeminiPR define a very restricted amount of keys. This isn't an
|
||||
issue for English Stenotype, but makes it so that something like a velotype
|
||||
machine won't be able to use those protocols.
|
||||
4. Plover handles serial disconnects pretty badly, causing the user to have to
|
||||
reconfigure their serial port in settings. This is not a big issue but has
|
||||
led to some user confusion in the plover discord server.
|
||||
5. There has been talk about creating hobbyist machines supporting variable
|
||||
key-pressure/lever-pressure. Many professional machines have configurable
|
||||
per-key pressure settings, but we could also design a protocol to send the
|
||||
key pressure and handling the configuration on the plover side.
|
||||
|
||||
## Using HID
|
||||
Arguably stenography input is Human Input, so making a steno machine a human
|
||||
input device would make sense. The pros of using HID are that it's supported
|
||||
both over USB, and also over BLE. By sending each state change instead of
|
||||
whole chords we allow for having features like first up chord send and auto
|
||||
repeat in plover. In the best of worlds we would have been able to just choose
|
||||
a good HID page for steno, but unfortunately no such standard page exists.
|
||||
|
||||
So instead we choose a vendor-defined page, and choose a usage code that no one
|
||||
else seems to use. It would of course be nice if this could be standardized in
|
||||
the future, but that is probably out of reach for the amateur steno community.
|
||||
|
||||
It would also have been nice to just define the usage page and usage, and allow
|
||||
the device itself to decide how its reports should be sent (how many buttons it
|
||||
has, if it has pressure information, and so on), and then parse the hid
|
||||
descriptor on the plover side. Unfortunately there isn't a good platform
|
||||
independent way to retreive the HID descriptors from a device.
|
||||
|
||||
Instead we choose an approach where we defined two different report formats.
|
||||
One we call the "simple report format" and it consists of a bitmap of 64 bits
|
||||
each encoding if a certain key/lever is pressed or not. The other we call the
|
||||
"complicated report format" and it encodes the pressure of each of 64 keys/levers as byte for each lever.
|
||||
|
||||
## The HID Descriptor
|
||||
```
|
||||
{
|
||||
0x06, 0x50, 0xff, // UsagePage (65360)
|
||||
0x0a, 0x56, 0x4c, // Usage (19542)
|
||||
0xa1, 0x02, // Collection (Logical)
|
||||
0x85, 0x01, // ReportID (1)
|
||||
0x25, 0x01, // LogicalMaximum (1)
|
||||
0x75, 0x01, // ReportSize (1)
|
||||
0x95, 0x40, // ReportCount (64)
|
||||
0x05, 0x09, // UsagePage (button)
|
||||
0x19, 0x00, // UsageMinimum (Button(0))
|
||||
0x29, 0x3f, // UsageMaximum (Button(63))
|
||||
0x81, 0x02, // Input (Variable)
|
||||
0x85, 0x02, // ReportID (2)
|
||||
0x26, 0xff, 0x00, // LogicalMaximum (255)
|
||||
0x75, 0x08, // ReportSize (8)
|
||||
0x19, 0x00, // UsageMinimum (Button(0))
|
||||
0x29, 0x3f, // UsageMaximum (Button(63))
|
||||
0x81, 0x02, // Input (Variable)
|
||||
0xc0, // EndCollection
|
||||
}
|
||||
```
|
||||
Where the first byte of the Usage Page is 0xff (vendor-defined) and the second
|
||||
byte is "S" and the usage bytes are "TN", together encoding the string "STN".
|
||||
The HID descriptor describes both the "simple" and the "complicated" report
|
||||
format and the idea is that a device can choose with which format it sends its
|
||||
reports, and the plover side should handle both types of reports.
|
||||
|
||||
A nice side effect of this architecture is that it would be trivial to extend
|
||||
the report format with new report types if needed without having to change firmware on
|
||||
existing devices using one the existing report types.
|
||||
|
||||
The descriptor was generated by the [HID Report Descriptor Compiler](https://github.com/nipo/hrdc) from the following python code:
|
||||
```
|
||||
from hrdc.usage import *
|
||||
from hrdc.descriptor import *
|
||||
|
||||
usage = Usage('vendor-defined', 0xff504c56)
|
||||
stenomachine = Collection(Collection.Logical, usage, #consumer.ConsumerControl,
|
||||
Report(1, *(Value(Value.Input, button.Button(x), 1, logicalMin=0, logicalMax=1) for x in range(64))),
|
||||
Report(2, *(Value(Value.Input, button.Button(x), 8, logicalMin=0, logicalMax=255) for x in range(64))))
|
||||
|
||||
if __name__ == '__main__':
|
||||
compile_main(stenomachine)
|
||||
```
|
||||
|
||||
## The keys
|
||||
For historical reasons we reuse most of the key names from the GeminiPR protocol, but we add extra keys so that we reach 64 keys in total.
|
||||
The keys are as follows, and the bit/byte position in the reports map to the following keys in order (left-to-right):
|
||||
```
|
||||
#1 #2 #3 #4 #5 #6 #7 #8 #9 #A #B #C
|
||||
X1 S1- T- P- H- *1 *3 -F -P -L -T -D
|
||||
X2 S2- K- W- R- *2 *4 -R -B -G -S -Z
|
||||
X3 A- O- -E -U X4
|
||||
|
||||
X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
|
||||
X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26
|
||||
```
|
||||
|
||||
So the first bit/byte of the report (after the report type byte) maps to key
|
||||
`#2` and the last bit/byte of the report maps to `X26`.
|
||||
|
||||
## Sample Firmware
|
||||
|
||||
Sample firmware for the georgi is included in this repository. It defines a default keymap of the form:
|
||||
```
|
||||
X1 S1- T- P- H- *1 *3 -F -P -L -T -D
|
||||
X2 S2- K- W- R- *2 *4 -R -B -G -S -Z
|
||||
#1 A O E U #7
|
||||
```
|
687
georgi_plover-hid.hex
Normal file
687
georgi_plover-hid.hex
Normal file
|
@ -0,0 +1,687 @@
|
|||
:100000000C943D010C9484010C9484010C948401A3
|
||||
:100010000C9484010C9484010C9484010C9484014C
|
||||
:100020000C9484010C9484010C9440120C94FC11E7
|
||||
:100030000C943B130C9484010C9484010C94840163
|
||||
:100040000C9484010C9484010C9484010C9484011C
|
||||
:100050000C9484010C9417130C9484010C94840167
|
||||
:100060000C9484010C9484010C9484010C948401FC
|
||||
:100070000C9484010C9484010C9484010C948401EC
|
||||
:100080000C9484010C9484010C9484010C948401DC
|
||||
:100090000C9484010C9484010C9484010C948401CC
|
||||
:1000A0000C9484010C9484010C9484010000525A35
|
||||
:1000B0005E5A685A0000535A5F5A675A0000545AF1
|
||||
:1000C000605A465A0000555A615A00000000565ABC
|
||||
:1000D000625A00000000575A635A000000000000F6
|
||||
:1000E000000000000000515A5D5A665A0000505A44
|
||||
:1000F0005C5A655A00004F5A5B5A405A00004E5AEB
|
||||
:100100005A5A000000004D5A595A000000004C5A3B
|
||||
:10011000585A000000000000000000000650FF0ACE
|
||||
:10012000564CA1028501250175019540050919006C
|
||||
:10013000293F8102850226FF0075081900293F81A9
|
||||
:1001400002C005010906A1018501050719E029E79B
|
||||
:100150001500250195087501810295017508810139
|
||||
:100160000507190029FF150026FF0095067508816F
|
||||
:10017000000508190129059505750191029501757C
|
||||
:10018000039101C005010980A101850319012AB766
|
||||
:1001900000150126B700950175108100C0050C09F6
|
||||
:1001A00001A101850419012AA002150126A00295CA
|
||||
:1001B0000175108100C005010906A101850505072B
|
||||
:1001C00019E029E715002501950875018102050749
|
||||
:1001D000190029EF1500250195F075018102050828
|
||||
:1001E0001901290595057501910295017503910184
|
||||
:1001F000C009023B00020100A0FA0904000001034B
|
||||
:1002000001010009211101000122AF00070582034D
|
||||
:1002100020000A0904010001030000000921110166
|
||||
:1002200000012226000705810320000112010002BF
|
||||
:1002300000000008EDFE37130100010200010E036B
|
||||
:10024000470065006F007200670069000000260328
|
||||
:1002500067002000480065006100760079002000FA
|
||||
:1002600049006E006400750073007400720069003C
|
||||
:100270006500730000000403090411241FBECFEFC2
|
||||
:10028000DAE0DEBFCDBF04B603FE27C08091410295
|
||||
:1002900090914202A0914302B09144028730904B6A
|
||||
:1002A000A740B04BD1F4109241021092420210923A
|
||||
:1002B00043021092440214BE84B7877F84BF0FB6F6
|
||||
:1002C000F894A895809160008861809360001092F6
|
||||
:1002D00060000FBEE0E0F8E3099511E0A0E0B1E0B6
|
||||
:1002E000E8E8FAE202C005900D92A834B107D9F708
|
||||
:1002F00022E0A8E4B1E001C01D92A134B207E1F709
|
||||
:100300000E9462130C9438150C940000E8EDF0E0A4
|
||||
:1003100080818E7F80831092E2001092DA0010922A
|
||||
:10032000E100A0EEB0E08C9181608C9380818F77AA
|
||||
:10033000808319BCA7EDB0E08C918E7F8C93808177
|
||||
:100340008F7E808310920B0208952091E4003091FB
|
||||
:10035000E50095E6A9012091EC00822F817020FF35
|
||||
:1003600006C08091E80080FF06C080E008952091DB
|
||||
:10037000E80022FD1AC080913002882389F0853080
|
||||
:1003800089F08091EB0085FD0FC02091E400309151
|
||||
:10039000E50042175307F9F29150E1F684E0089521
|
||||
:1003A00082E0089583E0089581E00895EF92FF923E
|
||||
:1003B0000F931F93CF937C018B010E94A501C82F3F
|
||||
:1003C000811117C08091E80085FD0BC08091E80085
|
||||
:1003D0008E778093E8000E94A501882399F3C82FA7
|
||||
:1003E00008C0F70181917F018093F100015011094C
|
||||
:1003F00049F78C2FCF911F910F91FF90EF900895A7
|
||||
:100400008091320287FF13C08091E80082FF06C00E
|
||||
:100410008091E8008B778093E80004C080913002DF
|
||||
:100420008111F2CF0895809130028823D9F3809111
|
||||
:10043000E80080FFF8CF8091E8008E77ECCF982F0E
|
||||
:100440009093E900242F762F50E0891731F07091B6
|
||||
:10045000EC002091ED005091F00021FD07C09F5F5E
|
||||
:10046000973071F78093E90081E008953091EB00B7
|
||||
:100470003E7F3093EB003091ED003D7F3093ED00F7
|
||||
:100480003091EB0031603093EB007093EC002093DF
|
||||
:10049000ED005093F0002091EE0027FDE0CF80E0CA
|
||||
:1004A0000895CF92DF92EF92FF920F931F93CF9315
|
||||
:1004B000DF93C8EDD0E088818F7E8883E7EDF0E0A0
|
||||
:1004C00080818160808384E082BF81E080930B0221
|
||||
:1004D00088818E7F888302EE10E0F80110821092EE
|
||||
:1004E000DA0081EEC82ED12CF601108288818F7738
|
||||
:1004F000888388818068888388818F7D888319BC00
|
||||
:10050000109230021092310210922F0210922E029D
|
||||
:1005100090EEE92EF12CF70180818B7F808388811A
|
||||
:100520008160888342E060E080E00E941F02F60163
|
||||
:1005300080818E7F8083F8018081816080838081CB
|
||||
:1005400088608083F70180818E7F808388818061CD
|
||||
:100550008883DF91CF911F910F91FF90EF90DF90F3
|
||||
:10056000CF900895FC01809138029091390286174E
|
||||
:100570009707A0F06115710529F49091E8009E7726
|
||||
:100580009093E80090E06115710551F4911108C055
|
||||
:100590008091E80082FF34C080E00895BC01F2CF72
|
||||
:1005A000809130028823C1F18530C1F18091E8004B
|
||||
:1005B00083FD30C08091E80082FDEACF8091E800A1
|
||||
:1005C00080FFE1CF8091F3002091F200382F611578
|
||||
:1005D000710519F02830310558F091E028303105C7
|
||||
:1005E00009F090E02091E8002E772093E800CBCF2F
|
||||
:1005F00081918093F100615071092F5F3F4FE7CFE8
|
||||
:1006000080913002882341F0853041F08091E800EC
|
||||
:1006100083FFBECF81E0089582E0089583E00895CE
|
||||
:10062000089580910D0208952FB7F89480913D02AE
|
||||
:1006300090913E02A0913F02B09140022FBF0895D9
|
||||
:10064000CF92DF92FF920F931F93CF93DF93182FD8
|
||||
:100650000E941403EC0104EA84E8F82E1092BC0016
|
||||
:100660000093BC000E9414036C018091BC0087FFC2
|
||||
:100670000DC08091B900887F883041F18091B90028
|
||||
:10068000887F803119F18FEF9FEF08C00E9414031B
|
||||
:100690008C199D09C29748F38EEF9FEF2FB7F894FE
|
||||
:1006A00040913D0250913E0260913F0270914002A4
|
||||
:1006B0002FBF4C1B5D0B483E534080F2DF91CF9122
|
||||
:1006C0001F910F91FF90DF90CF9008951093BB0082
|
||||
:1006D000F092BC000E9414036C018091BC0087FF63
|
||||
:1006E0000AC08091B900887F883111F0803459F6B2
|
||||
:1006F00090E080E0E3CF0E9414038C199D09C2971B
|
||||
:1007000060F3CACFCF93DF938093BB0084E88093DC
|
||||
:10071000BC000E941403EC018091BC0087FF0FC055
|
||||
:100720002091B900287F81E090E0283211F490E018
|
||||
:1007300080E0919581959109DF91CF9108950E9474
|
||||
:1007400014038C1B9D0B883E934030F38EEF9FEF7C
|
||||
:10075000F3CF20910302309104022817390771F07A
|
||||
:100760009093040280930302E0910102F09102024F
|
||||
:10077000309721F00084F185E02D099408952091AF
|
||||
:10078000FF01309100022817390771F090930002A1
|
||||
:100790008093FF01E0910102F0910202309721F075
|
||||
:1007A0000680F781E02D09940895E0910102F0910F
|
||||
:1007B0000202309721F00190F081E02D099480E051
|
||||
:1007C000089580E008958238910591F1C0F5813354
|
||||
:1007D000910509F490C028F58932910509F484C087
|
||||
:1007E0008A32910509F48EC0811520E5920708F040
|
||||
:1007F0009EC0811540E4940708F022C18F3B91050B
|
||||
:1008000008F087C0883A910508F00FC1853A910534
|
||||
:1008100008F002C18430910500F581309105E9F0BE
|
||||
:100820003CC08533910509F458C089339105E1F640
|
||||
:1008300020910602237089F080EE90E00895833EB7
|
||||
:10084000910571F158F4803E9105E9F0823E9105E1
|
||||
:1008500059F62091060222FD1EC00895863E91059C
|
||||
:1008600051F1873E910571F1843E910509F0BCCFAD
|
||||
:100870002091070221FFF1CF8091060284FD0DC077
|
||||
:1008800087EE90E008952091060220FD05C1309189
|
||||
:10089000070230FFE2CF24FF02C190E080E0DDCF0D
|
||||
:1008A0002091060222FDFEC03091070230FDC4CF28
|
||||
:1008B00024FFD3CFF2CF2091060223FFCECF24FD19
|
||||
:1008C000ECCFDECF2091060223FDEFC0309107026E
|
||||
:1008D00031FFEECF84EE90E008952091060225FFCF
|
||||
:1008E000BCCF89E290E008952091060225FFB5CFA4
|
||||
:1008F00085E390E008952091060226FFAECF8AE2BC
|
||||
:1009000090E008952091060226FFA7CF81E390E0B2
|
||||
:100910000895803E910508F2883E910508F49DCF28
|
||||
:100920009C013A9521153F4108F497CFB6CF811528
|
||||
:1009300023E5920740F5811542E5940708F088C049
|
||||
:10094000811521E5920708F07EC09C0164E0369590
|
||||
:1009500027956A95E1F7922F9370282F2695269573
|
||||
:10096000237040E2249F90011124392B482F4370BB
|
||||
:1009700081E090E002C0880F991F4A95E2F7822B30
|
||||
:10098000932B9C680895811549E59407F0F481152F
|
||||
:1009900028E5920708F06DC0811544E5940708F03A
|
||||
:1009A0007CCFAC014370552721E030E002C0220F1C
|
||||
:1009B000331F4A95E2F78695869540E2849FC001F1
|
||||
:1009C0001124822B932B9A68089581152AE59207AA
|
||||
:1009D00008F063CF282F2F704091060242FF05C018
|
||||
:1009E00083FF4CC0282F277024603091070230FF0E
|
||||
:1009F00007C0322F3871383009F046C0277F216098
|
||||
:100A000044FD277E34E0969587953A95E1F78F70FF
|
||||
:100A1000982F822F90690895855AE82FF0E0EA5EBA
|
||||
:100A2000FE4F808190E090640895885AE82FF0E0AE
|
||||
:100A3000EE0FFF1FE75EFE4F808191819464089561
|
||||
:100A40009F70906A0895982F8827816F906A089503
|
||||
:100A5000AC014370552721E030E002C0220F331F64
|
||||
:100A60004A95E2F78695869540E2849FC00111245D
|
||||
:100A700086CF982F8827806F906A089582FFB5CF20
|
||||
:100A8000282F2B702860B1CF322F3171313009F00F
|
||||
:100A9000B7CF2E7F2860B4CF89E390E0089583EE2E
|
||||
:100AA00090E0089582EE90E0089586EE90E008953B
|
||||
:100AB0008091920190919101892B90919001892BC5
|
||||
:100AC00080934B01E0910102F0910202309799F07E
|
||||
:100AD00080911501882369F08091060287FF09C083
|
||||
:100AE00085E080934A010280F381E02D8AE491E061
|
||||
:100AF000099481E0F6CF0895909115019923D1F0E2
|
||||
:100B00009091060297FF16C0E82FE695E695E695C8
|
||||
:100B1000EE31E0F4F0E0E65BFE4F282F277081E035
|
||||
:100B200090E001C0880F2A95EAF780959281892389
|
||||
:100B300082830895EDE4F1E09191891303C0DF0110
|
||||
:100B400011971C9291E0E335F907B1F70895909160
|
||||
:100B500015019923C1F09091060297FF14C0E82F68
|
||||
:100B6000E695E695E695EE31F8F4F0E0E65BFE4FAB
|
||||
:100B7000877021E030E001C0220F8A95EAF7828178
|
||||
:100B8000822B82830895ADE4B1E0EFEF90E02D91E8
|
||||
:100B9000821751F0EF3F19F4211101C0E92F9F5F37
|
||||
:100BA0009630A9F7EF3F09F408950E2E000CFF0BC5
|
||||
:100BB000E65BFE4F838308958F929F92AF92BF9220
|
||||
:100BC000CF92DF92EF92FF920F931F93CF93DF9319
|
||||
:100BD0008090970190909801A0909901B0909A010F
|
||||
:100BE000409193015091940160919501709196010B
|
||||
:100BF000842A952AA62AB72ACFE1D0E0E92EF12C43
|
||||
:100C00002EE0C22E082F10E0DC2ED501C4010C2EE0
|
||||
:100C100004C0B695A795979587950A94D2F780FD5D
|
||||
:100C200011C0219788F7D12C8D2DDF91CF911F9185
|
||||
:100C30000F91FF90EF90DF90CF90BF90AF909F907B
|
||||
:100C40008F900895CC9EF001CD9EF00D1124EE0DF5
|
||||
:100C5000FF1DEE0FFF1FEE0FFF1FE00FF11FEE0F46
|
||||
:100C6000FF1FE455FF4F859194910E94E303019784
|
||||
:100C7000C1F2DACF990F990F890F982F9770869547
|
||||
:100C80008695869525E0829FF0011124E359FE4F59
|
||||
:100C900050E040E080E0219130E0092E02C036951E
|
||||
:100CA00027950A94E2F721703327042E01C0220F02
|
||||
:100CB0000A94EAF7822B4F5F5F4F4530510559F791
|
||||
:100CC0000895990F990F890F982F977041E001C0EF
|
||||
:100CD000440F9A95EAF786958695869595E0899FC3
|
||||
:100CE000F0011124E359FE4F30E020E070E0519113
|
||||
:100CF000DF011197CB01022E02C0969587950A94C9
|
||||
:100D0000E2F7817081958527842385278C932F5F57
|
||||
:100D10003F4F2530310559F7089590E080E00E945B
|
||||
:100D2000BF0390E080E00E94A9031092910110920D
|
||||
:100D300090010C94580560939701709398018093EB
|
||||
:100D4000990190939A010C948D066093930170938E
|
||||
:100D5000940180939501909396010C948D068823BD
|
||||
:100D600041F08095909192018923809392010C9497
|
||||
:100D700058050895882339F090919201982B90930B
|
||||
:100D800092010C9458050895882309F452C08238C2
|
||||
:100D900071F40E94D50381FF4CC089E30E94A7052E
|
||||
:100DA0000E94580589E30E947C050C9458058338FD
|
||||
:100DB00059F40E94D50380FF3CC083E50E94A7053B
|
||||
:100DC0000E94580583E5EFCF843859F40E94D5037B
|
||||
:100DD00082FF2FC087E40E94A7050E94580587E480
|
||||
:100DE000E2CF9CEF980F913AF0F290E2980F983092
|
||||
:100DF00088F4877021E030E0A90102C0440F551F3C
|
||||
:100E00008A95E2F7CA018095909192018923809397
|
||||
:100E10009201CBCF9BE5980F933020F490E080E0D7
|
||||
:100E20000C94BF03885A873120F490E080E00C9442
|
||||
:100E3000A9030895CF93C82F873050F580911301EF
|
||||
:100E400090911401892B11F580E40E942003909366
|
||||
:100E5000140180931301892BB1F482E10E94820373
|
||||
:100E60009093140180931301892B69F481E090E041
|
||||
:100E700001C0880FCA95EAF780950E94820390937B
|
||||
:100E800014018093130184E98093BC00CF910895ED
|
||||
:100E90008A30B1F038F4883069F0893071F0209AE6
|
||||
:100EA0002898F4CF8C3091F070F08D30C1F73E9AD5
|
||||
:100EB0004698ECCF219A2998E9CF229A2A98E6CF32
|
||||
:100EC000239A2B98E3CF529A5A98E0CF539A5B9883
|
||||
:100ED000DDCF84B1807F84B985B1807F85B93E98AC
|
||||
:100EE00046988AB1837F8AB98BB1837F8BB9089585
|
||||
:100EF00080B38D7880BB81B3826781BB0895CF9228
|
||||
:100F0000DF92EF92FF920F931F93CF93DF93C82F3F
|
||||
:100F1000873008F090C08091130190911401892BC3
|
||||
:100F200009F094C080E40E94200390931401809300
|
||||
:100F30001301892B09F44BC090E084E98093BC0035
|
||||
:100F40002C2F30E0F901ED52FE4FA081A9279083AC
|
||||
:100F5000F901EE0FFF1FEE0FFF1FE556FE4F70E089
|
||||
:100F600060E040E0C1E0D0E0CA2ED12C55E0162F61
|
||||
:100F70008191882309F46CC07F01A1E0EA1AF1088D
|
||||
:100F80008150D7018C93D60102C0B595A7951A95CB
|
||||
:100F9000E2F7A0FF05C08F0101501109D8015C9351
|
||||
:100FA0006F5F7F4F6430710511F72F513E4F842FD3
|
||||
:100FB0008095F901208182239423892BDF91CF91A1
|
||||
:100FC0001F910F91FF90EF90DF90CF90089583E1F4
|
||||
:100FD0000E9482039093140180931301892B09F0DE
|
||||
:100FE000ABCF81E40E9420039093140180931301FE
|
||||
:100FF000892B09F0A1CF84E88093BC000E941403E0
|
||||
:101000008C018091BC0087FF08C09091BB00909537
|
||||
:10101000109214011092130190CF0E941403801BB0
|
||||
:10102000910B883E934068F38EEF9FEF90931401ED
|
||||
:101030008093130181CF8FB19FB186958170969572
|
||||
:10104000969596959E70982B90957ACF90E078CF54
|
||||
:101050007E01062E01C0EE0C0A94EAF74E2993CFCA
|
||||
:1010600090913002943031F58093080270930A0217
|
||||
:101070006093090282E08093E9008FEF9091E8008D
|
||||
:10108000815095FD06C095ED9A95F1F7000081110C
|
||||
:10109000F5CF8091E80085FF0DC050E040E063E0AF
|
||||
:1010A00070E088E092E00E94D6018091E8008E779F
|
||||
:1010B0008093E8000895BC0184E00C943008BC01E2
|
||||
:1010C00083E00C943008CF93DF93EC0180911501FD
|
||||
:1010D000882321F08091060260E287FF69E082E0C8
|
||||
:1010E0008093E9008FEF9091E800815095FD06C054
|
||||
:1010F00095ED9A95F1F700008111F5CF8091E80008
|
||||
:1011000085FF19C080911501811118C050E040E0A1
|
||||
:1011100068E070E0CE0101960E94D6018091E8005F
|
||||
:101120008E778093E80080E2FE01AEE0B2E00190AD
|
||||
:101130000D928A95E1F7DF91CF91089570E050E02C
|
||||
:1011400040E0CE01E9CFCF93C82F882309F4A6C091
|
||||
:101150008238C1F40E94D50381FDA0C089E30E94BA
|
||||
:10116000A7050E9458052FEF81EE94E021508040A2
|
||||
:101170009040E1F700C0000089E30E947C05CF9118
|
||||
:101180000C9458058338A1F40E94D50380FD86C0D5
|
||||
:1011900083E50E94A7050E9458052FEF81EE94E099
|
||||
:1011A000215080409040E1F700C0000083E5E5CF8A
|
||||
:1011B0008438A1F40E94D50382FD70C087E40E94A8
|
||||
:1011C000A7050E9458052FEF81EE94E02150804042
|
||||
:1011D0009040E1F700C0000087E4CFCF8CEF8C0F88
|
||||
:1011E000813A88F580911501882301F180910602EA
|
||||
:1011F00087FF1CC0EC2FE695E695E695F0E0E65BF0
|
||||
:10120000FE4F828190E04C2F477021E030E002C019
|
||||
:10121000220F331F4A95E2F782239323892B79F01B
|
||||
:101220008C2F0E947C050E94580509C0EDE4F1E076
|
||||
:101230008191C817A9F321E0E335F207C9F78C2F94
|
||||
:101240000E94A7059CCF80E28C0F883068F4C7709D
|
||||
:1012500021E030E001C0220FCA95EAF780919201A7
|
||||
:10126000822B809392018BCFEBE5EC0FE33040F4BF
|
||||
:10127000F0E0EA5EFE4F808190E0CF910C94BF03D6
|
||||
:10128000C85AC73158F4EC2FF0E0EE0FFF1FE75EAD
|
||||
:10129000FE4F80819181CF910C94A903CF91089545
|
||||
:1012A0000F931F93CF93DF93C62FD42F022FFC01F0
|
||||
:1012B00082818823A1F060933C020E9414039093E2
|
||||
:1012C0003B0280933A02C77081E001C0880FCA9543
|
||||
:1012D000EAF7DF91CF911F910F910C94BA0680919C
|
||||
:1012E0003C02681343C020913A0230913B024FB751
|
||||
:1012F000F89480913D0290913E02A0913F02B091FE
|
||||
:1013000040024FBF821B930B883C910578F510E299
|
||||
:101310001D0F6D17B9F080E2860F883040F4C7705A
|
||||
:1013200081E001C0880FCA95EAF70E94AF06183025
|
||||
:1013300048F481E09D2F977001C0880F9A95EAF7D5
|
||||
:101340000E94BA06802F0E94A308802F0E94C40624
|
||||
:10135000183098F4D77081E001C0880FDA95EAF769
|
||||
:10136000DF91CF911F910F910C94AF06C77081E070
|
||||
:1013700001C0880FCA95EAF7F3CFDF91CF911F9193
|
||||
:101380000F91089580E290E09093140180931301EF
|
||||
:1013900080916B01811111C01092B9008CE0809393
|
||||
:1013A000B80081E080936B012FEF83ED90E3215033
|
||||
:1013B00080409040E1F700C0000080E40E942003DC
|
||||
:1013C0009093140180931301892B09F040C080E0B1
|
||||
:1013D0000E9482039093140180931301892BB9F525
|
||||
:1013E00080E80E9482039093140180931301892B5B
|
||||
:1013F00071F58FEF0E948203909314018093130183
|
||||
:10140000892B29F584E98093BC0080E40E942003A5
|
||||
:101410009093140180931301892BC9F48CE00E94EE
|
||||
:1014200082039093140180931301892B81F480E847
|
||||
:101430000E9482039093140180931301892B39F445
|
||||
:101440008FEF0E948203909314018093130184E92B
|
||||
:101450008093BC008091130108950F931F93CF9345
|
||||
:10146000DF938091130190911401892B71F0809189
|
||||
:101470006A018F5F80936A01811107C00E94C209CF
|
||||
:1014800090E0909314018093130101EE11E0C0E00D
|
||||
:101490008C2F0E941A07D7E0DC0F8D2F0E941A07AD
|
||||
:1014A0008C2F0E947F07F80181938F018D2F0E945E
|
||||
:1014B0007F07F80186830E946907CF5FC73041F735
|
||||
:1014C00081E0DF91CF911F910F910895CF9384E038
|
||||
:1014D00090E00E94F614C82F82E290E00E94F61479
|
||||
:1014E000982F8C2FCF91089569EE7EEF90E080E0E9
|
||||
:1014F0000E94221560E082E090E00E94041560E006
|
||||
:1015000083E090E00E9404151092930110929401E0
|
||||
:10151000109295011092960160E084E090E00E94A4
|
||||
:10152000041560E082E290E00E94041560E085E02E
|
||||
:1015300090E00E94041560E086E090E00E940415AF
|
||||
:101540006FEF87E090E00E94041540E050E0BA01A0
|
||||
:1015500088E090E00E94161560E08DE090E00E9427
|
||||
:10156000041540E050E0BA0188E190E00E941615B1
|
||||
:1015700060E087E190E00E94041540E050E0BA018D
|
||||
:101580008CE190E00E94161570E060E080E290E04F
|
||||
:101590000E94221540E050E0BA0188E190E00E94EC
|
||||
:1015A000161540E050E0BA018FE090E00E94161559
|
||||
:1015B00040E050E0BA0183E190E00C9416151092DF
|
||||
:1015C000920180911501882369F08091060287FFBE
|
||||
:1015D00009C0ECE4F1E08EE1DF011D928A95E9F7A4
|
||||
:1015E0000C948D06EDE4F1E086E0F6CF1F93CF93E7
|
||||
:1015F000DF93CDB7DEB7AA970FB6F894DEBF0FBE64
|
||||
:10160000CDBF82E392E02091F100FC012193CF0154
|
||||
:10161000F2E08A339F07B9F780913302833009F4EF
|
||||
:101620006FC0B8F4813009F446C0823009F4B0C00C
|
||||
:101630008091E80083FF7BC2809132029091330257
|
||||
:101640009A3008F074C2E92FF0E0E65CFA4E0C9490
|
||||
:10165000F0148A3009F48BC08B3009F46EC08930E5
|
||||
:1016600039F780913202813219F7809136029091D8
|
||||
:101670003702892BE9F68091E800877F8093E800A4
|
||||
:101680008091E80082FF37C09091F3008091F200D2
|
||||
:10169000029729F48091F1008B7F813021F48091B1
|
||||
:1016A000F10080930D028091E8008B778093E80031
|
||||
:1016B0000E940002BDCF80913202813A09F0B8CF7A
|
||||
:1016C0008091E800877F8093E800809136029091B6
|
||||
:1016D0003702892B61F460E28EE092E070E00E94B4
|
||||
:1016E000B2028091E8008B778093E800A1CF60E0A0
|
||||
:1016F00090E080E0F3CF809130028111C1CF98CF8C
|
||||
:1017000080913202813A09F093CF80913602909114
|
||||
:101710003702892B09F08CCF8091E800877F809376
|
||||
:10172000E8008091E80080FFFCCF80911501809354
|
||||
:10173000F1008091E8008E77B9CF8091320281323A
|
||||
:1017400009F076CF8091360290913702892B09F00B
|
||||
:101750006FCF8091E800877F8093E8000E940002AD
|
||||
:1017600080913402809315010E94DF0A61CF80913D
|
||||
:101770003202813209F05CCF8091E800877F80934C
|
||||
:10178000E8000E9400028091350280930C0250CF45
|
||||
:1017900080913202813A09F04BCF8091E800877F37
|
||||
:1017A0008093E8008091E80080FFFCCF80910C02DC
|
||||
:1017B000BECF803899F0823809F0B9C180913602E5
|
||||
:1017C0008F70873008F0B3C18093E9008091EB00FF
|
||||
:1017D00085FB882780F91092E90006C080912E02CF
|
||||
:1017E00090912F02911182609091E800977F9093E1
|
||||
:1017F000E8008093F1001092F1008091E8008E776C
|
||||
:1018000092C1882309F480C1823009F090C180918F
|
||||
:101810003402811183C1809136028F702FEF280F1F
|
||||
:10182000263008F084C18093E9002091EB0020FF6E
|
||||
:1018300075C1933031F48091EB0080628093EB00AE
|
||||
:101840006DC19091EB0090619093EB0021E030E04E
|
||||
:1018500001C0220F8A95EAF72093EA001092EA006D
|
||||
:101860008091EB008860EACF811161C11091340250
|
||||
:101870001F778091E3008078812B8093E300809133
|
||||
:10188000E800877F8093E8000E9400028091E800D2
|
||||
:1018900080FFFCCF8091E30080688093E30082E0CA
|
||||
:1018A000111183E08093300242C18058823008F0E9
|
||||
:1018B0003EC180913402909135028C3D23E0920725
|
||||
:1018C000A1F583E08A838AE289834FB7F894DE0129
|
||||
:1018D000139620E03EE051E2E32FF0E050935700F2
|
||||
:1018E000E49120FF03C0E295EF703F5FEF708E2F11
|
||||
:1018F00090E0EA30C0F0C7968D939D932F5F24311E
|
||||
:1019000059F74FBF8091E800877F8093E8006AE233
|
||||
:1019100070E0CE0101960E94B2028091E8008B77C0
|
||||
:101920008093E80004C1C096E7CF40913602509101
|
||||
:101930003702292F33272330310509F444C078F5C5
|
||||
:101940002130310509F46FC08BE390E0E1EFF1E065
|
||||
:101950002230310509F0EBC02091E800277F209369
|
||||
:10196000E80020913802309139028217930708F479
|
||||
:101970009C0140E02115310509F064C0411162C0AD
|
||||
:101980008091E80082FDC9CF80913002882329F23E
|
||||
:10199000853019F28091E80083FFF2CFBECF21326B
|
||||
:1019A0003105A9F12232310509F0C1C041155105B7
|
||||
:1019B00009F443C04130510509F0B9C086E290E016
|
||||
:1019C000ECE1F1E0C9CF992781309105C1F0009792
|
||||
:1019D00059F0029709F0ABC0EEE3F2E0E4918E2FEC
|
||||
:1019E00090E0EEE3F2E007C0E6E7F2E0E4918E2F4C
|
||||
:1019F00090E0E6E7F2E0009709F499C0ADCFEEE49D
|
||||
:101A0000F2E0E4918E2F90E0EEE4F2E0F4CF4115A5
|
||||
:101A1000510571F04130510509F089C089E090E02D
|
||||
:101A2000ECE1F2E099CF82E190E0ECE2F2E094CFD9
|
||||
:101A300089E090E0E3E0F2E08FCF8FEA90E0E2E42B
|
||||
:101A4000F1E08ACF80913002882309F466CF853097
|
||||
:101A500009F463CF8091E80083FD5FCF8091E800B7
|
||||
:101A600082FD8ECF8091E80080FF84CF9091F300BB
|
||||
:101A70008091F2002115310519F08830910550F060
|
||||
:101A800041E0089709F040E08091E8008E7780936C
|
||||
:101A9000E80070CF44914093F10031962150310914
|
||||
:101AA0000196E8CF803809F042C08091E800877F36
|
||||
:101AB0008093E800809131028093F1009ECE8111E5
|
||||
:101AC00036C010913402123090F58091E800877F83
|
||||
:101AD0008093E800109331020E940002112311F05C
|
||||
:101AE00084E005C08091E30087FDFACF81E0809318
|
||||
:101AF000300242E261EC82E00E941F0242E161ECAE
|
||||
:101B000081E00E941F0213C080913402813079F479
|
||||
:101B100081E0933009F080E080932F021092E90079
|
||||
:101B20008091E800877F8093E8000E940002809106
|
||||
:101B3000E80083FF0AC08091E800877F8093E80077
|
||||
:101B40008091EB0080628093EB00AA960FB6F89428
|
||||
:101B5000DEBF0FBECDBFDF91CF911F9108958F9251
|
||||
:101B60009F92AF92BF92CF92DF92EF92FF920F932C
|
||||
:101B70001F93CF93DF93CDB7DEB72F970FB6F894AF
|
||||
:101B8000DEBF0FBECDBF4B875C876D877E878F879B
|
||||
:101B900061111092910185E0FE013B96DE011696DF
|
||||
:101BA00001900D928A95E1F789859A85892B39F004
|
||||
:101BB0001E810F81812F80238F3F09F09AC32F96BA
|
||||
:101BC0000FB6F894DEBF0FBECDBFDF91CF911F914E
|
||||
:101BD0000F91FF90EF90DF90CF90BF90AF909F90CC
|
||||
:101BE0008F9008950E94DC05F82E682F89819A81D4
|
||||
:101BF0000E946106E02FF0E02EE0F29EE00DF11D64
|
||||
:101C00001124EE0FFF1FEE0FFF1FE10FF11DEE0F6E
|
||||
:101C1000FF1FE455FF4F05911491980120543A4558
|
||||
:101C20002034310508F475C0043F3CE5130709F47E
|
||||
:101C3000B6C0B0F4093D9CE5190709F4ACC00A3DF3
|
||||
:101C40002CE5120709F4BBC0083D3CE51307A1F4DD
|
||||
:101C500026E241EE61EECE0106960E945009AFCF1A
|
||||
:101C6000063F8CE5180709F4A2C008F49CC0073FA2
|
||||
:101C70002CE5120709F49FC08885882309F44AC31C
|
||||
:101C800010923C0202303CE5130708F477C106319C
|
||||
:101C90009CE5190738F098012B5F3C452930310548
|
||||
:101CA00008F06CC10E94660A9093070280930602B6
|
||||
:101CB00000312CE5120709F430C108F0BAC0083031
|
||||
:101CC0008CE5180709F417C108F08FC004302CE523
|
||||
:101CD000120709F408C108F075C002308CE5180736
|
||||
:101CE00009F4FBC080910602826003301C4509F4B0
|
||||
:101CF000F7C0609106021091070284E090E00E9414
|
||||
:101D00000415612F82E290E00E9404150E94DF0A10
|
||||
:101D100056CFF90103E0F695E7950A95E1F7EF5FF5
|
||||
:101D2000FE4F4081209530952770332781E090E069
|
||||
:101D300001C0880F2A95EAF72885222349F1842BD0
|
||||
:101D4000808380913002843009F039CF1091E9000E
|
||||
:101D50001F709091EC00892F817090FD80E8182B06
|
||||
:101D600081E08093E9008091E80080FF0DC050E0A1
|
||||
:101D700040E069E070E080E091E00E94D60180914F
|
||||
:101D8000E8008E778093E8001F701093E90017CF6A
|
||||
:101D900080958423D5CF27E245EE65EE5CCF26E221
|
||||
:101DA00041EE60EE58CF27E245EE64EE54CF26E2D6
|
||||
:101DB00041EE62EE50CF27E245EE66EE4CCF28E2D0
|
||||
:101DC00041E0EBCF80910602806106302CE51207DE
|
||||
:101DD00009F486C080910602886007301C4508F42B
|
||||
:101DE0007FC08091060280627BC00C308CE51807B2
|
||||
:101DF00009F48BC070F4809106028C600A302CE5E7
|
||||
:101E0000120709F46DC008F47AC0809106028E7F33
|
||||
:101E100067C00E308CE5180709F47BC0809106027C
|
||||
:101E20008B7F0F301C4508F45BC0809106028F7ECB
|
||||
:101E300057C00C3F2CE5120709F459C030F50331A7
|
||||
:101E40008CE5180709F471C078F401312CE512070C
|
||||
:101E500009F467C002311C4509F04BCF0E94DF0A2C
|
||||
:101E6000809106028F773CC005318CE5180709F494
|
||||
:101E700064C008F478C08091070281600B3F1C4564
|
||||
:101E800009F037CF8093070234CF01153DE51307E2
|
||||
:101E900009F44FC088F4809107028D7F0E3F9CE5C6
|
||||
:101EA000190781F3809107028E7F0F3F1C4550F385
|
||||
:101EB000809107028360E6CF02303DE5130709F405
|
||||
:101EC0005BC008F446C060E003301D4509F011CF47
|
||||
:101ED0008EE090E00E9404150CCF80910602816094
|
||||
:101EE0008093060206CF809106028460F9CF80912C
|
||||
:101EF00007028260C7CF809106028064F1CF0E9402
|
||||
:101F0000DF0A809106028068EBCF809106028D7F08
|
||||
:101F1000E7CF80910602877FE3CF809106028F7D15
|
||||
:101F2000DFCF809106028F7BDBCF80910602837F1B
|
||||
:101F3000D7CF809107028C7FA5CF8091060282FBCC
|
||||
:101F4000992790F921E0922790FB82F990FB83F981
|
||||
:101F5000C7CF80910702982F909591708E7F892B23
|
||||
:101F600090FB81F98FCF0E94DF0A90910602892FA2
|
||||
:101F700097FB87F98058B4CF61E0AACF06312CE5F2
|
||||
:101F8000120709F0D2C1809192018A7A91E009F496
|
||||
:101F900090E090936C01811106C089E20E94A70530
|
||||
:101FA0000E9458050CCE85E3F9CF85E3BBC10E94A2
|
||||
:101FB000DF0A3FEF84E39CE0315080409040E1F73E
|
||||
:101FC00000C0000081E08093E00080E28093D800B0
|
||||
:101FD0001092C9008FE19EE40197F1F700C0000064
|
||||
:101FE00087E090EBDC018093410290934202A09342
|
||||
:101FF0004302B093440288E19CE00FB6F894A895A0
|
||||
:10200000809360000FBE90936000FFCF0E94740A1F
|
||||
:10201000D6CD812F902F0E943A06F82E9EC11830FF
|
||||
:1020200009F47DC0193009F0BBC19F70C12CD12CBF
|
||||
:102030007601C39404C0CC0CDD1CEE1CFF1C9A95E9
|
||||
:10204000D2F7882309F43FC16091970170919801FC
|
||||
:102050008091990190919A016C297D298E299F295F
|
||||
:102060000E949B06802F0E94BA069AC1292F2F70CA
|
||||
:10207000F22E907F19F0F294A0EFFA228823C9F093
|
||||
:10208000FF2069F080E2800F883010F001110BC052
|
||||
:1020900080919201F82AF09292010E945805802FB7
|
||||
:1020A0000E94A3087DC180919101F82AF0929101CC
|
||||
:1020B000F4CF802F0E94C406FF2009F471C1F09470
|
||||
:1020C000005E083010F0E11008C080919201F82203
|
||||
:1020D000F09292010E94580563C180919101F8220B
|
||||
:1020E000F0929101F7CF292F26952695237051F074
|
||||
:1020F000213009F055C1882379F0802F93700E9418
|
||||
:10210000A9034EC1882329F0802F93700E94BF033A
|
||||
:1021100047C190E080E0FACF90E080E0F0CF292F37
|
||||
:10212000237009F065C081113BC1802F829586958F
|
||||
:102130008770880F880F402F4F7050E070E060E08C
|
||||
:10214000082E04C0440F551F661F771F0A94D2F74C
|
||||
:10215000C12CD12C760104FF10C0FFE0CF2ED12C72
|
||||
:10216000E12CF12C04C0CC0CDD1CEE1CFF1C8A956C
|
||||
:10217000D2F7C094D094E094F0949695969593708D
|
||||
:10218000923019F1D8F48090930190909401A0902E
|
||||
:102190009501B0909601913069F04C295D296E2926
|
||||
:1021A0007F29CB01BA01682179218A219B210E94D4
|
||||
:1021B000A506F6C0482959296A297B29CB01BA010D
|
||||
:1021C0006C297D298E299F29F2CF4C295D296E2902
|
||||
:1021D0007F29C0909301D0909401E0909501F090F8
|
||||
:1021E0009601CB01BA016C257D258E259F25DFCF79
|
||||
:1021F0002695882311F0292F2170222309F4D0C0BD
|
||||
:10220000802F829586958770880F880F402F4F709A
|
||||
:1022100050E070E060E0082E04C0440F551F661FB8
|
||||
:10222000771F0A94D2F7C12CD12C760104FF10C07D
|
||||
:10223000EFE0CE2ED12CE12CF12C04C0CC0CDD1C17
|
||||
:10224000EE1CFF1C8A95D2F7C094D094E094F094D1
|
||||
:10225000969596959370923019F1D8F480909701E5
|
||||
:1022600090909801A0909901B0909A01913069F0F6
|
||||
:102270004C295D296E297F29CB01BA01682179217A
|
||||
:102280008A219B210E949B068BC0482959296A29D3
|
||||
:102290007B29CB01BA016C297D298E299F29F2CF98
|
||||
:1022A0004C295D296E297F29C0909701D090980113
|
||||
:1022B000E0909901F0909A01CB01BA016C257D253F
|
||||
:1022C0008E259F25DFCF802F0E94AF06C701B60164
|
||||
:1022D0006095709580959095C0909701D0909801E9
|
||||
:1022E000E0909901F0909A016C217D218E219F212F
|
||||
:1022F000C9CF85E0FE013696DE01119601900D9260
|
||||
:102300008A95E1F789819A8161116CCC0E943A0625
|
||||
:10231000F82E70CC06311C4589F480916C01811136
|
||||
:1023200044CE89E20E947C053BCE01152CE51207C4
|
||||
:1023300009F43DCE0F3D1C4509F468CE1E810F8186
|
||||
:10234000882309F466CE812F902F0E94DC05F82E99
|
||||
:10235000682F812F902F0E946106E02FF0E09EE011
|
||||
:10236000F99EE00DF11D1124EE0FFF1FEE0FFF1F70
|
||||
:10237000E10FF11DEE0FFF1FE455FF4F8591949182
|
||||
:102380000E94E303082FE82E8885192F12951F70ED
|
||||
:10239000143009F4A8CE08F042CE123008F466CE0C
|
||||
:1023A000212F2850330B2230310510F40E94D50321
|
||||
:1023B00085E0FE013696DE01119601900D928A9518
|
||||
:1023C000E1F789819A810E943A06EA81F0E03EE0D5
|
||||
:1023D000839FE00DF11D1124CF01880F991F880FF5
|
||||
:1023E000991FE981E80FF92FF11DEE0FFF1FE4554A
|
||||
:1023F000FF4F85919491E3CB1F920F920FB60F92EE
|
||||
:1024000011242F933F934F935F936F937F938F93F9
|
||||
:102410009F93AF93BF93CF93DF93EF93FF93D091AD
|
||||
:10242000E900DF708091EC00C82FC17080FDC0E82A
|
||||
:102430001092E9008091F000877F8093F0007894FB
|
||||
:102440000E94F60A1092E9008091F0008860809363
|
||||
:10245000F000CD2BCF70C093E900FF91EF91DF9199
|
||||
:10246000CF91BF91AF919F918F917F916F915F912C
|
||||
:102470004F913F912F910F900FBE0F901F90189585
|
||||
:102480001F920F920FB60F9211242F933F934F93E9
|
||||
:102490005F936F937F938F939F93AF93BF93EF93CC
|
||||
:1024A000FF938091E10082FF09C08091E20082FFEA
|
||||
:1024B00005C08091E1008B7F8093E1008091DA007C
|
||||
:1024C00080FF24C08091D80080FF20C08091DA0076
|
||||
:1024D0008E7F8093DA008091D90080FF9BC080E1DD
|
||||
:1024E00089BD82E189BD09B400FEFDCF81E0809302
|
||||
:1024F000300280910B02811109C00E9486010E9466
|
||||
:1025000051028091E20084608093E2008091E100BA
|
||||
:1025100080FF17C08091E20080FF13C08091E2002D
|
||||
:102520008E7F8093E2008091E20080618093E200E0
|
||||
:102530008091D80080628093D80019BC85E0809398
|
||||
:1025400030028091E10084FF29C08091E20084FF85
|
||||
:1025500025C080E189BD82E189BD89B5982F917040
|
||||
:1025600080FFFBCF8091D8008F7D8093D800809131
|
||||
:10257000E1008F7E8093E1008091E2008F7E809366
|
||||
:10258000E2008091E20081608093E200809131025C
|
||||
:10259000882309F445C084E0809330028091E100F3
|
||||
:1025A00083FF27C08091E20083FF23C08091E10078
|
||||
:1025B000877F8093E10082E08093300210923102A5
|
||||
:1025C0008091E1008E7F8093E1008091E2008E7F18
|
||||
:1025D0008093E2008091E20080618093E20042E01B
|
||||
:1025E00060E080E00E941F028091F000886080938C
|
||||
:1025F000F000FF91EF91BF91AF919F918F917F91EB
|
||||
:102600006F915F914F913F912F910F900FBE0F905F
|
||||
:102610001F90189519BC1092300210920B0276CFC1
|
||||
:102620008091E30087FD93E090933002B7CF7894D8
|
||||
:102630001F921FB61F9211248F939F93AF93BF9346
|
||||
:1026400080913D0290913E02A0913F02B0914002E4
|
||||
:102650000196A11DB11D80933D0290933E02A0936F
|
||||
:102660003F02B0934002BF91AF919F918F911F9015
|
||||
:102670001FBE1F9018951F921FB61F9211248F9393
|
||||
:102680009F93AF93BF9380910502811113C08091F6
|
||||
:102690003D0290913E02A0913F02B09140024196CE
|
||||
:1026A000A11DB11D80933D0290933E02A0933F0275
|
||||
:1026B000B0934002BF91AF919F918F911F901FBE29
|
||||
:1026C0001F901895CDB7DEB72A970FB6F894DEBFE6
|
||||
:1026D0000FBECDBF84B7877F84BF0FB6F894A8958F
|
||||
:1026E00080916000886180936000109260000FBE4E
|
||||
:1026F00080E890E00FB6F8948093610090936100B9
|
||||
:102700000FBE85B7806885BF85B7806885BF81EEBD
|
||||
:1027100093E090934901809348010E9486010E94B2
|
||||
:1027200051028091E20084608093E200789480916D
|
||||
:1027300030028823A1F01091E9001F709091EC0005
|
||||
:10274000892F817090FD80E8182B1092E90080910C
|
||||
:10275000E80083FD0E94F60A1F701093E90082E0F2
|
||||
:1027600084BD93E095BD9AEF97BD80936E000E9463
|
||||
:10277000C20990E090931401809313010E946907AD
|
||||
:102780000E94780783ED91E0EBE9F1E041EE51E042
|
||||
:10279000DA011D92AD01DC011D92CD011082118282
|
||||
:1027A000128213823496B1E04F3E5B0789F790E0C6
|
||||
:1027B00080E00E94FE14893E9E4F11F00E94740A30
|
||||
:1027C00082E090E00E94F6148093F0010E94660A75
|
||||
:1027D000909307028093060283E090E00E94F61433
|
||||
:1027E000682F70E090E080E00E94A5063F988AB1D3
|
||||
:1027F0008F708AB96E98479A8BB1806F8BB9769A31
|
||||
:10280000609106026068609306021091070284E0FE
|
||||
:1028100090E00E940415612F82E290E00E9404156E
|
||||
:1028200089E091E0909302028093010288E1C82E32
|
||||
:10283000D12C90E4992E20E1A22E32E1B32EEE2489
|
||||
:10284000EA9480913002853049F4809130028530DD
|
||||
:1028500009F44DC00E94DF0A0E94D5030E942D0A90
|
||||
:10286000882359F08FB7F89440913D0250913E0271
|
||||
:1028700060913F02709140028FBFE1EFF1E0A1EE65
|
||||
:10288000B1E010E000E0302F8D919191981709F49C
|
||||
:102890007BC0292F282790E0FF24F3944F2D42235B
|
||||
:1028A00009F46DC099833A838F2191E009F490E097
|
||||
:1028B0009B830E9414038160782F9D838C834981C0
|
||||
:1028C0005A816B818D810E94AF0DF801EF50FE4F50
|
||||
:1028D0008081F826F0820E94D5039091EF0189173C
|
||||
:1028E00009F4AFCF0E94D5038093EF01AACF809166
|
||||
:1028F0003002843009F1109205020FB6F894A895C1
|
||||
:10290000C09260000FBE9092600083B7817F8460A8
|
||||
:1029100083BF83B7816083BF7894889583B78E7FA8
|
||||
:1029200083BF0FB6F894A89580916000886180936A
|
||||
:102930006000109260000FBE80912F02882309F47E
|
||||
:1029400084CF0E94C20990E09093140180931301F8
|
||||
:102950000E9469070E947807E1EEF1E0119281E0A0
|
||||
:10296000EF3EF807D9F70E942D0AE1EEF1E08191E0
|
||||
:10297000811120C0A1E0EF3EFA07C9F766CF9F5F43
|
||||
:10298000FF0C943009F08ACF0F5F1F4F0E301105F6
|
||||
:1029900009F079CFEE82EF8218860E9414038160DD
|
||||
:1029A000782F9A8789874E815F8168858A850E9402
|
||||
:1029B000AF0D91CFA9BCB9BC09B400FEFDCF809189
|
||||
:1029C000D8008F7D8093D8008091E0008260809352
|
||||
:1029D000E0008091E00081FDFCCF0E94DF0A35CF4E
|
||||
:1029E000EE0FFF1F0590F491E02D0994F999FECFA9
|
||||
:1029F00092BD81BDF89A992780B50895A8E1B0E00D
|
||||
:102A000042E050E00C942A15262FF999FECF92BD92
|
||||
:102A100081BDF89A019700B4021639F01FBA20BDA3
|
||||
:102A20000FB6F894FA9AF99A0FBE08950396272FD5
|
||||
:102A30000E9405150E940415252F0E940515242FBC
|
||||
:102A40000C9405150196272F0E9405150C9404156A
|
||||
:102A5000DC01CB01FC01F999FECF06C0F2BDE1BD5E
|
||||
:102A6000F89A319600B40D9241505040B8F708954D
|
||||
:102A7000F894FFCFD90B010C970D010C970D340C76
|
||||
:082A8000550C970D520D5F0D7E
|
||||
:102A88000100000000000000001103630810035F4C
|
||||
:102A9800085B08200001818283E200E900EA00B5B2
|
||||
:102AA80000B600B700CD008301CC008A01920194E2
|
||||
:102AB800012102230224022502260227022A02B348
|
||||
:082AC80000B4006F0070000073
|
||||
:00000001FF
|
173
plover_machine_hid.py
Normal file
173
plover_machine_hid.py
Normal file
|
@ -0,0 +1,173 @@
|
|||
'''
|
||||
A plover machine plugin for supporting the Plover HID protocol.
|
||||
|
||||
This protocol is a simple HID-based protocol that sends the current state
|
||||
of the steno machine every time that state changes.
|
||||
|
||||
This gives us two things compared to using a serial protocol, first of all the
|
||||
same protocol can be used when using both USB and bluetooth, secondly we can do
|
||||
all of the logic for things like first up chord send, and repeat on the plover
|
||||
side instead of having to rewrite firmware for all of the different hobbyist
|
||||
machines.
|
||||
|
||||
The protocol is a standard HID protocol with the following HID descriptor:
|
||||
{
|
||||
0x06, 0x50, 0xff, // UsagePage (65360)
|
||||
0x0a, 0x56, 0x4c, // Usage (19542)
|
||||
0xa1, 0x02, // Collection (Logical)
|
||||
0x85, 0x01, // ReportID (1)
|
||||
0x25, 0x01, // LogicalMaximum (1)
|
||||
0x75, 0x01, // ReportSize (1)
|
||||
0x95, 0x40, // ReportCount (64)
|
||||
0x05, 0x09, // UsagePage (button)
|
||||
0x19, 0x00, // UsageMinimum (Button(0))
|
||||
0x29, 0x3f, // UsageMaximum (Button(63))
|
||||
0x81, 0x02, // Input (Variable)
|
||||
0x85, 0x02, // ReportID (2)
|
||||
0x26, 0xff, 0x00, // LogicalMaximum (255)
|
||||
0x75, 0x08, // ReportSize (8)
|
||||
0x19, 0x00, // UsageMinimum (Button(0))
|
||||
0x29, 0x3f, // UsageMaximum (Button(63))
|
||||
0x81, 0x02, // Input (Variable)
|
||||
0xc0, // EndCollection
|
||||
}
|
||||
|
||||
The descriptor is generated by the HID Report Descriptor Compiler (https://github.com/nipo/hrdc) from
|
||||
the following python description:
|
||||
```
|
||||
stenomachine = Collection(Collection.Logical, Usage('vendor-defined', 0xFF504C56),
|
||||
Report(1, *(Value(Value.Input, button.Button(x), 1, logicalMin=0, logicalMax=1) for x in range(64))),
|
||||
Report(2, *(Value(Value.Input, button.Button(x), 8, logicalMin=0, logicalMax=255) for x in range(64))))
|
||||
```
|
||||
|
||||
The usage page is a vendor-defined usage page (starts with 0xFF), the following
|
||||
bytes of the usage page and usage are set to the ascii values of the text
|
||||
string "STN".
|
||||
|
||||
This hid-descriptor defines two types of reports, the first one being what we
|
||||
call the simple report, which defines 64 buttons with one bit for each button,
|
||||
a one signifying that the button is pressed and a zero that the button in that
|
||||
position isn't pressed.
|
||||
|
||||
The second kind of report is what we call a complicated report, that one uses
|
||||
one byte for each button, and allows for things such as sending lever pressure
|
||||
information, a zero signifying no pressure on the lever, and 255 signifying
|
||||
maximum pressure.
|
||||
|
||||
The order of the buttons (from left to right) is the same as in `KEYS_LAYOUT`.
|
||||
Most buttons have the same names as in GeminiPR, except for the extra buttons
|
||||
which are called X1-X26.
|
||||
'''
|
||||
from plover.machine.base import ThreadedStenotypeBase
|
||||
|
||||
from bitstring import BitString
|
||||
import hid
|
||||
|
||||
USAGE_PAGE: int = 0xFF50
|
||||
USAGE: int = 0x4C56
|
||||
|
||||
N_BUTTONS: int = 64
|
||||
|
||||
# A simple report contains the report id 1 and one bit
|
||||
# for each of the 64 buttons in the report.
|
||||
SIMPLE_REPORT_TYPE: int = 0x01
|
||||
SIMPLE_REPORT_LEN: int = 1 + N_BUTTONS // 8
|
||||
|
||||
# A complicated report contains the report id 2 and one byte
|
||||
# for each of the 64 buttons in the report.
|
||||
COMPLICATED_REPORT_TYPE = 0x02
|
||||
COMPLICATED_REPORT_LEN = 1 + N_BUTTONS
|
||||
|
||||
class InvalidReport(Exception):
|
||||
pass
|
||||
|
||||
class HidMachine(ThreadedStenotypeBase):
|
||||
KEYS_LAYOUT: str = """
|
||||
#1 #2 #3 #4 #5 #6 #7 #8 #9 #A #B #C
|
||||
X1 S1- T- P- H- *1 *3 -F -P -L -T -D
|
||||
X2 S2- K- W- R- *2 *4 -R -B -G -S -Z
|
||||
X3 A- O- -E -U X4
|
||||
|
||||
X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
|
||||
X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26
|
||||
"""
|
||||
STENO_KEY_MAP: [str] = KEYS_LAYOUT.split()
|
||||
|
||||
def __init__(self, params):
|
||||
super().__init__()
|
||||
self._params = params
|
||||
self._hid = None
|
||||
# FIXME: this should be configurable by the end user
|
||||
self._tresholds = [0.5]*N_BUTTONS
|
||||
|
||||
def _parse(self, report):
|
||||
if report[0] == SIMPLE_REPORT_TYPE and len(report) == SIMPLE_REPORT_LEN:
|
||||
return BitString(report[1:])
|
||||
elif (
|
||||
report[0] == COMPLICATED_REPORT_TYPE
|
||||
and len(report) == COMPLICATED_REPORT_LEN
|
||||
):
|
||||
# Scale the key pressure information to a float between 0 and 1 and
|
||||
# compare it to the tresholds to see if it should count as a key
|
||||
# press or not.
|
||||
return BitString(
|
||||
[
|
||||
pressure / 256 >= treshold
|
||||
for (pressure, threshold) in zip(report[1:], self._tresholds)
|
||||
]
|
||||
)
|
||||
else:
|
||||
raise InvalidReport()
|
||||
|
||||
def run(self):
|
||||
self._ready()
|
||||
keystate = BitString(N_BUTTONS)
|
||||
while not self.finished.wait(0):
|
||||
try:
|
||||
report = self._hid.read(65536, timeout=1000)
|
||||
except hid.HIDException:
|
||||
self._error()
|
||||
return
|
||||
if not report:
|
||||
continue
|
||||
report = self._parse(report)
|
||||
keystate |= report
|
||||
if not report:
|
||||
steno_actions = self.keymap.keys_to_actions(
|
||||
[self.STENO_KEY_MAP[i] for (i, x) in enumerate(keystate) if x]
|
||||
)
|
||||
if steno_actions:
|
||||
self._notify(steno_actions)
|
||||
keystate = BitString(N_BUTTONS)
|
||||
|
||||
def start_capture(self):
|
||||
self._initializing()
|
||||
# Enumerate all hid devices on the machine and if we find one with our
|
||||
# usage page and usage we try to connect to it.
|
||||
try:
|
||||
devices = [
|
||||
device["path"]
|
||||
for device in hid.enumerate()
|
||||
if device["usage_page"] == USAGE_PAGE and device["usage"] == USAGE
|
||||
]
|
||||
if not devices:
|
||||
self._error()
|
||||
return
|
||||
# FIXME: if multiple compatible devices are found we should either
|
||||
# let the end user configure which one they want, or support reading
|
||||
# from all connected plover hid devices at the same time.
|
||||
self._hid = hid.Device(path=devices[0])
|
||||
except hid.HIDException:
|
||||
self._error()
|
||||
return
|
||||
self.start()
|
||||
|
||||
def stop_capture(self):
|
||||
if self._hid:
|
||||
self._hid.close()
|
||||
self._hid = None
|
||||
self._stopped()
|
||||
|
||||
@classmethod
|
||||
def get_option_info(cls):
|
||||
return {}
|
18
setup.cfg
Normal file
18
setup.cfg
Normal file
|
@ -0,0 +1,18 @@
|
|||
[metadata]
|
||||
name = plover-machine-hid
|
||||
keywords = plover plover_plugin
|
||||
|
||||
[options]
|
||||
zip_safe = True
|
||||
setup_requires =
|
||||
setuptools>=30.3.0
|
||||
install_requires =
|
||||
plover>=4.0.0.dev10
|
||||
hid>=1.0.4
|
||||
bitstring>=3.1.9
|
||||
py_modules =
|
||||
plover_machine_hid
|
||||
|
||||
[options.entry_points]
|
||||
plover.machine =
|
||||
Plover HID = plover_machine_hid:HidMachine
|
3
setup.py
Normal file
3
setup.py
Normal file
|
@ -0,0 +1,3 @@
|
|||
from setuptools import setup
|
||||
|
||||
setup()
|
Loading…
Reference in a new issue